package org.batfish.z3;
import java.util.ArrayList;
import java.util.List;
import org.batfish.datamodel.IpAccessList;
import org.batfish.datamodel.IpAccessListLine;
import org.batfish.z3.node.AndExpr;
import org.batfish.z3.node.BooleanExpr;
import org.batfish.z3.node.DeclareRelExpr;
import org.batfish.z3.node.NotExpr;
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 class EarliestMoreGeneralReachableLineQuerySynthesizer
extends FirstUnsatQuerySynthesizer<AclLine, Integer> {
private String _aclName;
private List<AclLine> _earlierReachableLines;
private String _hostname;
private IpAccessList _list;
private AclLine _unreachableLine;
public EarliestMoreGeneralReachableLineQuerySynthesizer(
AclLine unreachableLine, List<AclLine> earlierReachableLines,
IpAccessList list) {
super(unreachableLine);
_unreachableLine = unreachableLine;
_earlierReachableLines = earlierReachableLines;
_hostname = _unreachableLine.getHostname();
_aclName = _unreachableLine.getAclName();
_list = list;
}
@Override
public NodProgram getNodProgram(NodProgram baseProgram) throws Z3Exception {
Context ctx = baseProgram.getContext();
NodProgram program = new NodProgram(ctx);
int unreachableLineIndex = _unreachableLine.getLine();
IpAccessListLine unreachableLine = _list.getLines()
.get(unreachableLineIndex);
BooleanExpr matchUnreachableLineHeaderSpace = Synthesizer
.matchHeaderSpace(unreachableLine);
for (AclLine earlierReachableLine : _earlierReachableLines) {
int earlierLineIndex = earlierReachableLine.getLine();
IpAccessListLine earlierLine = _list.getLines().get(earlierLineIndex);
BooleanExpr matchEarlierLineHeaderSpace = Synthesizer
.matchHeaderSpace(earlierLine);
AndExpr queryConditions = new AndExpr();
queryConditions.addConjunct(new NotExpr(matchEarlierLineHeaderSpace));
queryConditions.addConjunct(matchUnreachableLineHeaderSpace);
queryConditions.addConjunct(SaneExpr.INSTANCE);
NumberedQueryExpr queryRel = new NumberedQueryExpr(earlierLineIndex);
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);
_resultsByQueryIndex.add(earlierLineIndex);
}
return program;
}
@Override
public NodProgram synthesizeBaseProgram(Synthesizer synthesizer,
Context ctx) {
return synthesizer.synthesizeNodAclProgram(_hostname, _aclName, ctx);
}
}