replaces Object/casts/ignore_warnings with generics that compile cleanly
authorThomas Walker Lynch <eknp9n@reasoningtechnology.com>
Thu, 16 Jan 2025 13:06:39 +0000 (13:06 +0000)
committerThomas Walker Lynch <eknp9n@reasoningtechnology.com>
Thu, 16 Jan 2025 13:06:39 +0000 (13:06 +0000)
16 files changed:
developer/document🖉/bugs.txt
developer/example/CountingNumber/CountingNumber.java
developer/example/GraphCycleCFinder/TM_SR_ND_Depth.java
developer/example/GraphIndexTree/Graph.java
developer/example/GraphIndexTree/Node.java
developer/example/GraphIndexTree/TM_SR_ND_Child.java
developer/example/GraphIndexTree/TM_SR_ND_Diagonal.java
developer/example/TM_SR_ND/TM_SR_ND_Print_CLI.java
developer/example/TM_SR_ND/TM_SR_ND_Print_transcript.txt
developer/javac🖉/Ariadne_Graph.java
developer/javac🖉/Ariadne_Node.java
developer/javac🖉/Ariadne_TM_SR_ND.java
developer/javac🖉/Ariadne_TM_SR_ND_Array.java
developer/javac🖉/Ariadne_TM_SR_ND_Label.java [deleted file]
developer/javac🖉/Ariadne_TM_SR_ND_List.java
developer/javac🖉/Ariadne_TM_SR_ND_Set.java

index 2a42aef..a519022 100644 (file)
@@ -2,9 +2,50 @@
 
 2024-12-31T01:47:53Z
 
-The pencil on file names has been working well .. until yesterday.  The jvm doesn't like the `example🖉` directory and refuses to run code in it, so I had to change it to `example`.
+  The pencil on file names has been working well .. until yesterday.  The jvm doesn't like the `example🖉` directory and refuses to run code in it, so I had to change it to `example`.
 
-  2024-12-31T01:47:53Z
+    2024-12-31T01:47:53Z
 
-  The example directory turns out to be mixed content anyway.
+    The example directory turns out to be mixed content anyway.
 
+2025-01-16T07:46:45Z[]
+
+  Interesting Java 23 bug-feature. For purposes of backwards compatibility they have added
+  'type erasure' where generics are dropped and replaced with 'Object'.  This then causes
+  type mismatch warnings in places there are no type mismatches in the code.  An example
+  line of code that causes this is:
+
+  ```
+    protected final TopoIface topo_null = new TopoIface(){
+      ...
+      };
+
+  ```
+  Though perfectly legal, and it compiles, class extensions give type mismatch warnings.  This is then replaced with:
+
+  ```
+    protected class NullTopo<RT> implements TopoIface<RT>{
+       ...
+    }
+    protected final TopoIface<RT> topo_null = new NullTopo<>();
+  ```
+
+  And the type mismatch warnings go away.
+
+
+2025-01-16T10:09:24Z[]
+
+  Nuance:
+
+    `Label` is child type of `Ariadne_Label`.
+
+    However the compiler does not consider:
+
+      `Ariadne_TM_SR_ND<Label>`
+
+    To be a type of 
+
+      `Ariadne_TM_SR_ND<Ariadne_Label>`
+
+    This is awkward because `Graph::start` returns a TM of labels,
+    where the labels are derived from `Ariadne_Label`
index f8c751c..9b017fe 100644 (file)
@@ -1,60 +1,52 @@
 import com.ReasoningTechnology.Ariadne.Ariadne_TM_SR_ND;
 import java.math.BigInteger;
 
