Search in sources :

Example 6 with BitVecExpr

use of com.microsoft.z3.BitVecExpr in project batfish by batfish.

the class Z3ContextJob method getSolverInput.

protected BoolExpr getSolverInput(Expr answer, NodProgram program, boolean negate) {
    BoolExpr solverInput;
    if (answer.getArgs().length > 0) {
        Map<String, BitVecExpr> variablesAsConsts = program.getNodContext().getVariablesAsConsts();
        List<BitVecExpr> reversedVars = Lists.reverse(program.getNodContext().getVariableNames().stream().filter(name -> !TransformationHeaderField.transformationHeaderFieldNames.contains(name)).map(variablesAsConsts::get).collect(Collectors.toList()));
        Expr substitutedAnswer = answer.substituteVars(reversedVars.toArray(new Expr[] {}));
        solverInput = (BoolExpr) substitutedAnswer;
    } else {
        solverInput = (BoolExpr) answer;
    }
    if (negate) {
        solverInput = program.getNodContext().getContext().mkNot(solverInput);
    }
    return solverInput;
}
Also used : Arrays(java.util.Arrays) FuncDecl(com.microsoft.z3.FuncDecl) IpProtocol(org.batfish.datamodel.IpProtocol) ImmutableMap(com.google.common.collect.ImmutableMap) BatfishJob(org.batfish.job.BatfishJob) Context(com.microsoft.z3.Context) BitVecExpr(com.microsoft.z3.BitVecExpr) BatfishException(org.batfish.common.BatfishException) Streams(com.google.common.collect.Streams) Function(java.util.function.Function) Collectors(java.util.stream.Collectors) State(org.batfish.datamodel.State) Fixedpoint(com.microsoft.z3.Fixedpoint) Settings(org.batfish.config.Settings) Flow(org.batfish.datamodel.Flow) List(java.util.List) BatfishJobResult(org.batfish.job.BatfishJobResult) Lists(com.google.common.collect.Lists) Params(com.microsoft.z3.Params) Map(java.util.Map) BoolExpr(com.microsoft.z3.BoolExpr) Expr(com.microsoft.z3.Expr) Status(com.microsoft.z3.Status) Ip(org.batfish.datamodel.Ip) BoolExpr(com.microsoft.z3.BoolExpr) BitVecExpr(com.microsoft.z3.BitVecExpr) BitVecExpr(com.microsoft.z3.BitVecExpr) BoolExpr(com.microsoft.z3.BoolExpr) Expr(com.microsoft.z3.Expr)

Example 7 with BitVecExpr

use of com.microsoft.z3.BitVecExpr in project batfish by batfish.

the class BitVecExprTransformer method visitVarIntExpr.

@Override
public BitVecExpr visitVarIntExpr(VarIntExpr varIntExpr) {
    String headerField = varIntExpr.getField().getName();
    BitVecExpr ret = _nodContext.getVariables().get(headerField);
    if (ret == null) {
        throw new BatfishException("nodContext missing mapping for variable: '" + headerField + "'");
    }
    return ret;
}
Also used : BatfishException(org.batfish.common.BatfishException) BitVecExpr(com.microsoft.z3.BitVecExpr)

Example 8 with BitVecExpr

use of com.microsoft.z3.BitVecExpr in project batfish by batfish.

the class EncoderSlice method computeWildcardMatch.

/*
   * Convert a set of wildcards and a packet field to a symbolic boolean expression
   */
private BoolExpr computeWildcardMatch(Set<IpWildcard> wcs, BitVecExpr field) {
    BoolExpr acc = mkFalse();
    for (IpWildcard wc : wcs) {
        ipWildCardBound(field, wc);
        acc = mkOr(acc, ipWildCardBound(field, wc));
    }
    return (BoolExpr) acc.simplify();
}
Also used : IpWildcard(org.batfish.datamodel.IpWildcard) BoolExpr(com.microsoft.z3.BoolExpr)

Example 9 with BitVecExpr

use of com.microsoft.z3.BitVecExpr in project batfish by batfish.

the class EncoderSlice method addControlForwardingConstraints.

/*
   * Constraints that define control-plane forwarding.
   * If there is some valid import, then control plane forwarding
   * will occur out an interface when this is the best choice.
   * Otherwise, it will not occur.
   */
