use of kodkod.ast.Node in project org.alloytools.alloy by AlloyTools.
the class ResolutionBasedProof method connectedCore.
/**
* Returns the connected core based on the given set of core variables.
*
* @requires coreVar = StrategyUtils.coreVars(solver.proof());
* @return let formulas = (this.log.records[int] & literal.{i: int | abs(i) in
* coreVars}).formula | connected = {f: formulas | some s: set coreNodes
* | f + this.log.formula in s and (s - this.log.formula).~components in
* s }
*/
private Set<Formula> connectedCore(final IntSet coreVars) {
final Set<Formula> coreNodes = new IdentityHashSet<Formula>();
final RecordFilter filter = new RecordFilter() {
@Override
public boolean accept(Node node, Formula translated, int literal, Map<Variable, TupleSet> env) {
return coreVars.contains(StrictMath.abs(literal));
}
};
for (Iterator<TranslationRecord> itr = log().replay(filter); itr.hasNext(); ) {
coreNodes.add(itr.next().translated());
}
final Set<Formula> connected = new IdentityHashSet<Formula>();
final AbstractVoidVisitor traverser = new AbstractVoidVisitor() {
final Set<Node> visited = new IdentityHashSet<Node>();
/**
* Returns true if the given node has been visited before or if it is not
* contained in this.nodes set. Otherwise adds the node to the connected set and
* returns false.
*
* @ensures this.visited' = this.visited + n
* @ensures n !in this.visited && n in coreNodes => connected' = connected + n
* else connected' = connected
* @return n in visited || n !in coreNodes
*/
@Override
protected boolean visited(Node n) {
if (visited.add(n) && coreNodes.contains(n)) {
connected.add((Formula) n);
return false;
}
return true;
}
};
for (Formula root : log().roots()) {
root.accept(traverser);
}
return connected;
}
use of kodkod.ast.Node in project org.alloytools.alloy by AlloyTools.
the class A4Solution method highLevelCore.
/**
* If this solution is unsatisfiable and its unsat core is available, then
* return the core; else return an empty set.
*/
public Pair<Set<Pos>, Set<Pos>> highLevelCore() {
if (hCoreCache != null)
return hCoreCache;
Set<Pos> ans1 = new LinkedHashSet<Pos>(), ans2 = new LinkedHashSet<Pos>();
if (hCore != null)
for (Node f : hCore) {
Object x = k2pos(f);
if (x instanceof Pos) {
// System.out.println("F: "+f+" at "+x+"\n");
// System.out.flush();
ans1.add((Pos) x);
} else if (x instanceof Expr) {
Expr expr = (Expr) x;
Pos p = ((Expr) x).span();
ans1.add(p);
// System.out.flush();
for (Func func : expr.findAllFunctions()) ans2.add(func.getBody().span());
}
}
return hCoreCache = new Pair<Set<Pos>, Set<Pos>>(Collections.unmodifiableSet(ans1), Collections.unmodifiableSet(ans2));
}
use of kodkod.ast.Node in project org.alloytools.alloy by AlloyTools.
the class TrivialProof method minimize.
/**
* Minimizes the current core using the trivial strategy that does one of the
* following: (1) if there is a root that simplified to FALSE, sets the minimal
* core to that root; or (2) if not, there must be two roots that translated to
* x and -x, where x is a boolean literal, so we pick those two as the minimal
* core. The strategy argument is ignored (it can be null).
*
* @see Proof#minimize(ReductionStrategy)
*/
@Override
public void minimize(ReductionStrategy strategy) {
final Map<Formula, int[]> rootLits = new LinkedHashMap<Formula, int[]>();
final Map<Formula, Node> rootNodes = new LinkedHashMap<Formula, Node>();
final Set<Formula> roots = log().roots();
for (Iterator<TranslationRecord> itr = core(); itr.hasNext(); ) {
final TranslationRecord rec = itr.next();
if (roots.contains(rec.translated())) {
// simply record the most recent output value for each formula:
// this is guaranteed to be the final output value for that
// formula because of the translation log guarantee that the
// log is replayed in the order of translation: i.e. a child's
// output value is always recorded before the parent's
int[] val = rootLits.get(rec.translated());
if (val == null) {
val = new int[1];
rootLits.put(rec.translated(), val);
}
val[0] = rec.literal();
rootNodes.put(rec.translated(), rec.node());
}
}
final SparseSequence<Formula> lits = new TreeSequence<Formula>();
for (Map.Entry<Formula, int[]> entry : rootLits.entrySet()) {
final int lit = entry.getValue()[0];
if (lit == -Integer.MAX_VALUE) {
coreRoots = Collections.singletonMap(entry.getKey(), rootNodes.get(entry.getKey()));
break;
} else if (lits.containsIndex(-lit)) {
final Formula f0 = lits.get(-lit);
final Formula f1 = entry.getKey();
coreRoots = new LinkedHashMap<Formula, Node>(3);
coreRoots.put(f0, rootNodes.get(f0));
coreRoots.put(f1, rootNodes.get(f1));
coreRoots = Collections.unmodifiableMap(coreRoots);
break;
} else {
lits.put(lit, entry.getKey());
}
}
coreFilter = null;
assert coreRoots.size() == 1 && rootLits.get(coreRoots.keySet().iterator().next())[0] == -Integer.MAX_VALUE || coreRoots.size() == 2;
}
use of kodkod.ast.Node in project org.alloytools.alloy by AlloyTools.
the class TrivialProof method highLevelCore.
/**
* {@inheritDoc}
*
* @see kodkod.engine.Proof#highLevelCore()
*/
@Override
public final Map<Formula, Node> highLevelCore() {
if (coreRoots == null) {
final Iterator<TranslationRecord> itr = core();
final Set<Formula> roots = log().roots();
coreRoots = new LinkedHashMap<Formula, Node>();
while (itr.hasNext()) {
TranslationRecord rec = itr.next();
if (roots.contains(rec.translated()))
coreRoots.put(rec.translated(), rec.node());
}
coreRoots = Collections.unmodifiableMap(coreRoots);
}
return coreRoots;
}
use of kodkod.ast.Node in project org.alloytools.alloy by AlloyTools.
the class Nodes method minRoots.
/**
* Returns a minimal subset of {@linkplain #roots(Formula) roots} of the given
* formula such that all nodes in the given collection are reachable from those
* roots. The returned subset is a local minimum in that none of its members can
* be removed without leaving some node in the descendants set unreachable from
* the remaining roots.
*
* @requires descendants in formula.*components
* @return { s: Set<Formula> | s.elements in roots(formula) and descendants in
* s.elements.*components and no s': Set<Formula> | s.containsAll(s')
* and s'.size()<s.size() and descendants in s.elements.*components }
* @throws IllegalArgumentException descendants !in formula.*components
*/
public static Set<Formula> minRoots(Formula formula, Collection<? extends Node> descendants) {
final Set<Node> desc = new IdentityHashSet<Node>(descendants);
final VoidVisitor visitor = new AbstractVoidVisitor() {
final Set<Node> visited = new IdentityHashSet<Node>();
@Override
protected boolean visited(Node n) {
if (visited.add(n)) {
desc.remove(n);
return false;
}
return true;
}
};
final Set<Formula> roots = new LinkedHashSet<Formula>();
for (Formula root : roots(formula)) {
final int size = desc.size();
root.accept(visitor);
if (desc.size() < size) {
roots.add(root);
}
if (desc.isEmpty()) {
break;
}
}
if (!desc.isEmpty())
throw new IllegalArgumentException("descendants !in formula.*components: formula=" + formula + " ; descendants=" + descendants);
return roots;
}
Aggregations