/*
* Copyright (C) 2012 University of Freiburg
*
* This file is part of SMTInterpol.
*
* SMTInterpol is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SMTInterpol is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with SMTInterpol. If not, see <http://www.gnu.org/licenses/>.
*/
package de.uni_freiburg.informatik.ultimate.smtinterpol.proof;
import de.uni_freiburg.informatik.ultimate.logic.AnnotatedTerm;
import de.uni_freiburg.informatik.ultimate.logic.ApplicationTerm;
import de.uni_freiburg.informatik.ultimate.logic.ConstantTerm;
import de.uni_freiburg.informatik.ultimate.logic.FunctionSymbol;
import de.uni_freiburg.informatik.ultimate.logic.Term;
import de.uni_freiburg.informatik.ultimate.logic.Theory;
import de.uni_freiburg.informatik.ultimate.smtinterpol.convert.SMTAffineTerm;
import de.uni_freiburg.informatik.ultimate.smtinterpol.dpll.DPLLAtom;
import de.uni_freiburg.informatik.ultimate.smtinterpol.dpll.Literal;
/**
* A tracker for rewrite steps done while rewriting the original formula into
* canonical form and producing clauses. The interface is designed to prevent
* creation of unneeded terms if proof tracking is disabled.
* @author Juergen Christ
*/
public interface IProofTracker {
//// ==== Tracking ====
/**
* Track an expansion rewrite.
* @param orig The original term.
*/
public void expand(ApplicationTerm orig);
/**
* Track the expand definition rule.
* @param orig The original term.
* @param res The result of the expansion.
*/
public void expandDef(Term orig, Term res);
/**
* Track an equality rewrite.
* @param args The arguments to the equality.
* @param res The result of the rewrite.
* @param rule The number of the rule used.
*/
public void equality(Term[] args, Object res, int rule);
/**
* Track a distinct rewrite.
* @param args The arguments to the distinct.
* @param res The result of the rewrite.
* @param rule The number of the rule used.
*/
public void distinct(Term[] args, Term res, int rule);
/**
* Track the transformation of a Boolean distinct into a negated equality.
* @param lhs The left-hand-side of the distinct.
* @param rhs The right-hand-side of the distinct.
* @param firstNegated Should the lhs be negated?
*/
public void distinctBoolEq(Term lhs, Term rhs, boolean firstNegated);
/**
* Track the result of a negation rewrite.
* @param pos What to negate.
* @param res The result of the rewrite.
* @param rule The number of the rule.
*/
public void negation(Term pos, Term res, int rule);
/**
* Track an or rewrite
* @param args The arguments to the disjunction.
* @param res The simplification result.
* @param rule The rule number.
*/
public void or(Term[] args, Term res, int rule);
/**
* Track an ite rewrite.
* @param cond The condition.
* @param thenTerm The then-term.
* @param elseTerm The else-term.
* @param res The result.
* @param rule The rule number.
*/
public void ite(Term cond, Term thenTerm, Term elseTerm, Term res, int rule);
/**
* Track removal of a Boolean connective.
* @param origArgs The original term.
* @param result (Part of) the resulting term (used for SMTAffineTerms).
* @param rule The rule number.
*/
public void removeConnective(Term[] origArgs, Term result, int rule);
/**
* Track an annotation stripping.
* @param orig The annotated term.
*/
public void strip(AnnotatedTerm orig);
/**
* Track a canonical summarization.
* @param fsym The function symbol of the original term.
* @param args The arguments of the original term.
* @param res The result of the rewrite.
*/
public void sum(FunctionSymbol fsym, Term[] args, Term res);
/**
* Track a normalization of a constant term. This rule is needed, e.g., to
* justify the transformation of 1.5 into (/ 3 2).
* @param term The constant.
* @param res The result of the transformation.
*/
public void normalized(ConstantTerm term, SMTAffineTerm res);
/**
* Track an leq simplification.
* @param leq The leq0-term.
* @param res The rewrite result.
* @param rule The simplification rule.
*/
public void leqSimp(SMTAffineTerm leq, Term res, int rule);
/**
* Track an application of the IRA-Hack.
* @param orig The original term.
* @param origArgs Arguments that should be used for the original term.
* @param newArgs The arguments to that term after applying the IRA-Hack.
*/
public void desugar(ApplicationTerm orig, Term[] origArgs, Term[] newArgs);
/**
* Track a modulo-rewrite. (mod x y) ==> (- x (* y (div x y))) under the
* assumption y is integral and not 0.
* @param appTerm The modulo application term.
* @param res The resulting term.
*/
public void modulo(ApplicationTerm appTerm, Term res);
/**
* Track a modulo simplification, i.e., a rewrite that does not transform
* a modulo into an application term like
* {@link #modulo(ApplicationTerm, Term)}, but evaluates applications
* (mod x y) where either y is 1 or -1, or x is constant.
* @param x The first argument of the mod.
* @param y The second argument of the mod.
* @param res The result of the rule.
* @param rule The simplification rule applied.
*/
public void mod(Term x, Term y, Term res, int rule);
/**
* Track a divison simplification, i.e., a rewrite that evaluates
* applications (div x y) where either y is 1 or -1, or x is constant.
* @param x The first argument of the div.
* @param y The second argument of the div.
* @param res The result of the rule.
* @param rule The simplification rule applied.
*/
public void div(Term x, Term y, Term res, int rule);
/**
* Track a divisible-rewrite. ((_ divisible n) x) ==> (= x (* n (div x n))).
* @param divn The divisible-by-n symbol.
* @param div The divisible term.
* @param res The rewritten result.
*/
public void divisible(FunctionSymbol divn, Term div, Term res);
/**
* Track a to_int simplification where the argument is constant.
* @param arg The argument.
* @param res The result.
*/
public void toInt(Term arg, Term res);
/**
* Track a to_real simplification where the argument is constant.
* @param arg The argument.
* @param res The result.
*/
public void toReal(Term arg, Term res);
/**
* Track an array rewrite.
* @param args The arguments of the original array.
* @param result The result of the rewrite.
* @param rule The rule used.
*/
public void arrayRewrite(Term[] args, Term result, int rule);
/**
* Rewrite for "useless store": (= a (store a i v)).
* @param store The store term.
* @param result The result of the rewrite.
* @param arrayFirst Is the array the lhs?
*/
public void storeRewrite(ApplicationTerm store, Term result, boolean arrayFirst);
//// ==== Tracking of clausification ====
/**
* Track the introduction of a quote.
* @param orig The original term.
* @param quote The quoted term.
*/
public void quoted(Term orig, Literal quote);
/**
* Track an equality interning.
* @param lhs The left-hand-side.
* @param rhs The right-hand-side.
* @param res The result.
*/
public void eq(Term lhs, Term rhs, Term res);
/**
* Convenience function to prevent term creation of equality terms if
* proof generation is disabled.
* @param lhs The left-hand-side.
* @param rhs The right-hand-side.
* @param eqAtom The equality atom.
*/
public void eq(Term lhs, Term rhs, DPLLAtom eqAtom);
/**
* Convenience function to prevent creation of leq0 terms if proof
* generation is disabled.
* @param sum The sum to be less than or equal to 0.
* @param lit The resulting literal.
*/
public void leq0(SMTAffineTerm sum, Literal lit);
/**
* Track literal creation.
* @param term The term transformed into a literal.
* @param lit The resulting literal.
*/
public void intern(Term term, Literal lit);
/**
* Apply double negation elimination on a literal. Note that the literal
* has to be negated already.
* @param lit The literal to negate
* @param theory The theory to use in conversion.
*/
public void negateLit(Literal lit, Theory theory);
/**
* Apply disjunction flattening.
* @param args The term to flatten.
* @param simpOr Apply disjunction simplification on the flattened and
* interned clause.
*/
public void flatten(Term[] args, boolean simpOr);
/**
* Prepend a disjunction simplification step.
* @param args The disjunction to simplify.
*/
public void orSimpClause(Term[] args);
/**
* Create a clause-creation proof.
* @param proof The proof whose result is transformed into a clause.
* @return The clause conversion proof.
*/
public Term clause(Term proof);
/**
* Create aux axiom input (tautologies).
* @param auxKind The kind of the aux axiom.
* @param auxLit The term auxiliary literal.
* @param data Data needed to construct the result term.
* @param base Base used for Term-ITEs.
* @param auxData Auxiliary data (needed for Term-ITEs).
* @return Proof node of the auxiliary tautology.
*/
public Term auxAxiom(int auxKind, Literal auxLit, Term data, Term base,
Object auxData);
/**
* Track a structural splitting step.
* @param data Data used to produce the result of the split.
* @param proof The proof for the formula being split.
* @param splitKind The kind of split (@see ProofConstants).
* @return The proof for the split.
*/
public Term split(Term data, Term proof, int splitKind);
//// ===== Accessors ====
/**
* Get a rewrite proof justifying the rewrites from <code>asserted</code>
* into <code>result</code>.
*
* Note that <code>asserted</code> is a Boolean term from the input. If a
* proof should be produced, it has to be wrapped by the
* <code>@asserted</code> function. The <code>result</code> might contain
* SMTAffineTerms.
* @param asserted The input term.
* @return The rewrite proof or <code>null</code> if proof-production is
* disabled.
*/
public Term getRewriteProof(Term asserted);
//// ==== Incrementality ====
/**
* Reset the cached proof data.
*/
public void reset();
//// ==== Creating descendent trackers
/**
* Create a sub-tracker.
* @return A sub-tracker with the same tracking capabilities than this
* tracker.
*/
public IProofTracker getDescendent();
/**
* Prepare to apply the IRA-Hack. This should return a copy of the original
* arguments to ensure correct applications of the desugar rule.
* @param args The original arguments.
* @return <code>null</code> if no desugar should be applied and a copy of
* the argument otherwise.
*/
public Term[] prepareIRAHack(Term[] args);
/**
* Mark the position where a clause simplification rule can be applied.
* This function is necessary since clause simplification is delayed and,
* hence, recognized at the wrong time.
*/
public void markPosition();
/**
* Produce the disjunctive arguments of an auxiliary axiom.
* @param auxlit The auxiliary literal (in polarity of the aux axiom)
* @param args The remaining arguments.
* @return Arguments of the clause (stub) or <code>null</code> if no proof
* tracking.
*/
public Term[] produceAuxAxiom(Literal auxlit, Term... args);
/**
* Save the current position in the rewrite list.
*/
public void save();
/**
* Restore to the last position in the list.
*/
public void restore();
/**
* Remove all saved information.
*/
public void cleanSave();
/**
* Notification about the creation of a literal. This function is only
* used to compute the correct delayed clause simplification axiom.
* @param lit The created literal (in correct polarity.
* @param t The term for which the literal has been created.
* @return Was <code>lit</code> the first literal for <code>t</code>?
*/
public boolean notifyLiteral(Literal lit, Term t);
/**
* Notification about the simplification of a literal to false. This
* function is only used to compute the correct delayed clause
* simplification axiom.
* @param t The term that simplified to false.
*/
public void notifyFalseLiteral(Term t);
}