Search in sources :

Example 36 with GraphEdge

use of org.batfish.symbolic.GraphEdge in project batfish by batfish.

the class PropertyChecker method failLinkSet.

private Set<GraphEdge> failLinkSet(Graph g, HeaderLocationQuestion q) {
    Pattern p1 = Pattern.compile(q.getFailNode1Regex());
    Pattern p2 = Pattern.compile(q.getFailNode2Regex());
    Pattern p3 = Pattern.compile(q.getNotFailNode1Regex());
    Pattern p4 = Pattern.compile(q.getNotFailNode2Regex());
    Set<GraphEdge> failChoices = PatternUtils.findMatchingEdges(g, p1, p2);
    Set<GraphEdge> failChoices2 = PatternUtils.findMatchingEdges(g, p2, p1);
    Set<GraphEdge> notFailChoices = PatternUtils.findMatchingEdges(g, p3, p4);
    Set<GraphEdge> notFailChoices2 = PatternUtils.findMatchingEdges(g, p4, p3);
    failChoices.addAll(failChoices2);
    failChoices.removeAll(notFailChoices);
    failChoices.removeAll(notFailChoices2);
    return failChoices;
}
Also used : Pattern(java.util.regex.Pattern) GraphEdge(org.batfish.symbolic.GraphEdge)

Example 37 with GraphEdge

use of org.batfish.symbolic.GraphEdge in project batfish by batfish.

the class PropertyChecker method checkLocalEquivalence.

/*
   * Computes whether or not two routers are equivalent.
   * To be equivalent, each router must have identical intefaces.
   *
   * We then relate the environments on each interface for each router
   * so that they are required to be equal.
   *
   * We finally check that their forwarding decisions and exported messages
   * will be equal given their equal inputs.
   */
