/** * 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.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; import at.iaik.suraq.exceptions.SuraqException; 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.FormulaCache; import at.iaik.suraq.util.HashTagContainer; import at.iaik.suraq.util.Util; /** * A class for formulas of the form (a => b). * * @author Georg Hofferek <georg.hofferek@iaik.tugraz.at> * */ public class ImpliesFormula extends BooleanCombinationFormula { /** * */ private static final long serialVersionUID = -701197449376211245L; /** * The left side of the implication. */ private final Formula leftSide; /** * The right side of the implication. */ private final Formula rightSide; public static ImpliesFormula create(Formula leftSide, Formula rightSide) { return FormulaCache.impliesFormula.put(new ImpliesFormula(leftSide, rightSide)); } /** * * Constructs a new <code>ImpliesFormula</code>. * * @param leftSide * the left side of the implication * @param rightSide * the right side of the implication */ private ImpliesFormula(Formula leftSide, Formula rightSide) { if (leftSide instanceof FormulaTerm) this.leftSide = ((FormulaTerm) leftSide).getFormula(); else this.leftSide = leftSide; if (rightSide instanceof FormulaTerm) this.rightSide = ((FormulaTerm) rightSide).getFormula(); else this.rightSide = rightSide; } /** * @see at.iaik.suraq.smtlib.formula.BooleanCombinationFormula#getSubFormulas() */ @Override public Collection<Formula> getSubFormulas() { List<Formula> list = new ArrayList<Formula>(); list.add(leftSide); list.add(rightSide); return list; } /** * @see at.iaik.suraq.smtlib.formula.Formula#deepFormulaCopy() */ @Override public Formula deepFormulaCopy() { return this; // experimental // return new ImpliesFormula(leftSide.deepFormulaCopy(), // rightSide.deepFormulaCopy()); } /** * @see at.iaik.suraq.smtlib.formula.Formula#getArrayVariables() */ @Override public void getArrayVariables(Set<ArrayVariable> result, Set<SMTLibObject> done) { if (done.contains(this)) return; leftSide.getArrayVariables(result, done); rightSide.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; leftSide.getDomainVariables(result, done); rightSide.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; leftSide.getPropositionalVariables(result, done); rightSide.getPropositionalVariables(result, done); done.add(this); } /** * @see at.iaik.suraq.smtlib.formula.Formula#negationNormalForm() */ @Override public Formula negationNormalForm() throws SuraqException { List<Formula> list = new ArrayList<Formula>(); list.add((NotFormula.create(leftSide)).negationNormalForm()); list.add(rightSide.negationNormalForm()); return OrFormula.generate(list); } /** * @return the <code>leftSide</code> */ public Formula getLeftSide() { return leftSide; } /** * @return the <code>rightSide</code> */ public Formula getRightSide() { return rightSide; } /** * @see at.iaik.suraq.smtlib.formula.Formula#getUninterpretedFunctionNames() */ @Override public void getUninterpretedFunctionNames(Set<String> result, Set<SMTLibObject> done) { if (done.contains(this)) return; leftSide.getUninterpretedFunctionNames(result, done); rightSide.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; leftSide.getFunctionMacroNames(result, done); rightSide.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; leftSide.getFunctionMacros(result, done); rightSide.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 (!(obj instanceof ImpliesFormula)) return false; if (this.hashCode() != obj.hashCode()) return false; return ((ImpliesFormula) obj).leftSide.equals(leftSide) && ((ImpliesFormula) obj).rightSide.equals(rightSide); } /** * @see java.lang.Object#hashCode() */ @Override public int hashCode() { return leftSide.hashCode() * 31 + rightSide.hashCode(); } /** * @see at.iaik.suraq.smtlib.formula.Formula#getIndexSet() */ @Override public Set<DomainTerm> getIndexSet() throws SuraqException { Set<DomainTerm> result = leftSide.getIndexSet(); result.addAll(rightSide.getIndexSet()); return result; } /** * @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); } Formula result = ImpliesFormula.create( leftSide.substituteFormula(paramMap, done), rightSide.substituteFormula(paramMap, done)); assert (result != null); done.put(this, result); return result; } /** * @see at.iaik.suraq.smtlib.formula.Formula#removeArrayEqualitiesTerm() */ @Override public Formula removeArrayEqualities() { Formula rightSide = this.rightSide; Formula leftSide = this.leftSide; if (leftSide instanceof ArrayEq) leftSide = ((ArrayEq) leftSide).toArrayProperties(); else leftSide = leftSide.removeArrayEqualities(); if (rightSide instanceof ArrayEq) rightSide = ((ArrayEq) rightSide).toArrayProperties(); else rightSide = rightSide.removeArrayEqualities(); return ImpliesFormula.create(leftSide, rightSide); } /** * @see at.iaik.suraq.smtlib.formula.Formula#arrayPropertiesToFiniteConjunctions(java.util.Set) */ @Override public Formula arrayPropertiesToFiniteConjunctions(Set<DomainTerm> indexSet) { Formula rightSide = this.rightSide; Formula leftSide = this.leftSide; if (leftSide instanceof ArrayProperty) leftSide = ((ArrayProperty) leftSide).toFiniteConjunction(indexSet); else leftSide = leftSide.arrayPropertiesToFiniteConjunctions(indexSet); if (rightSide instanceof ArrayProperty) rightSide = ((ArrayProperty) rightSide) .toFiniteConjunction(indexSet); else rightSide = rightSide.arrayPropertiesToFiniteConjunctions(indexSet); return ImpliesFormula.create(leftSide, rightSide); } /** * @see at.iaik.suraq.smtlib.formula.Formula#simplify() */ @Override public Formula simplify() { Formula leftSide = this.leftSide.simplify(); Formula rightSide = this.rightSide.simplify(); if (leftSide instanceof PropositionalConstant) { if (((PropositionalConstant) leftSide).getValue()) return rightSide; else return PropositionalConstant.create(true); } if (rightSide instanceof PropositionalConstant) { if (((PropositionalConstant) rightSide).getValue()) return PropositionalConstant.create(true); else return NotFormula.create(leftSide).simplify(); } if (leftSide.equals(rightSide)) return PropositionalConstant.create(true); if (leftSide instanceof NotFormula) if (rightSide.equals(((NotFormula) leftSide).getNegatedFormula())) return rightSide; if (rightSide instanceof NotFormula) if (leftSide.equals(((NotFormula) rightSide).getNegatedFormula())) return rightSide; return ImpliesFormula.create(leftSide, rightSide); } /** * @see at.iaik.suraq.smtlib.formula.Formula#flatten() */ @Override public Formula flatten() { return ImpliesFormula.create(leftSide.flatten(), rightSide.flatten()); } /** * @see at.iaik.suraq.smtlib.formula.Formula#toSmtlibV2() */ @Override public SExpression toSmtlibV2() { return new SExpression(SExpressionConstants.IMPLIES, leftSide.toSmtlibV2(), rightSide.toSmtlibV2()); } /** * @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) { Formula rightSide = this.rightSide; Formula leftSide = this.leftSide; leftSide = leftSide.removeArrayWrites(topLevelFormula, constraints, noDependenceVars); rightSide = rightSide.removeArrayWrites(topLevelFormula, constraints, noDependenceVars); return ImpliesFormula.create(leftSide, rightSide); } /** * @see at.iaik.suraq.smtlib.formula.Formula#arrayReadsToUninterpretedFunctions() */ @Override public Formula arrayReadsToUninterpretedFunctions( Set<Token> noDependenceVars) { Formula rightSide = this.rightSide; Formula leftSide = this.leftSide; leftSide = leftSide .arrayReadsToUninterpretedFunctions(noDependenceVars); rightSide = rightSide .arrayReadsToUninterpretedFunctions(noDependenceVars); return ImpliesFormula.create(leftSide, rightSide); } /** * @see at.iaik.suraq.smtlib.formula.Formula#getUninterpretedFunctions() */ @Override public void getUninterpretedFunctions(Set<UninterpretedFunction> result, Set<SMTLibObject> done) { if (done.contains(this)) return; leftSide.getUninterpretedFunctions(result, done); rightSide.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); } Formula rightSide = this.rightSide; Formula leftSide = this.leftSide; leftSide = leftSide .substituteUninterpretedFunction(substitutions, done); rightSide = rightSide.substituteUninterpretedFunction(substitutions, done); Formula result = ImpliesFormula.create(leftSide, rightSide); done.put(this, result); return result; } /** * @see at.iaik.suraq.smtlib.formula.Formula#makeArrayReadsSimple(at.iaik.suraq.smtlib.formula.Formula, * java.util.Set, java.util.Set) */ @Override public Formula makeArrayReadsSimple(Formula topLevelFormula, Set<Formula> constraints, Set<Token> noDependenceVars) { Formula rightSide = this.rightSide; Formula leftSide = this.leftSide; leftSide = leftSide.makeArrayReadsSimple(topLevelFormula, constraints, noDependenceVars); rightSide = rightSide.makeArrayReadsSimple(topLevelFormula, constraints, noDependenceVars); return ImpliesFormula.create(leftSide, rightSide); } /** * @see at.iaik.suraq.smtlib.formula.Formula#uninterpretedPredicatesToAuxiliaryVariables(at.iaik.suraq.smtlib.formula.Formula, * java.util.Set, java.util.Set) */ /* * @Override public Formula uninterpretedPredicatesToAuxiliaryVariables( * Formula topLeveFormula, Set<Formula> constraints, Set<Token> * noDependenceVars) { return new ImpliesFormula( * leftSide.uninterpretedPredicatesToAuxiliaryVariables( topLeveFormula, * constraints, noDependenceVars), * rightSide.uninterpretedPredicatesToAuxiliaryVariables( topLeveFormula, * constraints, noDependenceVars)); } */ /** * Returns the elements assert-partition. * * @return assert-partition of the element. */ @Override public Set<Integer> getPartitionsFromSymbols() { Set<Integer> partitions = this.leftSide.getPartitionsFromSymbols(); partitions.addAll(this.rightSide.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) { // a => b equals NOT a OR b if (notFlag == true) throw new RuntimeException( "An implies formula is now allowed to occur inside an NOT formula"); List<Formula> subFormulas = new ArrayList<Formula>(); if (isValidChild(this.leftSide)) { if (this.leftSide instanceof AndFormula) { ArrayList<Formula> conjuncts = (ArrayList<Formula>) ((AndFormula) this.leftSide) .getConjuncts(); for (Formula conjunct : conjuncts) { // remove nested AND formula if (conjunct instanceof AndFormula) { ArrayList<Formula> subConjuncts = (ArrayList<Formula>) ((AndFormula) conjunct) .getConjuncts(); for (Formula subConjunct : subConjuncts) { Formula transformedSubFormula = subConjunct .transformToConsequentsForm(!notFlag, false); subFormulas.add(transformedSubFormula); } } else { Formula transformedSubFormula = conjunct .transformToConsequentsForm(!notFlag, false); subFormulas.add(transformedSubFormula); } } } else if (Util.isLiteral(this.leftSide) || this.leftSide instanceof NotFormula) { Formula transformedSubFormula = this.leftSide .transformToConsequentsForm(!notFlag, false); subFormulas.add(transformedSubFormula); } else throw new RuntimeException( "left side of implication is OR Formula, which isn`t valid"); } else throw new RuntimeException( "Unexpected Chid: left child of implies formula is not valid"); if (isValidChild(this.rightSide)) { if (this.rightSide instanceof OrFormula) { ArrayList<Formula> disjuncts = (ArrayList<Formula>) ((OrFormula) this.rightSide) .getDisjuncts(); for (Formula disjunct : disjuncts) { // remove nested OR formula if (disjunct instanceof OrFormula) { ArrayList<Formula> subDisjuncts = (ArrayList<Formula>) ((OrFormula) disjunct) .getDisjuncts(); for (Formula subDisjunct : subDisjuncts) { Formula transformedSubFormula = subDisjunct .transformToConsequentsForm(notFlag, false); subFormulas.add(transformedSubFormula); } } else { Formula transformedSubFormula = disjunct .transformToConsequentsForm(notFlag, false); subFormulas.add(transformedSubFormula); } } } else if (Util.isLiteral(this.rightSide) || this.rightSide instanceof NotFormula) { Formula transformedSubFormula = this.rightSide .transformToConsequentsForm(notFlag, false); subFormulas.add(transformedSubFormula); } else throw new RuntimeException( "rightSide side of implication is AND Formula, which isn`t valid"); } else throw new RuntimeException( "Unexpected Chid: right child of implies formula is not valid"); return OrFormula.generate(subFormulas); } /** * Checks if a given formula is a literal, or an OR formula, an AND formula * or a NOT formula. * * @param formula * formula to check * @return true, iff formula is valid */ public boolean isValidChild(Formula formula) { if (formula instanceof OrFormula) return true; if (formula instanceof AndFormula) return true; if (formula instanceof NotFormula) return true; if (Util.isLiteral(formula)) return true; return false; } /** * @see at.iaik.suraq.smtlib.formula.Formula#tseitinEncode(java.util.Map) */ @Override public Formula tseitinEncode(List<OrFormula> clauses, Map<PropositionalVariable, Formula> encoding, Map<Formula, PropositionalVariable> done, int partition) { List<Formula> disjuncts = new ArrayList<Formula>(2); if (leftSide instanceof NotFormula) disjuncts.add(((NotFormula) leftSide).getNegatedFormula()); else disjuncts.add(NotFormula.create(leftSide)); disjuncts.add(rightSide); OrFormula implication = OrFormula.generate(disjuncts); return implication.tseitinEncode(clauses, encoding, done, partition); } /** * @see at.iaik.suraq.formula.Formula#uninterpretedPredicatesToAuxiliaryVariables(at.iaik.suraq.formula.Formula, * java.util.Map, java.util.Map) */ @Override public Formula uninterpretedPredicatesToAuxiliaryVariables( Formula topLeveFormula, Map<String, List<PropositionalVariable>> predicateInstances, Map<PropositionalVariable, List<DomainTerm>> instanceParameters, Set<Token> noDependenceVars) { Formula rightSide = this.rightSide; Formula leftSide = this.leftSide; if (leftSide instanceof UninterpretedPredicateInstance) leftSide = ((UninterpretedPredicateInstance) leftSide) .applyReplaceUninterpretedPredicates(topLeveFormula, predicateInstances, instanceParameters, noDependenceVars); else leftSide = leftSide.uninterpretedPredicatesToAuxiliaryVariables( topLeveFormula, predicateInstances, instanceParameters, noDependenceVars); if (rightSide instanceof UninterpretedPredicateInstance) rightSide = ((UninterpretedPredicateInstance) rightSide) .applyReplaceUninterpretedPredicates(topLeveFormula, predicateInstances, instanceParameters, noDependenceVars); else rightSide = rightSide.uninterpretedPredicatesToAuxiliaryVariables( topLeveFormula, predicateInstances, instanceParameters, noDependenceVars); return ImpliesFormula.create(leftSide, rightSide); } /** * @see at.iaik.suraq.formula.Formula#uninterpretedFunctionsToAuxiliaryVariables(at.iaik.suraq.formula.Formula, * java.util.Map, java.util.Map) */ @Override public Formula uninterpretedFunctionsToAuxiliaryVariables( Formula topLeveFormula, Map<String, List<DomainVariable>> functionInstances, Map<DomainVariable, List<DomainTerm>> instanceParameters, Set<Token> noDependenceVars) { Formula rightSide = this.rightSide; Formula leftSide = this.leftSide; leftSide = leftSide.uninterpretedFunctionsToAuxiliaryVariables( topLeveFormula, functionInstances, instanceParameters, noDependenceVars); rightSide = rightSide.uninterpretedFunctionsToAuxiliaryVariables( topLeveFormula, functionInstances, instanceParameters, noDependenceVars); return ImpliesFormula.create(leftSide, rightSide); } @Override public Formula replaceEquivalences(Formula topLeveFormula, Map<EqualityFormula, String> replacements, Set<Token> noDependenceVars) { Formula rightSide = this.rightSide; Formula leftSide = this.leftSide; leftSide = leftSide.replaceEquivalences(topLeveFormula, replacements, noDependenceVars); rightSide = rightSide.replaceEquivalences(topLeveFormula, replacements, noDependenceVars); return ImpliesFormula.create(leftSide, rightSide); } @Override public Formula removeDomainITE(Formula topLevelFormula, Set<Token> noDependenceVars, List<Formula> andPreList) { Formula rightSide = this.rightSide; Formula leftSide = this.leftSide; leftSide = leftSide.removeDomainITE(topLevelFormula, noDependenceVars, andPreList); rightSide = rightSide.removeDomainITE(topLevelFormula, noDependenceVars, andPreList); return ImpliesFormula.create(leftSide, rightSide); } /** * @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); Formula result = ImpliesFormula.create((Formula) leftSide .uninterpretedFunctionsBackToArrayReads(arrayVars, done), (Formula) rightSide.uninterpretedFunctionsBackToArrayReads( arrayVars, done)); done.put(this, result); return result; } /** * @see at.iaik.suraq.smtlib.formula.Formula#removeArrayITE(at.iaik.suraq.smtlib.formula.Formula, * java.util.Set, java.util.Collection) */ @Override public Formula removeArrayITE(Formula topLevelFormula, Set<Token> noDependenceVars, Collection<Formula> constraints) { Formula newLeftSide = leftSide.removeArrayITE(topLevelFormula, noDependenceVars, constraints); Formula newRightSide = rightSide.removeArrayITE(topLevelFormula, noDependenceVars, constraints); return ImpliesFormula.create(newLeftSide, newRightSide); } /** * @see at.iaik.suraq.smtlib.formula.Formula#writeOut(java.io.BufferedWriter, * at.iaik.suraq.util.HashTagContainer, boolean) */ @Override public void writeOut(BufferedWriter writer, HashTagContainer tagContainer, boolean handleThisWithTagContainer) throws IOException { if (handleThisWithTagContainer) { tagContainer.handle(this, writer); } else { writer.append('(').append(SExpressionConstants.IMPLIES.toString()); writer.append(' '); leftSide.writeOut(writer, tagContainer, true); writer.append(' '); rightSide.writeOut(writer, tagContainer, true); writer.append(')'); } } /** * @throws IOException * @see at.iaik.suraq.smtlib.formula.Term#writeTo(java.io.Writer) */ @Override public void writeTo(Writer writer) throws IOException { writer.append('(').append(SExpressionConstants.IMPLIES.toString()); writer.append(' '); leftSide.writeTo(writer); writer.append(' '); rightSide.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(SExpressionConstants.IMPLIES.toString()); writer.append(' '); String idLeft = definitions.get(leftSide); assert (idLeft != null); writer.write(idLeft); writer.append(' '); String idRight = definitions.get(rightSide); assert (idRight != null); writer.write(idRight); writer.append(')'); } /** * @see at.iaik.suraq.smtlib.formula.Formula#getLiterals(java.util.Set, * java.util.Set) */ @Override public void getLiterals(Set<Formula> result, Set<Formula> done) { if (done.contains(this)) return; leftSide.getLiterals(result, done); rightSide.getLiterals(result, done); done.add(this); } /** * @see at.iaik.suraq.smtlib.formula.Formula#numAigNodes(java.util.Set) */ @Override public int numAigNodes(Set<Formula> done) { if (done.contains(this)) return 0; int result = 0; result += leftSide.numAigNodes(done); result += rightSide.numAigNodes(done); result++; done.add(this); return result; } /** * @see at.iaik.suraq.smtlib.formula.Formula#toAig(TreeMap, java.util.Map) */ @Override public int toAig(TreeMap<Integer, Integer[]> aigNodes, Map<Formula, Integer> done) { if (done.get(this) != null) return done.get(this); int left = leftSide.toAig(aigNodes, done); int right = rightSide.toAig(aigNodes, done); int result = Util.nextFreePositiveAigLiteral(aigNodes, done); Integer[] node = new Integer[2]; node[0] = left; node[1] = right ^ 1; aigNodes.put(result, node); result ^= 1; done.put(this, result); return result; } /** * @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; } BigInteger result = BigInteger.ONE; result = result.add(leftSide.size(expandDAG, done)); result = result.add(rightSide.size(expandDAG, done)); 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) { if (done.contains(this)) return; Formula[] formulas = { leftSide, rightSide }; for (Formula child : formulas) { Set<Formula> childsParents = parents.get(child); if (childsParents == null) { childsParents = new TreeSet<Formula>(); parents.put(child, childsParents); } assert (childsParents != null); childsParents.add(this); child.computeParents(parents, done); } done.add(this); } /** * @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; } Formula[] formulas = { leftSide, rightSide }; boolean result = true; for (Formula formula : formulas) { if (!leaves.contains(formula)) result = false; formula.computeSubformulasWithOnlyLeafChildren(onlyLeafChildren, leaves, done); } if (result) onlyLeafChildren.add(this); done.add(this); return; } /** * @see at.iaik.suraq.smtlib.formula.Formula#getTerms(java.util.Set, * java.util.Set) */ @Override public void getTerms(Set<Term> result, Set<Formula> done) { if (done.contains(this)) return; leftSide.getTerms(result, done); rightSide.getTerms(result, done); done.add(this); } /** * @see at.iaik.suraq.smtlib.formula.Formula#dependsOnlyOn(java.util.Set) */ @Override public boolean dependsOnlyOn(Set<Formula> formulaSet) { if (!formulaSet.contains(leftSide)) return false; if (!formulaSet.contains(rightSide)) return false; return true; } }