Search in sources :

Example 16 with ArithExpr

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

the class TransferSSA method joinPoint.

/*
   * The [phi] function from SSA that merges variables that may differ across
   * different branches of an mkIf statement.
   */
private Pair<Expr, Expr> joinPoint(TransferParam<SymbolicRoute> p, TransferResult<BoolExpr, BoolExpr> r, BoolExpr guard, Pair<String, Pair<Expr, Expr>> values) {
    String variableName = values.getFirst();
    Expr trueBranch = values.getSecond().getFirst();
    Expr falseBranch = values.getSecond().getSecond();
    if (variableName.equals("RETURN") || variableName.equals("FALLTHROUGH")) {
        Expr t = (trueBranch == null ? _enc.mkFalse() : // can use False because the value has not been assigned
        trueBranch);
        Expr f = (falseBranch == null ? _enc.mkFalse() : falseBranch);
        Expr tass = (trueBranch == null ? r.getReturnAssignedValue() : _enc.mkTrue());
        Expr fass = (falseBranch == null ? r.getReturnAssignedValue() : _enc.mkTrue());
        BoolExpr newAss = _enc.mkIf(guard, (BoolExpr) tass, (BoolExpr) fass);
        BoolExpr retAss = createBoolVariableWith(p, "ASSIGNED", newAss);
        BoolExpr variable = (variableName.equals("RETURN") ? r.getReturnValue() : r.getFallthroughValue());
        BoolExpr newValue = _enc.mkIf(r.getReturnAssignedValue(), variable, _enc.mkIf(guard, (BoolExpr) t, (BoolExpr) f));
        BoolExpr ret = createBoolVariableWith(p, variableName, newValue);
        return new Pair<>(ret, retAss);
    }
    if (variableName.equals("PREFIX-LEN")) {
        Expr t = (trueBranch == null ? p.getData().getPrefixLength() : trueBranch);
        Expr f = (falseBranch == null ? p.getData().getPrefixLength() : falseBranch);
        ArithExpr newValue = _enc.mkIf(guard, (ArithExpr) t, (ArithExpr) f);
        newValue = _enc.mkIf(r.getReturnAssignedValue(), p.getData().getPrefixLength(), newValue);
        ArithExpr ret = createArithVariableWith(p, "PREFIX-LEN", newValue);
        p.getData().setPrefixLength(ret);
        return new Pair<>(ret, null);
    }
    if (variableName.equals("ADMIN-DIST")) {
        Expr t = (trueBranch == null ? p.getData().getAdminDist() : trueBranch);
        Expr f = (falseBranch == null ? p.getData().getAdminDist() : falseBranch);
        ArithExpr newValue = _enc.mkIf(guard, (ArithExpr) t, (ArithExpr) f);
        newValue = _enc.mkIf(r.getReturnAssignedValue(), p.getData().getAdminDist(), newValue);
        ArithExpr ret = createArithVariableWith(p, "ADMIN-DIST", newValue);
        p.getData().setAdminDist(ret);
        return new Pair<>(ret, null);
    }
    if (variableName.equals("LOCAL-PREF")) {
        Expr t = (trueBranch == null ? p.getData().getLocalPref() : trueBranch);
        Expr f = (falseBranch == null ? p.getData().getLocalPref() : falseBranch);
        ArithExpr newValue = _enc.mkIf(guard, (ArithExpr) t, (ArithExpr) f);
        newValue = _enc.mkIf(r.getReturnAssignedValue(), p.getData().getLocalPref(), newValue);
        ArithExpr ret = createArithVariableWith(p, "LOCAL-PREF", newValue);
        p.getData().setLocalPref(ret);
        return new Pair<>(ret, null);
    }
    if (variableName.equals("METRIC")) {
        Expr t = (trueBranch == null ? p.getData().getMetric() : trueBranch);
        Expr f = (falseBranch == null ? p.getData().getMetric() : falseBranch);
        ArithExpr newValue = _enc.mkIf(guard, (ArithExpr) t, (ArithExpr) f);
        newValue = _enc.mkIf(r.getReturnAssignedValue(), p.getData().getMetric(), newValue);
        ArithExpr ret = createArithVariableWith(p, "METRIC", newValue);
        p.getData().setMetric(ret);
        return new Pair<>(ret, null);
    }
    if (variableName.equals("OSPF-TYPE")) {
        Expr t = (trueBranch == null ? p.getData().getOspfType().getBitVec() : trueBranch);
        Expr f = (falseBranch == null ? p.getData().getOspfType().getBitVec() : falseBranch);
        BitVecExpr newValue = _enc.mkIf(guard, (BitVecExpr) t, (BitVecExpr) f);
        newValue = _enc.mkIf(r.getReturnAssignedValue(), p.getData().getOspfType().getBitVec(), newValue);
        BitVecExpr ret = createBitVecVariableWith(p, "OSPF-TYPE", 2, newValue);
        p.getData().getOspfType().setBitVec(ret);
        return new Pair<>(ret, null);
    }
    for (Map.Entry<CommunityVar, BoolExpr> entry : p.getData().getCommunities().entrySet()) {
        CommunityVar cvar = entry.getKey();
        if (variableName.equals(cvar.getValue())) {
            Expr t = (trueBranch == null ? p.getData().getCommunities().get(cvar) : trueBranch);
            Expr f = (falseBranch == null ? p.getData().getCommunities().get(cvar) : falseBranch);
            BoolExpr newValue = _enc.mkIf(guard, (BoolExpr) t, (BoolExpr) f);
            newValue = _enc.mkIf(r.getReturnAssignedValue(), p.getData().getCommunities().get(cvar), newValue);
            BoolExpr ret = createBoolVariableWith(p, cvar.getValue(), newValue);
            p.getData().getCommunities().put(cvar, ret);
            return new Pair<>(ret, null);
        }
    }
    throw new BatfishException("[joinPoint]: unhandled case for " + variableName);
}
Also used : ArithExpr(com.microsoft.z3.ArithExpr) CommunityVar(org.batfish.symbolic.CommunityVar) BoolExpr(com.microsoft.z3.BoolExpr) BatfishException(org.batfish.common.BatfishException) BitVecExpr(com.microsoft.z3.BitVecExpr) IntExpr(org.batfish.datamodel.routing_policy.expr.IntExpr) CommunitySetExpr(org.batfish.datamodel.routing_policy.expr.CommunitySetExpr) CallExpr(org.batfish.datamodel.routing_policy.expr.CallExpr) BooleanExpr(org.batfish.datamodel.routing_policy.expr.BooleanExpr) AsPathListExpr(org.batfish.datamodel.routing_policy.expr.AsPathListExpr) BoolExpr(com.microsoft.z3.BoolExpr) ArithExpr(com.microsoft.z3.ArithExpr) WithEnvironmentExpr(org.batfish.datamodel.routing_policy.expr.WithEnvironmentExpr) PrefixSetExpr(org.batfish.datamodel.routing_policy.expr.PrefixSetExpr) BitVecExpr(com.microsoft.z3.BitVecExpr) Expr(com.microsoft.z3.Expr) LongExpr(org.batfish.datamodel.routing_policy.expr.LongExpr) Map(java.util.Map) HashMap(java.util.HashMap) Pair(org.batfish.common.Pair)

