/** * Author: Georg Hofferek <georg.hofferek@iaik.tugraz.at> */ package at.iaik.suraq.smtlib.formula; 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.TreeMap; import at.iaik.suraq.exceptions.SuraqException; import at.iaik.suraq.sexp.Token; import at.iaik.suraq.util.FormulaCache; import at.iaik.suraq.util.Util; /** * A formula consisting of the equality of domain terms. * * @author Georg Hofferek <georg.hofferek@iaik.tugraz.at> * */ public class DomainEq extends EqualityFormula { /** * */ private static final long serialVersionUID = -8408624046605834100L; /** * * Constructs a new <code>TermEq</code>. * * @param terms * the terms of the (in)equality. * @param equal * <code>true</code> if an equality should be constructed, * <code>false</code> for an inequality. * */ private DomainEq(Collection<? extends DomainTerm> domainTerms, boolean equal) { super(domainTerms, equal); } public static DomainEq create(Collection<? extends DomainTerm> domainTerms, boolean equal) { return (DomainEq) FormulaCache.equalityFormula.put(new DomainEq( domainTerms, equal)); } /** * Returns a list (copy) of the terms compared by this formula. * * @return a list of the terms compared by this formula. */ public List<DomainTerm> getDomainTerms() { List<DomainTerm> terms = new ArrayList<DomainTerm>(); for (Term term : this.terms) terms.add(((DomainTerm) term)); return terms; } /** * @see at.iaik.suraq.smtlib.formula.Formula#deepFormulaCopy() */ @Override public Formula deepFormulaCopy() { return this; // experimental /* * List<DomainTerm> terms = new ArrayList<DomainTerm>(); for (Term term * : this.terms) { terms.add((DomainTerm) term.deepTermCopy()); } return * FormulaCache.equalityFormula.put(new DomainEq(terms, equal)); */ } /** * @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(((DomainTerm) term).getIndexSet()); return indexSet; } /** * @see at.iaik.suraq.smtlib.formula.EqualityFormula#arrayReadsToUninterpretedFunctions() */ @Override public Formula arrayReadsToUninterpretedFunctions( Set<Token> noDependenceVars) { List<Term> pairs = new ArrayList<Term>(terms); for (DomainTerm term : getDomainTerms()) { if (term instanceof ArrayRead) { while (pairs.remove(term)) { // this block is intentionally empty } pairs.add(((ArrayRead) term) .toUninterpretedFunctionInstance(noDependenceVars)); } else { pairs.remove(term); 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#tseitinEncode(java.util.List, * java.util.Map) */ @Override public Formula tseitinEncode(List<OrFormula> clauses, Map<PropositionalVariable, Formula> encoding, Map<Formula, PropositionalVariable> done, int partition) { assert (terms.size() == 2); // TODO: split larger equalities assert (clauses != null); assert (encoding != null); // BEGIN OLD CODE // Literals should not be Tseitin encoded. This is a waste. // Set<Integer> partitions = this.getPartitionsFromSymbols(); // assert (partitions.size() == 1 || partitions.size() == 2); // if (partitions.size() == 2) // partitions.remove(-1); // assert (partitions.size() == 1); // int partition = partitions.iterator().next(); // PropositionalVariable tseitinVar = Util.freshTseitinVar(partition); // encoding.put(tseitinVar, this.deepFormulaCopy()); // // List<Formula> disjuncts = new ArrayList<Formula>(2); // disjuncts.add(NotFormula.create(tseitinVar)); // disjuncts.add(this.deepFormulaCopy()); // clauses.add(OrFormula.generate(disjuncts)); // // disjuncts.clear(); // disjuncts.add(tseitinVar); // disjuncts.add(NotFormula.create(this.deepFormulaCopy())); // clauses.add(OrFormula.generate(disjuncts)); // return tseitinVar; // END OLD CODE - BEGIN REPLACEMENT Set<Integer> partitions = this.getPartitionsFromSymbols(); assert (partitions.size() == 1 || partitions.size() == 2); if (partitions.size() == 2) partitions.remove(-1); assert (partitions.size() == 1); assert (partitions.iterator().next().equals(partition) || partitions .iterator().next().equals(-1)); assert (Util.isLiteral(this)); return this; // END REPLACEMENT } /** * @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) { List<Term> terms2 = new ArrayList<Term>(); for (DomainTerm term : getDomainTerms()) { if (term instanceof UninterpretedFunctionInstance) { DomainVariable auxiliaryVariable = ((UninterpretedFunctionInstance) term) .applyReplaceUninterpretedFunctions(topLeveFormula, functionInstances, instanceParameters, noDependenceVars); terms2.add(auxiliaryVariable); } else terms2.add(term.uninterpretedFunctionsToAuxiliaryVariablesTerm( topLeveFormula, functionInstances, instanceParameters, noDependenceVars)); } try { return EqualityFormula.create(terms2, equal); } catch (Exception ex) { ex.printStackTrace(); throw new RuntimeException(ex); } } /** * @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; assert (terms.size() == 2); result.add(this); 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; assert (terms.size() == 2); done.add(this); return 0; } /** * @see at.iaik.suraq.smtlib.formula.Formula#toAig(TreeMap, java.util.Map) */ @Override public int toAig(TreeMap<Integer, Integer[]> aigNodes, Map<Formula, Integer> done) { assert (this.terms.size() == 2); assert (done.get(this) != null); return done.get(this) ^ (equal ? 0 : 1); } /** * @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; result.addAll(terms); done.add(this); } }