Revised PrimitiveOp to use rho-mu-kappa normal form
diff --git a/org.eclipse.rephraserengine.core.vpg.tests/src/org/eclipse/rephraserengine/internal/core/tests/preservation/NormalizationTestCase.java b/org.eclipse.rephraserengine.core.vpg.tests/src/org/eclipse/rephraserengine/internal/core/tests/preservation/NormalizationTestCase.java
index 62577fc..5553130 100644
--- a/org.eclipse.rephraserengine.core.vpg.tests/src/org/eclipse/rephraserengine/internal/core/tests/preservation/NormalizationTestCase.java
+++ b/org.eclipse.rephraserengine.core.vpg.tests/src/org/eclipse/rephraserengine/internal/core/tests/preservation/NormalizationTestCase.java
@@ -23,15 +23,19 @@
 {
     public void testOffset()
     {
-        PrimitiveOp.Alpha alpha = PrimitiveOp.alpha("", 3, 6);
-        assertEquals(3, alpha.j.cardinality());
+        PrimitiveOp.Alpha alpha = PrimitiveOp.alpha("no_filename", 3, 6);
+        int count = alpha.k.cardinality();
+        assertEquals(3, count);
 
         Interval before = new Interval(0, 3);
         Interval overlapped = new Interval(3, 7);
         Interval after = new Interval(7, 11);
 
-        assertEquals(before, alpha.offset(before));
-        assertEquals(new Interval(3+3, 7+3), alpha.offset(overlapped));
-        assertEquals(new Interval(7+3, 11+3), alpha.offset(after));
+        assertEquals(before.lb, alpha.offset(before.lb));
+        assertEquals(before.ub-1, alpha.offset(before.ub-1));
+        assertEquals(overlapped.lb+count, alpha.offset(overlapped.lb));
+        assertEquals(overlapped.ub-1+count, alpha.offset(overlapped.ub-1));
+        assertEquals(after.lb+count, alpha.offset(after.lb));
+        assertEquals(after.ub-1+count, alpha.offset(after.ub-1));
     }
 }
diff --git a/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/core/preservation/PreservationAnalysis.java b/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/core/preservation/PreservationAnalysis.java
index 160e1b9..bba7b35 100644
--- a/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/core/preservation/PreservationAnalysis.java
+++ b/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/core/preservation/PreservationAnalysis.java
@@ -67,7 +67,7 @@
     public void monitor(IFile file)
     {
         ensureDatabaseIsInHypotheticalMode();
-        
+
         ArrayList<String> singleton = new ArrayList<String>();
         singleton.add(EclipseVPG.getFilenameForIFile(file));
         monitor(vpg.sortFilesAccordingToDependencies(singleton, new NullProgressMonitor()));
@@ -151,8 +151,8 @@
 
         Alpha newAlpha = PrimitiveOp.alpha(
             alpha1.filename,
-            alpha1.j.lb,
-            alpha1.j.lb + alpha1.j.cardinality() + alpha2.j.cardinality());
+            alpha1.k.lb,
+            alpha1.k.lb + alpha1.k.cardinality() + alpha2.k.cardinality());
             //alpha1.preserveEdgeTypes);
 
         addAlpha(newAlpha);
@@ -208,20 +208,33 @@
 
     private void checkForPreservation(RefactoringStatus status, String filename)
     {
+        printDebug("INITIAL MODEL", initialModels.get(filename));
+
         progressMonitor.subTask("Normalizing initial model - " + lastSegment(filename));
         initialModels.get(filename).inormalize(primitiveOps, preserveEdgeTypes);
+        printDebug("NORMALIZED INITIAL MODEL", initialModels.get(filename));
 
         progressMonitor.subTask("Computing derivative model - " + lastSegment(filename));
         Model derivativeModel = new Model(vpg, filename);
+        printDebug("DERIVATIVE MODEL", derivativeModel);
 
         progressMonitor.subTask("Normalizing derivative model - " + lastSegment(filename));
         derivativeModel.dnormalize(primitiveOps, preserveEdgeTypes);
+        printDebug("NORMALIZED DERIVATIVE MODEL", derivativeModel);
 
         progressMonitor.subTask("Differencing initial and derivative models - " + lastSegment(filename));
         ModelDiff diff = initialModels.get(filename).compareAgainst(derivativeModel);
         describeDifferences(status, diff, EclipseVPG.getIFileForFilename(filename));
     }
 
