/** * Author: Georg Hofferek <georg.hofferek@iaik.tugraz.at> */ package at.iaik.suraq.smtlib.formula; import java.io.BufferedWriter; import java.io.IOException; import java.io.Writer; import java.math.BigInteger; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; import at.iaik.suraq.exceptions.IncomparableTermsException; import at.iaik.suraq.exceptions.SuraqException; import at.iaik.suraq.main.GraphReduction; import at.iaik.suraq.sexp.SExpression; import at.iaik.suraq.sexp.SExpressionConstants; import at.iaik.suraq.sexp.Token; import at.iaik.suraq.smtlib.SMTLibObject; import at.iaik.suraq.util.HashTagContainer; import at.iaik.suraq.util.IdGenerator; import at.iaik.suraq.util.ImmutableArrayList; /** * @author Georg Hofferek <georg.hofferek@iaik.tugraz.at> * */ public abstract class EqualityFormula implements Formula { /** * */ private static final long serialVersionUID = -6614135139526500209L; /** * The terms to be compared. */ protected final ImmutableArrayList<Term> terms; /** * <code>true</code> for an equality, <code>false</code> for an inequality. */ protected final boolean equal; private final int hashCode; private final long id = IdGenerator.getId(); /** * * Constructs a new <code>EqualityFormula</code>. * * @param terms * the list of terms * @param equal * <code>true</code> if it is an equality, <code>false</code> if * it is an inequality. */ protected EqualityFormula(Collection<? extends Term> terms, boolean equal) { assert (terms != null); assert (terms.size() > 1); this.equal = equal; ArrayList<Term> termList = new ArrayList<Term>(terms); // for (Term term : terms) // termList.add(term); this.terms = new ImmutableArrayList<Term>(termList); hashCode = terms.hashCode() * (equal ? 1 : -1); } /** * Creates an instance of (an adequate subclass of) * <code>EqualityFormula</code>, based on the given <code>terms</code>. * * @param terms * the list of terms to compare. * @param equal * <code>true</code> if it is an equality, <code>false</code> if * it is an inequality. * @return an instance of the adequate subclass of * <code>EqualityFormula</code>. * @throws IncomparableTermsException * if the given terms are incomparable. */ public static EqualityFormula create(Collection<? extends Term> terms, boolean equal) throws IncomparableTermsException { Class<?> termType = Term.checkTypeCompatibility(terms); if (termType == null) throw new IncomparableTermsException(); if (termType.equals(Term.domainTermClass)) { Collection<DomainTerm> domainTerms = new ArrayList<DomainTerm>(); for (Term term : terms) { domainTerms.add((DomainTerm) term); } return DomainEq.create(domainTerms, equal); } if (termType.equals(Term.arrayTermClass)) { Collection<ArrayTerm> arrayTerms = new ArrayList<ArrayTerm>(); for (Term term : terms) { arrayTerms.add((ArrayTerm) term); } return ArrayEq.create(arrayTerms, equal); } if (termType.equals(Term.propositionalTermClass)) { Collection<PropositionalTerm> propositionalTerms = new ArrayList<PropositionalTerm>(); for (Term term : terms) { propositionalTerms.add((PropositionalTerm) term); } return PropositionalEq.create(propositionalTerms, equal); } // This should never be reached throw new RuntimeException( "Unexpected situation while trying to construct term equality."); } /** * Returns a list (copy) of the terms compared by this formula. * * @return a list of the terms compared by this formula. */ public List<Term> getTerms() { return new ArrayList<Term>(terms); } /** * Determines whether this is an equality or an inequality. * * @return <code>true</code> if this is an equality, <code>false</code> * otherwise. */ public boolean isEqual() { return equal; } /** * @see at.iaik.suraq.smtlib.formula.Formula#getArrayVariables() */ @Override public void getArrayVariables(Set<ArrayVariable> result, Set<SMTLibObject> done) { if (done.contains(this)) return; for (Term term : terms) term.getArrayVariables(result, done); done.add(this); } /** * @see at.iaik.suraq.smtlib.formula.Formula#getDomainVariables() */ @Override public void getDomainVariables(Set<DomainVariable> result, Set<SMTLibObject> done) { if (done.contains(this)) return; for (Term term : terms) term.getDomainVariables(result, done); done.add(this); } /** * @see at.iaik.suraq.smtlib.formula.Formula#getPropositionalVariables() */ @Override public void getPropositionalVariables(Set<PropositionalVariable> result, Set<SMTLibObject> done) { if (done.contains(this)) return; for (Term term : terms) term.getPropositionalVariables(result, done); done.add(this); } /** * @see at.iaik.suraq.smtlib.formula.Formula#negationNormalForm() */ @Override public Formula negationNormalForm() throws SuraqException { return this.deepFormulaCopy(); } /** * @return */ public boolean isPair() { return terms.size() == 2; } /** * @return */ public AndFormula toPairwise() { List<Formula> pairs = new ArrayList<Formula>(); for (int i = 0; i < terms.size(); i++) { for (int j = i; j < terms.size(); j++) { List<Term> list = new ArrayList<Term>(); list.add(terms.get(i)); list.add(terms.get(j)); try { pairs.add(EqualityFormula.create(list, equal)); } catch (IncomparableTermsException exc) { // This should never happen throw new RuntimeException( "Unexpected situaton while making pairwise equalities.", exc); } } } return AndFormula.generate(pairs); } /** * @see at.iaik.suraq.smtlib.formula.Formula#getUninterpretedFunctionNames() */ @Override public void getUninterpretedFunctionNames(Set<String> result, Set<SMTLibObject> done) { if (done.contains(this)) return; for (Term term : terms) term.getUninterpretedFunctionNames(result, done); done.add(this); } /** * @see at.iaik.suraq.smtlib.formula.Formula#getFunctionMacroNames() */ @Override public void getFunctionMacroNames(Set<String> result, Set<SMTLibObject> done) { if (done.contains(this)) return; for (Term term : terms) term.getFunctionMacroNames(result, done); done.add(this); } /** * @see at.iaik.suraq.smtlib.formula.Formula#getFunctionMacros() */ @Override public void getFunctionMacros(Set<FunctionMacro> result, Set<SMTLibObject> done) { if (done.contains(this)) return; for (Term term : terms) term.getFunctionMacros(result, done); done.add(this); } /** * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (this == obj) return true; if (!(this.getClass().isInstance(obj))) return false; if (!((EqualityFormula) obj).terms.equals(terms)) return false; if (((EqualityFormula) obj).equal != equal) return false; if (this.hashCode() != obj.hashCode()) return false; return true; } /** * @see java.lang.Object#hashCode() */ @Override public int hashCode() { return this.hashCode; } /** * @see at.iaik.suraq.smtlib.SMTLibObject#getId() */ @Override public final long getId() { return id; } /** * @see java.lang.Comparable#compareTo(java.lang.Object) */ @Override public final int compareTo(SMTLibObject o) { long otherId = o.getId(); if (this.id < otherId) return -1; if (this.id == otherId) return 0; if (this.id > otherId) return 1; throw new RuntimeException("Something is TERRIBLY wrong!!"); } /** * @see at.iaik.suraq.smtlib.formula.Formula#getIndexSet() */ @Override public Set<DomainTerm> getIndexSet() throws SuraqException { Set<DomainTerm> indexSet = new HashSet<DomainTerm>(); for (Term term : terms) indexSet.addAll(term.getIndexSet()); return indexSet; } /** * @see at.iaik.suraq.smtlib.formula.Formula#substituteFormula(Map) */ @Override public Formula substituteFormula(Map<Token, ? extends Term> paramMap, Map<SMTLibObject, SMTLibObject> done) { if (done.containsKey(this)) { assert (done.get(this) != null); assert (done.get(this) instanceof Formula); return (Formula) done.get(this); } List<Term> convertedTerms = new ArrayList<Term>(); for (Term term : terms) convertedTerms.add(term.substituteTerm(paramMap, done)); try { Formula result = EqualityFormula.create(convertedTerms, equal); assert (result != null); done.put(this, result); return result; } catch (IncomparableTermsException exc) { throw new RuntimeException( "Unexpected problems with term types while converting EqualityFormula to caller scope.", exc); } } /** * Returns the number of terms compared by this equality. * * @return the number of terms compared by this equality. */ public int numTerms() { return terms.size(); } /** * @see at.iaik.suraq.smtlib.formula.Formula#removeArrayEqualitiesTerm() */ @Override public Formula removeArrayEqualities() { // If this equality is an array equality, it will be dealt with on a // higher level. // For other equalities, recurse on their terms. List<Term> pairs = new ArrayList<Term>(); for (Term term : terms) { pairs.add(term.removeArrayEqualitiesTerm()); } try { return EqualityFormula.create(pairs, equal); } catch (Exception ex) { ex.printStackTrace(); throw new RuntimeException(ex); } } /** * @see at.iaik.suraq.smtlib.formula.Formula#arrayPropertiesToFiniteConjunctions(java.util.Set) */ @Override public Formula arrayPropertiesToFiniteConjunctions(Set<DomainTerm> indexSet) { // recurse on terms (ITE terms may have formulas in them) List<Term> pairs = new ArrayList<Term>(); for (Term term : terms) { pairs.add(term.arrayPropertiesToFiniteConjunctionsTerm(indexSet)); } try { return EqualityFormula.create(pairs, equal); } catch (Exception ex) { ex.printStackTrace(); throw new RuntimeException(ex); } } /** * @see at.iaik.suraq.smtlib.formula.Formula#simplify() */ @Override public Formula simplify() { List<Term> terms = new ArrayList<Term>(this.terms); for (int count = 0; count < terms.size(); count++) { if (terms.get(count) instanceof DomainIte) terms.set(count, ((DomainIte) terms.get(count)).simplify()); if (terms.get(count) instanceof ArrayIte) terms.set(count, ((ArrayIte) terms.get(count)).simplify()); } Set<Term> termSet = new HashSet<Term>(terms); if (equal) { terms.clear(); terms.addAll(termSet); if (terms.size() < 2) return PropositionalConstant.create(true); } else { if (termSet.size() != terms.size()) return PropositionalConstant.create(false); } try { return EqualityFormula.create(terms, equal); } catch (Exception ex) { ex.printStackTrace(); throw new RuntimeException(ex); } } /** * @see at.iaik.suraq.smtlib.formula.Formula#flatten() */ @Override public Formula flatten() { List<Term> termCopies = new ArrayList<Term>(); for (Term term : terms) termCopies.add(term.flatten()); try { return EqualityFormula.create(termCopies, equal); } catch (IncomparableTermsException exc) { throw new RuntimeException( "Unforeseen exception while flattening equality formula.", exc); } } /** * @see at.iaik.suraq.smtlib.formula.Formula#toSmtlibV2() */ @Override public SExpression toSmtlibV2() { List<SExpression> expr = new ArrayList<SExpression>(); expr.add(equal ? SExpressionConstants.EQUAL : SExpressionConstants.DISTINCT); for (Term term : terms) expr.add(term.toSmtlibV2()); return new SExpression(expr); } /** * @see at.iaik.suraq.smtlib.formula.Formula#removeArrayWrites(at.iaik.suraq.smtlib.formula.Formula) */ @Override public Formula removeArrayWrites(Formula topLevelFormula, Set<Formula> constraints, Set<Token> noDependenceVars) { List<Term> pairs = new ArrayList<Term>(); for (Term term : terms) pairs.add(term.removeArrayWritesTerm(topLevelFormula, constraints, noDependenceVars)); try { return EqualityFormula.create(pairs, equal); } catch (Exception ex) { ex.printStackTrace(); throw new RuntimeException(ex); } } /** * @see at.iaik.suraq.smtlib.formula.Formula#arrayReadsToUninterpretedFunctions() */ @Override public Formula arrayReadsToUninterpretedFunctions( Set<Token> noDependenceVars) { List<Term> pairs = new ArrayList<Term>(); for (Term term : terms) pairs.add(term .arrayReadsToUninterpretedFunctionsTerm(noDependenceVars)); try { return EqualityFormula.create(pairs, equal); } catch (Exception ex) { ex.printStackTrace(); throw new RuntimeException(ex); } } /** * @see at.iaik.suraq.smtlib.formula.Formula#getUninterpretedFunctions() */ @Override public void getUninterpretedFunctions(Set<UninterpretedFunction> result, Set<SMTLibObject> done) { if (done.contains(this)) return; for (Term term : terms) term.getUninterpretedFunctions(result, done); done.add(this); } /** * @see at.iaik.suraq.smtlib.formula.Formula#substituteUninterpretedFunction(Token, * at.iaik.suraq.smtlib.formula.UninterpretedFunction) */ @Override public Formula substituteUninterpretedFunction( Map<Token, UninterpretedFunction> substitutions, Map<SMTLibObject, SMTLibObject> done) { if (done.get(this) != null) { assert (done.get(this) instanceof Formula); return (Formula) done.get(this); } List<Term> pairs = new ArrayList<Term>(); for (Term term : terms) pairs.add(term.substituteUninterpretedFunction(substitutions, done)); try { Formula result = EqualityFormula.create(pairs, equal); done.put(this, result); return result; } catch (Exception ex) { ex.printStackTrace(); throw new RuntimeException(ex); } } /** * * @see java.lang.Object#toString() */ @Override public String toString() { return this.toSmtlibV2().toString(); } /** * @see at.iaik.suraq.smtlib.formula.Formula#makeArrayReadsSimple(Formula, * java.util.Set, Set) */ @Override public Formula makeArrayReadsSimple(Formula topLevelFormula, Set<Formula> constraints, Set<Token> noDependenceVars) { List<Term> pairs = new ArrayList<Term>(); for (Term term : terms) pairs.add(term.makeArrayReadsSimpleTerm(topLevelFormula, constraints, noDependenceVars)); try { return EqualityFormula.create(pairs, equal); } catch (Exception ex) { ex.printStackTrace(); throw new RuntimeException(ex); } } /** * Returns the elements assert-partition. * * @return assert-partition of the element. */ @Override public Set<Integer> getPartitionsFromSymbols() { Set<Integer> partitions = new TreeSet<Integer>(); for (Term term : terms) partitions.addAll(term.getPartitionsFromSymbols()); return partitions; } /** * @see at.iaik.suraq.smtlib.formula.Formula#transformToConsequentsForm() */ @Override public OrFormula transformToConsequentsForm() { return (OrFormula) transformToConsequentsForm(false, true); } /** * @see at.iaik.suraq.smtlib.formula.Formula#transformToConsequentsForm(boolean, * boolean) */ @Override public Formula transformToConsequentsForm(boolean notFlag, boolean firstLevel) { List<Formula> literals = new ArrayList<Formula>(); boolean equal = this.equal; // TODO: make this.equal final if (terms.size() != 2) throw new RuntimeException( "Equality should have only two terms for consequents form"); try { if (((equal == true) && (notFlag == false)) || ((equal == false) && (notFlag == true))) { equal = true; if (firstLevel == true) { literals.add(EqualityFormula.create(terms, equal)); return OrFormula.generate(literals); } else return EqualityFormula.create(terms, equal); } else if (((equal == false) && (notFlag == false)) || ((equal == true) && (notFlag == true))) { equal = true; if (firstLevel == true) { literals.add(NotFormula.create(EqualityFormula.create( terms, equal))); return OrFormula.generate(literals); } else return NotFormula.create(EqualityFormula.create(terms, equal)); } else throw new RuntimeException("This point should not be reachable"); } catch (Exception ex) { throw new RuntimeException(ex); } } /** * @see at.iaik.suraq.formula.Formula#uninterpretedPredicatesToAuxiliaryVariables(at.iaik.suraq.formula.Formula, * java.util.Set, java.util.Set) */ @Override public Formula uninterpretedPredicatesToAuxiliaryVariables( Formula topLeveFormula, Map<String, List<PropositionalVariable>> predicateInstances, Map<PropositionalVariable, List<DomainTerm>> instanceParameters, Set<Token> noDependenceVars) { List<Term> pairs = new ArrayList<Term>(); for (Term term : terms) pairs.add(term.uninterpretedPredicatesToAuxiliaryVariablesTerm( topLeveFormula, predicateInstances, instanceParameters, noDependenceVars)); try { return EqualityFormula.create(pairs, equal); } catch (Exception ex) { ex.printStackTrace(); throw new RuntimeException(ex); } } /** * @see at.iaik.suraq.formula.Formula#uninterpretedFunctionsToAuxiliaryVariables(at.iaik.suraq.formula.Formula, * java.util.Set, java.util.Set) */ @Override public Formula uninterpretedFunctionsToAuxiliaryVariables( Formula topLeveFormula, Map<String, List<DomainVariable>> functionInstances, Map<DomainVariable, List<DomainTerm>> instanceParameters, Set<Token> noDependenceVars) { List<Term> pairs = new ArrayList<Term>(); for (Term term : terms) pairs.add(term.uninterpretedFunctionsToAuxiliaryVariablesTerm( topLeveFormula, functionInstances, instanceParameters, noDependenceVars)); try { return EqualityFormula.create(pairs, equal); } catch (Exception ex) { ex.printStackTrace(); throw new RuntimeException(ex); } } @Override public Formula replaceEquivalences(Formula topLeveFormula, Map<EqualityFormula, String> replacements, Set<Token> noDependenceVars) { // FormulaTerm // System.out.println("Equivalence found: "+this.numTerms()); List<Formula> newTerms = new ArrayList<Formula>(); try { // Iterate through all terms of the Equality, because there could be // more than two. for (int i = 0; i < terms.size(); i++) { Term ti = terms.get(i); // if(!(ti instanceof PropositionalVariable || ti instanceof // FormulaTerm)) // do not handle propositional variables for (int j = i + 1; j < terms.size(); j++) { Term tj = terms.get(j); // if(!(tj instanceof PropositionalVariable || tj instanceof // FormulaTerm)) // do not handle propositional variables { // fix to a static order if (ti.toString().compareTo(tj.toString()) > 0) { Term help = tj; tj = ti; ti = help; } // Build EqualityFormula for the Map Collection<Term> terms = new HashSet<Term>(); terms.add(ti); terms.add(tj); if (terms.size() < 2) // this means ti = tj { // System.out.println("Propably there was an equality like x=x"); newTerms.add(PropositionalConstant.create(true)); continue; } EqualityFormula ef = EqualityFormula .create(terms, true); // Find a name for the Equality String newName; if (replacements.containsKey(ef)) { // take an existent replacement because it's the // same newName = replacements.get(ef); // System.err.print('+'); // approx. 44000 times } else { // add a new replacement -> get a new Varname and // add to the list // newName = "eq_"+ti.toString()+"_"+tj.toString(); // newName = Util.freshVarNameCached(topLeveFormula, // newName); newName = GraphReduction.getVarName(topLeveFormula, ti.toString(), tj.toString()); replacements.put(ef, newName); if (noDependenceVars.contains(Token.generate(ti .toString())) || noDependenceVars.contains(Token .generate(tj.toString()))) { noDependenceVars.add(Token.generate(newName)); } } // we must take care of inequalities, so we add a NOT // around single terms // x != y != z <=> x!=y && x!=z && y!=z <=> e12 && e13 // && e23 if (this.equal) newTerms.add(PropositionalVariable.create(newName)); else newTerms.add(NotFormula .create(PropositionalVariable .create(newName))); } } } // Concat the Terms with an AND-Formula, if there are more terms // than two. e.g.: // x=y <=> e_xy // x=y=z <=> e_xy && e_xz && e_yz if (newTerms.size() == 0) { // This should never happen. throw new RuntimeException( "??? Don't know what happened here ???"); } else if (newTerms.size() == 1) { return newTerms.iterator().next(); } else { return AndFormula.generate(newTerms); } } catch (IncomparableTermsException ex) { // This Exception should not be possible. // But it is necessary to suppress warnings. throw new RuntimeException("Incomparable Terms in Equality Formula"); } // TODO recursively } @Override public Formula removeDomainITE(Formula topLevelFormula, Set<Token> noDependenceVars, List<Formula> andPreList) { /* * List<Formula> _andlist = new ArrayList<Formula>(); * * List<Term> terms2 = new ArrayList<Term>(); for (int i = 0; i < * terms.size(); i++) { if (terms.get(i) instanceof DomainIte) { * DomainIte domainITE = (DomainIte) terms.get(i); * * // replace the ITE with a new variable // the ITE-constraint is added * on the end of the topLevelFormula // by this function Holder<Term> * newVarName = new Holder<Term>(); * _andlist.add(domainITE.removeDomainITE(topLevelFormula, * noDependenceVars, newVarName, andPreList)); // terms.set(i, * newVarName.value); terms2.add(newVarName.value); * * // GH 2013-04-30: The following block seems wrong. // It should * suffice if the variables *within* the // DomainIte are checked. The * variables to which it // is equated should not count! // ---- // if * (Util.formulaContainsAny(this, noDependenceVars)) { // assert * (newVarName.value instanceof DomainVariable); // Token name = Token * // .generate(((DomainVariable) newVarName.value) // .getVarName()); * // noDependenceVars.add(name); // } * * } else terms2.add(terms.get(i).removeDomainITE(topLevelFormula, * noDependenceVars, andPreList)); } * * andPreList.addAll(_andlist); try { return * EqualityFormula.create(terms2, equal); } catch (Exception ex) { * ex.printStackTrace(); throw new RuntimeException(ex); } */ List<Term> newTerms = new ArrayList<Term>(terms.size()); for (Term term : terms) { newTerms.add(term.removeDomainITE(topLevelFormula, noDependenceVars, andPreList)); } try { return EqualityFormula.create(newTerms, equal); } catch (SuraqException exc) { throw new RuntimeException( "Unexpected exception while removing DomainITEs.", exc); } } /** * @see at.iaik.suraq.smtlib.formula.Formula#uninterpretedFunctionsBackToArrayReads(java.util.Set) */ @Override public Formula uninterpretedFunctionsBackToArrayReads( Set<ArrayVariable> arrayVars, Map<SMTLibObject, SMTLibObject> done) { if (done.get(this) != null) return (Formula) done.get(this); List<Term> newTerms = new ArrayList<Term>(terms.size()); for (Term term : terms) { Term newTerm = (Term) term.uninterpretedFunctionsBackToArrayReads( arrayVars, done); newTerms.add(newTerm); } try { Formula result = EqualityFormula.create(newTerms, equal); done.put(this, result); return result; } catch (IncomparableTermsException exc) { throw new RuntimeException( "Unexpected IncomparableTermsException while back-substituting array reads.", exc); } } @Override public EqualityFormula removeArrayITE(Formula topLevelFormula, Set<Token> noDependenceVars, Collection<Formula> constraints) { List<Term> newTerms = new ArrayList<Term>(terms.size()); for (Term term : terms) { newTerms.add(term.removeArrayITE(topLevelFormula, noDependenceVars, constraints)); } try { return EqualityFormula.create(newTerms, equal); } catch (SuraqException exc) { throw new RuntimeException( "Unexpected exception while removing ArrayITEs.", exc); } } /** * @see at.iaik.suraq.smtlib.formula.Formula#writeOut(java.io.BufferedWriter, * java.util.Map, java.util.Map) */ @Override public void writeOut(BufferedWriter writer, HashTagContainer tagContainer, boolean handleThisWithTagContainer) throws IOException { if (handleThisWithTagContainer) { tagContainer.handle(this, writer); } else { writer.append('(') .append(this.equal ? SExpressionConstants.EQUAL.toString() : SExpressionConstants.DISTINCT.toString()) .append(' '); for (Term term : terms) { term.writeOut(writer, tagContainer); writer.append(' '); } writer.append(") "); } } /** * @see at.iaik.suraq.smtlib.formula.Formula#writeTo(java.io.Writer) */ @Override public void writeTo(Writer writer) throws IOException { if (!this.equal && this.terms.size() == 2) { writer.append("(not (="); for (Term term : terms) { writer.append(' '); term.writeTo(writer); } writer.append("))"); } else { writer.append('(').append( this.equal ? SExpressionConstants.EQUAL.toString() : SExpressionConstants.DISTINCT.toString()); for (Term term : terms) { writer.append(' '); term.writeTo(writer); } writer.append(") "); } } /** * @see at.iaik.suraq.smtlib.formula.Formula#writeTo(java.io.Writer, * java.util.Map) */ @Override public void writeTo(Writer writer, Map<SMTLibObject, String> definitions) throws IOException { writer.append('(') .append(this.equal ? SExpressionConstants.EQUAL.toString() : SExpressionConstants.DISTINCT.toString()).append(' '); for (Term term : terms) { String id = definitions.get(term); assert (id != null); writer.append(id); writer.append(' '); } writer.append(") "); } /** * @see at.iaik.suraq.smtlib.formula.Formula#size(boolean, java.util.Map) */ @Override public BigInteger size(boolean expandDAG, Map<Formula, BigInteger> done) { if (done.get(this) != null) { if (expandDAG) return done.get(this); else return BigInteger.ZERO; } assert (terms.size() == 2); BigInteger result = BigInteger.ONE; done.put(this, result); return result; } /** * @see at.iaik.suraq.smtlib.formula.Formula#computeParents(java.util.Map, * java.util.Set) */ @Override public void computeParents(Map<Formula, Set<Formula>> parents, Set<Formula> done) { return; // Leaf node } /** * @see at.iaik.suraq.smtlib.formula.Formula#computeSubformulasWithOnlyLeafChildren(java.util.Set, * java.util.HashSet) */ @Override public void computeSubformulasWithOnlyLeafChildren( Set<Formula> onlyLeafChildren, Set<Formula> leaves, Set<Formula> done) { if (done.contains(this)) return; if (leaves.contains(this)) { done.add(this); return; } done.add(this); return; } /** * @see at.iaik.suraq.smtlib.formula.Formula#dependsOnlyOn(java.util.Set) */ @Override public boolean dependsOnlyOn(Set<Formula> formulaSet) { return true; } }