use of kodkod.ast.Decl in project org.alloytools.alloy by AlloyTools.
the class FOL2BoolTranslator method visit.
/**
* Calls lookup(decls) and returns the cached value, if any. If a translation
* has not been cached, translates decls into a list of translations of its
* children, calls cache(...) on it and returns it.
*
* @return let t = lookup(decls) | some t => t, cache(decl,
* decls.declarations.expression.accept(this))
*/
@Override
public final List<BooleanMatrix> visit(Decls decls) {
List<BooleanMatrix> ret = lookup(decls);
if (ret != null)
return ret;
ret = new ArrayList<BooleanMatrix>(decls.size());
for (Decl decl : decls) {
ret.add(visit(decl));
}
return cache(decls, ret);
}
use of kodkod.ast.Decl 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.Decl in project org.alloytools.alloy by AlloyTools.
the class Skolemizer method visit.
/*-------declarations---------*/
/**
* Visits the given decl's expression. Note that we must not visit variables in
* case they are re-used. For example, consider the formula some x: X | all x: Y
* | F(x). Since x bound by the existential quantifier is going to be
* skolemized, if we visited the variable in the enclosed declaration, we would
* get the skolem constant as a return value and a ClassCastException would be
* thrown.
*
* @return { d: Declaration | d.variable = decl.variable && d.multiplicity =
* decl.multiplicity && d.expression = decl.expression.accept(this) }
*/
@Override
public final Decl visit(Decl decl) {
Decl ret = lookup(decl);
if (ret != null)
return ret;
final int oldDepth = skolemDepth;
// can't skolemize inside a decl
skolemDepth = -1;
final Expression expression = decl.expression().accept(this);
skolemDepth = oldDepth;
ret = (expression == decl.expression()) ? decl : decl.variable().declare(decl.multiplicity(), expression);
return cache(decl, ret);
}
use of kodkod.ast.Decl in project org.alloytools.alloy by AlloyTools.
the class Skolemizer method visit.
/**
* This method should be accessed only from the context of a non-skolemizable
* node, because it extends the replacement environment with identity mappings
* for the variables declared in the given decls. To ensure that the environment
* is always extended, the method should be called using the visit((Decls)
* node.declarations()) syntax, since the accept syntax may dynamically dispatch
* the call to the {@link #visit(Decl)} method, producing UnboundLeafExceptions.
*
* @ensures this.repEnv in this.repEnv'.^parent && #(this.repEnv'.*parent -
* this.repEnv.*parent) = decls.size() && all v: decls.variable |
* this.repEnv'.lookup(v) = v
* @requires this.skolemDepth < 0
* @return { d: Decls | d.size = decls.size && all i: [0..d.size) |
* d.declarations[i] = decls.declarations[i].accept(this) }
*/
@Override
public final Decls visit(Decls decls) {
Decls ret = lookup(decls);
if (ret == null) {
Decls visitedDecls = null;
boolean allSame = true;
for (Decl decl : decls) {
Decls newDecl = visit(decl);
if (newDecl != decl)
allSame = false;
visitedDecls = (visitedDecls == null) ? newDecl : visitedDecls.and(newDecl);
repEnv = repEnv.extend(decl.variable(), decl.expression(), decl.variable());
}
ret = allSame ? decls : visitedDecls;
return cache(decls, ret);
} else {
// just extend the replacement environment
for (Decl decl : decls) {
repEnv = repEnv.extend(decl.variable(), decl.expression(), decl.variable());
}
return ret;
}
}
use of kodkod.ast.Decl in project org.alloytools.alloy by AlloyTools.
the class AbstractCollector method visit.
/**
* Calls lookup(decls) and returns the cached value, if any. If no cached value
* exists, visits each child, caches the union of the sets returned by the
* children and returns it.
*
* @return let x = lookup(decls) | x != null => x, cache(decls,
* decls.declarations[0].accept(this) +...+
* decls.declarations[decls.size-1].accept(this))
*/
@Override
public Set<T> visit(Decls decls) {
Set<T> ret = lookup(decls);
if (ret != null)
return ret;
ret = newSet();
for (Decl d : decls) {
ret.addAll(d.accept(this));
}
return cache(decls, ret);
}
Aggregations