ProgramState { @Override public String toString() { return "{" + values.toString() + "} {" + constraints.toString() + "}" + " { " + stack.toString() + " }"; } private  ProgramState(PMap<Symbol, SymbolicValue> values,PMap<Integer, SymbolicValue> valuesByIndex, PMap<SymbolicValue, Integer> references,
                       PMap<SymbolicValue, ConstraintsByDomain> constraints, PMap<ProgramPoint, Integer> visitedPoints,
                       PStack<SymbolicValueSymbol> stack, SymbolicValue exitSymbolicValue); private  ProgramState(PMap<Symbol, SymbolicValue> values, PMap<SymbolicValue, Integer> references,
                       PMap<SymbolicValue, ConstraintsByDomain> constraints, PMap<ProgramPoint, Integer> visitedPoints,
                       PStack<SymbolicValueSymbol> stack, SymbolicValue exitSymbolicValue); private  ProgramState(ProgramState ps, PStack<SymbolicValueSymbol> newStack); private  ProgramState(ProgramState ps, PMap<SymbolicValue, ConstraintsByDomain> newConstraints); ProgramState stackValue(SymbolicValue sv); ProgramState stackValue(SymbolicValue sv, @Nullable Symbol symbol); Pop unstackValue(int nbElements); @CheckForNull SymbolicValue peekValue(); SymbolicValueSymbol peekValueSymbol(); SymbolicValue peekValue(int i); List<SymbolicValue> peekValues(int n); List<SymbolicValueSymbol> peekValuesAndSymbols(int n); int numberOfTimeVisited(ProgramPoint programPoint); @Override boolean equals(Object o); @Override int hashCode(); @Override String toString(); ProgramState addConstraintTransitively(SymbolicValue symbolicValue, Constraint constraint); Set<RelationalSymbolicValue> knownRelations(); ProgramState addConstraint(SymbolicValue symbolicValue, Constraint constraint); ProgramState addConstraints(SymbolicValue symbolicValue, ConstraintsByDomain constraintsForSV); ProgramState removeConstraintsOnDomain(SymbolicValue sv, Class<? extends Constraint> domain); @VisibleForTesting ProgramState put(Symbol symbol, SymbolicValue value); ProgramState cleanupDeadSymbols(Set<Symbol> liveVariables, Collection<SymbolicValue> protectedSymbolicValues); ProgramState cleanupConstraints(Collection<SymbolicValue> protectedSymbolicValues); static boolean isField(Symbol symbol); boolean canReach(SymbolicValue symbolicValue); ProgramState visitedPoint(ProgramPoint programPoint, int nbOfVisit); @Nullable ConstraintsByDomain getConstraints(SymbolicValue sv); @CheckForNull T getConstraint(SymbolicValue sv, Class<T> domain); int constraintsSize(); @CheckForNull SymbolicValue getValue(int index); @CheckForNull SymbolicValue getValue(Symbol symbol); List<SymbolicValue> getValuesWithConstraints(final Constraint constraint); void storeExitValue(); @CheckForNull SymbolicValue exitValue(); boolean exitingOnRuntimeException(); static final ProgramState EMPTY_STATE; }
@Test void testToString() { SymbolicValue sv3 = new SymbolicValue() { @Override public String toString() { return "SV_3"; } }; ProgramState state = ProgramState.EMPTY_STATE.stackValue(sv3); Symbol variable = variable("x"); SymbolicValue sv4 = new SymbolicValue() { @Override public String toString() { return "SV_4"; } }; state = state.put(variable, sv4); SymbolicValue sv5 = new SymbolicValue() { @Override public String toString() { return "SV_5"; } }; state = state.stackValue(sv5, variable); assertThat(state.toString()).contains("A#x->SV_4", "SV_NULL", "SV_TRUE", "SV_FALSE", "A#x->SV_5", "SV_3"); }