/**
* 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.TreeMap;
import at.iaik.suraq.exceptions.SuraqException;
import at.iaik.suraq.exceptions.WrongFunctionTypeException;
import at.iaik.suraq.exceptions.WrongNumberOfParametersException;
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.ImmutableArrayList;
import at.iaik.suraq.util.Util;
/**
* @author Georg Hofferek <georg.hofferek@iaik.tugraz.at>
*
*/
public class UninterpretedPredicateInstance extends PropositionalTerm {
/**
*
*/
private static final long serialVersionUID = 7300557099748461681L;
private final int hashCode;
/**
* The function of which this is an instance.
*/
private final UninterpretedFunction function;
/**
* The list of parameters of this instance.
*/
private final ImmutableArrayList<DomainTerm> parameters;
private UninterpretedPredicateInstance(UninterpretedFunction function,
List<DomainTerm> parameters, int partition)
throws WrongNumberOfParametersException, WrongFunctionTypeException {
this(function, parameters);
if (partition != -1) {
assert (partition == this.assertPartition || this.assertPartition == -1);
this.assertPartition = partition;
}
}
public static UninterpretedPredicateInstance create(
UninterpretedFunction function, List<DomainTerm> parameters,
int partition) throws WrongNumberOfParametersException,
WrongFunctionTypeException {
return (UninterpretedPredicateInstance) FormulaCache.term
.put(new UninterpretedPredicateInstance(function, parameters,
partition));
}
/**
* Constructs a new <code>UninterpretedPredicateInstance</code> with the
* given values.
*
* @param function
* the function that is applied.
* @param parameters
* the parameters of the function
*
* @throws WrongNumberOfParametersException
* if the number of parameters of the function does not match
* the size of <code>parameters</code>.
* @throws WrongFunctionTypeException
* if the type of the given function is not <code>Value</code>.
*/
private UninterpretedPredicateInstance(UninterpretedFunction function,
List<DomainTerm> parameters)
throws WrongNumberOfParametersException, WrongFunctionTypeException {
if (function.getNumParams() != parameters.size())
throw new WrongNumberOfParametersException();
this.function = function;
if (!function.getType().equals(SExpressionConstants.BOOL_TYPE))
throw new WrongFunctionTypeException(
"Expected a domain function. Received type: "
+ function.getType().toString());
this.parameters = new ImmutableArrayList<DomainTerm>(parameters);
Set<Integer> partitions = new HashSet<Integer>();
for (DomainTerm parameter : this.parameters)
partitions.addAll(parameter.getPartitionsFromSymbols());
assert (partitions.size() <= 2);
if (partitions.size() == 2)
partitions.remove(-1);
assert (partitions.size() == 1);
this.assertPartition = partitions.iterator().next();
this.hashCode = this.function.hashCode() * 31
+ this.parameters.hashCode();
}
public static UninterpretedPredicateInstance create(
UninterpretedFunction function, List<DomainTerm> parameters)
throws WrongNumberOfParametersException, WrongFunctionTypeException {
return (UninterpretedPredicateInstance) FormulaCache.term
.put(new UninterpretedPredicateInstance(function, parameters));
}
public static UninterpretedPredicateInstance create(
UninterpretedFunction function, DomainTerm parameter)
throws WrongNumberOfParametersException, WrongFunctionTypeException {
if (function.getNumParams() != 1)
throw new WrongNumberOfParametersException("Predicate "
+ function.getName().toString() + " expects "
+ function.getNumParams() + " parameters.");
List<DomainTerm> parameters = new ArrayList<DomainTerm>(1);
parameters.add(parameter);
return (UninterpretedPredicateInstance) FormulaCache.term
.put(new UninterpretedPredicateInstance(function, parameters));
}
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!(obj instanceof UninterpretedPredicateInstance))
return false;
if (this.hashCode() != obj.hashCode())
return false;
UninterpretedPredicateInstance other = (UninterpretedPredicateInstance) obj;
if (!other.parameters.equals(parameters))
return false;
if (!other.function.equals(function))
return false;
return true;
}
/**
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
return this.hashCode;
}
/**
* Returns the function of which this is an instance
*
* @return the <code>function</code>
*/
public UninterpretedFunction getFunction() {
return function;
}
/**
* Returns a copy of the list of parameters of this instance.
*
* @return the <code>parameters</code> (copy)
*/
public List<DomainTerm> getParameters() {
return new ArrayList<DomainTerm>(parameters);
}
/**
* @see at.iaik.suraq.smtlib.formula.Formula#deepFormulaCopy()
*/
@Override
public UninterpretedPredicateInstance deepFormulaCopy() {
return this; // experimental
/*
* List<DomainTerm> parameterCopies = new ArrayList<DomainTerm>(); for
* (DomainTerm term : parameters)
* parameterCopies.add(term.deepTermCopy()); try { return new
* UninterpretedPredicateInstance( new UninterpretedFunction(function),
* parameterCopies, assertPartition); } catch (SuraqException exc) {
* throw new RuntimeException(
* "Unexpected situation whily copying predicate.", exc); }
*/
}
/**
* @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 : parameters)
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 : parameters)
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 : parameters)
term.getPropositionalVariables(result, done);
done.add(this);
}
/**
* @see at.iaik.suraq.smtlib.formula.Formula#getUninterpretedFunctionNames()
*/
@Override
public void getUninterpretedFunctionNames(Set<String> result,
Set<SMTLibObject> done) {
if (done.contains(this))
return;
result.add(this.function.getName().toString());
for (DomainTerm term : parameters)
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 : parameters)
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 : parameters)
term.getFunctionMacros(result, done);
done.add(this);
}
/**
* @see at.iaik.suraq.smtlib.formula.Formula#getIndexSet()
*/
@Override
public Set<DomainTerm> getIndexSet() throws SuraqException {
Set<DomainTerm> result = new HashSet<DomainTerm>();
for (DomainTerm term : parameters) {
result.addAll(term.getIndexSet());
}
return result;
}
/**
* @see at.iaik.suraq.smtlib.formula.Formula#negationNormalForm()
*/
@Override
public Formula negationNormalForm() throws SuraqException {
return deepFormulaCopy();
}
/**
* @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<DomainTerm> convertedParameters = new ArrayList<DomainTerm>();
for (int count = 0; count < parameters.size(); count++)
convertedParameters.add((DomainTerm) parameters.get(count)
.substituteTerm(paramMap, done));
UninterpretedPredicateInstance result;
try {
result = UninterpretedPredicateInstance.create(function,
convertedParameters);
} catch (SuraqException exc) {
throw new RuntimeException(
"Unexpected error while subsituting parameters.", exc);
}
assert (result != null);
done.put(this, result);
return result;
}
/**
* @see at.iaik.suraq.smtlib.formula.Formula#substituteUninterpretedFunction(at.iaik.suraq.sexp.Token,
* at.iaik.suraq.smtlib.formula.UninterpretedFunction)
*/
@Override
public UninterpretedPredicateInstance substituteUninterpretedFunction(
Map<Token, UninterpretedFunction> substitutions,
Map<SMTLibObject, SMTLibObject> done) {
if (done.get(this) != null) {
assert (done.get(this) instanceof UninterpretedPredicateInstance);
return (UninterpretedPredicateInstance) done.get(this);
}
UninterpretedFunction function = this.function;
if (substitutions.containsKey(function.getName())) {
function = substitutions.get(function.getName());
assert ((function.getType()).equals(SExpressionConstants.BOOL_TYPE));
}
// if (function.getName().equals(oldFunction)) {
// function = newFunction;
// assert (newFunction.getType()
// .equals(SExpressionConstants.BOOL_TYPE));
// }
List<DomainTerm> paramNew = new ArrayList<DomainTerm>();
for (Term term : parameters)
paramNew.add((DomainTerm) term.substituteUninterpretedFunction(
substitutions, done));
try {
UninterpretedPredicateInstance result = UninterpretedPredicateInstance
.create(function, paramNew);
done.put(this, result);
return result;
} catch (SuraqException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* @see at.iaik.suraq.smtlib.formula.Formula#removeArrayEqualities()
*/
@Override
public Formula removeArrayEqualities() {
List<DomainTerm> paramNew = new ArrayList<DomainTerm>();
for (Term param : parameters)
paramNew.add((DomainTerm) param.removeArrayEqualitiesTerm());
try {
return UninterpretedPredicateInstance.create(function, paramNew);
} catch (SuraqException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
@Override
public Term removeArrayEqualitiesTerm() {
List<DomainTerm> paramNew = new ArrayList<DomainTerm>();
for (Term param : parameters)
paramNew.add((DomainTerm) param.removeArrayEqualitiesTerm());
try {
return UninterpretedPredicateInstance.create(function, paramNew);
} catch (SuraqException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* @see at.iaik.suraq.smtlib.formula.Formula#arrayPropertiesToFiniteConjunctions(java.util.Set)
*/
@Override
public Formula arrayPropertiesToFiniteConjunctions(Set<DomainTerm> indexSet) {
List<DomainTerm> paramNew = new ArrayList<DomainTerm>();
for (Term param : parameters)
paramNew.add((DomainTerm) param
.arrayPropertiesToFiniteConjunctionsTerm(indexSet));
try {
return UninterpretedPredicateInstance.create(function, paramNew);
} catch (SuraqException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
@Override
public Term arrayPropertiesToFiniteConjunctionsTerm(Set<DomainTerm> indexSet) {
List<DomainTerm> paramNew = new ArrayList<DomainTerm>();
for (Term param : parameters)
paramNew.add((DomainTerm) param
.arrayPropertiesToFiniteConjunctionsTerm(indexSet));
try {
return UninterpretedPredicateInstance.create(function, paramNew);
} catch (SuraqException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* @see at.iaik.suraq.smtlib.formula.Formula#simplify()
*/
@Override
public Formula simplify() {
return deepFormulaCopy();
}
/**
* @see at.iaik.suraq.smtlib.formula.Formula#flatten()
*/
@Override
public UninterpretedPredicateInstance flatten() {
List<DomainTerm> flattenedParams = new ArrayList<DomainTerm>();
for (DomainTerm term : parameters)
flattenedParams.add((DomainTerm) term.flatten());
try {
return UninterpretedPredicateInstance.create(function,
flattenedParams);
} catch (SuraqException exc) {
throw new RuntimeException(
"Unexpected error while flattening UninterpretedFunctionInstance.",
exc);
}
}
/**
* @see at.iaik.suraq.smtlib.formula.Formula#toSmtlibV2()
*/
@Override
public SExpression toSmtlibV2() {
List<SExpression> expr = new ArrayList<SExpression>();
expr.add(function.getName());
for (DomainTerm term : parameters)
expr.add(term.toSmtlibV2());
return new SExpression(expr);
}
/**
* @see at.iaik.suraq.smtlib.formula.Formula#removeArrayWrites(at.iaik.suraq.smtlib.formula.Formula,
* java.util.Set, java.util.Set)
*/
@Override
public Formula removeArrayWrites(Formula topLevelFormula,
Set<Formula> constraints, Set<Token> noDependenceVars) {
List<DomainTerm> paramNew = new ArrayList<DomainTerm>();
for (Term param : parameters)
paramNew.add((DomainTerm) param.removeArrayWritesTerm(
topLevelFormula, constraints, noDependenceVars));
try {
return UninterpretedPredicateInstance.create(function, paramNew);
} catch (SuraqException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
@Override
public Term removeArrayWritesTerm(Formula topLevelFormula,
Set<Formula> constraints, Set<Token> noDependenceVars) {
List<DomainTerm> paramNew = new ArrayList<DomainTerm>();
for (Term param : parameters)
paramNew.add((DomainTerm) param.removeArrayWritesTerm(
topLevelFormula, constraints, noDependenceVars));
try {
return UninterpretedPredicateInstance.create(function, paramNew);
} catch (SuraqException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* @see at.iaik.suraq.smtlib.formula.Formula#arrayReadsToUninterpretedFunctions(java.util.Set)
*/
@Override
public Formula arrayReadsToUninterpretedFunctions(
Set<Token> noDependenceVars) {
List<DomainTerm> paramNew = new ArrayList<DomainTerm>();
for (DomainTerm term : parameters)
if (term instanceof ArrayRead) {
paramNew.add(((ArrayRead) term)
.toUninterpretedFunctionInstance(noDependenceVars));
} else
paramNew.add((DomainTerm) term
.arrayReadsToUninterpretedFunctionsTerm(noDependenceVars));
try {
return UninterpretedPredicateInstance.create(function, paramNew);
} catch (SuraqException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
@Override
public Term arrayReadsToUninterpretedFunctionsTerm(
Set<Token> noDependenceVars) {
List<DomainTerm> paramNew = new ArrayList<DomainTerm>();
for (DomainTerm term : parameters)
if (term instanceof ArrayRead) {
paramNew.add(((ArrayRead) term)
.toUninterpretedFunctionInstance(noDependenceVars));
} else
paramNew.add((DomainTerm) term
.arrayReadsToUninterpretedFunctionsTerm(noDependenceVars));
try {
return UninterpretedPredicateInstance.create(function, paramNew);
} catch (SuraqException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public static boolean method = true; // TODO remove this
/**
* @see at.iaik.suraq.smtlib.formula.Formula#getUninterpretedFunctions()
*/
@Override
public void getUninterpretedFunctions(Set<UninterpretedFunction> result,
Set<SMTLibObject> done) {
if (done.contains(this))
return;
result.add(function);
for (DomainTerm term : parameters)
term.getUninterpretedFunctions(result, done);
done.add(this);
}
/**
* @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) {
List<DomainTerm> paramNew = new ArrayList<DomainTerm>();
for (Term param : parameters)
paramNew.add((DomainTerm) param.makeArrayReadsSimpleTerm(
topLevelFormula, constraints, noDependenceVars));
try {
return UninterpretedPredicateInstance.create(function, paramNew);
} catch (SuraqException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
@Override
public Term makeArrayReadsSimpleTerm(Formula topLevelFormula,
Set<Formula> constraints, Set<Token> noDependenceVars) {
List<DomainTerm> paramNew = new ArrayList<DomainTerm>();
for (Term param : parameters)
paramNew.add((DomainTerm) param.makeArrayReadsSimpleTerm(
topLevelFormula, constraints, noDependenceVars));
try {
return UninterpretedPredicateInstance.create(function, paramNew);
} catch (SuraqException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* @see at.iaik.suraq.smtlib.formula.Formula#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) {
* PropositionalVariable newVar = new PropositionalVariable(
* Util.freshVarName(topLeveFormula, "aux")); List<PropositionalTerm> terms
* = new ArrayList<PropositionalTerm>(); terms.add(newVar);
* terms.add(FormulaTerm.create(this.deepFormulaCopy()));
* constraints.add(new PropositionalEq(terms, true));
*
* if (Util.formulaContainsAny(this, noDependenceVars))
* noDependenceVars.add(new Token(newVar.getVarName()));
*
* return newVar; }
*/
/**
* Returns the elements assert-partition.
*
* @return assert-partition of the element.
*/
@Override
public Set<Integer> getPartitionsFromSymbols() {
Set<Integer> partitions = function.getAssertPartitionFromSymbols();
for (DomainTerm term : parameters)
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) {
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.Term#deepTermCopy()
*/
@Override
public Term deepTermCopy() {
return deepFormulaCopy();
}
/**
* @see at.iaik.suraq.smtlib.formula.Term#substituteTerm(Map)
*/
@Override
public Term substituteTerm(Map<Token, ? extends Term> paramMap,
Map<SMTLibObject, SMTLibObject> done) {
return (Term) substituteFormula(paramMap, done);
}
/**
* @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) {
// OLD Code (that encodes a predicate instance)
// assert (clauses != null);
// assert (encoding != null);
//
// 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));
//
// 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;
// BEGIN REPLACEMENT (do not encode predicate instance, as it already is
// a literal)
return this;
// END REPLACEMENT
}
/**
* Searches predicate-instance and instance-parameter mappings for match of
* current UninterpretedPredicateInstance's function and parameter
* valuation.
*
* @param predicateInstances
* map containing mapping from function names to auxiliary
* variables.
*
* @param instanceParameters
* map containing mapping from auxiliary variables to function
* instance parameters.
*
* @return the found auxiliary PropositionalVariable. If no match exists
* NULL is returned.
*/
private PropositionalVariable matchPredicateInstance(
Map<String, List<PropositionalVariable>> predicateInstances,
Map<PropositionalVariable, List<DomainTerm>> instanceParameters) {
String predicateName = function.getName().toString();
List<PropositionalVariable> instances = predicateInstances
.get(predicateName);
if (instances != null)
for (PropositionalVariable instance : instances) {
List<DomainTerm> instParameters = instanceParameters
.get(instance);
boolean found = true;
for (int x = 0; x < instParameters.size(); x++) {
DomainTerm a = parameters.get(x);
DomainTerm b = instParameters.get(x);
if (!(a.equals(b))) {
found = false;
break;
}
}
if (found)
return instance;
}
return null;
}
/**
* Add the current UninterpretedPredicateInstance as new entry into the
* predicate-instance and instance-parameter mappings.
*
* @param predicateInstances
* map containing mapping from function names to auxiliary
* variables.
*
* @param instanceParameters
* map containing mapping from auxiliary variables to function
* instance parameters.
*
* @return newly created auxiliary DomainVariable as substitute for the
* current UninterpretedFunctionInstace.
*/
private PropositionalVariable addPredicateInstance(Formula topLeveFormula,
Map<String, List<PropositionalVariable>> predicateInstances,
Map<PropositionalVariable, List<DomainTerm>> instanceParameters) {
PropositionalVariable result = null;
Set<String> instancesStr = new HashSet<String>();
for (PropositionalVariable pv : instanceParameters.keySet())
instancesStr.add(pv.getVarName());
String varName = Util.freshVarNameCached(topLeveFormula, function
.getName().toString(), instancesStr);
result = PropositionalVariable.create(varName);
String predicateName = function.getName().toString();
List<PropositionalVariable> instances = predicateInstances
.get(predicateName);
if (instances == null)
instances = new ArrayList<PropositionalVariable>();
instances.add(result);
predicateInstances.put(predicateName, instances);
instanceParameters.put(result, parameters);
return result;
}
/**
* @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) {
throw new RuntimeException(
"uninterpretedPredicatesToAuxiliaryVariables cannot be called on an UninterpretedPredicateInstance.\nUse applyReplaceUninterpretedPredicates instead.");
}
@Override
public Term uninterpretedPredicatesToAuxiliaryVariablesTerm(
Formula topLeveFormula,
Map<String, List<PropositionalVariable>> predicateInstances,
Map<PropositionalVariable, List<DomainTerm>> instanceParameters,
Set<Token> noDependenceVars) {
throw new RuntimeException(
"uninterpretedPredicatesToAuxiliaryVariables cannot be called on an UninterpretedPredicateInstance.\nUse applyReplaceUninterpretedPredicates instead.");
}
/**
* @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<DomainTerm> paramNew = new ArrayList<DomainTerm>();
for (DomainTerm term : parameters) {
if (term instanceof UninterpretedFunctionInstance) {
DomainVariable auxiliaryVariable = ((UninterpretedFunctionInstance) term)
.applyReplaceUninterpretedFunctions(topLeveFormula,
functionInstances, instanceParameters,
noDependenceVars);
// chillebold: imho: the order of these terms may be important!
// parameters.remove(term);
// parameters.add(auxiliaryVariable);
// verify if still working - need a testcase for this
// Let's try this instead.
// I don't know how the for-loop is implemented.
// In some programming languages the following action throws an
// exception, because the for-loop does not know how to
// continue.
// parameters.set(parameters.indexOf(term), auxiliaryVariable);
paramNew.add(auxiliaryVariable);
} else
paramNew.add((DomainTerm) term
.uninterpretedFunctionsToAuxiliaryVariablesTerm(
topLeveFormula, functionInstances,
instanceParameters, noDependenceVars));
}
try {
return UninterpretedPredicateInstance.create(function, paramNew);
} catch (SuraqException e) {
System.err.println("is: " + function.getNumParams() + " should:"
+ paramNew.size());
e.printStackTrace();
throw new RuntimeException(e);
}
}
@Override
public Term uninterpretedFunctionsToAuxiliaryVariablesTerm(
Formula topLeveFormula,
Map<String, List<DomainVariable>> functionInstances,
Map<DomainVariable, List<DomainTerm>> instanceParameters,
Set<Token> noDependenceVars) {
List<DomainTerm> paramNew = new ArrayList<DomainTerm>();
for (DomainTerm term : parameters) {
if (term instanceof UninterpretedFunctionInstance) {
DomainVariable auxiliaryVariable = ((UninterpretedFunctionInstance) term)
.applyReplaceUninterpretedFunctions(topLeveFormula,
functionInstances, instanceParameters,
noDependenceVars);
// chillebold: imho: the order of these terms may be important!
// parameters.remove(term);
// parameters.add(auxiliaryVariable);
// verify if still working - need a testcase for this
// Let's try this instead.
// I don't know how the for-loop is implemented.
// In some programming languages the following action throws an
// exception, because the for-loop does not know how to
// continue.
// parameters.set(parameters.indexOf(term), auxiliaryVariable);
paramNew.add(auxiliaryVariable);
} else
term.uninterpretedFunctionsToAuxiliaryVariablesTerm(
topLeveFormula, functionInstances, instanceParameters,
noDependenceVars);
}
try {
return UninterpretedPredicateInstance.create(function, paramNew);
} catch (SuraqException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* Performs a substitution of UninterpretedPredicateInstances with auxiliary
* PropositionalVariables.
*
* @param topLeveFormula
* the top level formula (for finding fresh variable names).
*
* @param predicateInstances
* map containing mapping from predicate names to auxiliary
* variables.
*
* @param instanceParameters
* map containing mapping from auxiliary variables to function
* instance parameters.
*
* @return auxiliary PropositionalVariable as substitute for the current
* UninterpretedPredicateInstace.
*/
public PropositionalVariable applyReplaceUninterpretedPredicates(
Formula topLeveFormula,
Map<String, List<PropositionalVariable>> predicateInstances,
Map<PropositionalVariable, List<DomainTerm>> instanceParameters,
Set<Token> noDependenceVars) {
PropositionalVariable result = matchPredicateInstance(
predicateInstances, instanceParameters);
if (result == null)
result = addPredicateInstance(topLeveFormula, predicateInstances,
instanceParameters);
// Check if the function is noDependence or at least one parameter of
// the function is noDependence
// This might be conservative and might not be complete (i.e., may
// result unnecessary unrealizability)
boolean insert = false;
for (DomainTerm term : parameters) {
if (Util.termContainsAny(term, noDependenceVars))
insert = true;
}
String funcName = function.getName().toString();
for (Token t : noDependenceVars) {
if (funcName.equals(t.toString())) {
insert = true;
break;
}
}
if (insert == true) {
noDependenceVars.add(Token.generate(result.getVarName()));
}
return result;
}
@Override
public Formula replaceEquivalences(Formula topLeveFormula,
Map<EqualityFormula, String> replacements,
Set<Token> noDependenceVars) {
throw new RuntimeException(
"replaceEquivalences cannot be called on an UninterpretedFunctions.\n"
+ "UninterpretedFunctions should be removed by now.");
}
@Override
public PropositionalTerm removeDomainITE(Formula topLevelFormula,
Set<Token> noDependenceVars, List<Formula> andPreList) {
// List<Formula> _andlist = new ArrayList<Formula>();
// List<DomainTerm> terms2 = new ArrayList<DomainTerm>();
// for (DomainTerm term : parameters) {
// if (term instanceof DomainIte) {
// Holder<Term> newVarName = new Holder<Term>();
// _andlist.add(((DomainIte) term).removeDomainITE(
// topLevelFormula, noDependenceVars, newVarName,
// andPreList));
// if (Util.formulaContainsAny(this, noDependenceVars)) {
// assert (newVarName.value instanceof DomainVariable);
// Token name = Token
// .generate(((DomainVariable) newVarName.value)
// .getVarName());
// noDependenceVars.add(name);
// }
// assert (newVarName.value instanceof DomainTerm);
// terms2.add((DomainTerm) newVarName.value);
// } else {
// terms2.add(term.removeDomainITE(topLevelFormula,
// noDependenceVars, andPreList));
// }
// }
//
// andPreList.addAll(_andlist);
// try {
// return UninterpretedPredicateInstance.create(this.function, terms2);
// } catch (Exception ex) {
// ex.printStackTrace();
// throw new RuntimeException(ex);
// }
List<DomainTerm> newParams = new ArrayList<DomainTerm>(
parameters.size());
for (DomainTerm parameter : parameters) {
newParams.add(parameter.removeDomainITE(topLevelFormula,
noDependenceVars, andPreList));
}
try {
return UninterpretedPredicateInstance.create(function, newParams);
} catch (SuraqException exc) {
throw new RuntimeException(
"Unexpected exception while removing DomainITEs.", exc);
}
}
/**
* @see at.iaik.suraq.smtlib.formula.PropositionalTerm#uninterpretedFunctionsBackToArrayReads(java.util.Set)
*/
@Override
public PropositionalTerm uninterpretedFunctionsBackToArrayReads(
Set<ArrayVariable> arrayVars, Map<SMTLibObject, SMTLibObject> done) {
if (done.get(this) != null)
return (PropositionalTerm) done.get(this);
List<DomainTerm> newParameters = new ArrayList<DomainTerm>();
for (DomainTerm parameter : parameters) {
newParameters.add((DomainTerm) parameter
.uninterpretedFunctionsBackToArrayReads(arrayVars, done));
}
try {
PropositionalTerm result = UninterpretedPredicateInstance.create(
function, newParameters);
done.put(this, result);
return result;
} catch (WrongNumberOfParametersException exc) {
throw new RuntimeException(
"Unexpected WrongNumberOfParametersException while back-substituting array reads.",
exc);
} catch (WrongFunctionTypeException exc) {
throw new RuntimeException(
"Unexpected WrongFunctionTypeException while back-substituting array reads.",
exc);
}
}
/**
* @see at.iaik.suraq.smtlib.formula.Term#removeArrayITE(at.iaik.suraq.smtlib.formula.Formula,
* java.util.Set, java.util.Collection)
*/
@Override
public UninterpretedPredicateInstance removeArrayITE(
Formula topLevelFormula, Set<Token> noDependenceVars,
Collection<Formula> constraints) {
List<DomainTerm> newParams = new ArrayList<DomainTerm>(
parameters.size());
for (DomainTerm parameter : parameters) {
newParams.add(parameter.removeArrayITE(topLevelFormula,
noDependenceVars, constraints));
}
try {
return UninterpretedPredicateInstance.create(function, newParams);
} catch (SuraqException exc) {
throw new RuntimeException(
"Unexpected exception while removing ArrayITEs.", exc);
}
}
/**
* @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(function.toString());
writer.append(' ');
for (DomainTerm parameter : parameters) {
parameter.writeOut(writer, tagContainer);
writer.append(' ');
}
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.append("(").append(function.toString());
for (DomainTerm parameter : parameters) {
writer.write(" ");
parameter.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(function.toString());
for (DomainTerm parameter : parameters) {
writer.write(" ");
String id = definitions.get(parameter);
assert (id != null);
writer.write(id);
}
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) {
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) {
if (done.contains(this))
return;
result.addAll(parameters);
done.add(this);
}
/**
* @see at.iaik.suraq.smtlib.formula.Formula#dependsOnlyOn(java.util.Set)
*/
@Override
public boolean dependsOnlyOn(Set<Formula> formulaSet) {
return true;
}
}