/**
* Author: Georg Hofferek <georg.hofferek@iaik.tugraz.at>
*/
package at.iaik.suraq.smtlib.formula;
import java.io.Serializable;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
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.IdGenerator;
/**
* This class represents uninterpreted functions. It stores the name of the
* function and the number of parameters. All parameters need to be of sort
* <code>Value</code>. The return type may be <code>Value</code> or
* <code>Bool</code>.
*
* @author Georg Hofferek <georg.hofferek@iaik.tugraz.at>
*
*/
public class UninterpretedFunction implements SMTLibObject, Serializable {
/**
*
*/
private static final long serialVersionUID = 5520322987626682279L;
private final long id = IdGenerator.getId();
/**
* The assert-partitions
*/
protected final int assertPartition;
/**
* The number of parameters.
*/
private final int numParams;
/**
* The name of this function.
*/
private final Token name;
/**
* The return type of the function.
*/
private final Token type;
private final int hashCode;
public static UninterpretedFunction create(String name, int numParams,
Token type) {
return FormulaCache.uninterpretedFunction
.put(new UninterpretedFunction(name, numParams, type));
}
public static UninterpretedFunction create(Token name, int numParams,
Token type) {
return FormulaCache.uninterpretedFunction
.put(new UninterpretedFunction(name, numParams, type));
}
public static UninterpretedFunction create(String name, int numParams,
Token type, int assertPartition) {
return FormulaCache.uninterpretedFunction
.put(new UninterpretedFunction(name, numParams, type,
assertPartition));
}
public static UninterpretedFunction create(UninterpretedFunction original) {
return original; // experimental
}
/**
*
* Constructs a new <code>UninterpretedFunction</code>.
*
* @param name
* the name of the function
* @param numParams
* the number of parameters.
* @param type
* the return type of the function (<code>Value</code> or
* <code>Bool</code>).
*/
private UninterpretedFunction(String name, int numParams, Token type) {
this.name = Token.generate(name);
this.numParams = numParams;
this.type = type;
assertPartition = Term.GLOBAL_PARTITION;
this.hashCode = name.hashCode() * 31 * 31 + type.hashCode() * 31
+ numParams;
}
/**
*
* Constructs a new <code>UninterpretedFunction</code>.
*
* @param name
* the name of the function
* @param numParams
* the number of parameters.
* @param type
* the return type of the function (<code>Value</code> or
* <code>Bool</code>).
*/
private UninterpretedFunction(Token name, int numParams, Token type) {
this.name = name;
this.numParams = numParams;
this.type = type;
assertPartition = Term.GLOBAL_PARTITION;
this.hashCode = name.hashCode() * 31 * 31 + type.hashCode() * 31
+ numParams;
}
/**
*
* Constructs a new <code>UninterpretedFunction</code> as a deep copy of the
* given one.
*
* @param original
* the object to (deep) copy
*/
private UninterpretedFunction(UninterpretedFunction original) {
this.numParams = original.numParams;
this.name = Token.generate(original.name);
this.type = Token.generate(original.type);
this.assertPartition = original.assertPartition;
this.hashCode = name.hashCode() * 31 * 31 + type.hashCode() * 31
+ numParams;
}
/**
*
* Constructs a new <code>UninterpretedFunction</code>.
*
* @param name
* the name of the function
* @param numParams
* the number of parameters.
* @param type
* the return type of the function (<code>Value</code> or
* <code>Bool</code>).
* @param assertPartition
* the function's assert-partition.
*/
private UninterpretedFunction(String name, int numParams, Token type,
int assertPartition) {
this.name = Token.generate(name);
this.numParams = numParams;
this.type = type;
this.assertPartition = assertPartition;
this.hashCode = name.hashCode() * 31 * 31 + type.hashCode() * 31
+ numParams;
}
/**
* Returns the number of parameters of this function.
*
* @return the number of parameters.
*/
public int getNumParams() {
return numParams;
}
/**
* Returns the name of this function.
*
* @return the <code>name</code>
*/
public Token getName() {
return name;
}
/**
* Returns the type of this function.
*
* @return the <code>name</code>
*/
public Token getType() {
return type;
}
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!(obj instanceof UninterpretedFunction))
return false;
if (this.hashCode != ((UninterpretedFunction) obj).hashCode)
return false;
if (((UninterpretedFunction) obj).numParams != numParams)
return false;
if (!((UninterpretedFunction) obj).name.equals(name))
return false;
if (!(this.type.equals(((UninterpretedFunction) obj).type)))
return false;
return true;
}
/**
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
return hashCode;
}
/**
* @see at.iaik.suraq.smtlib.SMTLibObject#getId()
*/
@Override
public long getId() {
return id;
}
/**
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return this.name.toString();
}
/**
* Returns the elements assert-partition.
*
* @return assert-partition of the element.
*/
public Set<Integer> getAssertPartitionFromSymbols() {
Set<Integer> partitions = new TreeSet<Integer>();
partitions.add(this.assertPartition);
return partitions;
}
/**
* @see java.lang.Comparable#compareTo(java.lang.Object)
*/
@Override
public int compareTo(SMTLibObject o) {
return name.compareTo(((UninterpretedFunction) o).name);
}
/**
* @see at.iaik.suraq.smtlib.SMTLibObject#getPartitionsFromSymbols()
*/
@Override
public Set<Integer> getPartitionsFromSymbols() {
assert (false); // TODO Auto-generated method stub
return null;
}
/**
* @see at.iaik.suraq.smtlib.SMTLibObject#toSmtlibV2()
*/
@Override
public SExpression toSmtlibV2() {
return name;
}
/**
* @see at.iaik.suraq.smtlib.SMTLibObject#getArrayVariables(java.util.Set,
* java.util.Set)
*/
@Override
public void getArrayVariables(Set<ArrayVariable> result,
Set<SMTLibObject> done) {
return;
}
/**
* @see at.iaik.suraq.smtlib.SMTLibObject#getDomainVariables()
*/
@Override
public void getDomainVariables(Set<DomainVariable> result,
Set<SMTLibObject> done) {
return;
}
/**
* @see at.iaik.suraq.smtlib.SMTLibObject#getPropositionalVariables()
*/
@Override
public void getPropositionalVariables(Set<PropositionalVariable> result,
Set<SMTLibObject> done) {
return;
}
/**
* @see at.iaik.suraq.smtlib.SMTLibObject#getUninterpretedFunctionNames()
*/
@Override
public void getUninterpretedFunctionNames(Set<String> result,
Set<SMTLibObject> done) {
result.add(name.toString());
}
/**
* @see at.iaik.suraq.smtlib.SMTLibObject#getUninterpretedFunctions(java.util.Set,
* java.util.Set)
*/
@Override
public void getUninterpretedFunctions(Set<UninterpretedFunction> result,
Set<SMTLibObject> done) {
result.add(this);
}
/**
* @see at.iaik.suraq.smtlib.SMTLibObject#getFunctionMacroNames()
*/
@Override
public void getFunctionMacroNames(Set<String> result, Set<SMTLibObject> done) {
return;
}
/**
* @see at.iaik.suraq.smtlib.SMTLibObject#getFunctionMacros()
*/
@Override
public void getFunctionMacros(Set<FunctionMacro> result,
Set<SMTLibObject> done) {
return;
}
/**
* @see at.iaik.suraq.smtlib.SMTLibObject#substituteUninterpretedFunction(java.util.Map,
* java.util.Map)
*/
@Override
public SMTLibObject substituteUninterpretedFunction(
Map<Token, UninterpretedFunction> substitutions,
Map<SMTLibObject, SMTLibObject> done) {
throw new NotImplementedException();
}
/**
* @see at.iaik.suraq.smtlib.SMTLibObject#uninterpretedFunctionsBackToArrayReads(java.util.Set,
* java.util.Map)
*/
@Override
public SMTLibObject uninterpretedFunctionsBackToArrayReads(
Set<ArrayVariable> arrayVars, Map<SMTLibObject, SMTLibObject> done) {
throw new NotImplementedException();
}
}