+    private void printDebug(String string, Object object)
+    {
+        System.out.println();
+        System.out.println();
+        System.out.print(string); System.out.println(":");
+        System.out.println(object.toString());
+    }
+
     private void describeDifferences(final RefactoringStatus status, ModelDiff diff, final IFile file)
     {
         Object ast = vpg.acquireTransientAST(EclipseVPG.getFilenameForIFile(file));
diff --git a/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/internal/core/preservation/Interval.java b/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/internal/core/preservation/Interval.java
index 29b9732..7db0055 100644
--- a/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/internal/core/preservation/Interval.java
+++ b/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/internal/core/preservation/Interval.java
@@ -34,7 +34,7 @@
     {
         return lb == ub;
     }
-    
+
     public boolean contains(int n)
     {
         return lb <= n && n < ub;
@@ -49,7 +49,7 @@
         else
             return other.lb <= this.lb && this.ub <= other.ub;
     }
-    
+
 // THESE DEFINITIONS ARE **WRONG**!
 //    public Interval union(Interval that)
 //    {
@@ -57,7 +57,7 @@
 //            Math.min(this.lb, that.lb),
 //            Math.max(this.ub, that.ub));
 //    }
-//    
+//
 //    public Interval intersection(Interval that)
 //    {
 //        return new Interval(
@@ -70,9 +70,24 @@
         return ub - lb;
     }
 
-    public boolean isLessThan(Interval other)
+    public boolean isLessThan(Interval that)
     {
-        return this.ub <= other.lb && !this.equals(other);
+        return this.ub <= that.lb && !this.equals(that);
+    }
+
+    public boolean isGreaterThan(Interval that)
+    {
+        return this.lb >= that.ub && !this.equals(that);
+    }
+
+    public boolean overlaps(Interval that)
+    {
+        return !doesNotOverlap(that);
+    }
+
+    private boolean doesNotOverlap(Interval that)
+    {
+        return this.ub <= that.lb || this.lb >= that.ub;
     }
 
     public Interval plus(int offset)
diff --git a/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/internal/core/preservation/Model.java b/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/internal/core/preservation/Model.java
index 58f881d..ac8e66d 100644
--- a/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/internal/core/preservation/Model.java
+++ b/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/internal/core/preservation/Model.java
@@ -142,7 +142,7 @@
         for (PrimitiveOp op : primitiveOps)
             inormalize(op, preserveEdgeTypes);
     }
