Added reachability classes, all of which are extensions of Canonical such that
authorjjenista <jjenista>
Wed, 9 Jul 2008 21:07:04 +0000 (21:07 +0000)
committerjjenista <jjenista>
Wed, 9 Jul 2008 21:07:04 +0000 (21:07 +0000)
after makeCanonical() two equivalent reachability classes are actually the same
class.  This was the bug that kept the orginial analysis tests from terminating
and now they run fine.

14 files changed:
Robust/src/Analysis/OwnershipAnalysis/Canonical.java [new file with mode: 0644]
Robust/src/Analysis/OwnershipAnalysis/ChangeTuple.java
Robust/src/Analysis/OwnershipAnalysis/ChangeTupleSet.java
Robust/src/Analysis/OwnershipAnalysis/HeapRegionNode.java
Robust/src/Analysis/OwnershipAnalysis/OwnershipAnalysis.java
Robust/src/Analysis/OwnershipAnalysis/OwnershipGraph.java
Robust/src/Analysis/OwnershipAnalysis/ReachabilitySet.java
Robust/src/Analysis/OwnershipAnalysis/ReferenceEdgeProperties.java
Robust/src/Analysis/OwnershipAnalysis/TokenTuple.java
Robust/src/Analysis/OwnershipAnalysis/TokenTupleSet.java
Robust/src/Makefile
Robust/src/Tests/OwnershipAnalysisTest/test01/makefile
Robust/src/Tests/OwnershipAnalysisTest/test01/test01.java
Robust/src/Tests/OwnershipAnalysisTest/testTokens/Main.java

diff --git a/Robust/src/Analysis/OwnershipAnalysis/Canonical.java b/Robust/src/Analysis/OwnershipAnalysis/Canonical.java
new file mode 100644 (file)
index 0000000..f2d5901
--- /dev/null
@@ -0,0 +1,20 @@
+package Analysis.OwnershipAnalysis;
+
+import IR.*;
+import IR.Flat.*;
+import java.util.*;
+import java.io.*;
+
+public class Canonical {
+
+    private static Hashtable<Canonical, Canonical> canon = new Hashtable<Canonical, Canonical>();
+
+    public static Canonical makeCanonical( Canonical c ) {
+       if( canon.containsKey( c ) ) {
+           return canon.get( c );
+       }
+
+       canon.put( c, c );
+       return c;
+    }
+}
index 9a1f8bdfda54fe8a4b2876354cb3bb6cc1436f93..296e578d353900ec1f8af3d9e0fb3dc352a2f9f6 100644 (file)
@@ -12,7 +12,7 @@ import java.io.*;
 
 // THIS CLASS IS IMMUTABLE!
 
-public class ChangeTuple
+public class ChangeTuple extends Canonical
 {
     private TokenTupleSet toMatch;
     private TokenTupleSet toAdd;
@@ -23,6 +23,10 @@ public class ChangeTuple
        this.toAdd   = toAdd;
     }
 
+    public ChangeTuple makeCanonical() {
+       return (ChangeTuple) Canonical.makeCanonical( this );
+    }
+
     public TokenTupleSet getSetToMatch() { return toMatch; }
     public TokenTupleSet getSetToAdd()   { return toAdd;   }
 
index 5593285b1ce5a2be9785e6850e5f54cc2d12736f..afbd04052c87aa67229867b29e4ddc1c93bdf26a 100644 (file)
@@ -6,7 +6,7 @@ import java.util.*;
 import java.io.*;
 
 
