Fix tabbing.... Please fix your editors so they do tabbing correctly!!! (Spaces...
[IRC.git] / Robust / src / Analysis / Disjoint / ChangeTuple.java
index 8a91b609b20fbefe4fde2cdd439e5ca1acf3917f..9d1b96dc6e9aac585da2630d8868f8148c14ca90 100644 (file)
@@ -5,37 +5,67 @@ import IR.Flat.*;
 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;
     }
@@ -45,31 +75,17 @@ public class ChangeTuple extends Canonical
     }
 
     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+")");
   }