use of kodkod.ast.Formula 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.ast.Formula 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.ast.Formula in project org.alloytools.alloy by AlloyTools.
the class FullNegationPropagator method visit.
/**
* Visits the formula's children with appropriate settings for the negated flag
* if bf has not been visited before.
*
* @see kodkod.ast.visitor.AbstractVoidVisitor#visit(kodkod.ast.BinaryFormula)
*/
@Override
public final void visit(BinaryFormula bf) {
if (visited(bf))
return;
final FormulaOperator op = bf.op();
switch(op) {
case AND:
if (!negated) {
// left && right
bf.left().accept(this);
bf.right().accept(this);
} else {
// !(left && right) --> !left || !right
FullNegationPropagator fne1 = new FullNegationPropagator(shared, annotations);
bf.left().not().accept(fne1);
FullNegationPropagator fne2 = new FullNegationPropagator(shared, annotations);
bf.right().not().accept(fne2);
addConjunct(Formula.and(fne1.conjuncts).or(Formula.and(fne2.conjuncts)), false, bf);
hasChanged = true;
}
break;
case OR:
if (!negated) {
// left || right
FullNegationPropagator fne1 = new FullNegationPropagator(shared, annotations);
bf.left().accept(fne1);
FullNegationPropagator fne2 = new FullNegationPropagator(shared, annotations);
bf.right().accept(fne2);
if (!fne1.hasChanged && !fne2.hasChanged) {
addConjunct(bf);
} else {
addConjunct(Formula.and(fne1.conjuncts).or(Formula.and(fne2.conjuncts)), false, bf);
hasChanged = true;
}
} else {
// !(left || right) --> !left && !right
bf.left().accept(this);
bf.right().accept(this);
hasChanged = true;
}
break;
case IMPLIES:
if (!negated) {
// left => right --> !left || right
FullNegationPropagator fne1 = new FullNegationPropagator(shared, annotations);
bf.left().not().accept(fne1);
FullNegationPropagator fne2 = new FullNegationPropagator(shared, annotations);
bf.right().accept(fne2);
addConjunct(Formula.and(fne1.conjuncts).or(Formula.and(fne2.conjuncts)), false, bf);
} else {
// !(left => right) --> left && !right
negated = false;
bf.left().accept(this);
negated = true;
bf.right().accept(this);
}
hasChanged = true;
break;
case IFF:
FullNegationPropagator fne1 = new FullNegationPropagator(shared, annotations);
FullNegationPropagator fne2 = new FullNegationPropagator(shared, annotations);
if (!negated) {
// a <=> b --> (a && b) || (!a && !b)
bf.left().and(bf.right()).accept(fne1);
bf.left().not().and(bf.right().not()).accept(fne2);
} else {
// !(a = b) --> (a && !b) || (!a && b)
Formula orLhs = bf.left().and(bf.right().not());
orLhs.accept(fne1);
Formula orRhs = bf.left().not().and(bf.right());
orRhs.accept(fne2);
}
addConjunct(Formula.and(fne1.conjuncts).or(Formula.and(fne2.conjuncts)), false, bf);
hasChanged = true;
break;
default:
addConjunct(bf);
}
}
use of kodkod.ast.Formula 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.ast.Formula in project org.alloytools.alloy by AlloyTools.
the class PrenexNFConverter method visit.
@Override
public Formula visit(NotFormula not) {
Formula sub = not.formula().accept(this);
Pair p = new Pair(sub, null);
Formula ans;
if (p.hasNoQuant() && sub == not.formula())
ans = not;
else if (p.hasNoQuant())
ans = sub.not();
else
ans = pushNegation(p.leftQF);
return saveMapping(ans, not);
}
Aggregations