use of kodkod.util.nodes.AnnotatedNode in project org.alloytools.alloy by AlloyTools.
the class Translator method inlinePredicates.
/**
* Returns an annotated formula f such that f.node is equivalent to
* annotated.node with its <tt>simplified</tt> predicates replaced with their
* corresponding Formulas and the remaining predicates replaced with equivalent
* constraints. The annotated formula f will contain transitive source
* information for each of the subformulas of f.node. Specifically, let t be a
* subformula of f.node, and s be a descdendent of annotated.node from which t
* was derived. Then, f.source[t] = annotated.source[s].
* </p>
*
* @requires simplified.keySet() in
* annotated.predicates()[RelationPredicate.NAME]
* @requires no disj p, p': simplified.keySet() | simplified.get(p) =
* simplifed.get(p') // this must hold in order to maintain the
* invariant that each subformula of the returned formula has exactly
* one source
* @requires for each p in simplified.keySet(), the formulas "p and
* [[this.bounds]]" and "simplified.get(p) and [[this.bounds]]" are
* equisatisfiable
* @return an annotated formula f such that f.node is equivalent to
* annotated.node with its <tt>simplified</tt> predicates replaced with
* their corresponding Formulas and the remaining predicates replaced
* with equivalent constraints.
*/
private AnnotatedNode<Formula> inlinePredicates(final AnnotatedNode<Formula> annotated, final Map<RelationPredicate, Formula> simplified) {
final Map<Node, Node> sources = new IdentityHashMap<Node, Node>();
final AbstractReplacer inliner = new AbstractReplacer(annotated.sharedNodes()) {
private RelationPredicate source = null;
@Override
protected <N extends Node> N cache(N node, N replacement) {
if (replacement instanceof Formula) {
if (source == null) {
final Node nsource = annotated.sourceOf(node);
if (replacement != nsource)
sources.put(replacement, nsource);
} else {
sources.put(replacement, source);
}
}
return super.cache(node, replacement);
}
@Override
public Formula visit(RelationPredicate pred) {
Formula ret = lookup(pred);
if (ret != null)
return ret;
source = pred;
if (simplified.containsKey(pred)) {
ret = simplified.get(pred).accept(this);
} else {
ret = pred.toConstraints().accept(this);
}
source = null;
return cache(pred, ret);
}
};
return annotate(annotated.node().accept(inliner), sources);
}
use of kodkod.util.nodes.AnnotatedNode in project org.alloytools.alloy by AlloyTools.
the class FormulaFlattener method apply.
/**
* Returns the result of applying this visitor to the given annotated formula.
*
* @return the result of applying this visitor to the given annotated formula.
*/
final AnnotatedNode<Formula> apply(AnnotatedNode<Formula> annotated) {
annotated.node().accept(this);
final List<Formula> roots = new ArrayList<Formula>(conjuncts.size());
roots.addAll(conjuncts.keySet());
for (Iterator<Map.Entry<Formula, Node>> itr = conjuncts.entrySet().iterator(); itr.hasNext(); ) {
final Map.Entry<Formula, Node> entry = itr.next();
final Node source = annotated.sourceOf(entry.getValue());
if (entry.getKey() == source) {
itr.remove();
} else {
entry.setValue(source);
}
}
return AnnotatedNode.annotate(Formula.and(roots), conjuncts);
}
use of kodkod.util.nodes.AnnotatedNode in project org.alloytools.alloy by AlloyTools.
the class FormulaFlattener method flatten.
/**
* Flattens the given formula into a set of conjuncts by pushing negations
* through quantifier-free formulas, if breakupQuantifiers is false. Otherwise,
* pushes the negations through all formulas, breaking up universal quantifiers
* whenever possible. The source map of the returned annotated node reflects the
* source relationships from the descendants of the returned formula to the
* sources of the corresponding descendants of annotated.node.
*
* @return a map that binds each flattened conjuncts to the corresponding
* subformula of annotated.node
*/
public static AnnotatedNode<Formula> flatten(AnnotatedNode<Formula> annotated, boolean breakupQuantifiers) {
final FormulaFlattener flat = new FormulaFlattener(annotated.sharedNodes(), breakupQuantifiers);
annotated.node().accept(flat);
final List<Formula> roots = new ArrayList<Formula>(flat.conjuncts.size());
roots.addAll(flat.conjuncts.keySet());
for (Iterator<Map.Entry<Formula, Node>> itr = flat.conjuncts.entrySet().iterator(); itr.hasNext(); ) {
final Map.Entry<Formula, Node> entry = itr.next();
final Node source = annotated.sourceOf(entry.getValue());
if (entry.getKey() == source) {
itr.remove();
} else {
entry.setValue(source);
}
}
return AnnotatedNode.annotate(Formula.and(roots), flat.conjuncts);
}
use of kodkod.util.nodes.AnnotatedNode in project org.alloytools.alloy by AlloyTools.
the class PrenexNFConverter method toPNF.
public static AnnotatedNode<Formula> toPNF(AnnotatedNode<Formula> annotated) {
final PrenexNFConverter pnfConv = new PrenexNFConverter(annotated.sharedNodes());
List<Formula> conj = new ArrayList<Formula>();
for (Formula f : Nodes.allConjuncts(annotated.node(), null)) conj.add(f.accept(pnfConv));
Formula ans = Formula.and(conj);
final List<Formula> roots = new ArrayList<Formula>(pnfConv.annotations.size());
roots.addAll(pnfConv.annotations.keySet());
for (Iterator<Map.Entry<Formula, Node>> itr = pnfConv.annotations.entrySet().iterator(); itr.hasNext(); ) {
final Map.Entry<Formula, Node> entry = itr.next();
final Node source = annotated.sourceOf(entry.getValue());
if (entry.getKey() == source) {
itr.remove();
} else {
entry.setValue(source);
}
}
return AnnotatedNode.annotate(ans, pnfConv.annotations);
}
use of kodkod.util.nodes.AnnotatedNode in project org.alloytools.alloy by AlloyTools.
the class Skolemizer method skolemize.
/**
* Skolemizes the given annotated formula using the given bounds and options. If
* Options.logTranslation is set and the formula is skolemizable, the resulting
* annotated formula will contain transitive source information for each of its
* subformulas. Specifically, let f be the returned annotated formula, t be a
* descendant of f.node, and s a descendant of annotated.node from which t was
* derived. Then, f.source[t] = annotated.source[s]. If options.logTranslation
* is false, no source information will be recorded (i.e. f.source[t] = t for
* all descendants t of f).
*
* @ensures upper bound mappings for skolem constants, if any, are added to the
* bounds
* @return the skolemized version of the given formula
* @throws NullPointerException any of the arguments are null
* @throws IllegalArgumentException some Relation & annotated.node.^children -
* bounds.relations
* @throws UnsupportedOperationException bounds is unmodifiable
*/
public static AnnotatedNode<Formula> skolemize(final AnnotatedNode<Formula> annotated, Bounds bounds, Options options) {
if (options.logTranslation() > 0) {
final Map<Node, Node> source = new IdentityHashMap<Node, Node>();
final Skolemizer r = new Skolemizer(annotated, bounds, options) {
@Override
protected Formula source(Formula f, Node n) {
// System.out.println("logging " + f + " <-- " + n);
final Node nsource = annotated.sourceOf(n);
if (f != nsource)
source.put(f, nsource);
return f;
}
};
final Formula f = annotated.node().accept(r);
return f == annotated.node() ? annotated : annotate(f, source);
} else {
final Skolemizer r = new Skolemizer(annotated, bounds, options) {
};
final Formula f = annotated.node().accept(r);
return f == annotated.node() ? annotated : annotate(f);
}
}
Aggregations