public AnswerElement checkLocalEquivalence(Pattern n, boolean strict, boolean fullModel) {
    Graph graph = new Graph(_batfish);
    List<String> routers = PatternUtils.findMatchingNodes(graph, n, Pattern.compile(""));
    HeaderQuestion q = new HeaderQuestion();
    q.setFullModel(fullModel);
    q.setFailures(0);
    q.setBaseEnvironmentType(EnvironmentType.ANY);
    Collections.sort(routers);
    SortedMap<String, VerificationResult> result = new TreeMap<>();
    int len = routers.size();
    if (len <= 1) {
        return new SmtManyAnswerElement(new TreeMap<>());
    }
    for (int i = 0; i < len - 1; i++) {
        String r1 = routers.get(i);
        String r2 = routers.get(i + 1);
        // TODO: reorder to encode after checking if we can compare them
        // Create transfer function for router 1
        Set<String> toModel1 = new TreeSet<>();
        toModel1.add(r1);
        Graph g1 = new Graph(_batfish, null, toModel1);
        Encoder e1 = new Encoder(_settings, g1, q);
        e1.computeEncoding();
        Context ctx = e1.getCtx();
        // Create transfer function for router 2
        Set<String> toModel2 = new TreeSet<>();
        toModel2.add(r2);
        Graph g2 = new Graph(_batfish, null, toModel2);
        Encoder e2 = new Encoder(e1, g2);
        e2.computeEncoding();
        EncoderSlice slice1 = e1.getMainSlice();
        EncoderSlice slice2 = e2.getMainSlice();
        // Ensure that the two routers have the same interfaces for comparison
        Pattern p = Pattern.compile(".*");
        Pattern neg = Pattern.compile("");
        List<GraphEdge> edges1 = PatternUtils.findMatchingEdges(g1, p, neg, p, neg);
        List<GraphEdge> edges2 = PatternUtils.findMatchingEdges(g2, p, neg, p, neg);
        Set<String> ifaces1 = interfaces(edges1);
        Set<String> ifaces2 = interfaces(edges2);
        if (!(ifaces1.containsAll(ifaces2) && ifaces2.containsAll(ifaces1))) {
            String msg = String.format("Routers %s and %s have different interfaces", r1, r2);
            System.out.println(msg);
            return new SmtManyAnswerElement(new TreeMap<>());
        }
        // TODO: check running same protocols?
        Map<String, Map<Protocol, Map<String, EnumMap<EdgeType, LogicalEdge>>>> lgeMap2 = logicalEdgeMap(slice2);
        BoolExpr equalEnvs = ctx.mkBool(true);
        BoolExpr equalOutputs = ctx.mkBool(true);
        BoolExpr equalIncomingAcls = ctx.mkBool(true);
        Configuration conf1 = g1.getConfigurations().get(r1);
        Configuration conf2 = g2.getConfigurations().get(r2);
        // Set environments equal
        Set<String> communities = new HashSet<>();
        Set<SymbolicRoute> envRecords = new HashSet<>();
        for (Protocol proto1 : slice1.getProtocols().get(r1)) {
            for (ArrayList<LogicalEdge> es : slice1.getLogicalGraph().getLogicalEdges().get(r1).get(proto1)) {
                for (LogicalEdge lge1 : es) {
                    String ifaceName = lge1.getEdge().getStart().getName();
                    LogicalEdge lge2 = lgeMap2.get(r2).get(proto1).get(ifaceName).get(lge1.getEdgeType());
                    if (lge1.getEdgeType() == EdgeType.IMPORT) {
                        SymbolicRoute vars1 = slice1.getLogicalGraph().getEnvironmentVars().get(lge1);
                        SymbolicRoute vars2 = slice2.getLogicalGraph().getEnvironmentVars().get(lge2);
                        BoolExpr aclIn1 = slice1.getIncomingAcls().get(lge1.getEdge());
                        BoolExpr aclIn2 = slice2.getIncomingAcls().get(lge2.getEdge());
                        if (aclIn1 == null) {
                            aclIn1 = ctx.mkBool(true);
                        }
                        if (aclIn2 == null) {
                            aclIn2 = ctx.mkBool(true);
                        }
                        equalIncomingAcls = ctx.mkAnd(equalIncomingAcls, ctx.mkEq(aclIn1, aclIn2));
                        boolean hasEnv1 = (vars1 != null);
                        boolean hasEnv2 = (vars2 != null);
                        if (hasEnv1 && hasEnv2) {
                            BoolExpr samePermitted = ctx.mkEq(vars1.getPermitted(), vars2.getPermitted());
                            // Set communities equal
                            BoolExpr equalComms = e1.mkTrue();
                            for (Map.Entry<CommunityVar, BoolExpr> entry : vars1.getCommunities().entrySet()) {
                                CommunityVar cvar = entry.getKey();
                                BoolExpr ce1 = entry.getValue();
                                BoolExpr ce2 = vars2.getCommunities().get(cvar);
                                if (ce2 != null) {
                                    equalComms = e1.mkAnd(equalComms, e1.mkEq(ce1, ce2));
                                }
                            }
                            // Set communities belonging to one but not the other
                            // off, but give a warning of the difference
                            BoolExpr unsetComms = e1.mkTrue();
                            for (Map.Entry<CommunityVar, BoolExpr> entry : vars1.getCommunities().entrySet()) {
                                CommunityVar cvar = entry.getKey();
                                BoolExpr ce1 = entry.getValue();
                                BoolExpr ce2 = vars2.getCommunities().get(cvar);
                                if (ce2 == null) {
                                    if (!communities.contains(cvar.getValue())) {
                                        communities.add(cvar.getValue());
                                    /* String msg =
                       String.format(
                           "Warning: community %s found for router %s but not %s.",
                           cvar.getValue(), conf1.getEnvName(), conf2.getEnvName());
                      System.out.println(msg); */
                                    }
                                    unsetComms = e1.mkAnd(unsetComms, e1.mkNot(ce1));
                                }
                            }
                            // Do the same thing for communities missing from the other side
                            for (Map.Entry<CommunityVar, BoolExpr> entry : vars2.getCommunities().entrySet()) {
                                CommunityVar cvar = entry.getKey();
                                BoolExpr ce2 = entry.getValue();
                                BoolExpr ce1 = vars1.getCommunities().get(cvar);
                                if (ce1 == null) {
                                    if (!communities.contains(cvar.getValue())) {
                                        communities.add(cvar.getValue());
                                    /* String msg =
                       String.format(
                           "Warning: community %s found for router %s but not %s.",
                           cvar.getValue(), conf2.getEnvName(), conf1.getEnvName());
                      System.out.println(msg); */
                                    }
                                    unsetComms = e1.mkAnd(unsetComms, e1.mkNot(ce2));
                                }
                            }
                            envRecords.add(vars1);
                            BoolExpr equalVars = slice1.equal(conf1, proto1, vars1, vars2, lge1, true);
                            equalEnvs = ctx.mkAnd(equalEnvs, unsetComms, samePermitted, equalVars, equalComms);
                        } else if (hasEnv1 || hasEnv2) {
                            System.out.println("Edge1: " + lge1);
                            System.out.println("Edge2: " + lge2);
                            throw new BatfishException("one had environment");
                        }
                    } else {
                        SymbolicRoute out1 = lge1.getSymbolicRecord();
                        SymbolicRoute out2 = lge2.getSymbolicRecord();
                        equalOutputs = ctx.mkAnd(equalOutputs, slice1.equal(conf1, proto1, out1, out2, lge1, false));
                    }
                }
            }
        }
        // check the stronger version of local equivalence
        if (strict) {
            for (SymbolicRoute env1 : envRecords) {
                for (SymbolicRoute env2 : envRecords) {
                    if (!env1.equals(env2)) {
                        BoolExpr c = e2.mkImplies(env1.getPermitted(), e2.mkNot(env2.getPermitted()));
                        e2.add(c);
                    }
                }
            }
        }
        // TODO: check both have same environment vars (e.g., screw up configuring peer connection)
        // Create assumptions
        BoolExpr validDest;
        validDest = ignoredDestinations(ctx, slice1, r1, conf1);
        validDest = ctx.mkAnd(validDest, ignoredDestinations(ctx, slice2, r2, conf2));
        SymbolicPacket p1 = slice1.getSymbolicPacket();
        SymbolicPacket p2 = slice2.getSymbolicPacket();
        BoolExpr equalPackets = p1.mkEqual(p2);
        BoolExpr assumptions = ctx.mkAnd(equalEnvs, equalPackets, validDest);
        // Create the requirements
        // Best choices should be the same
        BoolExpr required;
        if (strict) {
            SymbolicRoute best1 = e1.getMainSlice().getSymbolicDecisions().getBestNeighbor().get(conf1.getName());
            SymbolicRoute best2 = e2.getMainSlice().getSymbolicDecisions().getBestNeighbor().get(conf2.getName());
            // Just pick some protocol for defaults, shouldn't matter for best choice
            required = equal(e2, conf2, best1, best2);
        } else {
            // Forwarding decisions should be the sames
            Map<String, GraphEdge> geMap2 = interfaceMap(edges2);
            BoolExpr sameForwarding = ctx.mkBool(true);
            for (GraphEdge ge1 : edges1) {
                GraphEdge ge2 = geMap2.get(ge1.getStart().getName());
                BoolExpr dataFwd1 = slice1.getSymbolicDecisions().getDataForwarding().get(r1, ge1);
                BoolExpr dataFwd2 = slice2.getSymbolicDecisions().getDataForwarding().get(r2, ge2);
                assert (dataFwd1 != null);
                assert (dataFwd2 != null);
                sameForwarding = ctx.mkAnd(sameForwarding, ctx.mkEq(dataFwd1, dataFwd2));
            }
            // equalOutputs, equalIncomingAcls);
            required = ctx.mkAnd(sameForwarding);
        }
        e2.add(assumptions);
        e2.add(ctx.mkNot(required));
        VerificationResult res = e2.verify().getFirst();
        String name = r1 + "<-->" + r2;
        result.put(name, res);
    }
    return new SmtManyAnswerElement(result);
}
Also used : BoolExpr(com.microsoft.z3.BoolExpr) Configuration(org.batfish.datamodel.Configuration) TreeSet(java.util.TreeSet) SmtManyAnswerElement(org.batfish.symbolic.answers.SmtManyAnswerElement) Protocol(org.batfish.symbolic.Protocol) EnumMap(java.util.EnumMap) HashSet(java.util.HashSet) Context(com.microsoft.z3.Context) Pattern(java.util.regex.Pattern) BatfishException(org.batfish.common.BatfishException) TreeMap(java.util.TreeMap) CommunityVar(org.batfish.symbolic.CommunityVar) Graph(org.batfish.symbolic.Graph) HeaderQuestion(org.batfish.datamodel.questions.smt.HeaderQuestion) GraphEdge(org.batfish.symbolic.GraphEdge) Map(java.util.Map) EnumMap(java.util.EnumMap) SortedMap(java.util.SortedMap) HashMap(java.util.HashMap) TreeMap(java.util.TreeMap)

