/** * 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.Serializable; 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.TreeMap; import java.util.TreeSet; import at.iaik.suraq.exceptions.SuraqException; import at.iaik.suraq.sexp.SExpression; import at.iaik.suraq.sexp.Token; import at.iaik.suraq.smtlib.SMTLibObject; import at.iaik.suraq.util.FormulaCache; import at.iaik.suraq.util.HashTagContainer; /** * A class for formulas that consist just of one propositional variable. * * @author Georg Hofferek <georg.hofferek@iaik.tugraz.at> * */ public class PropositionalVariable extends PropositionalTerm implements Serializable { /** * */ private static final long serialVersionUID = 3473923317666080631L; /** * The name of the variable. */ private final String varName; private final int hashCode; public static PropositionalVariable create(String varname) { return FormulaCache.propVar.put(new PropositionalVariable(varname)); } public static PropositionalVariable create(Token name) { return FormulaCache.propVar.put(new PropositionalVariable(name .toString())); } public static PropositionalVariable create(Token name, int assertPartition) { return FormulaCache.propVar.put(new PropositionalVariable(name .toString(), assertPartition)); } public static PropositionalVariable create(String name, int assertPartition) { return FormulaCache.propVar.put(new PropositionalVariable(name, assertPartition)); } /** * * Constructs a new <code>PropositionalVariable</code>. * * @param varName * the name of the variable. */ private PropositionalVariable(String varName) { this.varName = varName; hashCode = varName.hashCode(); } /** * * Constructs a new <code>PropositionalVariable</code>. * * @param name * the <code>String</code> representing the variable name. * @param assertPartition * the assert partition of the variable. */ private PropositionalVariable(String name, int assertPartition) { this.varName = name.toString(); this.assertPartition = assertPartition; hashCode = varName.hashCode(); } /** * Get the variable name. * * @return the <code>varName</code> */ public String getVarName() { return varName; } /** * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof PropositionalVariable)) return false; if (this.hashCode != ((PropositionalVariable) obj).hashCode) return false; return varName.equals(((PropositionalVariable) obj).varName); } /** * @see java.lang.Object#hashCode() */ @Override public int hashCode() { return hashCode; } /** * @see at.iaik.suraq.smtlib.formula.Formula#deepFormulaCopy() */ @Override public Formula deepFormulaCopy() { return this; // experimental // return new PropositionalVariable(new String(varName), // this.assertPartition); } /** * @see at.iaik.suraq.smtlib.formula.Term#deepTermCopy() */ @Override public Term deepTermCopy() { return this; // experimental // return new PropositionalVariable(new String(varName), // this.assertPartition); } /** * @see at.iaik.suraq.smtlib.formula.Term#getArrayVariables() */ @Override public void getArrayVariables(Set<ArrayVariable> result, Set<SMTLibObject> done) { return; } /** * @see at.iaik.suraq.smtlib.formula.Term#getDomainVariables() */ @Override public void getDomainVariables(Set<DomainVariable> result, Set<SMTLibObject> done) { return; } /** * @see at.iaik.suraq.smtlib.formula.Term#getPropositionalVariables() */ @Override public void getPropositionalVariables(Set<PropositionalVariable> result, Set<SMTLibObject> done) { result.add(this); } /** * @see at.iaik.suraq.smtlib.formula.Formula#negationNormalForm() */ @Override public Formula negationNormalForm() throws SuraqException { return this.deepFormulaCopy(); } /** * @see at.iaik.suraq.smtlib.formula.Formula#getUninterpretedFunctionNames() */ @Override public void getUninterpretedFunctionNames(Set<String> result, Set<SMTLibObject> done) { return; } /** * @see at.iaik.suraq.smtlib.SMTLibObject#getUninterpretedFunctions(java.util.Set, * java.util.Set) */ @Override public void getUninterpretedFunctions(Set<UninterpretedFunction> result, Set<SMTLibObject> done) { return; } /** * @see at.iaik.suraq.smtlib.formula.Formula#getFunctionMacroNames() */ @Override public void getFunctionMacroNames(Set<String> result, Set<SMTLibObject> done) { return; } /** * @see at.iaik.suraq.smtlib.formula.Formula#getFunctionMacros() */ @Override public void getFunctionMacros(Set<FunctionMacro> result, Set<SMTLibObject> done) { return; } /** * @see at.iaik.suraq.smtlib.formula.Formula#getIndexSet() */ @Override public Set<DomainTerm> getIndexSet() throws SuraqException { return new HashSet<DomainTerm>(); } /** * @see at.iaik.suraq.smtlib.formula.Term#substituteTerm(Map) */ @Override public Term substituteTerm(Map<Token, ? extends Term> paramMap, Map<SMTLibObject, SMTLibObject> done) { if (done.containsKey(this)) { assert (done.get(this) != null); assert (done.get(this) instanceof Term); return (Term) done.get(this); } Term result; if (paramMap.containsKey(Token.generate(varName))) result = paramMap.get(Token.generate(varName)); else result = this; assert (result != null); done.put(this, result); 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; if (paramMap.containsKey(Token.generate(varName))) result = (PropositionalTerm) paramMap.get(Token.generate(varName)); else result = this; assert (result != null); done.put(this, result); return result; } /** * @see at.iaik.suraq.smtlib.formula.Formula#arrayPropertiesToFiniteConjunctions(java.util.Set) */ @Override public Formula arrayPropertiesToFiniteConjunctions(Set<DomainTerm> indexSet) { // Nothing to do here. return this; } @Override public Term arrayPropertiesToFiniteConjunctionsTerm(Set<DomainTerm> indexSet) { // Nothing to do here. return this; } /** * @see at.iaik.suraq.smtlib.formula.Formula#flatten() */ @Override public PropositionalVariable flatten() { return this; // experimental // return new PropositionalVariable(varName); } /** * @see at.iaik.suraq.smtlib.formula.Formula#toSmtlibV2() */ @Override public SExpression toSmtlibV2() { return Token.generate(varName); } /** * @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) { // nothing to do return this; } @Override public Term removeArrayWritesTerm(Formula topLevelFormula, Set<Formula> constraints, Set<Token> noDependenceVars) { // nothing to do return this; } /** * @see at.iaik.suraq.smtlib.formula.Formula#arrayReadsToUninterpretedFunctions() */ @Override public Formula arrayReadsToUninterpretedFunctions( Set<Token> noDependenceVars) { // nothing to do return this; } @Override public Term arrayReadsToUninterpretedFunctionsTerm( Set<Token> noDependenceVars) { // nothing to do return this; } /** * @see at.iaik.suraq.smtlib.formula.Formula#substituteUninterpretedFunction(Token, * at.iaik.suraq.smtlib.formula.UninterpretedFunction) */ @Override public PropositionalVariable substituteUninterpretedFunction( Map<Token, UninterpretedFunction> substitutions, Map<SMTLibObject, SMTLibObject> done) { return this; } /** * @see at.iaik.suraq.smtlib.formula.Term#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) { return this; } @Override public Term makeArrayReadsSimpleTerm(Formula topLevelFormula, Set<Formula> constraints, Set<Token> noDependenceVars) { return this; } /** * @see at.iaik.suraq.smtlib.formula.PropositionalTerm#uninterpretedPredicatesToAuxiliaryVariables(at.iaik.suraq.smtlib.formula.Formula, * java.util.Set, java.util.Set) */ /* * @Override public PropositionalTerm * uninterpretedPredicatesToAuxiliaryVariables( Formula topLeveFormula, * Set<Formula> constraints, Set<Token> noDependenceVars) { return new * PropositionalVariable(varName); } */ /** * Returns the elements assert-partition. * * @return assert-partition of the element. */ @Override public Set<Integer> getPartitionsFromSymbols() { Set<Integer> partitions = new TreeSet<Integer>(); partitions.add(this.assertPartition); 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) { if (firstLevel == true) { List<Formula> literals = new ArrayList<Formula>(); literals.add(this); return OrFormula.generate(literals); } if (notFlag == true) return NotFormula.create(this); return this; } /** * @see at.iaik.suraq.smtlib.formula.Formula#tseitinEncode(java.util.Map) */ @Override public PropositionalVariable tseitinEncode(List<OrFormula> clauses, Map<PropositionalVariable, Formula> encoding, Map<Formula, PropositionalVariable> done, int partition) { return PropositionalVariable.create(varName, partition); } /** * @see at.iaik.suraq.formula.Term#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) { return this; } @Override public Term uninterpretedPredicatesToAuxiliaryVariablesTerm( Formula topLeveFormula, Map<String, List<PropositionalVariable>> predicateInstances, Map<PropositionalVariable, List<DomainTerm>> instanceParameters, Set<Token> noDependenceVars) { return this; } /** * @see at.iaik.suraq.formula.Term#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) { return this; } @Override public Term uninterpretedFunctionsToAuxiliaryVariablesTerm( Formula topLeveFormula, Map<String, List<DomainVariable>> functionInstances, Map<DomainVariable, List<DomainTerm>> instanceParameters, Set<Token> noDependenceVars) { return this; } @Override public Formula replaceEquivalences(Formula topLeveFormula, Map<EqualityFormula, String> replacements, Set<Token> noDependenceVars) { return this; } @Override public PropositionalTerm removeDomainITE(Formula topLevelFormula, Set<Token> noDependenceVars, List<Formula> andPreList) { return this; } /** * @see at.iaik.suraq.smtlib.formula.Formula#uninterpretedFunctionsBackToArrayReads(java.util.Set) */ @Override public PropositionalTerm uninterpretedFunctionsBackToArrayReads( Set<ArrayVariable> arrayVars, Map<SMTLibObject, SMTLibObject> done) { return this; } /** * @see at.iaik.suraq.smtlib.formula.Term#removeArrayITE(at.iaik.suraq.smtlib.formula.Formula, * java.util.Set, java.util.Collection) */ @Override public PropositionalVariable removeArrayITE(Formula topLevelFormula, Set<Token> noDependenceVars, Collection<Formula> constraints) { return this; } /** * @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 { writer.append(varName); writer.append(' '); } /** * @see at.iaik.suraq.smtlib.formula.Term#writeOut(java.io.BufferedWriter, * at.iaik.suraq.util.HashTagContainer) */ @Override public void writeOut(BufferedWriter writer, HashTagContainer tagContainer) throws IOException { writeOut(writer, tagContainer, true); } /** * @see at.iaik.suraq.smtlib.formula.Term#writeTo(java.io.Writer) */ @Override public void writeTo(Writer writer) throws IOException { writer.write(varName); } /** * @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.write(varName); } /** * @see at.iaik.suraq.smtlib.formula.Formula#getLiterals(java.util.Set, * java.util.Set) */ @Override public void getLiterals(Set<Formula> result, Set<Formula> done) { result.add(this); } /** * @see at.iaik.suraq.smtlib.formula.Formula#numAigNodes(java.util.Set) */ @Override public int numAigNodes(Set<Formula> done) { 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 (done.get(this) != null); return done.get(this); } /** * @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; 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#getTerms(java.util.Set, * java.util.Set) */ @Override public void getTerms(Set<Term> result, Set<Formula> done) { return; } /** * @see at.iaik.suraq.smtlib.formula.Formula#dependsOnlyOn(java.util.Set) */ @Override public boolean dependsOnlyOn(Set<Formula> formulaSet) { return true; } }