/** * Constructs a proof finder for the given log. * * @ensures this.log' = log */ NodePruner(TranslationLog log) { visited = new IdentityHashSet<Node>(); relevant = new IdentityHashSet<Node>(); final RecordFilter filter = new RecordFilter() { public boolean accept( Node node, Formula translated, int literal, Map<Variable, TupleSet> env) { return env.isEmpty(); } }; constNodes = new LinkedHashMap<Formula, Boolean>(); for (Iterator<TranslationRecord> itr = log.replay(filter); itr.hasNext(); ) { TranslationRecord rec = itr.next(); int lit = rec.literal(); if (Math.abs(lit) != Integer.MAX_VALUE) { constNodes.remove(rec.translated()); } else if (lit == Integer.MAX_VALUE) { constNodes.put(rec.translated(), Boolean.TRUE); } else { constNodes.put(rec.translated(), Boolean.FALSE); } } }
/** * {@inheritDoc} * * @see kodkod.engine.Proof#highLevelCore() */ 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; }
/** * 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; }