Search in sources :

Example 1 with SmtDeterminismAnswerElement

use of org.batfish.symbolic.answers.SmtDeterminismAnswerElement in project batfish by batfish.

the class PropertyChecker method checkDeterminism.

/*
   * Check if there exist multiple stable solutions to the network.
   * If so, reports the forwarding differences between the two cases.
   */
public AnswerElement checkDeterminism(HeaderQuestion q) {
    Graph graph = new Graph(_batfish);
    Encoder enc1 = new Encoder(_settings, graph, q);
    Encoder enc2 = new Encoder(enc1, graph, q);
    enc1.computeEncoding();
    enc2.computeEncoding();
    addEnvironmentConstraints(enc1, q.getBaseEnvironmentType());
    BoolExpr relatedFailures = relateFailures(enc1, enc2);
    BoolExpr relatedEnvs = relateEnvironments(enc1, enc2);
    BoolExpr relatedPkts = relatePackets(enc1, enc2);
    BoolExpr related = enc1.mkAnd(relatedFailures, relatedEnvs, relatedPkts);
    BoolExpr required = enc1.mkTrue();
    for (GraphEdge ge : graph.getAllRealEdges()) {
        SymbolicDecisions d1 = enc1.getMainSlice().getSymbolicDecisions();
        SymbolicDecisions d2 = enc2.getMainSlice().getSymbolicDecisions();
        BoolExpr dataFwd1 = d1.getDataForwarding().get(ge.getRouter(), ge);
        BoolExpr dataFwd2 = d2.getDataForwarding().get(ge.getRouter(), ge);
        assert dataFwd1 != null;
        assert dataFwd2 != null;
        required = enc1.mkAnd(required, enc1.mkEq(dataFwd1, dataFwd2));
    }
    enc1.add(related);
    enc1.add(enc1.mkNot(required));
    Tuple<VerificationResult, Model> tup = enc1.verify();
    VerificationResult res = tup.getFirst();
    Model model = tup.getSecond();
    SortedSet<String> case1 = null;
    SortedSet<String> case2 = null;
    Flow flow = null;
    CounterExample ce = new CounterExample(model);
    if (!res.isVerified()) {
        case1 = new TreeSet<>();
        case2 = new TreeSet<>();
        flow = ce.buildFlow(enc1.getMainSlice().getSymbolicPacket(), "(none)");
        for (GraphEdge ge : graph.getAllRealEdges()) {
            SymbolicDecisions d1 = enc1.getMainSlice().getSymbolicDecisions();
            SymbolicDecisions d2 = enc2.getMainSlice().getSymbolicDecisions();
            BoolExpr dataFwd1 = d1.getDataForwarding().get(ge.getRouter(), ge);
            BoolExpr dataFwd2 = d2.getDataForwarding().get(ge.getRouter(), ge);
            assert dataFwd1 != null;
            assert dataFwd2 != null;
            boolean b1 = ce.boolVal(dataFwd1);
            boolean b2 = ce.boolVal(dataFwd2);
            if (b1 != b2) {
                if (b1) {
                    String route = ce.buildRoute(enc1.getMainSlice(), ge);
                    String msg = ge + " -- " + route;
                    case1.add(msg);
                }
                if (b2) {
                    String route = ce.buildRoute(enc2.getMainSlice(), ge);
                    String msg = ge + " -- " + route;
                    case2.add(msg);
                }
            }
        }
    }
    // Ensure canonical order
    boolean less = (case1 == null || (case1.first().compareTo(case2.first()) < 0));
    if (less) {
        return new SmtDeterminismAnswerElement(flow, case1, case2);
    } else {
        return new SmtDeterminismAnswerElement(flow, case2, case1);
    }
}
Also used : BoolExpr(com.microsoft.z3.BoolExpr) Flow(org.batfish.datamodel.Flow) Graph(org.batfish.symbolic.Graph) Model(com.microsoft.z3.Model) SmtDeterminismAnswerElement(org.batfish.symbolic.answers.SmtDeterminismAnswerElement) GraphEdge(org.batfish.symbolic.GraphEdge)

Aggregations

BoolExpr (com.microsoft.z3.BoolExpr)1 Model (com.microsoft.z3.Model)1 Flow (org.batfish.datamodel.Flow)1 Graph (org.batfish.symbolic.Graph)1 GraphEdge (org.batfish.symbolic.GraphEdge)1 SmtDeterminismAnswerElement (org.batfish.symbolic.answers.SmtDeterminismAnswerElement)1