private void addControlForwardingConstraints() {
    for (Entry<String, Configuration> entry : getGraph().getConfigurations().entrySet()) {
        String router = entry.getKey();
        Configuration conf = entry.getValue();
        boolean someEdge = false;
        SymbolicRoute best = _symbolicDecisions.getBestNeighbor().get(router);
        Map<GraphEdge, BoolExpr> cfExprs = new HashMap<>();
        Set<GraphEdge> constrained = new HashSet<>();
        for (Protocol proto : getProtocols().get(router)) {
            for (LogicalEdge e : collectAllImportLogicalEdges(router, conf, proto)) {
                someEdge = true;
                constrained.add(e.getEdge());
                SymbolicRoute vars = correctVars(e);
                BoolExpr choice = _symbolicDecisions.getChoiceVariables().get(router, proto, e);
                BoolExpr isBest = mkAnd(choice, equal(conf, proto, best, vars, e, false));
                GraphEdge ge = e.getEdge();
                // Connected routes should only forward if not absorbed by interface
                GraphEdge other = getGraph().getOtherEnd().get(ge);
                BoolExpr connectedWillSend;
                if (other == null || getGraph().isHost(ge.getPeer())) {
                    Ip ip = ge.getStart().getAddress().getIp();
                    BitVecExpr val = getCtx().mkBV(ip.asLong(), 32);
                    connectedWillSend = mkNot(mkEq(_symbolicPacket.getDstIp(), val));
                } else {
                    Ip ip = other.getStart().getAddress().getIp();
                    BitVecExpr val = getCtx().mkBV(ip.asLong(), 32);
                    connectedWillSend = mkEq(_symbolicPacket.getDstIp(), val);
                }
                BoolExpr canSend = (proto.isConnected() ? connectedWillSend : mkTrue());
                BoolExpr sends = mkAnd(canSend, isBest);
                BoolExpr cForward = _symbolicDecisions.getControlForwarding().get(router, ge);
                assert (cForward != null);
                add(mkImplies(sends, cForward));
                // record the negation as well
                cfExprs.merge(ge, sends, (a, b) -> mkOr(a, b));
            }
        }
        // For edges that are never used, we constraint them to not be forwarded out of
        for (GraphEdge ge : getGraph().getEdgeMap().get(router)) {
            if (!constrained.contains(ge)) {
                BoolExpr cForward = _symbolicDecisions.getControlForwarding().get(router, ge);
                assert (cForward != null);
                add(mkNot(cForward));
            }
        }
        // Handle the case that the router has no protocol running
        if (!someEdge) {
            for (GraphEdge ge : getGraph().getEdgeMap().get(router)) {
                BoolExpr cForward = _symbolicDecisions.getControlForwarding().get(router, ge);
                assert (cForward != null);
                add(mkNot(cForward));
            }
        } else {
            // If no best route, then no forwarding
            Map<Protocol, List<ArrayList<LogicalEdge>>> map = _logicalGraph.getLogicalEdges().get(router);
            Set<GraphEdge> seen = new HashSet<>();
            for (List<ArrayList<LogicalEdge>> eList : map.values()) {
                for (ArrayList<LogicalEdge> edges : eList) {
                    for (LogicalEdge le : edges) {
                        GraphEdge ge = le.getEdge();
                        if (seen.contains(ge)) {
                            continue;
                        }
                        seen.add(ge);
                        BoolExpr expr = cfExprs.get(ge);
                        BoolExpr cForward = _symbolicDecisions.getControlForwarding().get(router, ge);
                        assert (cForward != null);
                        if (expr != null) {
                            add(mkImplies(mkNot(expr), mkNot(cForward)));
                        } else {
                            add(mkNot(cForward));
                        }
                    }
                }
            }
        }
    }
}
Also used : BoolExpr(com.microsoft.z3.BoolExpr) Configuration(org.batfish.datamodel.Configuration) HashMap(java.util.HashMap) Ip(org.batfish.datamodel.Ip) ArrayList(java.util.ArrayList) BitVecExpr(com.microsoft.z3.BitVecExpr) IpAccessList(org.batfish.datamodel.IpAccessList) ArrayList(java.util.ArrayList) List(java.util.List) IpProtocol(org.batfish.datamodel.IpProtocol) RoutingProtocol(org.batfish.datamodel.RoutingProtocol) Protocol(org.batfish.symbolic.Protocol) MatchProtocol(org.batfish.datamodel.routing_policy.expr.MatchProtocol) GraphEdge(org.batfish.symbolic.GraphEdge) HashSet(java.util.HashSet)

Example 10 with BitVecExpr

use of com.microsoft.z3.BitVecExpr in project batfish by batfish.

the class EncoderSlice method greaterOrEqual.

/*
   * Check if a (best) symbolic record is better than another
   * symbolic record (vars). This is done using a recursive lexicographic
   * encoding. The encoding is as follows:
   *
   * (best.length > vars.length) or
   * (best.length = vars.length) and (
   *    (best.adminDist < vars.adminDist) or
   *    (best.adminDist = vars.adminDist) and (
   *     ...
   *    )
   * )
   *
   * This recursive encoding introduces a new variable for each subexpressions,
   * which ends up being much more efficient than expanding out options.
   */
