use of kodkod.ast.BinaryFormula in project org.alloytools.alloy by AlloyTools.
the class Nodes method roots.
/**
* Returns the roots of the given formula. In other words, breaks up the given
* formula into its conjunctive components, {f0, ..., fk}, such that, for all
* 0<=i<=k, f<sub>i</sub> is not a conjunction and [[f0 && ... && fk]] <=>
* [[formula]].
*
* @return subformulas, {f0, ..., fk}, of the given formula such that, for all
* 0<=i<=k, f<sub>i</sub> is not a conjuction and [[f0 && ... && fk]]
* <=> [[formula]].
*/
public static Set<Formula> roots(Formula formula) {
final List<Formula> formulas = new LinkedList<Formula>();
formulas.add(formula);
final ListIterator<Formula> itr = formulas.listIterator();
while (itr.hasNext()) {
final Formula f = itr.next();
if (f instanceof BinaryFormula) {
final BinaryFormula bin = (BinaryFormula) f;
if (bin.op() == FormulaOperator.AND) {
itr.remove();
itr.add(bin.left());
itr.add(bin.right());
itr.previous();
itr.previous();
}
} else if (f instanceof NaryFormula) {
final NaryFormula nf = (NaryFormula) f;
if (nf.op() == FormulaOperator.AND) {
itr.remove();
for (Formula child : nf) {
itr.add(child);
}
for (int i = nf.size(); i > 0; i--) {
itr.previous();
}
}
}
}
return new LinkedHashSet<Formula>(formulas);
}
use of kodkod.ast.BinaryFormula in project org.alloytools.alloy by AlloyTools.
the class A4Solution method k2pos.
/**
* Associates the Kodkod formula to a particular Alloy Expr (if the Kodkod
* formula is not already associated with an Alloy Expr or Alloy Pos)
*/
Formula k2pos(Formula formula, Expr expr) throws Err {
if (solved)
throw new ErrorFatal("Cannot alter the k->pos mapping since solve() has completed.");
if (formula == null || expr == null || k2pos.containsKey(formula))
return formula;
k2pos.put(formula, expr);
if (formula instanceof BinaryFormula) {
BinaryFormula b = (BinaryFormula) formula;
if (b.op() == FormulaOperator.AND) {
k2pos(b.left(), expr);
k2pos(b.right(), expr);
}
}
return formula;
}
use of kodkod.ast.BinaryFormula in project org.alloytools.alloy by AlloyTools.
the class A4Solution method k2pos.
/**
* Associates the Kodkod formula to a particular Alloy Pos (if the Kodkod
* formula is not already associated with an Alloy Expr or Alloy Pos)
*/
Formula k2pos(Formula formula, Pos pos) throws Err {
if (solved)
throw new ErrorFatal("Cannot alter the k->pos mapping since solve() has completed.");
if (formula == null || pos == null || pos == Pos.UNKNOWN || k2pos.containsKey(formula))
return formula;
k2pos.put(formula, pos);
if (formula instanceof BinaryFormula) {
BinaryFormula b = (BinaryFormula) formula;
if (b.op() == FormulaOperator.AND) {
k2pos(b.left(), pos);
k2pos(b.right(), pos);
}
}
return formula;
}
use of kodkod.ast.BinaryFormula 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.BinaryFormula in project org.alloytools.alloy by AlloyTools.
the class PrenexNFConverter method visit.
@Override
public Formula visit(BinaryFormula bf) {
Formula ans;
switch(bf.op()) {
case AND:
case OR:
Formula left = bf.left().accept(this);
Formula right = bf.right().accept(this);
Pair p = new Pair(left, right);
if (p.hasNoQuant() && left == bf.left() && right == bf.right())
ans = bf;
else
ans = p.compose(bf.op());
break;
case IMPLIES:
ans = bf.left().not().or(bf.right()).accept(this);
break;
case IFF:
ans = bf.left().and(bf.right()).or(bf.left().not().and(bf.right().not())).accept(this);
break;
default:
throw new IllegalStateException("Unknown BinaryFormula operator: " + bf.op());
}
return saveMapping(ans, bf);
}
Aggregations