use of com.microsoft.z3.Expr in project Dat3M by hernanponcedeleon.
the class Porthos method main.
public static void main(String[] args) throws Z3Exception, IOException {
List<String> MCMs = Arrays.asList("sc", "tso", "pso", "rmo", "alpha", "power", "arm");
Options options = new Options();
Option sourceOpt = new Option("s", "source", true, "source MCM");
sourceOpt.setRequired(true);
options.addOption(sourceOpt);
Option targetOpt = new Option("t", "target", true, "target MCM");
targetOpt.setRequired(true);
options.addOption(targetOpt);
Option inputOpt = new Option("i", "input", true, "input file path");
inputOpt.setRequired(true);
options.addOption(inputOpt);
options.addOption("state", false, "PORTHOS performs state portability");
options.addOption(Option.builder("draw").hasArg().desc("If a buf is found, it outputs a graph \\path_to_file.dot").build());
options.addOption(Option.builder("rels").hasArgs().desc("Relations to be drawn in the graph").build());
options.addOption(Option.builder("unroll").hasArg().desc("Unrolling steps").build());
CommandLineParser parserCmd = new DefaultParser();
HelpFormatter formatter = new HelpFormatter();
CommandLine cmd;
try {
cmd = parserCmd.parse(options, args);
} catch (ParseException e) {
System.out.println(e.getMessage());
formatter.printHelp("PORTHOS", options);
System.exit(1);
return;
}
String source = cmd.getOptionValue("source");
if (!MCMs.stream().anyMatch(mcms -> mcms.trim().equals(source))) {
System.out.println("Unrecognized source");
System.exit(0);
return;
}
String target = cmd.getOptionValue("target");
if (!MCMs.stream().anyMatch(mcms -> mcms.trim().equals(target))) {
System.out.println("Unrecognized target");
System.exit(0);
return;
}
String inputFilePath = cmd.getOptionValue("input");
if (!inputFilePath.endsWith("pts") && !inputFilePath.endsWith("litmus")) {
System.out.println("Unrecognized program format");
System.exit(0);
return;
}
File file = new File(inputFilePath);
boolean statePortability = cmd.hasOption("state");
String[] rels = new String[100];
if (cmd.hasOption("rels")) {
rels = cmd.getOptionValues("rels");
}
String program = FileUtils.readFileToString(file, "UTF-8");
ANTLRInputStream input = new ANTLRInputStream(program);
Program p = new Program(inputFilePath);
if (inputFilePath.endsWith("litmus")) {
LitmusLexer lexer = new LitmusLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
LitmusParser parser = new LitmusParser(tokens);
p = parser.program(inputFilePath).p;
}
if (inputFilePath.endsWith("pts")) {
PorthosLexer lexer = new PorthosLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
PorthosParser parser = new PorthosParser(tokens);
p = parser.program(inputFilePath).p;
}
int steps = 1;
if (cmd.hasOption("unroll")) {
steps = Integer.parseInt(cmd.getOptionValue("unroll"));
}
p.initialize(steps);
Program pSource = p.clone();
Program pTarget = p.clone();
pSource.compile(source, false, true);
Integer startEId = Collections.max(pSource.getEvents().stream().filter(e -> e instanceof Init).map(e -> e.getEId()).collect(Collectors.toSet())) + 1;
pTarget.compile(target, false, true, startEId);
Context ctx = new Context();
ctx.setPrintMode(Z3_ast_print_mode.Z3_PRINT_SMTLIB_FULL);
Solver s = ctx.mkSolver();
Solver s2 = ctx.mkSolver();
BoolExpr sourceDF = pSource.encodeDF(ctx);
BoolExpr sourceCF = pSource.encodeCF(ctx);
BoolExpr sourceDF_RF = pSource.encodeDF_RF(ctx);
BoolExpr sourceDomain = Domain.encode(pSource, ctx);
BoolExpr sourceMM = pSource.encodeMM(ctx, source);
s.add(pTarget.encodeDF(ctx));
s.add(pTarget.encodeCF(ctx));
s.add(pTarget.encodeDF_RF(ctx));
s.add(Domain.encode(pTarget, ctx));
s.add(pTarget.encodeMM(ctx, target));
s.add(pTarget.encodeConsistent(ctx, target));
s.add(sourceDF);
s.add(sourceCF);
s.add(sourceDF_RF);
s.add(sourceDomain);
s.add(sourceMM);
s.add(pSource.encodeInconsistent(ctx, source));
s.add(encodeCommonExecutions(pTarget, pSource, ctx));
s2.add(sourceDF);
s2.add(sourceCF);
s2.add(sourceDF_RF);
s2.add(sourceDomain);
s2.add(sourceMM);
s2.add(pSource.encodeConsistent(ctx, source));
if (!statePortability) {
if (s.check() == Status.SATISFIABLE) {
System.out.println("The program is not portable");
// System.out.println(" 0");
if (cmd.hasOption("draw")) {
String outputPath = cmd.getOptionValue("draw");
Utils.drawGraph(p, pSource, pTarget, ctx, s.getModel(), outputPath, rels);
}
return;
} else {
System.out.println("The program is portable");
// System.out.println(" 1");
return;
}
}
int iterations = 0;
Status lastCheck = Status.SATISFIABLE;
Set<Expr> visited = new HashSet<Expr>();
while (lastCheck == Status.SATISFIABLE) {
lastCheck = s.check();
if (lastCheck == Status.SATISFIABLE) {
iterations = iterations + 1;
Model model = s.getModel();
s2.push();
BoolExpr reachedState = encodeReachedState(pTarget, model, ctx);
visited.add(reachedState);
assert (iterations == visited.size());
s2.add(reachedState);
if (s2.check() == Status.UNSATISFIABLE) {
System.out.println("The program is not state-portable");
System.out.println("Iterations: " + iterations);
// System.out.println(" 0");
return;
} else {
s2.pop();
s.add(ctx.mkNot(reachedState));
}
} else {
System.out.println("The program is state-portable");
System.out.println("Iterations: " + iterations);
// System.out.println(" 1");
return;
}
}
}
use of com.microsoft.z3.Expr in project batfish by batfish.
the class Encoder method environmentBlockingClause.
/*
* Generate a blocking clause for the encoding that says that one
* of the environments that was true before must now be false.
*/
private BoolExpr environmentBlockingClause(Model m) {
BoolExpr acc1 = mkFalse();
BoolExpr acc2 = mkTrue();
// Disable an environment edge if possible
Map<LogicalEdge, SymbolicRoute> map = getMainSlice().getLogicalGraph().getEnvironmentVars();
for (Map.Entry<LogicalEdge, SymbolicRoute> entry : map.entrySet()) {
SymbolicRoute record = entry.getValue();
BoolExpr per = record.getPermitted();
Expr x = m.evaluate(per, false);
if (x.toString().equals("true")) {
acc1 = mkOr(acc1, mkNot(per));
} else {
acc2 = mkAnd(acc2, mkNot(per));
}
}
// Disable a community value if possible
for (Map.Entry<LogicalEdge, SymbolicRoute> entry : map.entrySet()) {
SymbolicRoute record = entry.getValue();
for (Map.Entry<CommunityVar, BoolExpr> centry : record.getCommunities().entrySet()) {
BoolExpr comm = centry.getValue();
Expr x = m.evaluate(comm, false);
if (x.toString().equals("true")) {
acc1 = mkOr(acc1, mkNot(comm));
} else {
acc2 = mkAnd(acc2, mkNot(comm));
}
}
}
return mkAnd(acc1, acc2);
}
use of com.microsoft.z3.Expr in project batfish by batfish.
the class EncoderSlice method addExportConstraint.
/*
* Creates the transfer function to represent export filters
* between two symbolic records. The import filter depends
* heavily on the protocol.
*/
private void addExportConstraint(LogicalEdge e, SymbolicRoute varsOther, @Nullable SymbolicRoute ospfRedistribVars, @Nullable SymbolicRoute overallBest, Configuration conf, Protocol proto, GraphEdge ge, String router, boolean usedExport, Set<Prefix> originations) {
SymbolicRoute vars = e.getSymbolicRecord();
Interface iface = ge.getStart();
ArithExpr failed = getSymbolicFailures().getFailedVariable(e.getEdge());
assert (failed != null);
BoolExpr notFailed = mkEq(failed, mkInt(0));
// only add constraints once when using a single copy of export variables
if (!_optimizations.getSliceCanKeepSingleExportVar().get(router).get(proto) || !usedExport) {
if (proto.isConnected()) {
BoolExpr val = mkNot(vars.getPermitted());
add(val);
}
if (proto.isStatic()) {
BoolExpr val = mkNot(vars.getPermitted());
add(val);
}
if (proto.isOspf() || proto.isBgp()) {
// BGP cost based on export
Integer cost = proto.isBgp() ? addedCost(proto, ge) : 0;
BoolExpr val = mkNot(vars.getPermitted());
BoolExpr active = interfaceActive(iface, proto);
// Apply BGP export policy and cost based on peer type
// (1) EBGP --> ALL
// (2) CLIENT --> ALL
// (3) NONCLIENT --> EBGP, CLIENT
boolean isNonClientEdge = proto.isBgp() && getGraph().peerType(ge) != Graph.BgpSendType.TO_EBGP;
boolean isClientEdge = proto.isBgp() && getGraph().peerType(ge) == Graph.BgpSendType.TO_CLIENT;
boolean isInternalExport = varsOther.isBest() && _optimizations.getNeedBgpInternal().contains(router);
BoolExpr doExport = mkTrue();
if (isInternalExport && proto.isBgp() && isNonClientEdge) {
if (isClientEdge) {
cost = 0;
} else {
// Lookup if we learned from iBGP, and if so, don't export the route
SymbolicRoute other = getBestNeighborPerProtocol(router, proto);
assert other != null;
assert other.getBgpInternal() != null;
if (other.getBgpInternal() != null) {
doExport = mkNot(other.getBgpInternal());
cost = 0;
}
}
}
BoolExpr acc;
RoutingPolicy pol = getGraph().findExportRoutingPolicy(router, proto, e.getEdge());
if (Encoder.ENABLE_DEBUGGING && pol != null) {
System.out.println("Export policy (" + _sliceName + "," + ge + "): " + pol.getName());
}
// We have to wrap this with the right thing for some reason
List<Statement> statements;
Statements.StaticStatement s1 = new Statements.StaticStatement(Statements.ExitAccept);
Statements.StaticStatement s2 = new Statements.StaticStatement(Statements.ExitReject);
if (proto.isOspf()) {
If i = new If();
List<Statement> stmts = (pol == null ? Collections.singletonList(s2) : pol.getStatements());
i.setTrueStatements(Collections.singletonList(s1));
i.setFalseStatements(stmts);
BooleanExpr expr = new MatchProtocol(RoutingProtocol.OSPF);
i.setGuard(expr);
statements = Collections.singletonList(i);
} else {
statements = (pol == null ? Collections.singletonList(s1) : pol.getStatements());
}
TransferSSA f = new TransferSSA(this, conf, varsOther, vars, proto, statements, cost, ge, true);
acc = f.compute();
BoolExpr usable = mkAnd(active, doExport, varsOther.getPermitted(), notFailed);
// will maintain the same preference when adding to the cost.
if (ospfRedistribVars != null) {
assert overallBest != null;
f = new TransferSSA(this, conf, overallBest, ospfRedistribVars, proto, statements, cost, ge, true);
BoolExpr acc2 = f.compute();
// System.out.println("ADDING: \n" + acc2.simplify());
add(acc2);
BoolExpr usable2 = mkAnd(active, doExport, ospfRedistribVars.getPermitted(), notFailed);
BoolExpr geq = greaterOrEqual(conf, proto, ospfRedistribVars, varsOther, e);
BoolExpr isBetter = mkNot(mkAnd(ospfRedistribVars.getPermitted(), geq));
BoolExpr usesOspf = mkAnd(varsOther.getPermitted(), isBetter);
BoolExpr eq = equal(conf, proto, ospfRedistribVars, vars, e, false);
BoolExpr eqPer = mkEq(ospfRedistribVars.getPermitted(), vars.getPermitted());
acc = mkIf(usesOspf, mkIf(usable, acc, val), mkIf(usable2, mkAnd(eq, eqPer), val));
} else {
acc = mkIf(usable, acc, val);
}
for (Prefix p : originations) {
// For OSPF, we need to explicitly initiate a route
if (proto.isOspf()) {
BoolExpr ifaceUp = interfaceActive(iface, proto);
BoolExpr relevantPrefix = isRelevantFor(p, _symbolicPacket.getDstIp());
BoolExpr relevant = mkAnd(ifaceUp, relevantPrefix);
int adminDistance = defaultAdminDistance(conf, proto);
int prefixLength = p.getPrefixLength();
BoolExpr per = vars.getPermitted();
BoolExpr lp = safeEq(vars.getLocalPref(), mkInt(0));
BoolExpr ad = safeEq(vars.getAdminDist(), mkInt(adminDistance));
BoolExpr met = safeEq(vars.getMetric(), mkInt(cost));
BoolExpr med = safeEq(vars.getMed(), mkInt(100));
BoolExpr len = safeEq(vars.getPrefixLength(), mkInt(prefixLength));
BoolExpr type = safeEqEnum(vars.getOspfType(), OspfType.O);
BoolExpr area = safeEqEnum(vars.getOspfArea(), iface.getOspfAreaName());
BoolExpr internal = safeEq(vars.getBgpInternal(), mkFalse());
BoolExpr igpMet = safeEq(vars.getIgpMetric(), mkInt(0));
BoolExpr comms = mkTrue();
for (Map.Entry<CommunityVar, BoolExpr> entry : vars.getCommunities().entrySet()) {
comms = mkAnd(comms, mkNot(entry.getValue()));
}
BoolExpr values = mkAnd(per, lp, ad, met, med, len, type, area, internal, igpMet, comms);
// Don't originate OSPF route when there is a better redistributed route
if (ospfRedistribVars != null) {
BoolExpr betterLen = mkGt(ospfRedistribVars.getPrefixLength(), mkInt(prefixLength));
BoolExpr equalLen = mkEq(ospfRedistribVars.getPrefixLength(), mkInt(prefixLength));
BoolExpr betterAd = mkLt(ospfRedistribVars.getAdminDist(), mkInt(110));
BoolExpr better = mkOr(betterLen, mkAnd(equalLen, betterAd));
BoolExpr betterRedistributed = mkAnd(ospfRedistribVars.getPermitted(), better);
relevant = mkAnd(relevant, mkNot(betterRedistributed));
}
acc = mkIf(relevant, values, acc);
}
}
add(acc);
if (Encoder.ENABLE_DEBUGGING) {
System.out.println("EXPORT: " + router + " " + varsOther.getName() + " " + ge);
System.out.println(acc.simplify());
System.out.println("\n\n");
}
}
}
}
use of com.microsoft.z3.Expr in project batfish by batfish.
the class PropertyAdder method allEqual.
static BoolExpr allEqual(Context ctx, List<Expr> exprs) {
BoolExpr acc = ctx.mkBool(true);
if (exprs.size() > 1) {
for (int i = 0; i < exprs.size() - 1; i++) {
Expr x = exprs.get(i);
Expr y = exprs.get(i + 1);
acc = ctx.mkAnd(acc, ctx.mkEq(x, y));
}
}
return acc;
}
use of com.microsoft.z3.Expr in project batfish by batfish.
the class CounterExample method buildEnvRoutingTable.
SortedSet<BgpAdvertisement> buildEnvRoutingTable(Encoder enc) {
SortedSet<BgpAdvertisement> routes = new TreeSet<>();
EncoderSlice slice = enc.getMainSlice();
LogicalGraph lg = slice.getLogicalGraph();
for (Entry<LogicalEdge, SymbolicRoute> entry : lg.getEnvironmentVars().entrySet()) {
LogicalEdge lge = entry.getKey();
SymbolicRoute record = entry.getValue();
// If there is an external advertisement
if (boolVal(record.getPermitted())) {
// If we actually use it
GraphEdge ge = lge.getEdge();
String router = ge.getRouter();
SymbolicDecisions decisions = slice.getSymbolicDecisions();
BoolExpr ctrFwd = decisions.getControlForwarding().get(router, ge);
assert ctrFwd != null;
if (boolVal(ctrFwd)) {
SymbolicRoute r = decisions.getBestNeighbor().get(router);
SymbolicPacket pkt = slice.getSymbolicPacket();
Flow f = buildFlow(pkt, router);
Prefix pfx = buildPrefix(r, f);
int pathLength = intVal(r.getMetric());
// Create dummy information
BgpNeighbor n = slice.getGraph().getEbgpNeighbors().get(lge.getEdge());
String srcNode = "as" + n.getRemoteAs();
Ip zeroIp = new Ip(0);
Ip dstIp = n.getLocalIp();
// Recover AS path
List<SortedSet<Integer>> asSets = new ArrayList<>();
for (int i = 0; i < pathLength; i++) {
SortedSet<Integer> asSet = new TreeSet<>();
asSet.add(-1);
asSets.add(asSet);
}
AsPath path = new AsPath(asSets);
// Recover communities
SortedSet<Long> communities = new TreeSet<>();
for (Entry<CommunityVar, BoolExpr> entry2 : r.getCommunities().entrySet()) {
CommunityVar cvar = entry2.getKey();
BoolExpr expr = entry2.getValue();
if (cvar.getType() == Type.EXACT && boolVal(expr)) {
communities.add(cvar.asLong());
}
}
BgpAdvertisement adv = new BgpAdvertisement(BgpAdvertisementType.EBGP_RECEIVED, pfx, zeroIp, srcNode, "default", zeroIp, router, "default", dstIp, RoutingProtocol.BGP, OriginType.EGP, 100, 80, zeroIp, path, communities, new TreeSet<>(), 0);
routes.add(adv);
}
}
}
return routes;
}
Aggregations