use of kodkod.engine.fol2sat.RecordFilter in project org.alloytools.alloy by AlloyTools.
the class StrategyUtils method roots.
/**
* Returns a map from variables to the corresponding roots of log.formula.
*
* @return
*
* <pre>
*
* { v: int, f: Formula | some r: log.records |
* r.translated in log.roots() and
* r.translated = f and
* r.env.isEmpty() and
* abs(r.literal) != Integer.MAX_VALUE and
* v = abs(r.literal) and
* no r': log.records | r'.node = r.node && log.replay.r' > log.replay.r }
* </pre>
*/
static SparseSequence<Formula> roots(TranslationLog log) {
final SparseSequence<Formula> rootVars = new TreeSequence<Formula>();
final Set<Formula> roots = log.roots();
final Map<Formula, int[]> maxRootVar = new IdentityHashMap<Formula, int[]>(roots.size());
final RecordFilter filter = new RecordFilter() {
@Override
public boolean accept(Node node, Formula translated, int literal, Map<Variable, TupleSet> env) {
return roots.contains(translated) && env.isEmpty();
}
};
for (Iterator<TranslationRecord> itr = log.replay(filter); itr.hasNext(); ) {
TranslationRecord record = itr.next();
int[] var = maxRootVar.get(record.translated());
if (var == null) {
var = new int[1];
maxRootVar.put(record.translated(), var);
}
var[0] = StrictMath.abs(record.literal());
}
for (Map.Entry<Formula, int[]> entry : maxRootVar.entrySet()) {
final int topVar = entry.getValue()[0];
if (// formula simplified to TRUE
topVar != Integer.MAX_VALUE)
rootVars.put(topVar, entry.getKey());
}
return rootVars;
}
use of kodkod.engine.fol2sat.RecordFilter in project org.alloytools.alloy by AlloyTools.
the class StrategyUtils method rootVars.
/**
* Returns the variables that correspond to the roots of log.formula.
*
* @return
*
* <pre>
*
* { v: int | some r: log.records |
* r.node in log.roots() and
* r.env.isEmpty() and
* abs(r.literal) != Integer.MAX_VALUE and
* v = abs(r.literal) and
* no r': log.records | r'.node = r.node && log.replay.r' > log.replay.r }
* </pre>
*/
public static IntSet rootVars(TranslationLog log) {
final IntSet rootVars = new IntTreeSet();
final Set<Formula> roots = log.roots();
final Map<Formula, int[]> maxRootVar = new LinkedHashMap<Formula, int[]>(roots.size());
final RecordFilter filter = new RecordFilter() {
@Override
public boolean accept(Node node, Formula translated, int literal, Map<Variable, TupleSet> env) {
return roots.contains(translated) && env.isEmpty();
}
};
for (Iterator<TranslationRecord> itr = log.replay(filter); itr.hasNext(); ) {
TranslationRecord record = itr.next();
int[] var = maxRootVar.get(record.translated());
if (var == null) {
var = new int[1];
maxRootVar.put(record.translated(), var);
}
var[0] = StrictMath.abs(record.literal());
}
for (int[] var : maxRootVar.values()) {
int topVar = var[0];
if (// formula simplified to TRUE
topVar != Integer.MAX_VALUE)
rootVars.add(var[0]);
}
return rootVars;
}
use of kodkod.engine.fol2sat.RecordFilter in project org.alloytools.alloy by AlloyTools.
the class ResolutionBasedProof method highLevelCore.
/**
* {@inheritDoc}
*
* @see kodkod.engine.Proof#highLevelCore()
*/
@Override
public final Map<Formula, Node> highLevelCore() {
if (coreRoots == null) {
final RecordFilter unitFilter = new RecordFilter() {
final IntSet coreUnits = StrategyUtils.coreUnits(solver.proof());
final Set<Formula> roots = log().roots();
@Override
public boolean accept(Node node, Formula translated, int literal, Map<Variable, TupleSet> env) {
return roots.contains(translated) && coreUnits.contains(Math.abs(literal));
}
};
coreRoots = new LinkedHashMap<Formula, Node>();
final IntSet seenUnits = new IntTreeSet();
for (Iterator<TranslationRecord> itr = log().replay(unitFilter); itr.hasNext(); ) {
// it is possible that two top-level formulas have identical
// meaning,
// and are represented with the same core unit; in that case, we
// want only
// one of them in the core.
final TranslationRecord rec = itr.next();
if (seenUnits.add(rec.literal())) {
coreRoots.put(rec.translated(), rec.node());
}
}
coreRoots = Collections.unmodifiableMap(coreRoots);
}
return coreRoots;
}
use of kodkod.engine.fol2sat.RecordFilter 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;
}
Aggregations