-public class ChangeTupleSet {
+public class ChangeTupleSet extends Canonical {
 
     private HashSet<ChangeTuple> changeTuples;
 
@@ -23,6 +23,10 @@ public class ChangeTupleSet {
        changeTuples = (HashSet<ChangeTuple>) cts.changeTuples.clone(); //COPY?!
     }
 
+    public ChangeTupleSet makeCanonical() {
+       return (ChangeTupleSet) Canonical.makeCanonical( this );
+    }
+
     public Iterator iterator() {
        return changeTuples.iterator();
     }
@@ -30,13 +34,26 @@ public class ChangeTupleSet {
     public ChangeTupleSet union( ChangeTupleSet ctsIn ) {
        ChangeTupleSet ctsOut = new ChangeTupleSet( this );
        ctsOut.changeTuples.addAll( ctsIn.changeTuples );
-       return ctsOut;
+       return ctsOut.makeCanonical();
     }
 
     public boolean isSubset( ChangeTupleSet ctsIn ) {
        return ctsIn.changeTuples.containsAll( this.changeTuples );
     }
 
+    public boolean equals( Object o ) {
+       if( !(o instanceof ChangeTupleSet) ) {
+           return false;
+       }
+
+       ChangeTupleSet cts = (ChangeTupleSet) o;
+       return changeTuples.equals( cts.changeTuples );
+    }
+
+    public int hashCode() {
+       return changeTuples.hashCode();
+    }
+
     public String toString() {
        String s = "[";
 
index 1e28f9045410f029f1cf67a5c358773f16c512c1..08502304f90a84cda4dfaeb2b0a040211b2d340f 100644 (file)
@@ -57,6 +57,7 @@ public class HeapRegionNode extends OwnershipNode {
        return id;
     }
 
+
     public boolean equals( HeapRegionNode hrn ) {
        assert hrn != null;
 
@@ -64,6 +65,7 @@ public class HeapRegionNode extends OwnershipNode {
            isSingleObject == hrn.isSingleObject() &&
            isFlagged      == hrn.isFlagged()      &&
            isNewSummary   == hrn.isNewSummary()   &&
+           alpha.equals( hrn.getAlpha() )         &&
            description.equals( hrn.getDescription() );
     }
 
@@ -116,6 +118,10 @@ public class HeapRegionNode extends OwnershipNode {
     }
 
 
+    public void setAlpha( ReachabilitySet alpha ) {
+       this.alpha = alpha;
+    }
+
     public ReachabilitySet getAlpha() {
        return alpha;
     }
index 991bd02b9d3f0cf6c219ad16e161652b5fbc0128..23d9af6fbabfb8b26900c9950ca3da0c0284404d 100644 (file)
@@ -318,6 +318,11 @@ public class OwnershipAnalysis {
        // the final ownership graph result to return as an empty set
        returnNodesToCombineForCompleteOwnershipGraph = new HashSet<FlatReturnNode>();
 
+
+       // DEBUG
+       //int x = 0;
+
+
        while( !flatNodesToVisit.isEmpty() ) {
            FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
            flatNodesToVisit.remove( fn );
@@ -351,6 +356,20 @@ public class OwnershipAnalysis {
            if( !og.equals( ogPrev ) ) {
                setGraphForFlatNode( fn, og );
 
+               // DEBUG
+               /*
+               ++x;    
+
+               if( x > 5000 ) {
+               String s = String.format( "%04d", x );
+               og.writeGraph( "debug"+s, false, false );
+               }
+
+               if( x == 5020 ) {
+                   System.exit( -1 );
+               }
+               */
+
                for( int i = 0; i < fn.numNext(); i++ ) {
                    FlatNode nn = fn.getNext( i );                
                    flatNodesToVisit.add( nn );
index 39fa29d8839e05f5592b2849df4c3c797136ccca..0eb63db786110f32e2efb0437dc7a9bc8f3ef768 100644 (file)
@@ -24,10 +24,6 @@ public class OwnershipGraph {
 
     public HashSet<AllocationSite> allocationSites;
 
-    // CHANGE!  Map HRN ID's to token sets (sets of IDs!)
-    //public Hashtable< HeapRegionNode,     HashSet< HashSet<HeapRegionNode> > > alpha;
-    //public Hashtable< touple< HRN, HRN >, HashSet< HashSet<HeapRegionNode> > > beta;
-
 
     public OwnershipGraph( int allocationDepth ) {
        this.allocationDepth = allocationDepth;
@@ -38,8 +34,6 @@ public class OwnershipGraph {
        paramIndex2id = new Hashtable<Integer,        Integer       >();
 
        allocationSites = new HashSet <AllocationSite>();
-
-       //alpha = new Hashtable< HeapRegionNode, HashSet< HashSet<HeapRegionNode> > >();
     }
 
 
@@ -658,6 +652,9 @@ public class OwnershipGraph {
     // in merge() and equals() methods the suffix A 
     // represents the passed in graph and the suffix
     // B refers to the graph in this object
+    // Merging means to take the incoming graph A and
+    // merge it into B, so after the operation graph B
+    // is the final result.
     ////////////////////////////////////////////////////
     public void merge( OwnershipGraph og ) {
 
@@ -669,9 +666,9 @@ public class OwnershipGraph {
        mergeReferenceEdges ( og );
        mergeId2paramIndex  ( og );
        mergeAllocationSites( og );
-       //mergeTokenSets      ( og );
     }
 
+
     protected void mergeOwnershipNodes( OwnershipGraph og ) {
        Set      sA = og.id2hrn.entrySet();
        Iterator iA = sA.iterator();
@@ -685,6 +682,12 @@ public class OwnershipGraph {
            if( !id2hrn.containsKey( idA ) ) {
                HeapRegionNode hrnB = hrnA.copy();
                id2hrn.put( idA, hrnB );
+           } else {
+               // otherwise this is a node present in both graphs
+               // so make the new reachability set a union of the
+               // nodes' reachability sets
+               HeapRegionNode hrnB = id2hrn.get( idA );
+               hrnB.setAlpha( hrnB.getAlpha().union( hrnA.getAlpha() ) );
            }
        }
 
@@ -708,7 +711,8 @@ public class OwnershipGraph {
        // for stroing heap region nodes retrieved by integer
        // ids.  Because finding edges requires interacting
        // with these disparate data structures frequently the
-       // process is nearly duplicated, one for each
+       // process is nearly duplicated, one for each structure
+       // that stores edges
 
        // heap regions
        Set      sA = og.id2hrn.entrySet();
@@ -733,14 +737,17 @@ public class OwnershipGraph {
                assert id2hrn.containsKey( idA );
                HeapRegionNode hrnB = id2hrn.get( idA );
 
-               HeapRegionNode hrnChildB = null;
+               HeapRegionNode          hrnChildB = null;
+               ReferenceEdgeProperties repB      = null;
                Iterator heapRegionsItrB = hrnB.setIteratorToReferencedRegions();
                while( heapRegionsItrB.hasNext() ) {
-                   Map.Entry meC = (Map.Entry)      heapRegionsItrB.next();
-                   hrnChildB     = (HeapRegionNode) meC.getKey();
+                   Map.Entry meC               = (Map.Entry)               heapRegionsItrB.next();
+                   hrnChildB                   = (HeapRegionNode)          meC.getKey();
+                   ReferenceEdgeProperties rep = (ReferenceEdgeProperties) meC.getValue();
 
                    if( hrnChildB.equals( idChildA ) ) {
                        edgeFound = true;
+                       repB      = rep;
                    }
                }
 
@@ -749,15 +756,15 @@ public class OwnershipGraph {
                if( !edgeFound ) {
                    assert id2hrn.containsKey( idChildA );
                    hrnChildB = id2hrn.get( idChildA );
-                   ReferenceEdgeProperties repB = repA.copy();
+                   repB = repA.copy();
                    addReferenceEdge( hrnB, hrnChildB, repB );
                }
-               // otherwise, the edge already existed in both graphs.
-               // if this is the case, check to see whether the isUnique
-               // predicate of the edges might change
-               else
-               {
-
+               // otherwise, the edge already existed in both graphs
+               // so merge their reachability sets
+               else {
+                   // just replace this beta set with the union
+                   assert repB != null;
+                   repB.setBeta( repB.getBeta().union( repA.getBeta() ) );
                }  
            } 
        }
@@ -785,14 +792,17 @@ public class OwnershipGraph {
                assert td2ln.containsKey( tdA );
                LabelNode lnB = td2ln.get( tdA );
 
-               HeapRegionNode hrnChildB = null;
+               HeapRegionNode          hrnChildB = null;
+               ReferenceEdgeProperties repB      = null;
                Iterator heapRegionsItrB = lnB.setIteratorToReferencedRegions();
                while( heapRegionsItrB.hasNext() ) {
-                   Map.Entry meC = (Map.Entry)      heapRegionsItrB.next();
-                   hrnChildB     = (HeapRegionNode) meC.getKey();
+                   Map.Entry meC               = (Map.Entry)               heapRegionsItrB.next();
+                   hrnChildB                   = (HeapRegionNode)          meC.getKey();
+                   ReferenceEdgeProperties rep = (ReferenceEdgeProperties) meC.getValue();
 
                    if( hrnChildB.equals( idChildA ) ) {
                        edgeFound = true;
+                       repB      = rep;
                    }
                }
 
@@ -801,15 +811,15 @@ public class OwnershipGraph {
                if( !edgeFound ) {
                    assert id2hrn.containsKey( idChildA );
                    hrnChildB = id2hrn.get( idChildA );
-                   ReferenceEdgeProperties repB = repA.copy();
+                   repB = repA.copy();
                    addReferenceEdge( lnB, hrnChildB, repB );
                }
-               // otherwise, the edge already existed in both graphs.
-               // if this is the case, check to see whether the isUnique
-               // predicate of the edges might change
-               else
-               {
-
+               // otherwise, the edge already existed in both graphs
+               // so merge the reachability sets
+               else {
+                   // just replace this beta set with the union
+                   assert repB != null;
+                   repB.setBeta( repB.getBeta().union( repA.getBeta() ) );
                }  
            } 
        }
@@ -837,38 +847,6 @@ public class OwnershipGraph {
     }
 
 
-    
-    //protected void mergeTokenSets( OwnershipGraph og ) {
-       //      alpha = new Hashtable< HeapRegionNode,     HashSet< HashSet<HeapRegionNode> > >();
-
-       // if a key is in one or the other token set,
-       // add it to the merged token set.
-       // if a key is in both graphs, the merged
-       // token set should have that key and the union
-       // of values as the merged value.
-
-       /*
-       Set      alphaB = og.alpha.entrySet();
-       Iterator iB     = alphaB.iterator();
-       while( iB.hasNext() ) {
-           Map.Entry      meB     = (Map.Entry) iB.next();
-           HeapRegionNode hrnKeyB = (HeapRegionNode) meB.getKey();
-           HashSet< HashSet<HeapRegionNode> > > tokenSetsB = 
-               (HashSet< HashSet<HeapRegionNode> > >) meB.getValue();
-
-           if( !alpha.containsKey( hrnKeyB ) ) {
-               alpha.put( hrnKeyB, tokenSetsB );
-           } else {
-               
-           }
-       }
-       */
-    //}
-
-
-
-
-
 
     // it is necessary in the equals() member functions
     // to "check both ways" when comparing the data
@@ -927,7 +905,8 @@ public class OwnershipGraph {
                return false;
            }
 
-           HeapRegionNode hrnB = og.id2hrn.get( idA );     
+           //HeapRegionNode hrnB = og.id2hrn.get( idA );           
+           HeapRegionNode hrnB = id2hrn.get( idA );        
            if( !hrnA.equals( hrnB ) ) {
                return false;
            }       
index 972e3d5b98cf141843a70542d6e12561535ada93..d333f2c8b6c3f38edeac6e79c5bf5eb83d0cc701 100644 (file)
@@ -6,7 +6,7 @@ import java.util.*;
 import java.io.*;
 
 
-public class ReachabilitySet {
+public class ReachabilitySet extends Canonical {
 
     private HashSet<TokenTupleSet> possibleReachabilities;
 
@@ -27,6 +27,10 @@ public class ReachabilitySet {
        possibleReachabilities = (HashSet<TokenTupleSet>) rs.possibleReachabilities.clone(); // again, DEEP COPY?!
     }
 
+    public ReachabilitySet makeCanonical() {
+       return (ReachabilitySet) Canonical.makeCanonical( this );
+    }
+
     public Iterator iterator() {
        return possibleReachabilities.iterator();
     }
@@ -34,7 +38,7 @@ public class ReachabilitySet {
     public ReachabilitySet union( ReachabilitySet rsIn ) {
        ReachabilitySet rsOut = new ReachabilitySet( this );
        rsOut.possibleReachabilities.addAll( rsIn.possibleReachabilities );
-       return rsOut;
+       return rsOut.makeCanonical();
     }
 
     public ReachabilitySet intersection( ReachabilitySet rsIn ) {
@@ -48,7 +52,7 @@ public class ReachabilitySet {
            }
        }
 
-       return rsOut;
+       return rsOut.makeCanonical();
     }
 
     public ChangeTupleSet unionUpArity( ReachabilitySet rsIn ) {
@@ -69,9 +73,9 @@ public class ReachabilitySet {
                    TokenTuple e = (TokenTuple) itrRelement.next();
 
                    if( o.containsToken( e.getToken() ) ) {
-                       theUnion = theUnion.union( new TokenTupleSet( e.increaseArity() ) );
+                       theUnion = theUnion.union( new TokenTupleSet( e.increaseArity() ) ).makeCanonical();
                    } else {
-                       theUnion = theUnion.union( new TokenTupleSet( e );
+                       theUnion = theUnion.union( new TokenTupleSet( e                 ) ).makeCanonical();
                    }
                }
 
@@ -80,7 +84,7 @@ public class ReachabilitySet {
                    TokenTuple e = (TokenTuple) itrOelement.next();
 
                    if( !theUnion.containsToken( e.getToken() ) ) {
-                       theUnion = theUnion.union( new TokenTupleSet( e ) );
+                       theUnion = theUnion.union( new TokenTupleSet( e ) ).makeCanonical();
                    }
                }
 
@@ -92,7 +96,21 @@ public class ReachabilitySet {
            }
        }
 
-       return ctsOut;
+       return ctsOut.makeCanonical();
+    }
+
+
+    public boolean equals( Object o ) {
+       if( !(o instanceof ReachabilitySet) ) {
+           return false;
+       }
+
+       ReachabilitySet rs = (ReachabilitySet) o;
+       return possibleReachabilities.equals( rs.possibleReachabilities );
+    }
+
+    public int hashCode() {
+       return possibleReachabilities.hashCode();
     }
 
 
@@ -109,7 +127,6 @@ public class ReachabilitySet {
        return s;       
     }
 
-
     public String toString() {
        String s = "[";
 
index eee529869093c4851310cf264e018a17aed51793..72b4457bf0c8157439106fbfba8866572fd0647c 100644 (file)
@@ -5,17 +5,28 @@ public class ReferenceEdgeProperties {
     public ReferenceEdgeProperties() {
        this.isUnique                = false;
        this.isInitialParamReflexive = false;
+       this.beta                    = new ReachabilitySet();
     }    
 
     public ReferenceEdgeProperties( boolean isUnique ) {
        this.isUnique                = isUnique;
        this.isInitialParamReflexive = false;
+       this.beta                    = new ReachabilitySet();
     }
 
     public ReferenceEdgeProperties( boolean isUnique,
                                    boolean isInitialParamReflexive ) {
        this.isUnique                = isUnique;
        this.isInitialParamReflexive = isInitialParamReflexive;
+       this.beta                    = new ReachabilitySet();
+    }
+
+    public ReferenceEdgeProperties( boolean         isUnique,
+                                   boolean         isInitialParamReflexive,
+                                   ReachabilitySet beta) {
+       this.isUnique                = isUnique;
+       this.isInitialParamReflexive = isInitialParamReflexive;
+       this.beta                    = beta;
     }
 
 
@@ -43,6 +54,18 @@ public class ReferenceEdgeProperties {
     }
 
 
+    protected ReachabilitySet beta;
+    public ReachabilitySet getBeta() {
+       return beta;
+    }
+    public void setBeta( ReachabilitySet beta ) {
+       this.beta = beta;
+    }
+    public String getBetaString() {
+       return beta.toStringEscapeNewline();
+    }
+
+
     public boolean equals( ReferenceEdgeProperties rep ) {
        return isUnique                == rep.isUnique()                &&
               isInitialParamReflexive == rep.isInitialParamReflexive();
index e135a68060bc2e32a25b9e8dc268973b9f1c0579..f198a0a08ea505072c875efe888504e376ca168e 100644 (file)
@@ -11,7 +11,7 @@ import java.io.*;
 
 // THIS CLASS IS IMMUTABLE!
 
-public class TokenTuple
+public class TokenTuple extends Canonical
 {
     private Integer token;
     private boolean isNewSummary;
@@ -35,12 +35,18 @@ public class TokenTuple
        this.arity        = arity;
     }
 
+    public TokenTuple makeCanonical() {
+       return (TokenTuple) Canonical.makeCanonical( this );
+    }
+
     public Integer getToken() { return token; }
     public int     getArity() {        return arity; }
 
     public TokenTuple increaseArity() {
        if( isNewSummary ) {
-           return new TokenTuple( token, isNewSummary, ARITY_MANY );
+           return (TokenTuple) Canonical.makeCanonical( 
+             new TokenTuple( token, isNewSummary, ARITY_MANY )
+                                                        );
        }
        return this;
     }
index 9a81a6583d1fb99f79ceec2e66f8ea949acc823e..d853290158d56f3c6bdd802589be45a92d83f864 100644 (file)
@@ -6,7 +6,7 @@ import java.util.*;
 import java.io.*;
 
 
-public class TokenTupleSet {
+public class TokenTupleSet extends Canonical {
 
     private HashSet<TokenTuple> tokenTuples;
 
@@ -23,6 +23,10 @@ public class TokenTupleSet {
        tokenTuples = (HashSet<TokenTuple>) tts.tokenTuples.clone(); //COPY?!
     }
 
+    public TokenTupleSet makeCanonical() {
+       return (TokenTupleSet) Canonical.makeCanonical( this );
+    }
+
     public Iterator iterator() {
        return tokenTuples.iterator();
     }
@@ -30,7 +34,7 @@ public class TokenTupleSet {
     public TokenTupleSet union( TokenTupleSet ttsIn ) {
        TokenTupleSet ttsOut = new TokenTupleSet( this );
        ttsOut.tokenTuples.addAll( ttsIn.tokenTuples );
-       return ttsOut;
+       return ttsOut.makeCanonical();
     }
 
     public boolean isEmpty() {
@@ -41,6 +45,19 @@ public class TokenTupleSet {
        return tokenTuples.contains( tt );
     }
 
+    public boolean equals( Object o ) {
+       if( !(o instanceof TokenTupleSet) ) {
+           return false;
+       }
+
+       TokenTupleSet tts = (TokenTupleSet) o;
+       return tokenTuples.equals( tts.tokenTuples );
+    }
+
+    public int hashCode() {
+       return tokenTuples.hashCode();
+    }
+
     // this should be a hash table so we can do this by key
     public boolean containsToken( Integer token ) {
        Iterator itr = tokenTuples.iterator();
index e51d471789ee068ecaea15c53eabc342d55db9c6..2ec4185240ed157a1e8825f751ebeac846bfc974 100644 (file)
@@ -85,6 +85,7 @@ Analysis/OwnershipAnalysis/TokenTupleSet.class                          \
 Analysis/OwnershipAnalysis/ReachabilitySet.class                        \
 Analysis/OwnershipAnalysis/ChangeTuple.class                            \
 Analysis/OwnershipAnalysis/ChangeTupleSet.class                         \
+Analysis/OwnershipAnalysis/Canonical.class                              \
 Util/GraphNode.class Util/Namer.class Util/Relation.class              \
 Interface/HTTPHeader.class Interface/HTTPResponse.class                        \
 Interface/HTTPServices.class Interface/HashStrings.class               \
index 37e72086b6db43325b6c1ccf221090943c12532a..3d08d27a6ae6ea1306920a7880db2447f63084df 100644 (file)
@@ -13,6 +13,7 @@ view: PNGs
        #eog *FN*.png &
        #eog *Ownership*.png &
        eog *COMPLETE*.png &
+       #eog *debug*.png &
 
 printable:
        rm -f *Startup*.dot
@@ -30,6 +31,8 @@ printable:
 
 PNGs: DOTs
        #rm -f *Startup*.dot
+       #rm -f *COMPLETE*.dot
+       rm -f *FlatIR*.dot
        rm -f *FlatMethod*.dot
        rm -f *FlatOpNode*.dot
        rm -f *FlatFieldNode*.dot
index 9349ccca2697c0d917b1126dbe11aedf2901ff54..dc45891502d82472cb96258326bcf2e25905f234 100644 (file)
@@ -61,7 +61,7 @@ task Startup( StartupObject s{ initialstate } ) {
 }
 
 
-
+/*
 // this task allocates a new object, so there should
 // be a heap region for the parameter, and several
 // heap regions for the allocation site, but the label
@@ -74,6 +74,7 @@ task NewObject( Voo v{ f } ) {
     taskexit( v{ !f } );
 }
 
+
 // this task 
 task Branch( Voo v{ f } ) {
     Voo w = new Voo();
@@ -88,7 +89,7 @@ task Branch( Voo v{ f } ) {
 
     taskexit( v{ !f } );
 }
-
+*/
 
 task NoAliasNewInLoop( Voo v{ f } ) {
 
@@ -101,6 +102,7 @@ task NoAliasNewInLoop( Voo v{ f } ) {
     taskexit( v{ !f } );
 }
 
+/*
 task NoAliasNewInLoopAnotherWay( Voo v{ f } ) {
 
     for( int i = 0; i < 10; ++i ) {
@@ -121,3 +123,4 @@ task ClobberInitParamReflex( Voo v{ f }, Voo w{ f } ) {
     taskexit( v{ !f }, w{ !f } );
 }
 
+*/
\ No newline at end of file
index 603ce6c94e6b341ee267de581debf4b6b8e89c30..ac1155558fd6c2f44c12737a4a9bfa2469233b4a 100644 (file)
@@ -21,6 +21,7 @@ public class Main {
 
     public static void main(String args[]) throws Exception {
 
+       
        // example test to know the testing routine is correct!
        test( "4 == 5?", false, 4 == 5 );
        test( "3 == 3?", true,  3 == 3 );
@@ -85,10 +86,10 @@ public class Main {
                                         true,
                                         TokenTuple.ARITY_ONE );
 
-       /*      TokenTuple tt5 = new TokenTuple( new Integer( 4 ),
-                                        true,
+               TokenTuple tt5 = new TokenTuple( new Integer( 4 ),
+                                        true,
                                         TokenTuple.ARITY_ONE );
-       */
+       
        TokenTuple tt6 = new TokenTuple( new Integer( 6 ),
                                         false,
                                         TokenTuple.ARITY_ONE );
@@ -107,5 +108,76 @@ public class Main {
 
        ChangeTupleSet cts0 = rs0.unionUpArity( rs1 );
        System.out.println( "cts0 is "+cts0 );
+       
+
+
+       TokenTuple tt00 = new TokenTuple( new Integer( 9 ),
+                                         true,
+                                         TokenTuple.ARITY_ONE );
+
+       TokenTuple tt01 = new TokenTuple( new Integer( 9 ),
+                                         true,
+                                         TokenTuple.ARITY_ONE );
+
+       test( "tt00 equals tt01?", true,  tt00.equals( tt01 ) );        
+       test( "tt00 ==     tt01?", false, tt00 ==      tt01   );        
+
+       tt00 = (TokenTuple) Canonical.makeCanonical( tt00 );
+       tt01 = (TokenTuple) Canonical.makeCanonical( tt01 );
+
+       test( "tt00 equals tt01?", true,  tt00.equals( tt01 ) );        
+       test( "tt00 ==     tt01?", true,  tt00 ==      tt01   );        
+
+
+       TokenTuple tt02 = 
+           (TokenTuple) Canonical.makeCanonical( 
+                                                new TokenTuple( new Integer( 10 ),
+                                                                true,
+                                                                TokenTuple.ARITY_ONE )
+                                                 );
+
+       TokenTuple tt03 = 
+           (TokenTuple) Canonical.makeCanonical( 
+                                                new TokenTuple( new Integer( 11 ),
+                                                                true,
+                                                                TokenTuple.ARITY_ONE )
+                                                 );
+
+       TokenTuple tt04 = 
+           (TokenTuple) Canonical.makeCanonical( 
+                                                new TokenTuple( new Integer( 12 ),
+                                                                true,
+                                                                TokenTuple.ARITY_ONE )
+                                                 );
+
+       TokenTupleSet ttsT00 =
+           (TokenTupleSet) Canonical.makeCanonical( new TokenTupleSet( tt00 ) );
+
+       TokenTupleSet ttsT01 =
+           (TokenTupleSet) Canonical.makeCanonical( new TokenTupleSet( tt01 ) );
+
+       TokenTupleSet ttsT02 =
+           (TokenTupleSet) Canonical.makeCanonical( new TokenTupleSet( tt02 ) );
+
+       TokenTupleSet ttsT03 =
+           (TokenTupleSet) Canonical.makeCanonical( new TokenTupleSet( tt03 ) );
+
+       TokenTupleSet ttsT04 =
+           (TokenTupleSet) Canonical.makeCanonical( new TokenTupleSet( tt04 ) );
+
+       TokenTupleSet tts00 = ttsT00.union( ttsT02.union( ttsT03.union( ttsT04 ) ) );
+       TokenTupleSet tts01 = ttsT01.union( ttsT02.union( ttsT03.union( ttsT04 ) ) );
+
+       test( "tts00 equals tts01?", true,  tts00.equals( tts01 ) );
+
+       // It's OK that this one turns out true--I changed the union operator
+       // to automatically canonicalize stuff!
+       test( "tts00 ==     tts01?", false, tts00 ==      tts01   );    
+
+       tts00 = (TokenTupleSet) Canonical.makeCanonical( tts00 );
+       tts01 = (TokenTupleSet) Canonical.makeCanonical( tts01 );
+
+       test( "tts00 equals tts01?", true,  tts00.equals( tts01 ) );    
+       test( "tts00 ==     tts01?", true,  tts00 ==      tts01   );    
     }
-}
\ No newline at end of file
+}