-
+    
     public void dnormalize(PrimitiveOp op, Set<Integer> preserveEdgeTypes)
     {
         TreeSet<Entry> revisedList = new TreeSet<Entry>();
diff --git a/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/internal/core/preservation/PrimitiveOp.java b/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/internal/core/preservation/PrimitiveOp.java
index eec572a..22e3bb9 100644
--- a/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/internal/core/preservation/PrimitiveOp.java
+++ b/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/internal/core/preservation/PrimitiveOp.java
@@ -10,25 +10,26 @@
  *******************************************************************************/
 package org.eclipse.rephraserengine.internal.core.preservation;
 
-
 /**
  *
  * @author Jeff Overbey
  */
 public abstract class PrimitiveOp
 {
+    public static final int UNDEFINED = Integer.MIN_VALUE;
+
     ///////////////////////////////////////////////////////////////////////////////////////////////
-    // Factory Methods
+    // Factory Methods (alpha/epsilon methods normalize to rho-operations)
     ///////////////////////////////////////////////////////////////////////////////////////////////
 
-    public static Alpha alpha(String filename, Interval j)
+    public static Alpha alpha(String filename, Interval k)
     {
-        return new Alpha(filename, j);
+        return new Alpha(filename, k);
     }
 
-    public static Alpha alpha(String filename, int j_lb, int j_ub)
+    public static Alpha alpha(String filename, int k_lb, int k_ub)
     {
-        return new Alpha(filename, new Interval(j_lb, j_ub));
+        return new Alpha(filename, new Interval(k_lb, k_ub));
     }
 
     public static Epsilon epsilon(String filename, Interval j)
@@ -64,7 +65,7 @@
 
     @Override public abstract String toString();
 
-    public abstract Interval offset(Interval i);
+    protected abstract int offset(int n);
 
     public abstract Interval inorm(Interval i);
 
@@ -78,104 +79,6 @@
     // Concrete Subclasses
     ///////////////////////////////////////////////////////////////////////////////////////////////
 
-    public static class Alpha extends PrimitiveOp
-    {
-        public final Interval j;
-
-        private Alpha(String filename, Interval j)
-        {
-            super(filename);
-            this.j = j;
-        }
-
-        @Override
-        public Interval offset(Interval i)
-        {
-            if (i.isLessThan(j))
-                return i;
-            else
-                return i.plus(j.cardinality());
-        }
-
-        @Override
-        public Interval inorm(Interval i)
-        {
-            return offset(i);
-        }
-
-        @Override
-        public Interval iaff()
-        {
-            return new Interval(j.lb, j.lb+1);
-        }
-
-        @Override
-        public Interval dnorm(Interval i)
-        {
-            return i;
-        }
-
-        @Override
-        public Interval daff()
-        {
-            return j;
-        }
-
-        @Override public String toString()
-        {
-            return "alpha(" + j + ")";
-        }
-    }
-
-    public static class Epsilon extends PrimitiveOp
-    {
-        public final Interval j;
-
-        private Epsilon(String filename, Interval j)
-        {
-            super(filename);
-            this.j = j;
-        }
-
-        @Override
-        public Interval offset(Interval i)
-        {
-            if (i.isLessThan(j))
-                return i;
-            else
-                return i.minus(j.cardinality());
-        }
-
-        @Override
-        public Interval inorm(Interval i)
-        {
-            return offset(i);
-        }
-
-        @Override
-        public Interval iaff()
-        {
-            return j;
-        }
-
-        @Override
-        public Interval dnorm(Interval i)
-        {
-            return i;
-        }
-
-        @Override
-        public Interval daff()
-        {
-            return new Interval(j.lb, j.lb+1);
-        }
-
-        @Override public String toString()
-        {
-            return "epsilon(" + j + ")";
-        }
-    }
-
     public static class Rho extends PrimitiveOp
     {
         public final Interval j, k;
@@ -192,21 +95,22 @@
         }
 
         @Override
-        public Interval offset(Interval i)
+        public int offset(int n)
         {
-            if (i.isLessThan(j))
-                return i;
+            if (n < j.lb)
+                return n;
+            else if (n >= j.ub)
+                return n - j.cardinality() + k.cardinality();
             else
-                return i.minus(j.cardinality()).plus(k.cardinality());
+                return UNDEFINED;
         }
 
         @Override
         public Interval inorm(Interval i)
         {
-            if (i.isSubsetOf(j))
-                return k;
-            else
-                return offset(i);
+            return new Interval(
+                offset(i.lb) != UNDEFINED ? offset(i.lb) : k.lb,
+                offset(i.ub) != UNDEFINED ? offset(i.ub) : k.ub);
         }
 
         @Override
@@ -235,4 +139,20 @@
             return "rho(" + j + ", " + k + ")";
         }
     }
+
+    public static class Alpha extends Rho
+    {
+        private Alpha(String filename, Interval k)
+        {
+            super(filename, new Interval(k.lb, k.lb), k);
+        }
+    }
+
+    public static class Epsilon extends Rho
+    {
+        private Epsilon(String filename, Interval j)
+        {
+            super(filename, j, new Interval(j.lb, j.lb));
+        }
+    }
 }