variables
are missing.
*/
STATE removeVariables(final Collectiondominator
(i.e., Var(return) = Var(this) ∪ Var(dominator)). If both states (this and dominator)
* share variables, the abstraction of dominator should replace the abstraction of this state (e.g., if
* Var(this)={x} and Var(dominator)={x}, then return dominator).
*
* Each variable from Var(dominator) is
* either identical to a variable from Var(this), (i.e. they have the same name, and the same type)
* or has a unique name that is not used by any variable in Var(this).
*
* @param dominator
* The dominator state that should be patched onto this
.
*/
STATE patch(STATE dominator);
/**
* Intersects this with another abstract state.
*
* @param other
* The other abstract state to intersect with.
* @return A new abstract state which is the result of the intersection of this and the other state.
*/
STATE intersect(final STATE other);
/**
* Computes the union of this state with another abstract state.
*
* @param other
* The other abstract state.
* @return A new abstract state which is the result of the union of this and the other state.
*/
STATE union(final STATE other);
/**
* Computes the union between this state and a set of abstract states s.t. the resulting union consists of
* less or equal than maxSize states and preserved as much information as possible.
*
* In particular, this is useful to separate the entry of a loop (i.e., the case were we do not enter a loop) from
* the cases were we enter a loop.
*
* Note:
*
other
or not. Instances are equal if they have the same set
* of variables and describe the same abstract state.
*
* @param other
* The other instance.
* @return true if both instances have the same set of variables and describe the same abstract state, false
* otherwise.
*/
boolean isEqualTo(final STATE other);
/**
* Check whether this instance is a strict subset, a subset, equal, or none of this compared to another instance.
* Only states with the same set of variables can be compared.
*
* @param other
* The other instance.
* @return A {@link SubsetResult}.
*/
SubsetResult isSubsetOf(final STATE other);
/**
* Return a compacted representation of the current {@link IAbstractState} where all variables are removed for which
* no information is present (i.e., remove all "top" variables).
*
* @return A compacted {@link IAbstractState} that is equivalent to this state except for the tracked variables.
*/
STATE compact();
/**
* Create an SMT constraint that represents this abstract state. If you do not want to implement this right away,
* just return script.term("true")
.
*
* @param script
* The {@link Script} instance of the current RCFG.
* @return A {@link Term} instance representing this abstract state. Must be false if isBottom is true.
*/
Term getTerm(final Script script);
/**
* Is used for debug output.
*
* @return A {@link String} representing this abstract state.
*/
String toLogString();
/**
* The result of {@link IAbstractState#isSubsetOf(IAbstractState)}.
*
* @author Daniel Dietsch (dietsch@informatik.uni-freiburg.de)
*
*/
public enum SubsetResult {
/**
* The set of program states represented by this abstract state is equal to the set of program states
* represented by the other abstract state.
*/
EQUAL,
/**
* The set of program states represented by this abstract state is either a strict subset of or equal to the set
* of program states represented by the other abstract state.
*/
NON_STRICT,
/**
* The set of program states represented by this abstract state is a strict subset of the set of program states
* represented by the other abstract state.
*/
STRICT,
/**
* If none of the other results apply.
*/
NONE;
/**
* Calculate the "minimum" between this and another {@link SubsetResult} (min(this,other)). The total order is
* {@link SubsetResult#EQUAL} > {@link SubsetResult#NON_STRICT} > {@link SubsetResult#STRICT} >
* {@link SubsetResult#NONE}.
*
* @param other
* The other {@link SubsetResult}.
* @return The result of min(this,other).
*/
public SubsetResult min(final SubsetResult other) {
switch (this) {
case EQUAL:
if (other == SubsetResult.EQUAL) {
return this;
}
break;
case NON_STRICT:
if (other == SubsetResult.NON_STRICT || other == SubsetResult.EQUAL) {
return this;
}
break;
case STRICT:
if (other != NONE) {
return this;
}
break;
case NONE:
return this;
default:
throw new UnsupportedOperationException("Unhandled case " + this);
}
return other;
}
public SubsetResult max(final SubsetResult other) {
switch (this) {
case EQUAL:
return this;
case NON_STRICT:
if (other != SubsetResult.EQUAL) {
return this;
}
break;
case STRICT:
if (other == NONE || other == STRICT) {
return this;
}
break;
case NONE:
if (other == SubsetResult.NONE) {
return this;
}
break;
default:
throw new UnsupportedOperationException("Unhandled case " + this);
}
return other;
}
}
}