import java.util.*;
import java.io.*;
-
-// a change touple is a pair that indicates if the
+///////////////////////////////////////////
+// IMPORTANT
+// This class is an immutable Canonical, so
+//
+// 0) construct them with a factory pattern
+// to ensure only canonical versions escape
+//
+// 1) any operation that modifies a Canonical
+// is a static method in the Canonical class
+//
+// 2) operations that just read this object
+// should be defined here
+//
+// 3) every Canonical subclass hashCode should
+// throw an error if the hash ever changes
+//
+///////////////////////////////////////////
+
+// a change tuple is a pair that indicates if the
// first ReachState is found in a ReachSet,
// then the second ReachState should be added
-// THIS CLASS IS IMMUTABLE!
-
public class ChangeTuple extends Canonical
{
- private ReachState toMatch;
- private ReachState toAdd;
+ protected ReachState toMatch;
+ protected ReachState toAdd;
+
+ public static ChangeTuple factory(ReachState toMatch,
+ ReachState toAdd) {
+ // we don't care about the predicates hanging on
+ // change tuple states, so always set them to empty
+ // to ensure change tuple sets work out
+ ReachState toMatchNoPreds =
+ ReachState.factory(toMatch.reachTuples,
+ ExistPredSet.factory()
+ );
+ ReachState toAddNoPreds =
+ ReachState.factory(toAdd.reachTuples,
+ ExistPredSet.factory()
+ );
+ ChangeTuple out = new ChangeTuple(toMatchNoPreds,
+ toAddNoPreds);
+ out = (ChangeTuple) Canonical.makeCanonical(out);
+ return out;
+ }
- public ChangeTuple(ReachState toMatch,
- ReachState toAdd) {
+ protected ChangeTuple(ReachState toMatch,
+ ReachState toAdd) {
this.toMatch = toMatch;
this.toAdd = toAdd;
}
- public ChangeTuple makeCanonical() {
- return (ChangeTuple) Canonical.makeCanonical(this);
- }
-
- public ReachState getSetToMatch() {
+ public ReachState getStateToMatch() {
return toMatch;
}
- public ReachState getSetToAdd() {
+ public ReachState getStateToAdd() {
return toAdd;
}
- public boolean equals(Object o) {
+ public boolean equalsSpecific(Object o) {
if( o == null ) {
return false;
}
}
ChangeTuple ct = (ChangeTuple) o;
-
- return toMatch.equals(ct.getSetToMatch() ) &&
- toAdd.equals(ct.getSetToAdd() );
+ return
+ toMatch.equals(ct.toMatch) &&
+ toAdd.equals(ct.toAdd);
}
- private boolean oldHashSet = false;
- private int oldHash = 0;
- public int hashCode() {
- int currentHash = toMatch.hashCode() + toAdd.hashCode()*3;
-
- if( oldHashSet == false ) {
- oldHash = currentHash;
- oldHashSet = true;
- } else {
- if( oldHash != currentHash ) {
- System.out.println("IF YOU SEE THIS A CANONICAL ChangeTuple CHANGED");
- Integer x = null;
- x.toString();
- }
- }
-
- return currentHash;
+ public int hashCodeSpecific() {
+ return
+ toMatch.hashCode() ^
+ toAdd.hashCode()*3;
}
-
public String toString() {
return new String("("+toMatch+" -> "+toAdd+")");
}