Example 38 with GraphEdge

use of org.batfish.symbolic.GraphEdge in project batfish by batfish.

the class PropertyChecker method checkProperty.

/*
   * General purpose logic for checking a property that holds that
   * handles the various flags and parameters for a query with endpoints
   *
   * q is the question from the user.
   * instrument instruments each router in the graph as needed to check the property.
   * answer takes the result from Z3 and produces the answer for the user.
   *
   */
private AnswerElement checkProperty(HeaderLocationQuestion q, TriFunction<Encoder, Set<String>, Set<GraphEdge>, Map<String, BoolExpr>> instrument, Function<VerifyParam, AnswerElement> answer) {
    long totalTime = System.currentTimeMillis();
    PathRegexes p = new PathRegexes(q);
    Graph graph = new Graph(_batfish);
    Set<GraphEdge> destPorts = findFinalInterfaces(graph, p);
    List<String> sourceRouters = PatternUtils.findMatchingSourceNodes(graph, p);
    if (destPorts.isEmpty()) {
        throw new BatfishException("Set of valid destination interfaces is empty");
    }
    if (sourceRouters.isEmpty()) {
        throw new BatfishException("Set of valid ingress nodes is empty");
    }
    inferDestinationHeaderSpace(graph, destPorts, q);
    Set<GraphEdge> failOptions = failLinkSet(graph, q);
    Tuple<Stream<Supplier<NetworkSlice>>, Long> ecs = findAllNetworkSlices(q, graph, true);
    Stream<Supplier<NetworkSlice>> stream = ecs.getFirst();
    Long timeAbstraction = ecs.getSecond();
    AnswerElement[] answerElement = new AnswerElement[1];
    VerificationResult[] result = new VerificationResult[2];
    List<VerificationStats> ecStats = new ArrayList<>();
    // Checks ECs in parallel, but short circuits when a counterexample is found
    boolean hasCounterExample = stream.anyMatch(lazyEc -> {
        long timeEc = System.currentTimeMillis();
        NetworkSlice slice = lazyEc.get();
        timeEc = System.currentTimeMillis() - timeEc;
        synchronized (_lock) {
            // Make sure the headerspace is correct
            HeaderLocationQuestion question = new HeaderLocationQuestion(q);
            question.setHeaderSpace(slice.getHeaderSpace());
            // Get the EC graph and mapping
            Graph g = slice.getGraph();
            Set<String> srcRouters = mapConcreteToAbstract(slice, sourceRouters);
            long timeEncoding = System.currentTimeMillis();
            Encoder enc = new Encoder(_settings, g, question);
            enc.computeEncoding();
            timeEncoding = System.currentTimeMillis() - timeEncoding;
            // Add environment constraints for base case
            if (question.getDiffType() != null) {
                if (question.getEnvDiff()) {
                    addEnvironmentConstraints(enc, question.getDeltaEnvironmentType());
                }
            } else {
                addEnvironmentConstraints(enc, question.getBaseEnvironmentType());
            }
            Map<String, BoolExpr> prop = instrument.apply(enc, srcRouters, destPorts);
            // If this is a equivalence query, we create a second copy of the network
            Encoder enc2 = null;
            Map<String, BoolExpr> prop2 = null;
            if (question.getDiffType() != null) {
                HeaderLocationQuestion q2 = new HeaderLocationQuestion(question);
                q2.setFailures(0);
                long timeDiffEncoding = System.currentTimeMillis();
                enc2 = new Encoder(enc, g, q2);
                enc2.computeEncoding();
                timeDiffEncoding = System.currentTimeMillis() - timeDiffEncoding;
                timeEncoding += timeDiffEncoding;
            }
            if (question.getDiffType() != null) {
                assert (enc2 != null);
                // create a map for enc2 to lookup a related environment variable from enc
                Table2<GraphEdge, EdgeType, SymbolicRoute> relatedEnv = new Table2<>();
                enc2.getMainSlice().getLogicalGraph().getEnvironmentVars().forEach((lge, r) -> relatedEnv.put(lge.getEdge(), lge.getEdgeType(), r));
                BoolExpr related = enc.mkTrue();
                addEnvironmentConstraints(enc2, question.getBaseEnvironmentType());
                if (!question.getEnvDiff()) {
                    related = relateEnvironments(enc, enc2);
                }
                prop2 = instrument.apply(enc2, srcRouters, destPorts);
                // Add diff constraints
                BoolExpr required = enc.mkTrue();
                for (String source : srcRouters) {
                    BoolExpr sourceProp1 = prop.get(source);
                    BoolExpr sourceProp2 = prop2.get(source);
                    BoolExpr val;
                    switch(q.getDiffType()) {
                        case INCREASED:
                            val = enc.mkImplies(sourceProp1, sourceProp2);
                            break;
                        case REDUCED:
                            val = enc.mkImplies(sourceProp2, sourceProp1);
                            break;
                        case ANY:
                            val = enc.mkEq(sourceProp1, sourceProp2);
                            break;
                        default:
                            throw new BatfishException("Missing case: " + q.getDiffType());
                    }
                    required = enc.mkAnd(required, val);
                }
                related = enc.mkAnd(related, relatePackets(enc, enc2));
                enc.add(related);
                enc.add(enc.mkNot(required));
            } else {
                // Not a differential query; just a query on a single version of the network.
                BoolExpr allProp = enc.mkTrue();
                for (String router : srcRouters) {
                    BoolExpr r = prop.get(router);
                    if (q.getNegate()) {
                        r = enc.mkNot(r);
                    }
                    allProp = enc.mkAnd(allProp, r);
                }
                enc.add(enc.mkNot(allProp));
            }
            addFailureConstraints(enc, destPorts, failOptions);
            Tuple<VerificationResult, Model> tup = enc.verify();
            VerificationResult res = tup.getFirst();
            Model model = tup.getSecond();
            if (q.getBenchmark()) {
                VerificationStats stats = res.getStats();
                stats.setAvgComputeEcTime(timeEc);
                stats.setMaxComputeEcTime(timeEc);
                stats.setMinComputeEcTime(timeEc);
                stats.setAvgEncodingTime(timeEncoding);
                stats.setMaxEncodingTime(timeEncoding);
                stats.setMinEncodingTime(timeEncoding);
                stats.setTimeCreateBdds((double) timeAbstraction);
                synchronized (_lock) {
                    ecStats.add(stats);
                }
            }
            if (!res.isVerified()) {
                VerifyParam vp = new VerifyParam(res, model, srcRouters, enc, enc2, prop, prop2);
                AnswerElement ae = answer.apply(vp);
                synchronized (_lock) {
                    answerElement[0] = ae;
                    result[0] = res;
                }
                return true;
            }
            synchronized (_lock) {
                result[1] = res;
            }
            return false;
        }
    });
    totalTime = (System.currentTimeMillis() - totalTime);
    VerificationResult res;
    AnswerElement ae;
    if (hasCounterExample) {
        res = result[0];
        ae = answerElement[0];
    } else {
        res = result[1];
        VerifyParam vp = new VerifyParam(res, null, null, null, null, null, null);
        ae = answer.apply(vp);
    }
    if (q.getBenchmark()) {
        VerificationStats stats = VerificationStats.combineAll(ecStats, totalTime);
        res.setStats(stats);
    }
    return ae;
}
Also used : BoolExpr(com.microsoft.z3.BoolExpr) HeaderLocationQuestion(org.batfish.datamodel.questions.smt.HeaderLocationQuestion) ArrayList(java.util.ArrayList) PathRegexes(org.batfish.symbolic.utils.PathRegexes) NetworkSlice(org.batfish.symbolic.abstraction.NetworkSlice) Table2(org.batfish.symbolic.collections.Table2) Stream(java.util.stream.Stream) Supplier(java.util.function.Supplier) BatfishException(org.batfish.common.BatfishException) SmtOneAnswerElement(org.batfish.symbolic.answers.SmtOneAnswerElement) SmtDeterminismAnswerElement(org.batfish.symbolic.answers.SmtDeterminismAnswerElement) SmtReachabilityAnswerElement(org.batfish.symbolic.answers.SmtReachabilityAnswerElement) AnswerElement(org.batfish.datamodel.answers.AnswerElement) SmtManyAnswerElement(org.batfish.symbolic.answers.SmtManyAnswerElement) Graph(org.batfish.symbolic.Graph) Model(com.microsoft.z3.Model) GraphEdge(org.batfish.symbolic.GraphEdge)

