package org.batfish.z3;
import java.util.ArrayList;
import java.util.List;
import org.batfish.z3.node.AclMatchExpr;
import org.batfish.z3.node.AndExpr;
import org.batfish.z3.node.DeclareRelExpr;
import org.batfish.z3.node.NumberedQueryExpr;
import org.batfish.z3.node.QueryExpr;
import org.batfish.z3.node.RuleExpr;
import org.batfish.z3.node.SaneExpr;
import com.microsoft.z3.BoolExpr;
import com.microsoft.z3.Context;
import com.microsoft.z3.Z3Exception;
public final class AclReachabilityQuerySynthesizer
extends SatQuerySynthesizer<AclLine> {
private final String _aclName;
private final String _hostname;
private final int _numLines;
public AclReachabilityQuerySynthesizer(String hostname, String aclName,
int numLines) {
_hostname = hostname;
_aclName = aclName;
_numLines = numLines;
}
@Override
public NodProgram getNodProgram(NodProgram baseProgram) throws Z3Exception {
Context ctx = baseProgram.getContext();
NodProgram program = new NodProgram(ctx);
for (int line = 0; line < _numLines; line++) {
AclMatchExpr matchAclLine = new AclMatchExpr(_hostname, _aclName,
line);
AndExpr queryConditions = new AndExpr();
queryConditions.addConjunct(matchAclLine);
queryConditions.addConjunct(SaneExpr.INSTANCE);
NumberedQueryExpr queryRel = new NumberedQueryExpr(line);
String queryRelName = queryRel.getRelations()
.toArray(new String[] {})[0];
List<Integer> sizes = new ArrayList<>();
sizes.addAll(Synthesizer.PACKET_VAR_SIZES.values());
DeclareRelExpr declaration = new DeclareRelExpr(queryRelName, sizes);
baseProgram.getRelationDeclarations().put(queryRelName,
declaration.toFuncDecl(ctx));
RuleExpr queryRule = new RuleExpr(queryConditions, queryRel);
List<BoolExpr> rules = program.getRules();
rules.add(queryRule.toBoolExpr(baseProgram));
QueryExpr query = new QueryExpr(queryRel);
BoolExpr queryBoolExpr = query.toBoolExpr(baseProgram);
program.getQueries().add(queryBoolExpr);
_keys.add(new AclLine(_hostname, _aclName, line));
}
return program;
}
@Override
public NodProgram synthesizeBaseProgram(Synthesizer synthesizer,
Context ctx) {
return synthesizer.synthesizeNodAclProgram(_hostname, _aclName, ctx);
}
}