/*
* 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.satlab;
import java.util.Iterator;
import kodkod.util.ints.IntSet;
/**
* <p>A proof of unsatisfiability generated by a {@linkplain SATProver}.
* Formally, a resolution trace is a sequence of inferences made by a
* prover that ends in a conflict (empty clause). An element in a resolution
* trace is called a clause. There are two kinds of clauses in the trace:
* axioms and resolvents. Axioms are the clauses given to the
* prover via the {@linkplain SATSolver#addClause(int[])} method, and resolvents are
* the clauses derived by the prover from axioms or previously learned resolvents through
* <a href="http://en.wikipedia.org/wiki/Resolution_%28logic%29">resolution</a>.</p>
*
* <p>Clauses in a resolution trace are ordered as follows. The first |<i>A</i>| elements
* in the trace correspond to the axioms given to the prover (i.e. prover.clauses).
* An axiom <i>a1</i> precedes an axiom <i>a2</i> in the trace if and only if
* <i>a1</i> was added to the prover before <i>a2</i>. (An axiom is "added" to the
* prover, and appears in the trace, if and only if the corresponding call to {@linkplain SATSolver#addClause(int[])})
* returned <tt>true</tt>.) The remaining elements in the trace
* are the resolvents. A resolvent <i>r</i> succeeds all of the resolvents needed for its derivation
* (i.e. all resolvents reachable from r via the {@linkplain Clause#antecedents()} relation).
* The last element in the trace is the conflict resolvent. The axioms that are reachable from the conflict
* form the <i>unsatisfiable core</i> of the trace. <p>
*
* @specfield prover: SATProver
* @specfield elts: Clause[]
* @specfield conflict: elts[#elts-1]
* @invariant #elts = #(prover.clauses + prover.resolvents)
* @invariant elts[[0..#prover.clauses)].literals = prover.clauses
* @invariant elts[[#prover.clauses..#elts)].literals = prover.resolvents
* @invariant all i: [0..#prover.clauses) | no elts[i].antecedents
* @invariant all i: [#prover.clauses..#elts) | all ante: elts[i].antecedents[int] | elts.ante < i
* @invariant no conflict.literals
*
* @author Emina Torlak
*/
public interface ResolutionTrace extends Iterable<Clause> {
/**
* Returns the length of this trace.
* @return #this.elts
*/
public int size();
/**
* Returns an iterator over the elements in this trace in proper sequence.
* <p><b>Note:</b>The clause objects returned by the iterator are not
* required to be immutable. In particular, the state of a clause object
* returned by <tt>next()</tt> (as well as the state of any object obtained
* through that clause's {@linkplain Clause#antecedents()} method) is guaranteed
* to remain the same only until the subsequent call to the <tt>next()</tt> method
* of the iterator instance.</p>
* @return an iterator over the elements in this trace in proper sequence.
*/
public abstract Iterator<Clause> iterator();
/**
* Returns an iterator over the elements at the given indices in this trace, in proper sequence.
* <p><b>Note:</b>The clause objects returned by the iterator are not
* required to be immutable. In particular, the state of a clause object
* returned by <tt>next()</tt> (as well as the state of any object obtained
* through that clause's {@linkplain Clause#antecedents()} method) is guaranteed
* to remain the same only until the subsequent call to the <tt>next()</tt> method
* of the iterator instance.</p>
* @requires indices.min() >= 0 && indices.max() < this.size()
* @return an iterator over the elements at the given indices in this trace, in proper sequence.
* @throws IndexOutOfBoundsException indices.min() < 0 || indices.max() >= this.size()
*/
public abstract Iterator<Clause> iterator(IntSet indices);
/**
* Returns an iterator over the elements at the given indices in this trace, in the
* reverse order of indices.
* <p><b>Note:</b>The clause objects returned by the iterator are not
* required to be immutable. In particular, the state of a clause object
* returned by <tt>next()</tt> (as well as the state of any object obtained
* through that clause's {@linkplain Clause#antecedents()} method) is guaranteed
* to remain the same only until the subsequent call to the <tt>next()</tt> method
* of the iterator instance.</p>
* @requires indices.min() >= 0 && indices.max() < this.size()
* @return an iterator over the elements at the given indices in this trace, in the
* reverse order of indices.
* @throws IndexOutOfBoundsException indices.min() < 0 || indices.max() >= this.size()
*/
public abstract Iterator<Clause> reverseIterator(IntSet indices);
/**
* Returns the indices of the axioms that form the unsatisfiable core of this trace.
* @return { i: int | no this.elts[i].antecedents and this.elts[i] in this.conflict.^antecedents }
*/
public abstract IntSet core();
/**
* Returns the indices of the axioms in this trace.
* @return { i: int | this.elts[i] in this.prover.clauses }
*/
public abstract IntSet axioms();
/**
* Returns the indices of the resolvents in this trace.
* @return { i: int | this.elts[i] in this.prover.resolvents }
*/
public abstract IntSet resolvents();
/**
* Returns the indices of all clauses reachable from the clauses at the given indices
* by following the antecedent relation zero or more times.
* @requires indices.min() >= 0 && indices.max() < this.size()
* @return { i: int | this.elts[i] in this.elts[indices].*antecedents }
* @throws IllegalArgumentException indices.min() < 0 || indices.max() >= this.size()
*/
public abstract IntSet reachable(IntSet indices);
/**
* Returns the indices of all clauses reachable from the clauses at the given indices
* by following the transpose of the antecedent relation zero or more times.
* @requires indices.min() >= 0 && indices.max() < this.size()
* @return { i: int | this.elts[i] in this.elts[indices].*~antecedents }
* @throws IllegalArgumentException indices.min() < 0 || indices.max() >= this.size()
*/
public abstract IntSet backwardReachable(IntSet indices);
/**
* Returns the indices of all clauses in this trace that can be learned solely from the
* clauses with the given indices.
* @requires indices.min() >= 0 && indices.max() < this.size()
* @return { i: int | this.elts[i].*antecedents = this.elts[indices].*antecedents + this.elts[i].*antecedents & this.elts[indices].*~antecedents }
* @throws IllegalArgumentException indices.min() < 0 || indices.max() >= this.size()
*/
public abstract IntSet learnable(IntSet indices);
/**
* Returns the indices of all clauses in this trace that can be learned solely and directly from the
* clauses with the given indices.
* @requires indices.min() >= 0 && indices.max() < this.size()
* @return { i: int | this.elts[i].antecedents in this.elts[indices] }
* @throws IllegalArgumentException indices.min() < 0 || indices.max() >= this.size()
*/
public abstract IntSet directlyLearnable(IntSet indices);
/**
* Returns the clause at the given index. Note that this method is not required
* to always return the same Clause object; it is only required to return Clause
* objects that are equal according to their <tt>equals</tt> methods. The Clause
* objects returned by this method are guaranteed to be immutable.
* @requires 0 <= index < this.size()
* @return this.elts[index]
* @throws IndexOutOfBoundsException 0 < index || index >= this.size()
*/
public abstract Clause get(int index);
}