Example 39 with GraphEdge

use of org.batfish.symbolic.GraphEdge in project batfish by batfish.

the class PropertyChecker method checkMultipathConsistency.

/*
   * Computes multipath consistency, which ensures traffic that travels
   * multiple paths will be treated equivalently by each path
   * (i.e., dropped or accepted by each).
   */
public AnswerElement checkMultipathConsistency(HeaderLocationQuestion q) {
    if (q.getNegate()) {
        throw new BatfishException("Negation not implemented for smt-multipath-consistency.");
    }
    PathRegexes p = new PathRegexes(q);
    Graph graph = new Graph(_batfish);
    Set<GraphEdge> destPorts = findFinalInterfaces(graph, p);
    inferDestinationHeaderSpace(graph, destPorts, q);
    Encoder enc = new Encoder(_settings, graph, q);
    enc.computeEncoding();
    EncoderSlice slice = enc.getMainSlice();
    PropertyAdder pa = new PropertyAdder(slice);
    Map<String, BoolExpr> reachableVars = pa.instrumentReachability(destPorts);
    BoolExpr acc = enc.mkFalse();
    for (Map.Entry<String, Configuration> entry : graph.getConfigurations().entrySet()) {
        String router = entry.getKey();
        BoolExpr reach = reachableVars.get(router);
        BoolExpr all = enc.mkTrue();
        for (GraphEdge edge : graph.getEdgeMap().get(router)) {
            BoolExpr dataFwd = slice.getForwardsAcross().get(router, edge);
            BoolExpr ctrFwd = slice.getSymbolicDecisions().getControlForwarding().get(router, edge);
            assert (ctrFwd != null);
            BoolExpr peerReach = enc.mkTrue();
            if (edge.getPeer() != null) {
                peerReach = reachableVars.get(edge.getPeer());
            }
            BoolExpr imp = enc.mkImplies(ctrFwd, enc.mkAnd(dataFwd, peerReach));
            all = enc.mkAnd(all, imp);
        }
        acc = enc.mkOr(acc, enc.mkNot(enc.mkImplies(reach, all)));
    }
    enc.add(acc);
    VerificationResult res = enc.verify().getFirst();
    return new SmtOneAnswerElement(res);
}
Also used : BatfishException(org.batfish.common.BatfishException) BoolExpr(com.microsoft.z3.BoolExpr) Configuration(org.batfish.datamodel.Configuration) SmtOneAnswerElement(org.batfish.symbolic.answers.SmtOneAnswerElement) PathRegexes(org.batfish.symbolic.utils.PathRegexes) Graph(org.batfish.symbolic.Graph) GraphEdge(org.batfish.symbolic.GraphEdge) Map(java.util.Map) EnumMap(java.util.EnumMap) SortedMap(java.util.SortedMap) HashMap(java.util.HashMap) TreeMap(java.util.TreeMap)

