/*
* Kodkod -- Copyright (c) 2005-present, Emina Torlak
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package kodkod.engine.fol2sat;
import java.util.Iterator;
import java.util.Set;
import kodkod.ast.Formula;
import kodkod.engine.config.Options;
import kodkod.instance.Bounds;
/**
* A log of the translations of the descendants of a given formula that
* are either formulas or that desugar to formulas.
* @specfield originalFormula: Formula // the original formula, as constructed by client
* @specfield originalBounds: Bounds // the original bounds, as constructed by client
* @specfield formula: Formula // optimization of this.originalFormula that was used for translation
* @specfield bounds: Bounds // optimization of this.originalBounds that was used for translation
* @specfield records: set TranslationRecord
* @specfield replay: [0..#records) one->one records // replay order -- i.e. the order in the which records were added to the log
* @invariant all r: records | r.node in formula.*children
* @invariant Solver.solve(formula, bounds).instance() == null iff Solver.solve(originalFormula, originalBounds).instance() == null
* @author Emina Torlak
*/
public abstract class TranslationLog {
TranslationLog() {}
/**
* Returns the roots of this.formula. In other words, returns the subformulas, {f0, ..., fk},
* of this.formula such that, for all 0<=i<=k, f<sub>i</sub> [[f0 && ... && fk]] <=> [[formula]].
* The granularity of the subdivision of this.formula into roots depends on the core granularity
* specified in the {@linkplain Options} that were used when translating this.formula.
*
* <p>Unless a given root translates to a constant, the highest magnitude literal corresponding to
* each root (as given by this.records) is guaranteed to be present in the translation of this.formula
* as a unit clause. All the remaining clauses (except those comprising the symmetry
* breaking predicate, encoded with its own unit clause containing the maximum literal)
* that are reachable from such a unit clause represent the translations
* of the given root's descendants. We define reachability over the clauses in a translation
* as follows: let l1 be the highest magnitude literal in the clause c1, and let l2 be the
* highest magnitude literal in c2. If l2 occurs in c1 (in any polarity), then there is
* an edge from c1 and c2. The unit clauses are always the last clauses to be added to a SAT solver
* during translation. </p>
*
* @return roots of this.formula
*/
public abstract Set<Formula> roots();
/**
* Returns this.bounds.
* @return this.bounds.
*/
public abstract Bounds bounds();
/**
* Returns an iterator over the translation records in this log that are accepted
* by the given filter. The iterator returns the records in the order in which
* they were generated. This guarantees that records for the descendants of a
* node are always returned before the record for the node itself.
*
* <p><b>Note:</b>The record objects returned by the iterator are not
* required to be immutable. In particular, the state of a record object
* returned by <tt>next()</tt> is guaranteed to remain the same only until the
* subsequent call to <tt>next()</tt>.</p>
* @return an iterator, in the proper replay sequence, over the translation records
* in this log that are accepted by the given filter.
*/
public abstract Iterator<TranslationRecord> replay(RecordFilter filter);
/**
* Returns an iterator over all translation records in this log. The iterator returns
* the records in the order in which they were generated. This guarantees that records for
* the descendants of a node are always returned before the record for the node itself.
* The effect of this method is the same as calling {@linkplain #replay(RecordFilter) replay(RecordFilter.ALL)}.
*
* <p><b>Note:</b>The record objects returned by the iterator are not
* required to be immutable. In particular, the state of a record object
* returned by <tt>next()</tt> is guaranteed to remain the same only until the
* subsequent call to <tt>next()</tt>.</p>
* @return an iterator over all translation records in this.log, in the proper replay sequence.
* @see #replay(RecordFilter)
*/
public final Iterator<TranslationRecord> replay() {
return replay(RecordFilter.ALL);
}
// /**
// * Compresses this translation log (optional operation) by eliminating
// * redundant records.
// * @ensures all r: this.records | one r': this.records' | r.node = r'.node && r.literal = r'.literal && r.env.equals(r'.env)
// * @throws UnsupportedOperationException this log does not support compression
// */
// public abstract void compress();
}