package jayhorn.hornify;
import java.util.List;
import java.util.Map;
import jayhorn.solver.Prover;
import jayhorn.solver.ProverExpr;
import jayhorn.solver.ProverFun;
import jayhorn.solver.ProverTupleExpr;
import jayhorn.solver.ProverTupleType;
import jayhorn.solver.ProverType;
import soottocfg.cfg.variable.Variable;
public class HornPredicate {
public final String name;
public final List<Variable> variables;
public final ProverFun predicate;
private final Prover p;
public HornPredicate(Prover p, String name, List<Variable> vars) {
this.name = name;
this.p = p;
variables = vars;
predicate = HornHelper.hh().genHornPredicate(p, name, vars);
}
public String toString() {
return "" + predicate;
}
public ProverExpr instPredicate(Map<Variable, ProverExpr> varMap) {
List<ProverExpr> allArgs = HornHelper.hh().findOrCreateProverVar(p, variables, varMap);
ProverExpr[] exprs = allArgs.toArray(new ProverExpr[allArgs.size()]);
/*
* Adjust the size of TupleExpr if necessary. This happens when dealing
* with subtyping etc.
*/
for (int i = 0; i<variables.size(); i++) {
ProverType pt = HornHelper.hh().getProverType(p,variables.get(i).getType());
if (pt instanceof ProverTupleType) {
ProverTupleType ptt = (ProverTupleType)pt;
ProverTupleExpr pte = (ProverTupleExpr)exprs[i];
if (pte.getArity()>ptt.getArity()) {
ProverExpr[] tupleElements = new ProverExpr[ptt.getArity()];
for (int j=0;j<ptt.getArity();j++) {
if (j<pte.getArity()) {
tupleElements[j]=pte.getSubExpr(j);
} else {
tupleElements[j]=p.mkVariable("$dummy"+i+j, ptt.getSubType(j));
}
}
exprs[i] = new ProverTupleExpr(tupleElements);
} else if (pte.getArity()<ptt.getArity()) {
ProverExpr[] tupleElements = new ProverExpr[ptt.getArity()];
for (int j=0;j<ptt.getArity();j++) {
tupleElements[j]=pte.getSubExpr(j);
}
exprs[i] = new ProverTupleExpr(tupleElements);
} else {
//do nothing.
}
}
}
return predicate.mkExpr(exprs);
}
}