use of kodkod.ast.operator.Quantifier in project org.alloytools.alloy by AlloyTools.
the class FOL2BoolTranslator method visit.
/**
* Calls lookup(quantFormula) and returns the cached value, if any. If a
* translation has not been cached, translates the formula, calls cache(...) on
* it and returns it.
*
* @return let t = lookup(quantFormula) | some t => t, cache(quantFormula,
* translate(quantFormula))
*/
@Override
public final BooleanValue visit(QuantifiedFormula quantFormula) {
BooleanValue ret = lookup(quantFormula);
if (ret != null)
return ret;
final Quantifier quantifier = quantFormula.quantifier();
switch(quantifier) {
case ALL:
final BooleanAccumulator and = BooleanAccumulator.treeGate(Operator.AND);
all(quantFormula.decls(), quantFormula.formula(), 0, BooleanConstant.FALSE, and);
ret = interpreter.factory().accumulate(and);
break;
case SOME:
final BooleanAccumulator or = BooleanAccumulator.treeGate(Operator.OR);
some(quantFormula.decls(), quantFormula.formula(), 0, BooleanConstant.TRUE, or);
ret = interpreter.factory().accumulate(or);
break;
default:
throw new IllegalArgumentException("Unknown quantifier: " + quantifier);
}
return cache(quantFormula, ret);
}
use of kodkod.ast.operator.Quantifier in project org.alloytools.alloy by AlloyTools.
the class Skolemizer method visit.
/**
* Skolemizes the given formula, if possible, otherwise returns the result of
* replacing its free variables according to the current replacement
* environment.
*
* @see kodkod.ast.visitor.AbstractReplacer#visit(kodkod.ast.QuantifiedFormula)
*/
@Override
public final Formula visit(QuantifiedFormula qf) {
Formula ret = lookup(qf);
if (ret != null)
return ret;
final Environment<Expression, Expression> oldRepEnv = repEnv;
final Quantifier quant = qf.quantifier();
final Decls decls = qf.decls();
if (skolemDepth >= 0 && (negated && quant == ALL || !negated && quant == SOME)) {
// skolemizable
// formula
final List<Formula> rangeConstraints = new LinkedList<Formula>();
final List<Formula> domConstraints = new LinkedList<Formula>();
for (Decl decl : decls) {
final Decl skolemDecl = visit(decl);
Variable skVar = skolemDecl.variable();
final Relation skolem = Relation.skolem("$" + skVar.name(), nonSkolems.size() + skVar.arity(), skVar, skolemDecl, quant);
reporter.skolemizing(decl, skolem, nonSkolemsView);
final Expression skolemExpr = skolemExpr(skolemDecl, skolem);
final Multiplicity mult = decl.multiplicity();
rangeConstraints.add(source(skolemExpr.in(skolemDecl.expression()), decl));
if (mult != Multiplicity.SET) {
rangeConstraints.add(source(skolemExpr.apply(mult), decl));
}
if (!nonSkolems.isEmpty())
domConstraints.add(source(domainConstraint(skolemDecl, skolem), decl));
repEnv = repEnv.extend(decl.variable(), decl.expression(), skolemExpr);
}
ret = source(Formula.and(rangeConstraints), decls).compose(negated ? IMPLIES : AND, qf.formula().accept(this));
if (!domConstraints.isEmpty())
topSkolemConstraints.add(source(Formula.and(domConstraints), decls));
} else {
// non-skolemizable formula
final Decls newDecls = visit(qf.decls());
if (skolemDepth >= nonSkolems.size() + newDecls.size()) {
// below
for (Decl d : newDecls) {
nonSkolems.add(new DeclInfo(d));
}
final Formula domain = qf.domain().accept(this);
final Formula body = qf.body().accept(this);
ret = ((newDecls == decls && domain == qf.domain() && body == qf.body()) ? qf : body.quantify(quant, newDecls, domain));
for (int i = newDecls.size(); i > 0; i--) {
nonSkolems.remove(nonSkolems.size() - 1);
}
} else {
// can't skolemize below
final int oldDepth = skolemDepth;
skolemDepth = -1;
final Formula domain = qf.domain().accept(this);
final Formula body = qf.body().accept(this);
ret = ((newDecls == decls && domain == qf.domain() && body == qf.body()) ? qf : body.quantify(quant, newDecls, domain));
skolemDepth = oldDepth;
}
}
repEnv = oldRepEnv;
if (repEnv.isEmpty() && !topSkolemConstraints.isEmpty()) {
ret = source(Formula.and(topSkolemConstraints), qf).compose(negated ? IMPLIES : AND, ret);
}
return source(cache(qf, ret), qf);
}
use of kodkod.ast.operator.Quantifier 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.operator.Quantifier 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;
}
Aggregations