Example 17 with ArithExpr

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

the class Encoder method initFailedLinkVariables.

/*
   * Initialize symbolic variables to represent link failures.
   */
private void initFailedLinkVariables() {
    for (List<GraphEdge> edges : _graph.getEdgeMap().values()) {
        for (GraphEdge ge : edges) {
            if (ge.getPeer() == null) {
                Interface i = ge.getStart();
                String name = getId() + "_FAILED-EDGE_" + ge.getRouter() + "_" + i.getName();
                ArithExpr var = getCtx().mkIntConst(name);
                _symbolicFailures.getFailedEdgeLinks().put(ge, var);
                _allVariables.put(var.toString(), var);
            }
        }
    }
    for (Entry<String, Set<String>> entry : _graph.getNeighbors().entrySet()) {
        String router = entry.getKey();
        Set<String> peers = entry.getValue();
        for (String peer : peers) {
            // sort names for unique
            String pair = (router.compareTo(peer) < 0 ? router + "_" + peer : peer + "_" + router);
            String name = getId() + "_FAILED-EDGE_" + pair;
            ArithExpr var = _ctx.mkIntConst(name);
            _symbolicFailures.getFailedInternalLinks().put(router, peer, var);
            _allVariables.put(var.toString(), var);
        }
    }
}
Also used : ArithExpr(com.microsoft.z3.ArithExpr) SortedSet(java.util.SortedSet) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) Set(java.util.Set) GraphEdge(org.batfish.symbolic.GraphEdge) Interface(org.batfish.datamodel.Interface)

Example 18 with ArithExpr

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

the class EncoderSlice method equal.

/*
   * Check for equality of a (best) symbolic record and another
   * symbolic record (vars). It checks pairwise that all fields
   * are equal, while filling in values missing due to optimizations
   * with default values based on the protocol.
   * If there is no corresponding edge e, then the value null can be used
   */
