use of kodkod.ast.QuantifiedFormula in project org.alloytools.alloy by AlloyTools.
the class TranslateAlloyToKodkod method visit_qt.
/**
* Helper method that translates the quantification expression "op vars | sub"
*/
private Object visit_qt(final ExprQt.Op op, final ConstList<Decl> xvars, final Expr sub) throws Err {
if (op == ExprQt.Op.NO) {
return visit_qt(ExprQt.Op.ALL, xvars, sub.not());
}
if (op == ExprQt.Op.ONE || op == ExprQt.Op.LONE) {
boolean ok = true;
for (int i = 0; i < xvars.size(); i++) {
Expr v = addOne(xvars.get(i).expr).deNOP();
if (v.type().arity() != 1 || v.mult() != ExprUnary.Op.ONEOF) {
ok = false;
break;
}
}
if (op == ExprQt.Op.ONE && ok)
return ((Expression) visit_qt(ExprQt.Op.COMPREHENSION, xvars, sub)).one();
if (op == ExprQt.Op.LONE && ok)
return ((Expression) visit_qt(ExprQt.Op.COMPREHENSION, xvars, sub)).lone();
}
if (op == ExprQt.Op.ONE) {
Formula f1 = (Formula) visit_qt(ExprQt.Op.LONE, xvars, sub);
Formula f2 = (Formula) visit_qt(ExprQt.Op.SOME, xvars, sub);
return f1.and(f2);
}
if (op == ExprQt.Op.LONE) {
QuantifiedFormula p1 = (QuantifiedFormula) visit_qt(ExprQt.Op.ALL, xvars, sub);
QuantifiedFormula p2 = (QuantifiedFormula) visit_qt(ExprQt.Op.ALL, xvars, sub);
Decls s1 = p1.decls(), s2 = p2.decls(), decls = null;
Formula f1 = p1.formula(), f2 = p2.formula();
Formula[] conjuncts = new Formula[s1.size()];
for (int i = 0; i < conjuncts.length; i++) {
kodkod.ast.Decl d1 = s1.get(i), d2 = s2.get(i);
conjuncts[i] = d1.variable().eq(d2.variable());
if (decls == null)
decls = d1.and(d2);
else
decls = decls.and(d1).and(d2);
}
return f1.and(f2).implies(Formula.and(conjuncts)).forAll(decls);
}
Decls dd = null;
List<Formula> guards = new ArrayList<Formula>();
for (Decl dep : xvars) {
final Expr dexexpr = addOne(dep.expr);
final Expression dv = cset(dexexpr);
for (ExprHasName dex : dep.names) {
final Variable v = Variable.nary(skolem(dex.label), dex.type().arity());
final kodkod.ast.Decl newd;
env.put((ExprVar) dex, v);
if (dex.type().arity() != 1) {
guards.add(isIn(v, dexexpr));
newd = v.setOf(dv);
} else
switch(dexexpr.mult()) {
case SETOF:
newd = v.setOf(dv);
break;
case SOMEOF:
newd = v.someOf(dv);
break;
case LONEOF:
newd = v.loneOf(dv);
break;
default:
newd = v.oneOf(dv);
}
if (frame != null)
frame.kv2typepos(v, dex.type(), dex.pos);
if (dd == null)
dd = newd;
else
dd = dd.and(newd);
}
}
final Formula ans = (op == ExprQt.Op.SUM) ? null : cform(sub);
final IntExpression ians = (op != ExprQt.Op.SUM) ? null : cint(sub);
for (Decl d : xvars) for (ExprHasName v : d.names) env.remove((ExprVar) v);
if (op == ExprQt.Op.COMPREHENSION)
// guards.size()==0, since each var
return ans.comprehension(dd);
// has to be unary
if (op == ExprQt.Op.SUM)
// guards.size()==0, since each var has to be
return ians.sum(dd);
// unary
if (op == ExprQt.Op.SOME) {
if (guards.size() == 0)
return ans.forSome(dd);
guards.add(ans);
return Formula.and(guards).forSome(dd);
} else {
if (guards.size() == 0)
return ans.forAll(dd);
return Formula.and(guards).implies(ans).forAll(dd);
}
}
use of kodkod.ast.QuantifiedFormula in project org.alloytools.alloy by AlloyTools.
the class AbstractReplacer method visit.
/**
* Calls lookup(quantFormula) and returns the cached value, if any. If a
* replacement has not been cached, visits the formula's children. If nothing
* changes, the argument is cached and returned, otherwise a replacement formula
* is cached and returned.
*
* @return { q: QuantifiedFormula | q.declarations =
* quantFormula.declarations.accept(delegate) && q.formula =
* quantFormula.formula.accept(delegate) }
*/
@Override
public Formula visit(QuantifiedFormula quantFormula) {
Formula ret = lookup(quantFormula);
if (ret != null)
return ret;
final Decls decls = quantFormula.decls().accept(delegate);
final Formula domain = quantFormula.domain().accept(delegate);
final Formula body = quantFormula.body().accept(delegate);
ret = (decls == quantFormula.decls() && domain == quantFormula.domain() && body == quantFormula.body()) ? quantFormula : body.quantify(quantFormula.quantifier(), decls, domain);
return cache(quantFormula, ret);
}
use of kodkod.ast.QuantifiedFormula in project org.alloytools.alloy by AlloyTools.
the class FormulaFlattener method visit.
/**
* {@inheritDoc}
*
* @see kodkod.ast.visitor.AbstractVoidVisitor#visit(kodkod.ast.QuantifiedFormula)
*/
@Override
public final void visit(QuantifiedFormula qf) {
if (visited(qf))
return;
if (breakupQuantifiers) {
final Quantifier quant = qf.quantifier();
if ((!negated && quant == ALL) || (negated && quant == SOME)) {
// may
// break
// down
// further
final Map<Formula, Node> oldConjuncts = conjuncts;
conjuncts = new LinkedHashMap<Formula, Node>();
qf.formula().accept(this);
if (conjuncts.size() > 1) {
// was broken down further
final Decls decls = qf.decls();
for (Map.Entry<Formula, Node> entry : conjuncts.entrySet()) {
oldConjuncts.put(entry.getKey().forAll(decls), entry.getValue());
}
conjuncts = oldConjuncts;
return;
} else {
// wasn't broken down further
conjuncts = oldConjuncts;
}
}
// won't break down further
}
addConjunct(qf);
}
use of kodkod.ast.QuantifiedFormula in project org.alloytools.alloy by AlloyTools.
the class FullNegationPropagator method visit.
@Override
public final void visit(QuantifiedFormula qf) {
if (visited(qf))
return;
FullNegationPropagator fneBody = new FullNegationPropagator(shared, annotations);
fneBody.negated = negated;
boolean wasNegated = negated;
negated = false;
qf.body().accept(fneBody);
FullNegationPropagator fneDomain = new FullNegationPropagator(shared, annotations);
qf.domain().accept(fneDomain);
if (fneBody.hasChanged || fneDomain.hasChanged || wasNegated) {
Formula qfBody = Formula.and(fneBody.conjuncts);
Quantifier quant = wasNegated ? qf.quantifier().opposite : qf.quantifier();
addConjunct(qfBody.quantify(quant, qf.decls(), Formula.and(fneDomain.conjuncts)), false, qf);
hasChanged = true;
} else {
addConjunct(qf);
}
negated = wasNegated;
}
use of kodkod.ast.QuantifiedFormula in project org.alloytools.alloy by AlloyTools.
the class PrenexNFConverter method visit.
@Override
public Formula visit(NaryFormula formula) {
final ArrayList<Formula> children = new ArrayList<Formula>(formula.size());
boolean allSame = true;
boolean noQuant = true;
for (Formula ch : formula) {
Formula ch2 = ch.accept(this);
allSame = allSame && ch == ch2;
noQuant = noQuant && !(ch2 instanceof QuantifiedFormula);
children.add(ch2);
}
Formula ans;
if (allSame && noQuant) {
ans = formula;
} else {
ans = children.get(0);
for (int i = 1; i < children.size(); i++) ans = new Pair(ans, children.get(i)).compose(formula.op());
}
return saveMapping(ans, formula);
}
Aggregations