Index: doc/theses/jiada_liang_MMath/offsetAlgorithm.cc
===================================================================
--- doc/theses/jiada_liang_MMath/offsetAlgorithm.cc	(revision 11f8ff7928e4f78b9608246eca503986d41a0e42)
+++ doc/theses/jiada_liang_MMath/offsetAlgorithm.cc	(revision bd686f0a4193bec9130edec2ddc51e8bbb5df7e5)
@@ -1,6 +1,6 @@
+#include <iostream>
 #include <string>
 #include <variant>
 #include <vector>
-#include <iostream>
 
 using namespace std;
@@ -29,24 +29,52 @@
     }
 
-    CFAEnum( string name ): name(name) {}
+    CFAEnum(string name) : name(name) {}
 };
 
-pair<bool, int> calculateEnumOffset(CFAEnum dst, Enumerator e) {
+inline static bool operator==(CFAEnum& lhs, CFAEnum& rhs) {
+    return lhs.name == rhs.name;
+}
+
+// pair<bool, int> calculateEnumOffset(CFAEnum dst, Enumerator e) {
+//     int offset = 0;
+//     // std::cout << dst.name << " : " << e.label << std::endl;
+//     for (auto v : dst.members) {
+//         // std::cout << "  offset: " << offset << std::endl;
+//         if (holds_alternative<Enumerator>(v)) {
+//             auto m = get<Enumerator>(v);
+//             // std::cout << "  Enumerator: " << ":" << m.label  << std::endl;
+//             if (m == e) return make_pair(true, offset);
+//             offset++;
+
+//         } else {
+//             auto m = get<CFAEnum>(v);
+//             // std::cout << "  CFAEnum: " << ":" << m.name << std::endl;
+//             auto p = calculateEnumOffset(m, e);
+//             if (p.first) return make_pair(true, offset + p.second);
+//             offset += p.second;
+//         }
+//     }
+//     // std::cout << "End  "  << dst.name << " offset " << offset  << std::endl;
+//     return make_pair(false, offset);
+// }
+
+pair<bool, int> calculateEnumOffset(CFAEnum src, CFAEnum dst) {
     int offset = 0;
     // std::cout << dst.name << " : " << e.label << std::endl;
+    if (src == dst) return make_pair(true, 0);
     for (auto v : dst.members) {
         // std::cout << "  offset: " << offset << std::endl;
         if (holds_alternative<Enumerator>(v)) {
-            auto m = get<Enumerator>(v);
-            // std::cout << "  Enumerator: " << ":" << m.label  << std::endl;
-            if (m == e) return make_pair(true, offset);
             offset++;
-        
         } else {
             auto m = get<CFAEnum>(v);
             // std::cout << "  CFAEnum: " << ":" << m.name << std::endl;
-            auto p = calculateEnumOffset(m, e);
-            if (p.first) return make_pair(true, offset + p.second);
-            offset += p.second;
+            if (m == src) return make_pair(true, offset);
+            auto dist = calculateEnumOffset(src, m);
+            if (dist.first) {
+                return make_pair(true, offset + dist.second);
+            } else {
+                offset += dist.second;
+            }
         }
     }
@@ -55,22 +83,52 @@
 }
 
+std::ostream& operator<<(std::ostream& os, const CFAEnum& e) {
+    os << e.name;
+    return os;
+}
+
+void printEnumOffset(CFAEnum src, CFAEnum dst) {
+    auto offset = calculateEnumOffset(src, dst);
+    if (offset.first) {
+        std::cout << src << " To " << dst << ":"
+                  << " " << calculateEnumOffset(src, dst).second << std::endl;
+    } else {
+        std::cout << src << " Cannot convert to " << dst << std::endl;
+    }
+
+}
+
 int main() {
     /**
-     * enum() E1 { A }; // A
+    enum() E1 { A }; // A
     enum() E2 { B, C }; // B C
-    enum() E3 { D, inline E1, inline E2, E }; // D A B C E
-    enum() E4 { F, inline E3, G }; // F D A B C E G
+    enum() E3 { D, inline E1, inline E2, E }; // D {A}_{E1} {B C}_{E2} E
+    enum() E4 { F, inline E3, G }; // F { D {A}_{E1} {B C}_{E2} E }_{E3} G
      *
      */
     struct Enumerator A("A"), B("B"), C("C"), D("D"), E("E"), F("F"), G("G");
-    CFAEnum E1("E1"), E2("E2"), E3("E3"), E4("E4");
+    struct CFAEnum E1("E1"), E2("E2"), E3("E3"), E4("E4");
     E1.addMember(A);
     E2.addMember(B).addMember(C);
     E3.addMember(D).addMember(E1).addMember(E2).addMember(E);
     E4.addMember(F).addMember(E3).addMember(G);
-    std::cout << calculateEnumOffset(E3, B).first << " " << calculateEnumOffset(E3, B).second << std::endl;
-    std::cout << calculateEnumOffset(E4, B).first << " " << calculateEnumOffset(E4, B).second << std::endl;
-    std::cout << calculateEnumOffset(E3, E).first << " " << calculateEnumOffset(E3, E).second << std::endl;
-    std::cout << calculateEnumOffset(E4, E).first << " " << calculateEnumOffset(E4, E).second << std::endl;
+    // std::cout << calculateEnumOffset(E3, B).first << " "
+    //           << calculateEnumOffset(E3, B).second << std::endl;
+    // std::cout << calculateEnumOffset(E4, B).first << " "
+    //           << calculateEnumOffset(E4, B).second << std::endl;
+    // std::cout << calculateEnumOffset(E3, E).first << " "
+    //           << calculateEnumOffset(E3, E).second << std::endl;
+    // std::cout << calculateEnumOffset(E4, E).first << " "
+    //           << calculateEnumOffset(E4, E).second << std::endl;
+    // std::cout << calculateEnumOffset(E3, G).first << " "
+    //           << calculateEnumOffset(E3, G).second << std::endl;
+
+    printEnumOffset(E1, E3);
+    printEnumOffset(E1, E4);
+    printEnumOffset(E2, E3);
+    printEnumOffset(E2, E4);
+    printEnumOffset(E3, E4);
+    printEnumOffset(E4, E4);
+    printEnumOffset(E4, E1);
 }
 