private BoolExpr greaterOrEqual(Configuration conf, Protocol proto, SymbolicRoute best, SymbolicRoute vars, @Nullable LogicalEdge e) {
    ArithExpr defaultLocal = mkInt(defaultLocalPref());
    ArithExpr defaultAdmin = defaultAdminDistance(conf, proto, vars);
    ArithExpr defaultMet = mkInt(defaultMetric());
    ArithExpr defaultMed = mkInt(defaultMed(proto));
    ArithExpr defaultLen = mkInt(defaultLength());
    ArithExpr defaultIgp = mkInt(defaultIgpMetric());
    ArithExpr defaultId = mkInt(0);
    BitVecExpr defaultOspfType = defaultOspfType();
    BoolExpr betterLen = geBetterHelper(best.getPrefixLength(), vars.getPrefixLength(), defaultLen, false);
    BoolExpr equalLen = geEqualHelper(best.getPrefixLength(), vars.getPrefixLength(), defaultLen);
    BoolExpr betterAd = geBetterHelper(best.getAdminDist(), vars.getAdminDist(), defaultAdmin, true);
    BoolExpr equalAd = geEqualHelper(best.getAdminDist(), vars.getAdminDist(), defaultAdmin);
    BoolExpr betterLp = geBetterHelper(best.getLocalPref(), vars.getLocalPref(), defaultLocal, false);
    BoolExpr equalLp = geEqualHelper(best.getLocalPref(), vars.getLocalPref(), defaultLocal);
    BoolExpr betterMet = geBetterHelper(best.getMetric(), vars.getMetric(), defaultMet, true);
    BoolExpr equalMet = geEqualHelper(best.getMetric(), vars.getMetric(), defaultMet);
    BoolExpr betterMed = geBetterHelper(best.getMed(), vars.getMed(), defaultMed, true);
    BoolExpr equalMed = geEqualHelper(best.getMed(), vars.getMed(), defaultMed);
    BitVecExpr bestType = (best.getOspfType() == null ? null : best.getOspfType().getBitVec());
    BitVecExpr varsType = (vars.getOspfType() == null ? null : vars.getOspfType().getBitVec());
    BoolExpr betterOspfType = geBetterHelper(bestType, varsType, defaultOspfType, true);
    BoolExpr equalOspfType = geEqualHelper(bestType, varsType, defaultOspfType);
    BoolExpr betterInternal = geBetterHelper(best.getBgpInternal(), vars.getBgpInternal(), mkFalse(), true);
    BoolExpr equalInternal = geEqualHelper(best.getBgpInternal(), vars.getBgpInternal(), mkFalse());
    BoolExpr betterIgpMet = geBetterHelper(best.getIgpMetric(), vars.getIgpMetric(), defaultIgp, true);
    BoolExpr equalIgpMet = geEqualHelper(best.getIgpMetric(), vars.getIgpMetric(), defaultIgp);
    BoolExpr tiebreak;
    if (vars.getRouterId() != null) {
        tiebreak = mkLe(best.getRouterId(), vars.getRouterId());
    } else if (best.getRouterId() != null) {
        if (e == null) {
            tiebreak = mkLe(best.getRouterId(), defaultId);
        } else {
            long peerId = getGraph().findRouterId(e.getEdge(), proto);
            tiebreak = mkLe(best.getRouterId(), mkInt(peerId));
        }
    } else {
        tiebreak = mkTrue();
    }
    BoolExpr b = mkAnd(equalOspfType, tiebreak);
    BoolExpr b1 = mkOr(betterOspfType, b);
    BoolExpr b2 = mkAnd(equalIgpMet, b1);
    BoolExpr b3 = mkOr(betterIgpMet, b2);
    BoolExpr b4 = mkAnd(equalInternal, b3);
    BoolExpr b5 = mkOr(betterInternal, b4);
    BoolExpr b6 = mkAnd(equalMed, b5);
    BoolExpr b7 = mkOr(betterMed, b6);
    BoolExpr b8 = mkAnd(equalMet, b7);
    BoolExpr b9 = mkOr(betterMet, b8);
    BoolExpr b10 = mkAnd(equalLp, b9);
    BoolExpr b11 = mkOr(betterLp, b10);
    BoolExpr b12 = mkAnd(equalAd, b11);
    BoolExpr b13 = mkOr(betterAd, b12);
    BoolExpr b14 = mkAnd(equalLen, b13);
    return mkOr(betterLen, b14);
}
Also used : ArithExpr(com.microsoft.z3.ArithExpr) BoolExpr(com.microsoft.z3.BoolExpr) BitVecExpr(com.microsoft.z3.BitVecExpr)

Aggregations

BitVecExpr (com.microsoft.z3.BitVecExpr)15 BoolExpr (com.microsoft.z3.BoolExpr)11 ArithExpr (com.microsoft.z3.ArithExpr)6 HashMap (java.util.HashMap)6 List (java.util.List)6 GraphEdge (org.batfish.symbolic.GraphEdge)5 Context (com.microsoft.z3.Context)4 Solver (com.microsoft.z3.Solver)4 Map (java.util.Map)4 BatfishException (org.batfish.common.BatfishException)4 Graph (org.batfish.symbolic.Graph)4 Expr (com.microsoft.z3.Expr)3 ImmutableMap (com.google.common.collect.ImmutableMap)2 ArrayList (java.util.ArrayList)2 HashSet (java.util.HashSet)2 Pair (org.batfish.common.Pair)2 Configuration (org.batfish.datamodel.Configuration)2 Ip (org.batfish.datamodel.Ip)2 IpProtocol (org.batfish.datamodel.IpProtocol)2 AsPathListExpr (org.batfish.datamodel.routing_policy.expr.AsPathListExpr)2