use of com.google.api.expr.v1alpha1.Expr in project spoon by INRIA.
the class AlwaysTrueFalseChecker method check.
private void check(CtExpression<?> expression, boolean isLoopCondition) {
Expr conditionExpr = (Expr) expression.getMetadata("value");
CtTypeReference<?> expressionType = getActualType(expression);
// Unboxing conversion
if (!expressionType.isPrimitive() && isCalculable(expressionType)) {
conditionExpr = getMemory().read(expressionType.unbox(), (IntExpr) conditionExpr);
}
ConditionStatus conditionStatus = checkCond((BoolExpr) conditionExpr);
if (conditionStatus == ConditionStatus.ALWAYS_TRUE && !isLoopCondition) {
addWarning(new Warning(expression, WarningKind.ALWAYS_TRUE));
} else if (conditionStatus == ConditionStatus.ALWAYS_FALSE) {
addWarning(new Warning(expression, WarningKind.ALWAYS_FALSE));
}
}
use of com.google.api.expr.v1alpha1.Expr in project batfish by batfish.
the class Encoder method buildCounterExample.
/*
* Add the relevant variables in the counterexample to
* display to the user in a human-readable fashion
*/
private void buildCounterExample(Encoder enc, Model m, SortedMap<String, String> model, SortedMap<String, String> packetModel, SortedSet<String> fwdModel, SortedMap<String, SortedMap<String, String>> envModel, SortedSet<String> failures) {
SortedMap<Expr, String> valuation = new TreeMap<>();
// If user asks for the full model
for (Entry<String, Expr> entry : _allVariables.entrySet()) {
String name = entry.getKey();
Expr e = entry.getValue();
Expr val = m.evaluate(e, true);
if (!val.equals(e)) {
String s = val.toString();
if (_question.getFullModel()) {
model.put(name, s);
}
valuation.put(e, s);
}
}
// Packet model
SymbolicPacket p = enc.getMainSlice().getSymbolicPacket();
String dstIp = valuation.get(p.getDstIp());
String srcIp = valuation.get(p.getSrcIp());
String dstPt = valuation.get(p.getDstPort());
String srcPt = valuation.get(p.getSrcPort());
String icmpCode = valuation.get(p.getIcmpCode());
String icmpType = valuation.get(p.getIcmpType());
String ipProtocol = valuation.get(p.getIpProtocol());
String tcpAck = valuation.get(p.getTcpAck());
String tcpCwr = valuation.get(p.getTcpCwr());
String tcpEce = valuation.get(p.getTcpEce());
String tcpFin = valuation.get(p.getTcpFin());
String tcpPsh = valuation.get(p.getTcpPsh());
String tcpRst = valuation.get(p.getTcpRst());
String tcpSyn = valuation.get(p.getTcpSyn());
String tcpUrg = valuation.get(p.getTcpUrg());
Ip dip = new Ip(Long.parseLong(dstIp));
Ip sip = new Ip(Long.parseLong(srcIp));
packetModel.put("dstIp", dip.toString());
if (sip.asLong() != 0) {
packetModel.put("srcIp", sip.toString());
}
if (dstPt != null && !dstPt.equals("0")) {
packetModel.put("dstPort", dstPt);
}
if (srcPt != null && !srcPt.equals("0")) {
packetModel.put("srcPort", srcPt);
}
if (icmpCode != null && !icmpCode.equals("0")) {
packetModel.put("icmpCode", icmpCode);
}
if (icmpType != null && !icmpType.equals("0")) {
packetModel.put("icmpType", icmpType);
}
if (ipProtocol != null && !ipProtocol.equals("0")) {
Integer number = Integer.parseInt(ipProtocol);
IpProtocol proto = IpProtocol.fromNumber(number);
packetModel.put("protocol", proto.toString());
}
if ("true".equals(tcpAck)) {
packetModel.put("tcpAck", "set");
}
if ("true".equals(tcpCwr)) {
packetModel.put("tcpCwr", "set");
}
if ("true".equals(tcpEce)) {
packetModel.put("tcpEce", "set");
}
if ("true".equals(tcpFin)) {
packetModel.put("tcpFin", "set");
}
if ("true".equals(tcpPsh)) {
packetModel.put("tcpPsh", "set");
}
if ("true".equals(tcpRst)) {
packetModel.put("tcpRst", "set");
}
if ("true".equals(tcpSyn)) {
packetModel.put("tcpSyn", "set");
}
if ("true".equals(tcpUrg)) {
packetModel.put("tcpUrg", "set");
}
for (EncoderSlice slice : enc.getSlices().values()) {
for (Entry<LogicalEdge, SymbolicRoute> entry2 : slice.getLogicalGraph().getEnvironmentVars().entrySet()) {
LogicalEdge lge = entry2.getKey();
SymbolicRoute r = entry2.getValue();
if ("true".equals(valuation.get(r.getPermitted()))) {
SortedMap<String, String> recordMap = new TreeMap<>();
GraphEdge ge = lge.getEdge();
String nodeIface = ge.getRouter() + "," + ge.getStart().getName() + " (BGP)";
envModel.put(nodeIface, recordMap);
if (r.getPrefixLength() != null) {
String x = valuation.get(r.getPrefixLength());
if (x != null) {
int len = Integer.parseInt(x);
Prefix p1 = new Prefix(dip, len);
recordMap.put("prefix", p1.toString());
}
}
if (r.getAdminDist() != null) {
String x = valuation.get(r.getAdminDist());
if (x != null) {
recordMap.put("admin distance", x);
}
}
if (r.getLocalPref() != null) {
String x = valuation.get(r.getLocalPref());
if (x != null) {
recordMap.put("local preference", x);
}
}
if (r.getMetric() != null) {
String x = valuation.get(r.getMetric());
if (x != null) {
recordMap.put("protocol metric", x);
}
}
if (r.getMed() != null) {
String x = valuation.get(r.getMed());
if (x != null) {
recordMap.put("multi-exit disc.", valuation.get(r.getMed()));
}
}
if (r.getOspfArea() != null && r.getOspfArea().getBitVec() != null) {
String x = valuation.get(r.getOspfArea().getBitVec());
if (x != null) {
Integer i = Integer.parseInt(x);
Long area = r.getOspfArea().value(i);
recordMap.put("OSPF Area", area.toString());
}
}
if (r.getOspfType() != null && r.getOspfType().getBitVec() != null) {
String x = valuation.get(r.getOspfType().getBitVec());
if (x != null) {
Integer i = Integer.parseInt(x);
OspfType type = r.getOspfType().value(i);
recordMap.put("OSPF Type", type.toString());
}
}
for (Entry<CommunityVar, BoolExpr> entry3 : r.getCommunities().entrySet()) {
CommunityVar cvar = entry3.getKey();
BoolExpr e = entry3.getValue();
String c = valuation.get(e);
// TODO: what about OTHER type?
if ("true".equals(c) && displayCommunity(cvar)) {
String s = cvar.getValue();
String t = slice.getNamedCommunities().get(cvar.getValue());
s = (t == null ? s : t);
recordMap.put("community " + s, "");
}
}
}
}
}
// Forwarding Model
enc.getMainSlice().getSymbolicDecisions().getDataForwarding().forEach((router, edge, e) -> {
String s = valuation.get(e);
if ("true".equals(s)) {
SymbolicRoute r = enc.getMainSlice().getSymbolicDecisions().getBestNeighbor().get(router);
if (r.getProtocolHistory() != null) {
Protocol proto;
List<Protocol> allProtocols = enc.getMainSlice().getProtocols().get(router);
if (allProtocols.size() == 1) {
proto = allProtocols.get(0);
} else {
s = valuation.get(r.getProtocolHistory().getBitVec());
int i = Integer.parseInt(s);
proto = r.getProtocolHistory().value(i);
}
fwdModel.add(edge + " (" + proto.name() + ")");
} else {
fwdModel.add(edge.toString());
}
}
});
_symbolicFailures.getFailedInternalLinks().forEach((x, y, e) -> {
String s = valuation.get(e);
if ("1".equals(s)) {
String pair = (x.compareTo(y) < 0 ? x + "," + y : y + "," + x);
failures.add("link(" + pair + ")");
}
});
_symbolicFailures.getFailedEdgeLinks().forEach((ge, e) -> {
String s = valuation.get(e);
if ("1".equals(s)) {
failures.add("link(" + ge.getRouter() + "," + ge.getStart().getName() + ")");
}
});
}
use of com.google.api.expr.v1alpha1.Expr in project batfish by batfish.
the class PropertyChecker method checkEqualLength.
/*
* Computes whether a collection of source routers will always have
* equal path length to destination port(s).
*/
public AnswerElement checkEqualLength(HeaderLocationQuestion q) {
return checkProperty(q, (enc, srcRouters, destPorts) -> {
PropertyAdder pa = new PropertyAdder(enc.getMainSlice());
Map<String, ArithExpr> lenVars = pa.instrumentPathLength(destPorts);
Map<String, BoolExpr> eqVars = new HashMap<>();
List<Expr> lens = new ArrayList<>();
for (String router : srcRouters) {
lens.add(lenVars.get(router));
}
BoolExpr allEqual = PropertyAdder.allEqual(enc.getCtx(), lens);
enc.add(enc.mkNot(allEqual));
for (Entry<String, ArithExpr> entry : lenVars.entrySet()) {
String name = entry.getKey();
BoolExpr b = srcRouters.contains(name) ? allEqual : enc.mkTrue();
eqVars.put(name, b);
}
return eqVars;
}, (vp) -> new SmtOneAnswerElement(vp.getResult()));
}
use of com.google.api.expr.v1alpha1.Expr in project batfish by batfish.
the class SymbolicRoute method addExprs.
// TODO: depends on configuration
/*
* Check if a particular protocol on a router is configured
* to use multipath routing or not.
*/
/* private boolean isMultipath(String router, Protocol proto, boolean isIbgp) {
Configuration conf = _enc.getGraph().getConfigurations().get(router);
if (proto.isConnected()) {
return true;
} else if (proto.isStatic()) {
return true;
} else if (proto.isOspf()) {
return true;
} else if (proto.isBgp()) {
BgpProcess p = conf.getDefaultVrf().getBgpProcess();
if (isIbgp) {
return p.getMultipathIbgp();
} else {
return p.getMultipathEbgp();
}
} else {
return true;
}
} */
private void addExprs(EncoderSlice enc) {
Map<String, Expr> all = enc.getAllVariables();
all.put(_permitted.toString(), _permitted);
if (_adminDist != null) {
all.put(_adminDist.toString(), _adminDist);
}
if (_med != null) {
all.put(_med.toString(), _med);
}
if (_localPref != null) {
all.put(_localPref.toString(), _localPref);
}
if (_metric != null) {
all.put(_metric.toString(), _metric);
}
if (_prefixLength != null) {
all.put(_prefixLength.toString(), _prefixLength);
}
if (_routerId != null) {
all.put(_routerId.toString(), _routerId);
}
if (_bgpInternal != null) {
all.put(_bgpInternal.toString(), _bgpInternal);
}
if (_ospfArea != null) {
all.put(_ospfArea.getBitVec().toString(), _ospfArea.getBitVec());
}
if (_ospfType != null) {
all.put(_ospfType.getBitVec().toString(), _ospfType.getBitVec());
}
if (_clientId != null) {
all.put(_clientId.getBitVec().toString(), _clientId.getBitVec());
}
if (_igpMetric != null) {
all.put(_igpMetric.toString(), _igpMetric);
}
for (BoolExpr var : _communities.values()) {
all.put(var.toString(), var);
}
}
use of com.google.api.expr.v1alpha1.Expr in project batfish by batfish.
the class TransferSSA method compute.
/*
* Convert a list of statements into a Z3 boolean expression for the transfer function.
*/
private TransferResult<BoolExpr, BoolExpr> compute(List<Statement> statements, TransferParam<SymbolicRoute> p, TransferResult<BoolExpr, BoolExpr> result) {
boolean doesReturn = false;
for (Statement stmt : statements) {
if (stmt instanceof StaticStatement) {
StaticStatement ss = (StaticStatement) stmt;
switch(ss.getType()) {
case ExitAccept:
doesReturn = true;
p.debug("ExitAccept");
result = returnValue(p, result, true);
break;
case ReturnTrue:
doesReturn = true;
p.debug("ReturnTrue");
result = returnValue(p, result, true);
break;
case ExitReject:
doesReturn = true;
p.debug("ExitReject");
result = returnValue(p, result, false);
break;
case ReturnFalse:
doesReturn = true;
p.debug("ReturnFalse");
result = returnValue(p, result, false);
break;
case SetDefaultActionAccept:
p.debug("SetDefaulActionAccept");
p = p.setDefaultAccept(true);
break;
case SetDefaultActionReject:
p.debug("SetDefaultActionReject");
p = p.setDefaultAccept(false);
break;
case SetLocalDefaultActionAccept:
p.debug("SetLocalDefaultActionAccept");
p = p.setDefaultAcceptLocal(true);
break;
case SetLocalDefaultActionReject:
p.debug("SetLocalDefaultActionReject");
p = p.setDefaultAcceptLocal(false);
break;
case ReturnLocalDefaultAction:
p.debug("ReturnLocalDefaultAction");
// TODO: need to set local default action in an environment
if (p.getDefaultAcceptLocal()) {
result = returnValue(p, result, true);
} else {
result = returnValue(p, result, false);
}
break;
case FallThrough:
p.debug("Fallthrough");
result = fallthrough(p, result);
break;
case Return:
// TODO: assumming this happens at the end of the function, so it is ignored for now.
p.debug("Return");
break;
case RemovePrivateAs:
p.debug("RemovePrivateAs");
System.out.println("Warning: use of unimplemented feature RemovePrivateAs");
break;
default:
throw new BatfishException("TODO: computeTransferFunction: " + ss.getType());
}
} else if (stmt instanceof If) {
p.debug("If");
If i = (If) stmt;
TransferResult<BoolExpr, BoolExpr> r = compute(i.getGuard(), p);
result = result.addChangedVariables(r);
BoolExpr guard = (BoolExpr) r.getReturnValue().simplify();
String str = guard.toString();
// If there are updates in the guard, add them to the parameter p before entering branches
for (Pair<String, Expr> changed : r.getChangedVariables()) {
p.debug("CHANGED: " + changed.getFirst());
updateSingleValue(p, changed.getFirst(), changed.getSecond());
}
p.debug("guard: " + str);
// If we know the branch ahead of time, then specialize
switch(str) {
case "true":
p.debug("True Branch");
result = compute(i.getTrueStatements(), p.indent(), result);
break;
case "false":
p.debug("False Branch");
compute(i.getFalseStatements(), p.indent(), result);
break;
default:
p.debug("True Branch");
// clear changed variables before proceeding
TransferParam<SymbolicRoute> p1 = p.indent().setData(p.getData().copy());
TransferParam<SymbolicRoute> p2 = p.indent().setData(p.getData().copy());
TransferResult<BoolExpr, BoolExpr> trueBranch = compute(i.getTrueStatements(), p1, initialResult());
p.debug("False Branch");
TransferResult<BoolExpr, BoolExpr> falseBranch = compute(i.getFalseStatements(), p2, initialResult());
p.debug("JOIN");
PList<Pair<String, Pair<Expr, Expr>>> pairs = trueBranch.mergeChangedVariables(falseBranch);
// Extract and deal with the return value first so that other
// variables have this reflected in their value
int idx = pairs.find(pair -> pair.getFirst().equals("RETURN"));
if (idx >= 0) {
Pair<String, Pair<Expr, Expr>> ret = pairs.get(idx);
pairs = pairs.minus(idx);
pairs = pairs.plus(pairs.size(), ret);
}
for (Pair<String, Pair<Expr, Expr>> pair : pairs) {
String s = pair.getFirst();
p.debug("CHANGED: " + s);
Pair<Expr, Expr> x = joinPoint(p, result, guard, pair);
result = result.addChangedVariable(s, x.getFirst());
if (s.equals("RETURN")) {
result = result.setReturnValue((BoolExpr) x.getFirst()).setReturnAssignedValue((BoolExpr) x.getSecond());
}
if (s.equals("FALLTHROUGH")) {
result = result.setFallthroughValue((BoolExpr) x.getFirst()).setReturnAssignedValue((BoolExpr) x.getSecond());
}
}
break;
}
} else if (stmt instanceof SetDefaultPolicy) {
p.debug("SetDefaultPolicy");
p = p.setDefaultPolicy((SetDefaultPolicy) stmt);
} else if (stmt instanceof SetMetric) {
p.debug("SetMetric");
// TODO: what is the semantics for BGP? Is this MED?
if (!_current.getProto().isBgp()) {
SetMetric sm = (SetMetric) stmt;
LongExpr ie = sm.getMetric();
ArithExpr newValue = applyLongExprModification(p.getData().getMetric(), ie);
newValue = _enc.mkIf(result.getReturnAssignedValue(), p.getData().getMetric(), newValue);
ArithExpr x = createArithVariableWith(p, "METRIC", newValue);
p.getData().setMetric(x);
result = result.addChangedVariable("METRIC", x);
}
} else if (stmt instanceof SetOspfMetricType) {
p.debug("SetOspfMetricType");
SetOspfMetricType somt = (SetOspfMetricType) stmt;
OspfMetricType mt = somt.getMetricType();
SymbolicOspfType t;
if (mt == OspfMetricType.E1) {
t = new SymbolicOspfType(_enc, OspfType.E1);
} else {
t = new SymbolicOspfType(_enc, OspfType.E2);
}
BitVecExpr newValue = t.getBitVec();
newValue = _enc.mkIf(result.getReturnAssignedValue(), p.getData().getOspfType().getBitVec(), newValue);
BitVecExpr x = createBitVecVariableWith(p, "OSPF-TYPE", 2, newValue);
p.getData().getOspfType().setBitVec(x);
result = result.addChangedVariable("OSPF-TYPE", x);
} else if (stmt instanceof SetLocalPreference) {
p.debug("SetLocalPreference");
SetLocalPreference slp = (SetLocalPreference) stmt;
IntExpr ie = slp.getLocalPreference();
ArithExpr newValue = applyIntExprModification(p.getData().getLocalPref(), ie);
newValue = _enc.mkIf(result.getReturnAssignedValue(), p.getData().getLocalPref(), newValue);
ArithExpr x = createArithVariableWith(p, "LOCAL-PREF", newValue);
p.getData().setLocalPref(x);
result = result.addChangedVariable("LOCAL-PREF", x);
} else if (stmt instanceof AddCommunity) {
p.debug("AddCommunity");
AddCommunity ac = (AddCommunity) stmt;
Set<CommunityVar> comms = _enc.getGraph().findAllCommunities(_conf, ac.getExpr());
for (CommunityVar cvar : comms) {
BoolExpr newValue = _enc.mkIf(result.getReturnAssignedValue(), p.getData().getCommunities().get(cvar), _enc.mkTrue());
BoolExpr x = createBoolVariableWith(p, cvar.getValue(), newValue);
p.getData().getCommunities().put(cvar, x);
result = result.addChangedVariable(cvar.getValue(), x);
}
} else if (stmt instanceof SetCommunity) {
p.debug("SetCommunity");
SetCommunity sc = (SetCommunity) stmt;
Set<CommunityVar> comms = _enc.getGraph().findAllCommunities(_conf, sc.getExpr());
for (CommunityVar cvar : comms) {
BoolExpr newValue = _enc.mkIf(result.getReturnAssignedValue(), p.getData().getCommunities().get(cvar), _enc.mkTrue());
BoolExpr x = createBoolVariableWith(p, cvar.getValue(), newValue);
p.getData().getCommunities().put(cvar, x);
result = result.addChangedVariable(cvar.getValue(), x);
}
} else if (stmt instanceof DeleteCommunity) {
p.debug("DeleteCommunity");
DeleteCommunity ac = (DeleteCommunity) stmt;
Set<CommunityVar> comms = _enc.getGraph().findAllCommunities(_conf, ac.getExpr());
Set<CommunityVar> toDelete = new HashSet<>();
// Find comms to delete
for (CommunityVar cvar : comms) {
if (cvar.getType() == Type.REGEX) {
toDelete.addAll(_enc.getCommunityDependencies().get(cvar));
} else {
toDelete.add(cvar);
}
}
// Delete each community
for (CommunityVar cvar : toDelete) {
BoolExpr newValue = _enc.mkIf(result.getReturnAssignedValue(), p.getData().getCommunities().get(cvar), _enc.mkFalse());
BoolExpr x = createBoolVariableWith(p, cvar.getValue(), newValue);
p.getData().getCommunities().put(cvar, x);
result = result.addChangedVariable(cvar.getValue(), x);
}
} else if (stmt instanceof RetainCommunity) {
p.debug("RetainCommunity");
// no op
} else if (stmt instanceof PrependAsPath) {
p.debug("PrependAsPath");
PrependAsPath pap = (PrependAsPath) stmt;
Integer prependCost = prependLength(pap.getExpr());
ArithExpr newValue = _enc.mkSum(p.getData().getMetric(), _enc.mkInt(prependCost));
newValue = _enc.mkIf(result.getReturnAssignedValue(), p.getData().getMetric(), newValue);
ArithExpr x = createArithVariableWith(p, "METRIC", newValue);
p.getData().setMetric(x);
result = result.addChangedVariable("METRIC", x);
} else if (stmt instanceof SetOrigin) {
p.debug("SetOrigin");
System.out.println("Warning: use of unimplemented feature SetOrigin");
} else if (stmt instanceof SetNextHop) {
p.debug("SetNextHop");
System.out.println("Warning: use of unimplemented feature SetNextHop");
} else {
String s = (_isExport ? "export" : "import");
String msg = String.format("Unimplemented feature %s for %s transfer function on interface %s", stmt.toString(), s, _graphEdge.toString());
throw new BatfishException(msg);
}
}
// If this is the outermost call, then we relate the variables
if (p.getInitialCall()) {
p.debug("InitialCall finalizing");
// Apply the default action
if (!doesReturn) {
p.debug("Applying default action: " + p.getDefaultAccept());
if (p.getDefaultAccept()) {
result = returnValue(p, result, true);
} else {
result = returnValue(p, result, false);
}
}
BoolExpr related = relateVariables(p, result);
BoolExpr retValue = _enc.mkIf(result.getReturnValue(), related, _enc.mkNot(_current.getPermitted()));
result = result.setReturnValue(retValue);
}
return result;
}
Aggregations