-public class CountingNumber extends Ariadne_TM_SR_ND{
+public class CountingNumber extends Ariadne_TM_SR_ND<BigInteger>{
 
   // Static
   //
-
   public static CountingNumber make(BigInteger maximum){
     return new CountingNumber(maximum);
   }
-
   public static CountingNumber make(){
     return new CountingNumber();
   }
 
   // Instance data
   //
-
   private BigInteger i;
   private BigInteger maximum;
-
-  private final TopoIface topo_null = new Topo_Null();
-  private final TopoIface topo_segment = new Topo_Segment();
-  private final TopoIface topo_rightmost = new Topo_Rightmost();
-  private final TopoIface topo_infinite = new Topo_Infinite();
+  private final TopoIface<BigInteger> topo_null = new TopoNull();
+  private final TopoIface<BigInteger> topo_segment = new TopoSegment();
+  private final TopoIface<BigInteger> topo_rightmost = new TopoRightmost();
+  private final TopoIface<BigInteger> topo_infinite = new TopoInfinite();
 
   // Constructor(s)
   //
-
   public CountingNumber(){
     this.i = BigInteger.ONE;
-    this.maximum = maximum;
+    this.maximum = null;
     set_topology(topo_infinite);
   }
-
   public CountingNumber(BigInteger maximum){
     this.i = BigInteger.ONE;
     this.maximum = maximum;
 
     if( maximum.compareTo(BigInteger.ZERO) <= 0 ){
-      set_topology( topo_null );
+      set_topology(topo_null);
       return;
     }
-
     if( maximum.equals(BigInteger.ONE) ){
       set_topology(topo_rightmost);
       return;
     }
-
     set_topology(topo_segment);
   }
 
   // Instance interface implementation
   //  
 
-  private class Topo_Null implements TopoIface{
+  private class TopoNull implements TopoIface<BigInteger>{
     @Override public boolean can_read(){
       return false;
     }
@@ -65,14 +57,13 @@ public class CountingNumber extends Ariadne_TM_SR_ND{
       return false;
     }
     @Override public void step(){
-      throw new UnsupportedOperationException( "Cannot step over NULL topology." );
+      throw new UnsupportedOperationException("Cannot step over NULL topology.");
     }
     @Override public Topology topology(){
       return Topology.NULL;
     }
   }
-
-  private class Topo_Segment implements TopoIface{
+  private class TopoSegment implements TopoIface<BigInteger>{
     @Override public boolean can_read(){
       return true;
     }
@@ -83,17 +74,16 @@ public class CountingNumber extends Ariadne_TM_SR_ND{
       return true;
     }
     @Override public void step(){
-      i = i.add( BigInteger.ONE );
-      if( i.equals( maximum ) ){
-        set_topology( topo_rightmost );
+      i = i.add(BigInteger.ONE);
+      if( i.equals(maximum) ){
+        set_topology(topo_rightmost);
       }
     }
     @Override public Topology topology(){
       return Topology.SEGMENT;
     }
   }
-
-  private class Topo_Rightmost implements TopoIface{
+  private class TopoRightmost implements TopoIface<BigInteger>{
     @Override public boolean can_read(){
       return true;
     }
@@ -104,14 +94,13 @@ public class CountingNumber extends Ariadne_TM_SR_ND{
       return false;
     }
     @Override public void step(){
-      throw new UnsupportedOperationException( "Cannot step from RIGHTMOST." );
+      throw new UnsupportedOperationException("Cannot step from RIGHTMOST.");
     }
     @Override public Topology topology(){
       return Topology.RIGHTMOST;
     }
   }
-
-  private class Topo_Infinite implements TopoIface{
+  private class TopoInfinite implements TopoIface<BigInteger>{
     @Override public boolean can_read(){
       return true;
     }
@@ -122,7 +111,7 @@ public class CountingNumber extends Ariadne_TM_SR_ND{
       return true;
     }
     @Override public void step(){
-      i = i.add( BigInteger.ONE );
+      i = i.add(BigInteger.ONE);
     }
     @Override public Topology topology(){
       return Topology.INFINITE;
index e8332bf..ea3abcd 100644 (file)
@@ -39,16 +39,22 @@ the child node that is no the path.
 
 */
 
-import java.util.HashMap;
+import java.util.HashSet;
+import java.util.ArrayList;
+import java.util.List;
 
 import com.ReasoningTechnology.Ariadne.Ariadne_TM_SR_ND;
 import com.ReasoningTechnology.Ariadne.Ariadne_Graph;
+import com.ReasoningTechnology.Ariadne.Ariadne_Node;
+import com.ReasoningTechnology.Ariadne.Ariadne_Label;
+import com.ReasoningTechnology.Ariadne.Ariadne_TM_SR_ND_Array;
+import com.ReasoningTechnology.Ariadne.Ariadne_TM_SR_ND_List;
 
-class TM_SR_ND_Depth{
+class TM_SR_ND_Depth extends Ariadne_TM_SR_ND{
 
   // static
   //
-  TM_SR_ND_Depth make(Graph graph){
+  TM_SR_ND_Depth make(Ariadne_Graph graph){
     TM_SR_ND_Depth depth = new TM_SR_ND_Depth();
     if(graph == null) return null;
     depth.graph = graph;
@@ -60,14 +66,14 @@ class TM_SR_ND_Depth{
 
   // instance data
   //
-  protected Graph graph = null;
+  protected Ariadne_Graph graph = null;
   protected List<Ariadne_TM_SR_ND> context_path = new ArrayList<>();
-  protected Label cycle_node_label = null;
+  protected Ariadne_Label cycle_node_label = null;
 
   // constructor
   //
   protected TM_SR_ND_Depth(){
-    set_topography(topo_null);
+    set_topology(topo_null);
   }
 
   // instance interface implementation
@@ -82,14 +88,14 @@ class TM_SR_ND_Depth{
       return false;
     }
 
-    private final HashSet<Label> path_node_label_set = new HashSet<>();
+    HashSet<Ariadne_Label> path_node_label_set = new HashSet<>();
     boolean is_cycle_node = false;
 
     // should add cycle check for anomalous case caller fed us an initial path with a cycle
     // initialize the path_node set
     Ariadne_TM_SR_ND_Array<Ariadne_TM_SR_ND> context_path_srtm = Ariadne_TM_SR_ND_Array.make(context_path);
-    Ariadne_TM_SR_ND_List<label> child_srtm = null;
-    Label path_node_label = null;
+    Ariadne_TM_SR_ND child_srtm = null;
+    Ariadne_Label path_node_label = null;
 
     // context_path is known not to be  empty, so can_read() is true
     do{
@@ -117,7 +123,7 @@ class TM_SR_ND_Depth{
     // path descends down the left side of the unvisted portion of the tree.
     // extend the context_path downward until leftmost is a leaf node or a cycle node
     Ariadne_Node path_node = null;
-    boolean is_leaf_node = null;
+    boolean is_leaf_node = false;
     do{
       path_node = graph.lookup(path_node_label);
       if(path_node == null){
index 0e7acea..67f7501 100644 (file)
@@ -1,6 +1,6 @@
 import com.ReasoningTechnology.Ariadne.Ariadne_Graph;
 
-public class Graph extends Ariadne_Graph{
+public class Graph extends Ariadne_Graph<Label>{
 
   public static Graph make(){
     return new Graph();
@@ -14,7 +14,7 @@ public class Graph extends Ariadne_Graph{
   }
 
   // no override, this graph does not lookup Ariadne_Label, only Label
-  Node lookup(Label label){
+  @Override public Node lookup(Label label){
     return Node.make(label);
   }
 
index a638f28..192786f 100644 (file)
@@ -1,7 +1,7 @@
 import java.util.Arrays;
 import com.ReasoningTechnology.Ariadne.Ariadne_Node;
 
-public class Node extends Ariadne_Node{
+public class Node extends Ariadne_Node<Label>{
 
   public static Node make(Label label){
     return new Node(label);
index 7c1e3e7..027d6a4 100644 (file)
@@ -9,75 +9,44 @@ node's label.
 
 */
 
+import com.ReasoningTechnology.Ariadne.Ariadne_TM_SR_ND;
 
-import com.ReasoningTechnology.Ariadne.Ariadne_TM_SR_ND_Label;
-
-public class TM_SR_ND_Child extends Ariadne_TM_SR_ND_Label{
+public class TM_SR_ND_Child extends Ariadne_TM_SR_ND<Label>{
 
   // Static
   //
-
-  public static TM_SR_ND_Child make( Label leftmost_child_label ){
-    return new TM_SR_ND_Child( leftmost_child_label );
+  public static TM_SR_ND_Child make(Label leftmost_child_label){
+    return new TM_SR_ND_Child(leftmost_child_label);
   }
 
   // Instance data
   //
-
-  // Label is a container of co-ordinates to a node, so the only thing 'final'
-  // is the container, not its contents.
   private final Label label;
 
   // Constructor(s)
   //
+  protected TM_SR_ND_Child(Label leftmost_child_label){
+    this.label = leftmost_child_label != null ? leftmost_child_label.copy() : null;
 
-  protected TM_SR_ND_Child( Label leftmost_child_label ){
-    this.label = leftmost_child_label.copy();
-
-    if( label == null ){
+    if(label == null){
       set_topology(topo_null);
       return;
     }
-
-    // the label for the root node is an empty array, "[]"
-    if( label.length() == 0){
+    if(label.length() == 0){
       set_topology(topo_rightmost);
       return;
     }
-
     set_topology(topo_infinite_right);
   }
 
   // Implementation of the instance interface
   //
 
-  @Override public Label read(){
-    return (Label)super.read();
-  }
-
-  private final TopoIface topo_null = new TopoIface(){
-    @Override public boolean can_read(){
-      return false;
-    }
-    @Override public Object read(){
-      throw new UnsupportedOperationException( "Cannot read from NULL topology." );
-    }
-    @Override public boolean can_step(){
-      return false;
-    }
-    @Override public void step(){
-      throw new UnsupportedOperationException( "Cannot step from NULL topology." );
-    }
-    @Override public Topology topology(){
-      return Topology.NULL;
-    }
-  };
-
-  private final TopoIface topo_infinite_right = new TopoIface(){
+  private class InfiniteRightTopo implements TopoIface<Label>{
     @Override public boolean can_read(){
       return true;
     }
-    @Override public Object read(){
+    @Override public Label read(){
       return label;
     }
     @Override public boolean can_step(){
@@ -89,24 +58,26 @@ public class TM_SR_ND_Child extends Ariadne_TM_SR_ND_Label{
     @Override public Topology topology(){
       return Topology.INFINITE;
     }
-  };
+  }
+  private final TopoIface<Label> topo_infinite_right = new InfiniteRightTopo();
 
-  private final TopoIface topo_rightmost = new TopoIface(){
+  private class RightmostTopo implements TopoIface<Label>{
     @Override public boolean can_read(){
       return true;
     }
-    @Override public Object read(){
+    @Override public Label read(){
       return label;
     }
     @Override public boolean can_step(){
       return false;
     }
     @Override public void step(){
-      throw new UnsupportedOperationException( "Cannot step from RIGHTMOST topology." );
+      throw new UnsupportedOperationException("Cannot step from RIGHTMOST topology.");
     }
     @Override public Topology topology(){
       return Topology.RIGHTMOST;
     }
-  };
-
+  }
+  private final TopoIface<Label> topo_rightmost = new RightmostTopo();
 }
+
index 580ddc0..4492f20 100644 (file)
@@ -6,7 +6,7 @@ can do this. This guarantee also applies to a pruned IndexTree.
 This implementation is nearly ready, to be included in the Ariadne
 library for generalized diagonal traversal. I have abstracted out all
 references to the IndexTree. It still needs to remove child lists that
-have been completely reversed from the child_srtm_list.  This was not
+have been completely reversed from the child_tm_list.  This was not
 needed for the IndexTree because it is infinite, so they will never be
 completely traversed. Also needed, is to stop when a node does not
 have a child list. Again, this is not needed here because the
@@ -21,134 +21,110 @@ import java.util.List;
 
 import com.ReasoningTechnology.Ariadne.Ariadne_Test;
 import com.ReasoningTechnology.Ariadne.Ariadne_TM_SR_ND;
-import com.ReasoningTechnology.Ariadne.Ariadne_TM_SR_ND_Label;
 import com.ReasoningTechnology.Ariadne.Ariadne_TM_SR_ND_List;
-import com.ReasoningTechnology.Ariadne.Ariadne_Node;
-import com.ReasoningTechnology.Ariadne.Ariadne_Label;
 
-public class TM_SR_ND_Diagonal extends Ariadne_TM_SR_ND{
+public class TM_SR_ND_Diagonal extends Ariadne_TM_SR_ND<List<Label>> {
 
   // Static
   //
 
-  public static TM_SR_ND_Diagonal make(Label start_node){
+  public static TM_SR_ND_Diagonal make(Label start_node) {
     return new TM_SR_ND_Diagonal(start_node);
   }
 
   // Instance data
   //
 
-  private List<Label> diagonal = new ArrayList<>(); // the read value
+  private List<Label> diagonal = new ArrayList<>();
   private final List<TM_SR_ND_Child> child_srtm_list = new ArrayList<>();
 
   // Constructor(s)
   //
 
-  // the diagonal will never be null nor empty
-  protected TM_SR_ND_Diagonal(Label start_node){
-
-    if( start_node == null ){
+  protected TM_SR_ND_Diagonal(Label start_node) {
+    if (start_node == null) {
       set_topology(topo_null);
       return;
     }
-
     set_topology(topo_infinite_right);
     diagonal.add(start_node);
   }
 
-  // Implementation of instance interface
+  // Instance interface implementation
   //
 
   @Override
-  public String toString(){
-    StringBuilder formatted = new StringBuilder("TM_SR_ND_Diagonal(");
-    Ariadne_TM_SR_ND_List<Label> diagonal_srtm = Ariadne_TM_SR_ND_List.make(diagonal);
-
-    if( diagonal_srtm.can_read() ){
-      do{
-        formatted.append(diagonal_srtm.read().toString());
-        if( !diagonal_srtm.can_step() ) break;
-        diagonal_srtm.step();
-        formatted.append(" ,");
-      }while(true);
-    }
-
-    formatted.append(")");
-    return formatted.toString();
-  }
-
-
-  @Override
-  @SuppressWarnings("unchecked")
-  public List<Label> read(){
-    return (List<Label>)super.read(); // Cast to ensure type consistency
+  public List<Label> read() {
+    return diagonal;
   }
 
-  private final TopoIface topo_null = new TopoIface(){
-      @Override public boolean can_read(){
-        return false;
-      }
-      @Override public Object read(){
-        throw new UnsupportedOperationException( "Cannot read from NULL topology." );
-      }
-      @Override public boolean can_step(){
-        return false;
-      }
-      @Override public void step(){
-        throw new UnsupportedOperationException( "Cannot step from NULL topology." );
-      }
-      @Override public Topology topology(){
-        return Topology.NULL;
-      }
-    };
-
-  private final TopoIface topo_infinite_right = new TopoIface(){
+  private class TopoInfiniteRight implements TopoIface<List<Label>> {
       @Override public boolean can_read(){
         return true;
       }
-      @Override public List read(){
+      @Override public List<Label> read(){
         return diagonal;
       }
       @Override public boolean can_step(){
         return true;
       }
 
-      @Override public void step(){
-
-        List<Label> diagonal_1 = new ArrayList<>();
-
-        // inc_down from each node on diagonal_0 -> entry on child_srtm list
-        Ariadne_TM_SR_ND_List<Label> diagonal_srtm = Ariadne_TM_SR_ND_List.make(diagonal);
-        if( diagonal_srtm.can_read() ){
-          do{
-            Node node = Node.make(diagonal_srtm.read());
-            child_srtm_list.add(node.neighbor()); // graph node neighbor == tree node child
-            if( !diagonal_srtm.can_step() ) break;
-            diagonal_srtm.step();
-          }while(true);
-        }
-
-        // add to diagonal_1 from each on entry on the child_srtm list
-        Ariadne_TM_SR_ND_List<TM_SR_ND_Child> child_srtm_srtm = Ariadne_TM_SR_ND_List.make(child_srtm_list);
-        if( child_srtm_srtm.can_read() ){
-          do{
-            TM_SR_ND_Child child_srtm = child_srtm_srtm.read();
-            Label label = child_srtm.read();
-            diagonal_1.add(label.copy());
-            child_srtm.step();
-            if( !child_srtm_srtm.can_step() ) break;
-            child_srtm_srtm.step();
-          }while(true);
-        }
-
-        // Update the state for the next step
-        diagonal = diagonal_1;
+    @Override public void step(){
+
+      List<Label> diagonal_1 = new ArrayList<>();
+
+      // inc_down from each node on diagonal_0 -> entry on child_srtm list
+      Ariadne_TM_SR_ND_List<Label> diagonal_srtm = Ariadne_TM_SR_ND_List.make(diagonal);
+      if( diagonal_srtm.can_read() ){
+        do{
+          Node node = Node.make(diagonal_srtm.read());
+          child_srtm_list.add(node.neighbor()); // graph node neighbor == tree node child
+          if( !diagonal_srtm.can_step() ) break;
+          diagonal_srtm.step();
+        }while(true);
       }
 
-      @Override public Topology topology(){
-        return Topology.INFINITE;
+      // add to diagonal_1 from each on entry on the child_srtm list
+      Ariadne_TM_SR_ND_List<TM_SR_ND_Child> child_srtm_srtm = Ariadne_TM_SR_ND_List.make(child_srtm_list);
+      if( child_srtm_srtm.can_read() ){
+        do{
+          TM_SR_ND_Child child_srtm = child_srtm_srtm.read();
+          Label label = child_srtm.read();
+          diagonal_1.add(label.copy());
+          child_srtm.step();
+          if( !child_srtm_srtm.can_step() ) break;
+          child_srtm_srtm.step();
+        }while(true);
       }
 
-    };
-}
+      // Update the state for the next step
+      diagonal = diagonal_1;
+    }
 
+    @Override public Topology topology() {
+      return Topology.INFINITE;
+    }
+  }
+  private final TopoIface<List<Label>> topo_infinite_right = new TopoInfiniteRight();
+
+  // good citizen
+  //
+  
+  @Override public String toString() {
+    StringBuilder formatted = new StringBuilder("TM_SR_ND_Diagonal(");
+    Ariadne_TM_SR_ND_List<Label> diagonal_srtm = Ariadne_TM_SR_ND_List.make(diagonal);
+
+    if (diagonal_srtm.can_read()) {
+      do {
+        formatted.append(diagonal_srtm.read());
+        if (!diagonal_srtm.can_step()) break;
+        diagonal_srtm.step();
+        formatted.append(" ,");
+      } while (true);
+    }
+
+    formatted.append(")");
+    return formatted.toString();
+  }
+
+}
index 4e24e17..771706c 100644 (file)
@@ -14,7 +14,13 @@ public class TM_SR_ND_Print_CLI{
   public static void main(String[] args){
     List<Object> data = Arrays.asList(42 ,null ,"" ,"World" ,1000);
     Ariadne_TM_SR_ND tm = Ariadne_TM_SR_ND_List.make(data);
+    System.out.println(tm.toString());
+    tm.step();
+    System.out.println(tm.toString());
     tm.step();
+    System.out.println(tm.toString());
+    tm.step();
+    System.out.println(tm.toString());
     tm.step();
     System.out.println(tm.toString());
   }
index 6ff8231..c7cfae2 100644 (file)
@@ -1,2 +1,15 @@
-TM_SR_ND(SEGMENT(  42        World  1000  )
-                  |dd||-|<e>|ddddd||dddd|  
+
+TM_SR_ND(SEGMENT( 42        World  1000  )
+                 <dd>|-||e||ddddd||dddd|  
+
+TM_SR_ND(SEGMENT( 42        World  1000  )
+                 |dd|<->|e||ddddd||dddd|  
+
+TM_SR_ND(SEGMENT( 42        World  1000  )
+                 |dd||-|<e>|ddddd||dddd|  
+
+TM_SR_ND(SEGMENT( 42        World  1000  )
+                 |dd||-||e|<ddddd>|dddd|  
+
+TM_SR_ND(RIGHTMOST( 42        World  1000  )
+                   |dd||-||e||ddddd|<dddd>  
index f2cb27a..8a9420d 100644 (file)
@@ -10,7 +10,8 @@
 
 package com.ReasoningTechnology.Ariadne;
 
-public class Ariadne_Graph{
+// LT = Label Type
+public class Ariadne_Graph<LT extends Ariadne_Label>{
 
   public static Ariadne_Graph make(){
     return new Ariadne_Graph();
@@ -18,11 +19,11 @@ public class Ariadne_Graph{
   protected Ariadne_Graph(){
   }
 
-  public Ariadne_TM_SR_ND start(){
+  public Ariadne_TM_SR_ND<LT> start(){
     throw new UnsupportedOperationException("Ariadne_Graph::start.");
   }
 
-  public Ariadne_Node lookup(Ariadne_Label label){
+  public Ariadne_Node lookup(LT label){
     throw new UnsupportedOperationException("Ariadne_Graph::lookup.");
   }
 
index 23f0f9a..0ed8f51 100644 (file)
@@ -31,30 +31,31 @@ package com.ReasoningTechnology.Ariadne;
 import java.util.HashMap;
 import java.util.HashSet;
 
-public class Ariadne_Node extends HashMap<String, Object>{
+// LT == Label Type
+public class Ariadne_Node<LT extends Ariadne_Label> extends HashMap<String, Object>{
 
   // Owned by the class
-  public static Ariadne_Node make(Ariadne_Label label){
-    return new Ariadne_Node(label);
+  public static <T extends Ariadne_Label> Ariadne_Node<T> make(T label) {
+    return new Ariadne_Node<>(label);
   }
 
   // Data owned by the instance
-  private final Ariadne_Label label;
+  private final LT label;
   private final HashSet<Ariadne_Token> mark_set;
   private static final String NEIGHBOR_PROPERTY_NAME = "neighbor_property";
 
   // Constructors
-  protected Ariadne_Node(Ariadne_Label label){
+  protected Ariadne_Node(LT label){
     this.label = label;
     this.mark_set = new HashSet<>();
   }
 
   // Instance interface
-  public Ariadne_Label label(){
+  public LT label(){
     return this.label;
   }
 
-  public Ariadne_TM_SR_ND_Label neighbor(){
+  public Ariadne_TM_SR_ND<LT> neighbor(){
     throw new UnsupportedOperationException("Ariadne_Node::neighbor not implemented in the base class.");
   }
 
index 4d53353..3d74a14 100644 (file)
@@ -12,7 +12,8 @@ to file system objects.
 package com.ReasoningTechnology.Ariadne;
 import java.math.BigInteger;
 
-public class Ariadne_TM_SR_ND{
+// RT == read type
+public class Ariadne_TM_SR_ND<RT>{
 
   // static
   //
@@ -36,7 +37,7 @@ public class Ariadne_TM_SR_ND{
 
   private int id;
   Ariadne_Test test = null;
-  protected TopoIface current_topology;
+  protected TopoIface<RT> current_topology;
   protected BigInteger index;
 
   // constructor(s)
@@ -65,7 +66,7 @@ public class Ariadne_TM_SR_ND{
     index = index.add(BigInteger.ONE);
   }
 
-  public boolean head_on_same_cell(Ariadne_TM_SR_ND tm){
+  public boolean head_on_same_cell(Ariadne_TM_SR_ND<RT> tm){
     boolean p = this.index.equals(tm.index);
     if( test.is_on() ){
       test.print("head_on_same_cell this id/index: " + this.id() + "/" + this.index );
@@ -75,13 +76,13 @@ public class Ariadne_TM_SR_ND{
     return p;
   }
 
-  protected void entangle(Ariadne_TM_SR_ND copy){
+  protected void entangle(Ariadne_TM_SR_ND<RT> copy){
     copy.current_topology = this.current_topology;
     // Nuance here, BigInteger is immutable, so operation on the original
     // index, and the copy index, will be independent, which is what we want.
     copy.index = this.index; 
   }
-  public Ariadne_TM_SR_ND entangle(){
+  public Ariadne_TM_SR_ND<RT> entangle(){
     throw new UnsupportedOperationException("Ariadne_TM_SR_ND::entangle not implemented.");
   }
 
@@ -106,8 +107,8 @@ public class Ariadne_TM_SR_ND{
     return p;
   }
 
-  public Object read(){
-    Object o = current_topology.read();
+  public RT read(){
+    RT o = current_topology.read();
     if( test.is_on() ) test.print("read: " + o);
     return o;
   }
@@ -129,7 +130,7 @@ public class Ariadne_TM_SR_ND{
   }
 
   // Sets the tape access methods to be used.
-  protected void set_topology(TopoIface new_topology){
+  protected void set_topology(TopoIface<RT> new_topology){
     current_topology = new_topology;
     if( test.is_on() ){
       test.print("set_topology i: " + index);
@@ -141,19 +142,22 @@ public class Ariadne_TM_SR_ND{
     }
   }
 
-  protected interface TopoIface{
+  protected interface TopoIface<T>{
     boolean can_read();
-    Object read();
+    T read();
     boolean can_step();
     void step();
     Topology topology();
   }
 
-  protected final TopoIface not_mounted = new TopoIface(){
+  // yes officially this works, but it introduces subtle problems at compile time:
+  //  protected final TopoIface<RT> not_mounted =  new TopoIface<RT>(){
+
+  protected class NotMountedTopo implements TopoIface<RT>{
     @Override public boolean can_read(){
       return false;
     }
-    @Override public Object read(){
+    @Override public RT read(){
       throw new UnsupportedOperationException("Ariadne_TM_SR_ND::NotMounted::read.");
     }
     @Override public boolean can_step(){
@@ -165,25 +169,32 @@ public class Ariadne_TM_SR_ND{
     @Override public Topology topology(){
       throw new UnsupportedOperationException("Ariadne_TM_SR_ND::NotMounted::topology.");
     }
-    };
+  }
+  protected final TopoIface<RT> not_mounted = new NotMountedTopo();
 
-  protected final TopoIface topo_null = new TopoIface(){
+
+  protected class NullTopo implements TopoIface<RT>{
     @Override public boolean can_read(){
       return false;
     }
-    @Override public Object read(){
-      throw new UnsupportedOperationException( "Cannot read from null topology." );
+
+    @Override public RT read(){
+      throw new UnsupportedOperationException("Cannot read from null topology.");
     }
+
     @Override public boolean can_step(){
       return false;
     }
+
     @Override public void step(){
-      throw new UnsupportedOperationException( "Cannot step over null topology." );
+      throw new UnsupportedOperationException("Cannot step over null topology.");
     }
+
     @Override public Topology topology(){
       return Topology.NULL;
     }
-    };
+  }
+  protected final TopoIface<RT> topo_null = new NullTopo();
 
   // good citizen
   //
@@ -192,14 +203,15 @@ public class Ariadne_TM_SR_ND{
     if(!is_mounted()) return "TM_SR_ND(NotMounted)";
     if(!can_read()) return "TM_SR_ND(Null)";
 
-    StringBuilder data_channel = new StringBuilder("");
+    // output takes two lines, starting from the left column on each
+    StringBuilder data_channel = new StringBuilder("\n");
     StringBuilder control_channel = new StringBuilder("");
     
-    data_channel.append( "TM_SR_ND(" ).append( topology().name()).append("( " );
-    control_channel.append( " ".repeat(data_channel.length()) );
+    data_channel.append( "TM_SR_ND(" ).append( topology().name()).append("(" );
+    control_channel.append( " ".repeat(data_channel.length()-1) );
 
     String element = null;
-    Ariadne_TM_SR_ND copy = this.entangle();
+    Ariadne_TM_SR_ND<RT> copy = this.entangle();
     if( copy.can_rewind() ) copy.rewind();
 
     Object o = null;
index 62a88dc..1f327af 100644 (file)
@@ -3,7 +3,7 @@ package com.ReasoningTechnology.Ariadne;
 import java.math.BigInteger;
 import java.util.List;
 
-public class Ariadne_TM_SR_ND_Array<T> extends Ariadne_TM_SR_ND{
+public class Ariadne_TM_SR_ND_Array<RT> extends Ariadne_TM_SR_ND<RT>{
 
   // Static methods
   //
@@ -15,10 +15,12 @@ public class Ariadne_TM_SR_ND_Array<T> extends Ariadne_TM_SR_ND{
   // Instance data
   //
   
-  private final List<T> array;
+  private final List<RT> array;
 
-  // Constructor
-  protected Ariadne_TM_SR_ND_Array(List<T> array){
+  // Constructor(s)
+  //
+  
+  protected Ariadne_TM_SR_ND_Array(List<RT> array){
     super();
     this.array = array;
 
@@ -36,6 +38,34 @@ public class Ariadne_TM_SR_ND_Array<T> extends Ariadne_TM_SR_ND{
   }
 
   // instance interface implementation
+  //
+
+  // Children of this can call super.entangle(copy) to perform the parent part of the entanglement.
+  // This calls super to perform its parent portion of the entanglement.
+  protected void entangle(Ariadne_TM_SR_ND_Array<RT> copy){
+    super.entangle(copy);
+  }
+
+  @Override public Ariadne_TM_SR_ND_Array<RT> entangle(){
+    Ariadne_TM_SR_ND_Array<RT> copy = Ariadne_TM_SR_ND_Array.make(this.array);
+    entangle(copy);
+
+    switch (this.current_topology.topology()) {
+    case NULL:
+      copy.current_topology = copy.topo_null;
+      break;
+    case SEGMENT:
+      copy.current_topology = copy.topo_segment;
+      break;
+    case RIGHTMOST:
+      copy.current_topology = copy.topo_rightmost;
+      break;
+    default:
+      throw new IllegalStateException("Unexpected topology: " + this.current_topology.topology());
+    }
+
+    return copy;
+  }
 
   @Override public boolean can_rewind(){
     return true;
@@ -50,41 +80,31 @@ public class Ariadne_TM_SR_ND_Array<T> extends Ariadne_TM_SR_ND{
     set_topology(array.size() == 1 ? topo_rightmost : topo_segment); // Adjust topology
   }
 
-  protected final TopoIface topo_segment = new TopoIface(){
-    @Override public boolean can_read(){
-      return true;
-    }
-    @Override public Object read(){
-      return array.get( head_address().intValueExact() );
-    }
-    @Override public boolean can_step(){
-      return true;
+  protected class SegmentTopo implements TopoIface<RT>{
+    @Override public boolean can_read(){return true;}
+    @Override public RT read(){
+      return array.get(head_address().intValueExact());
     }
+    @Override public boolean can_step(){return true;}
     @Override public void step(){
-      if( head_address().compareTo(BigInteger.valueOf(array.size() - 1)) == 0 )
+      if(head_address().compareTo(BigInteger.valueOf(array.size() - 1)) == 0)
         set_topology(topo_rightmost);
     }
-    @Override public Topology topology(){
-      return Topology.SEGMENT;
-    }
-    };
+    @Override public Topology topology(){return Topology.SEGMENT;}
+  }
+  protected final TopoIface<RT> topo_segment = new SegmentTopo();
 
-  protected final TopoIface topo_rightmost = new TopoIface(){
-    @Override public boolean can_read(){
-      return true;
-    }
-    @Override public Object read(){
-      return array.get( head_address().intValueExact() );
-    }
-    @Override public boolean can_step(){
-      return false;
+  protected class RightmostTopo implements TopoIface<RT>{
+    @Override public boolean can_read(){return true;}
+    @Override public RT read(){
+      return array.get(head_address().intValueExact());
     }
+    @Override public boolean can_step(){return false;}
     @Override public void step(){
-      throw new UnsupportedOperationException( "Cannot step from RIGHTMOST topo." );
+      throw new UnsupportedOperationException("Cannot step from RIGHTMOST topo.");
     }
-    @Override public Topology topology(){
-      return Topology.RIGHTMOST;
-    }
-    };
+    @Override public Topology topology(){return Topology.RIGHTMOST;}
+  }
+  protected final TopoIface<RT> topo_rightmost = new RightmostTopo();
   
 }
diff --git a/developer/javac🖉/Ariadne_TM_SR_ND_Label.java b/developer/javac🖉/Ariadne_TM_SR_ND_Label.java
deleted file mode 100644 (file)
index 2e39472..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
-Graph nodes are referenced by their labels.
-
-*/
-
-package com.ReasoningTechnology.Ariadne;
-
-public class Ariadne_TM_SR_ND_Label extends Ariadne_TM_SR_ND {
-
-  public static Ariadne_TM_SR_ND_Label make(){
-    return new Ariadne_TM_SR_ND_Label();
-  }
-
-  @Override public Ariadne_Label read(){
-    return (Ariadne_Label)super.read();
-  }
-
-}
index 9163754..be6de33 100644 (file)
@@ -11,7 +11,7 @@ package com.ReasoningTechnology.Ariadne;
 import java.util.List;
 import java.util.ListIterator;
 
-public class Ariadne_TM_SR_ND_List<T> extends Ariadne_TM_SR_ND{
+public class Ariadne_TM_SR_ND_List<RT> extends Ariadne_TM_SR_ND<RT>{
 
   // Static methods
   //
@@ -23,14 +23,14 @@ public class Ariadne_TM_SR_ND_List<T> extends Ariadne_TM_SR_ND{
   // instance data
   //
 
-  private List<T> list;  // The attached linked list
-  private ListIterator<T> iterator;  // Iterator for traversal
-  private T read_value;  // Stores the current cell value
+  private List<RT> list;  // The attached linked list
+  private ListIterator<RT> iterator;  // Iterator for traversal
+  private RT read_value;  // Stores the current cell value
 
   // constructor(s)
   //
 
-  protected Ariadne_TM_SR_ND_List(List<T> list){
+  protected Ariadne_TM_SR_ND_List(List<RT> list){
     this.list = list;
 
     if( list == null || list.isEmpty() ){
@@ -53,19 +53,17 @@ public class Ariadne_TM_SR_ND_List<T> extends Ariadne_TM_SR_ND{
   // instance interface implementation
   //
 
-  protected void entangle(Ariadne_TM_SR_ND_List<T> copy){
+  // Children of this can call entangle(copy) to perform the parent part of the entanglement.
+  // This calls super to perform its parent portion of the entanglement.
+  protected void entangle(Ariadne_TM_SR_ND_List<RT> copy){
     super.entangle(copy);
     copy.read_value = this.read_value;
     copy.iterator = this.list.listIterator(this.iterator.nextIndex());
   }
 
-  @Override public Ariadne_TM_SR_ND_List<T> entangle(){
-    Ariadne_TM_SR_ND_List<T> copy = Ariadne_TM_SR_ND_List.make(this.list);
-
-    // Copy shared fields
-    copy.index = this.index; // Copy the step count
-    copy.read_value = this.read_value; // Synchronize the current read value
-    copy.iterator = this.list.listIterator(this.iterator.nextIndex()); // Align iterator
+  @Override public Ariadne_TM_SR_ND_List<RT> entangle(){
+    Ariadne_TM_SR_ND_List<RT> copy = Ariadne_TM_SR_ND_List.make(this.list);
+    entangle(copy);
 
     // Set the appropriate topology in the copy based on the current topology
     switch (this.current_topology.topology()) {
@@ -100,48 +98,29 @@ public class Ariadne_TM_SR_ND_List<T> extends Ariadne_TM_SR_ND{
     set_topology(list.size() == 1 ? topo_rightmost : topo_segment); // Adjust topology
   }
 
-  @Override 
-  @SuppressWarnings("unchecked")
-  public T read(){
-    return (T) current_topology.read(); // Cast to ensure T is returned
-  }
-
-  protected final TopoIface topo_segment = new TopoIface(){
-    @Override public boolean can_read(){
-      return true;
-    }
-    @Override public T read(){
-      return (T)read_value;
-    }
-    @Override public boolean can_step(){
-      return true;
-    }
+  protected class SegmentTopo implements TopoIface<RT>{
+    @Override public boolean can_read(){ return true; }
+    @Override public RT read(){ return (RT) read_value; }
+    @Override public boolean can_step(){ return true; }
     @Override public void step(){
       read_value = iterator.next();
       if( !iterator.hasNext() ) set_topology(topo_rightmost);
     }
-    @Override public Topology topology(){
-      return Topology.SEGMENT;
-    }
-    };
+    @Override public Topology topology(){ return Topology.SEGMENT; }
+  }
+  protected final TopoIface<RT> topo_segment = new SegmentTopo();
 
-  protected final TopoIface topo_rightmost = new TopoIface(){
-    @Override public boolean can_read(){
-      return true;
-    }
-    @Override public T read(){
-      return read_value;
-    }
-    @Override public boolean can_step(){
-      return false;
-    }
+  protected class RightmostTopo implements TopoIface<RT>{
+    @Override public boolean can_read(){ return true; }
+    @Override public RT read(){ return read_value; }
+    @Override public boolean can_step(){ return false; }
     @Override public void step(){
-      throw new UnsupportedOperationException( "Cannot step from RIGHTMOST topo." );
+      throw new UnsupportedOperationException("Cannot step from RIGHTMOST topo.");
     }
-    @Override public Topology topology(){
-      return Topology.RIGHTMOST;
-    }
-    };
+    @Override public Topology topology(){ return Topology.RIGHTMOST; }
+  }
+  protected final TopoIface<RT> topo_rightmost = new RightmostTopo();
+
 }
 
 
index 9d6878d..b585710 100644 (file)
 package com.ReasoningTechnology.Ariadne;
 
-import java.util.Iterator;
 import java.util.Set;
+import java.util.Iterator;
 
-public class Ariadne_TM_SR_ND_Set<T> extends Ariadne_TM_SR_ND{
+public class Ariadne_TM_SR_ND_Set<RT> extends Ariadne_TM_SR_ND<RT>{
 
-  // Static factory method
-  public static <T> Ariadne_TM_SR_ND_Set<T> make(Set<T> set){
+  // Static methods
+  public static <RT> Ariadne_TM_SR_ND_Set<RT> make(Set<RT> set){
     return new Ariadne_TM_SR_ND_Set<>(set);
   }
 
   // Instance data
-  private final Set<T> set;
-  private final Iterator<T> iterator;
-  private T current_value;
+  private Set<RT> set;
+  private Iterator<RT> iterator;
+  private RT read_value;
 
-  private final TopoIface topo_null = new TopoNull();
-  private final TopoIface topo_segment = new TopoSegment();
-  private final TopoIface topo_rightmost = new TopoRightmost();
+  protected final TopoIface<RT> topo_segment = new SegmentTopo();
+  protected final TopoIface<RT> topo_rightmost = new RightmostTopo();
 
   // Constructor
-  protected Ariadne_TM_SR_ND_Set(Set<T> set){
+  protected Ariadne_TM_SR_ND_Set(Set<RT> set){
     this.set = set;
-
-    if( set == null || set.isEmpty() ){
+    if (set == null || set.isEmpty()){
       this.iterator = null;
       set_topology(topo_null);
       return;
     }
-
     this.iterator = set.iterator();
-    this.current_value = iterator.hasNext() ? iterator.next() : null;
-
-    if( set.size() == 1 ){
-      set_topology(topo_rightmost);
-    }else{
-      set_topology(topo_segment);
-    }
+    this.read_value = iterator.hasNext() ? iterator.next() : null;
+    set_topology(set.size() == 1 ? topo_rightmost : topo_segment);
   }
 
   // Instance interface implementation
+  @Override public void rewind(){
+    super.rewind();
+    if (set == null || set.isEmpty()){
+      set_topology(topo_null);
+      return;
+    }
+    this.iterator = set.iterator();
+    this.read_value = iterator.hasNext() ? iterator.next() : null;
+    set_topology(set.size() == 1 ? topo_rightmost : topo_segment);
+  }
 
-  @Override
-  @SuppressWarnings("unchecked")
-  public T read(){
-    return (T)current_topology.read();
+  protected void entangle(Ariadne_TM_SR_ND_Set<RT> copy){
+    super.entangle(copy);
+    copy.iterator = this.set.iterator();
+    copy.read_value = this.read_value;
   }
 
-  private class TopoNull implements TopoIface{
-    @Override public boolean can_read(){
-      return false;
-    }
-    @Override public T read(){
-      throw new UnsupportedOperationException("Cannot read from NULL topo.");
-    }
-    @Override public boolean can_step(){
-      return false;
-    }
-    @Override public void step(){
-      throw new UnsupportedOperationException("Cannot step from NULL topo.");
-    }
-    @Override public Topology topology(){
-      return Topology.NULL;
-    }
+  @Override public Ariadne_TM_SR_ND_Set<RT> entangle(){
+    Ariadne_TM_SR_ND_Set<RT> copy = Ariadne_TM_SR_ND_Set.make(this.set);
+    entangle(copy);
+    switch (this.current_topology.topology()){
+      case NULL:
+        copy.current_topology = copy.topo_null;
+        break;
+      case SEGMENT:
+        copy.current_topology = copy.topo_segment;
+        break;
+      case RIGHTMOST:
+        copy.current_topology = copy.topo_rightmost;
+        break;
+      default:
+        throw new IllegalStateException("Unexpected topology: " + this.current_topology.topology());
+    }
+    return copy;
   }
 
-  private class TopoSegment implements TopoIface{
-    @Override public boolean can_read(){
-      return true;
-    }
-    @Override public T read(){
-      return current_value;
-    }
-    @Override public boolean can_step(){
-      return iterator.hasNext();
-    }
+  protected class SegmentTopo implements TopoIface<RT>{
+    @Override public boolean can_read(){ return true; }
+    @Override public RT read(){ return read_value; }
+    @Override public boolean can_step(){ return iterator.hasNext(); }
     @Override public void step(){
-      current_value = iterator.next();
-      if( !iterator.hasNext() ) set_topology(topo_rightmost);
-    }
-    @Override public Topology topology(){
-      return Topology.SEGMENT;
+      read_value = iterator.next();
+      if (!iterator.hasNext()) set_topology(topo_rightmost);
     }
+    @Override public Topology topology(){ return Topology.SEGMENT; }
   }
 
-  private class TopoRightmost implements TopoIface{
-    @Override public boolean can_read(){
-      return true;
-    }
-    @Override public T read(){
-      return current_value;
-    }
-    @Override public boolean can_step(){
-      return false;
-    }
+  protected class RightmostTopo implements TopoIface<RT>{
+    @Override public boolean can_read(){ return true; }
+    @Override public RT read(){ return read_value; }
+    @Override public boolean can_step(){ return false; }
     @Override public void step(){
       throw new UnsupportedOperationException("Cannot step from RIGHTMOST topo.");
     }
-    @Override public Topology topology(){
-      return Topology.RIGHTMOST;
-    }
+    @Override public Topology topology(){ return Topology.RIGHTMOST; }
   }
 }