Example 40 with GraphEdge

use of org.batfish.symbolic.GraphEdge in project batfish by batfish.

the class PropertyChecker method relateEnvironments.

private BoolExpr relateEnvironments(Encoder enc1, Encoder enc2) {
    // create a map for enc2 to lookup a related environment variable from enc
    Table2<GraphEdge, EdgeType, SymbolicRoute> relatedEnv = new Table2<>();
    for (Entry<LogicalEdge, SymbolicRoute> entry : enc2.getMainSlice().getLogicalGraph().getEnvironmentVars().entrySet()) {
        LogicalEdge lge = entry.getKey();
        SymbolicRoute r = entry.getValue();
        relatedEnv.put(lge.getEdge(), lge.getEdgeType(), r);
    }
    // relate environments if necessary
    BoolExpr related = enc1.mkTrue();
    Map<LogicalEdge, SymbolicRoute> map = enc1.getMainSlice().getLogicalGraph().getEnvironmentVars();
    for (Map.Entry<LogicalEdge, SymbolicRoute> entry : map.entrySet()) {
        LogicalEdge le = entry.getKey();
        SymbolicRoute r1 = entry.getValue();
        String router = le.getEdge().getRouter();
        Configuration conf = enc1.getMainSlice().getGraph().getConfigurations().get(router);
        // Lookup the same environment variable in the other copy
        // The copy will have a different name but the same edge and type
        SymbolicRoute r2 = relatedEnv.get(le.getEdge(), le.getEdgeType());
        assert r2 != null;
        BoolExpr x = equal(enc1, conf, r1, r2);
        related = enc1.mkAnd(related, x);
    }
    return related;
}
Also used : BoolExpr(com.microsoft.z3.BoolExpr) Configuration(org.batfish.datamodel.Configuration) Table2(org.batfish.symbolic.collections.Table2) GraphEdge(org.batfish.symbolic.GraphEdge) Map(java.util.Map) EnumMap(java.util.EnumMap) SortedMap(java.util.SortedMap) HashMap(java.util.HashMap) TreeMap(java.util.TreeMap)

Aggregations

GraphEdge (org.batfish.symbolic.GraphEdge)47 BoolExpr (com.microsoft.z3.BoolExpr)23 HashMap (java.util.HashMap)19 ArrayList (java.util.ArrayList)16 List (java.util.List)16 Graph (org.batfish.symbolic.Graph)14 TreeSet (java.util.TreeSet)13 Prefix (org.batfish.datamodel.Prefix)12 ArithExpr (com.microsoft.z3.ArithExpr)10 Configuration (org.batfish.datamodel.Configuration)10 Protocol (org.batfish.symbolic.Protocol)10 HashSet (java.util.HashSet)8 Interface (org.batfish.datamodel.Interface)8 Context (com.microsoft.z3.Context)7 Map (java.util.Map)7 Ip (org.batfish.datamodel.Ip)7 IpAccessList (org.batfish.datamodel.IpAccessList)7 TreeMap (java.util.TreeMap)6 IpProtocol (org.batfish.datamodel.IpProtocol)6 BitVecExpr (com.microsoft.z3.BitVecExpr)5