public BoolExpr equal(Configuration conf, Protocol proto, SymbolicRoute best, SymbolicRoute vars, @Nullable LogicalEdge e, boolean compareCommunities) {
    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());
    BoolExpr equalLen;
    BoolExpr equalAd;
    BoolExpr equalLp;
    BoolExpr equalMet;
    BoolExpr equalMed;
    BoolExpr equalOspfArea;
    BoolExpr equalOspfType;
    BoolExpr equalId;
    BoolExpr equalHistory;
    BoolExpr equalBgpInternal;
    BoolExpr equalClientIds;
    BoolExpr equalIgpMet;
    BoolExpr equalCommunities;
    equalLen = equalHelper(best.getPrefixLength(), vars.getPrefixLength(), defaultLen);
    equalAd = equalHelper(best.getAdminDist(), vars.getAdminDist(), defaultAdmin);
    equalLp = equalHelper(best.getLocalPref(), vars.getLocalPref(), defaultLocal);
    equalMet = equalHelper(best.getMetric(), vars.getMetric(), defaultMet);
    equalMed = equalHelper(best.getMed(), vars.getMed(), defaultMed);
    equalIgpMet = equalHelper(best.getIgpMetric(), vars.getIgpMetric(), defaultIgp);
    equalOspfType = equalTypes(best, vars);
    equalOspfArea = equalAreas(best, vars, e);
    equalId = equalIds(best, vars, proto, e);
    equalHistory = equalHistories(best, vars);
    equalBgpInternal = equalBgpInternal(best, vars);
    equalClientIds = equalClientIds(conf.getName(), best, vars);
    equalCommunities = (compareCommunities ? equalCommunities(best, vars) : mkTrue());
    return mkAnd(equalLen, equalAd, equalLp, equalMet, equalMed, equalOspfArea, equalOspfType, equalId, equalHistory, equalBgpInternal, equalClientIds, equalIgpMet, equalCommunities);
}
Also used : ArithExpr(com.microsoft.z3.ArithExpr) BoolExpr(com.microsoft.z3.BoolExpr)

Example 19 with ArithExpr

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

the class EncoderSlice method isRelevantFor.

/*
   * Check if a prefix range match is applicable for the packet destination
   * Ip address, given the prefix length variable.
   */
BoolExpr isRelevantFor(ArithExpr prefixLen, PrefixRange range) {
    Prefix p = range.getPrefix();
    SubRange r = range.getLengthRange();
    long pfx = p.getStartIp().asLong();
    int len = p.getPrefixLength();
    int lower = r.getStart();
    int upper = r.getEnd();
    // well formed prefix
    assert (p.getPrefixLength() <= lower && lower <= upper);
    BoolExpr lowerBitsMatch = firstBitsEqual(_symbolicPacket.getDstIp(), pfx, len);
    if (lower == upper) {
        BoolExpr equalLen = mkEq(prefixLen, mkInt(lower));
        return mkAnd(equalLen, lowerBitsMatch);
    } else {
        BoolExpr lengthLowerBound = mkGe(prefixLen, mkInt(lower));
        BoolExpr lengthUpperBound = mkLe(prefixLen, mkInt(upper));
        return mkAnd(lengthLowerBound, lengthUpperBound, lowerBitsMatch);
    }
}
Also used : BoolExpr(com.microsoft.z3.BoolExpr) Prefix(org.batfish.datamodel.Prefix) SubRange(org.batfish.datamodel.SubRange)

Example 20 with ArithExpr

use of com.microsoft.z3.ArithExpr 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

ArithExpr (com.microsoft.z3.ArithExpr)27 BoolExpr (com.microsoft.z3.BoolExpr)25 HashMap (java.util.HashMap)12 GraphEdge (org.batfish.symbolic.GraphEdge)10 BitVecExpr (com.microsoft.z3.BitVecExpr)7 Prefix (org.batfish.datamodel.Prefix)6 Graph (org.batfish.symbolic.Graph)6 List (java.util.List)5 Map (java.util.Map)5 Context (com.microsoft.z3.Context)4 Solver (com.microsoft.z3.Solver)4 HashSet (java.util.HashSet)4 Interface (org.batfish.datamodel.Interface)4 CommunityVar (org.batfish.symbolic.CommunityVar)4 Expr (com.microsoft.z3.Expr)3 BatfishException (org.batfish.common.BatfishException)3 SubRange (org.batfish.datamodel.SubRange)3 RoutingPolicy (org.batfish.datamodel.routing_policy.RoutingPolicy)3 BooleanExpr (org.batfish.datamodel.routing_policy.expr.BooleanExpr)3 SmtOneAnswerElement (org.batfish.symbolic.answers.SmtOneAnswerElement)3