+++ /dev/null
-#!/bin/bash
-java com.ReasoningTechnology."Ariadne".Build
--- /dev/null
+ // Given a context_path_tm and path_member_set.
+ // Initializes the path_member_set. Leaves head on last cell of context_path_tm.
+ // Returns a successful initlaization flag and possibly not null cycle_node_label
+ public class initialize{
+ static public initialize f(context_path_tm ,path_member_set){
+ initialize instance = new initialize();
+ instance.g(context_path_tm ,path_member_set);
+ return instance;
+ }
+ public Label first_in_path_cycle_node_label = null;
+ public boolean success = false;
+
+ protected void g(context_path_tm ,path_member_set){
+
+ if( context_path.isEmpty() ){
+ System.out.println("TM_SR_NX_Depth::initialize required context_path is empty.");
+ success = false;
+ return;
+ }
+
+ boolean is_cycle_node = false;
+ Ariadne_TM_SR_NX sibling_tm = null;
+ Ariadne_Label path_node_label = null;
+
+ do{
+ sibling_tm = context_path_tm.read();
+ path_node_label = sibling_tm.read();
+ if(path_node_label == null){
+ System.out.println("TM_SR_NX_Depth::complete_context_path hit null path label on path");
+ success = false;
+ return;
+ }
+
+ is_cycle_node = path_member_set.contains(path_node_label);
+ if( is_cycle_node ) break;
+
+ path_member_set.add( path_node_label );
+
+ if( !context_path_tm.can_step() ) break;
+ context_path_tm.step();
+
+ }while(true);
+
+ if( is_cycle_node && context_path_tm.can_step() ){
+ System.out.println
+ (
+ "TM_SR_NX_Depth::initialize_path_member_set: cycle found in initial context_path."
+ );
+ first_in_path_cycle_node_label = path_node_label;
+ success = false;
+ return;
+ }
+
+ success = true;
+ return;
+ }
+ }
2025-01-24T10:54:26Z[]
global substitute in this file _ND -> _NX
+2025-01-26T15:35:15Z[]
+
+ Chat GPT explaining why Java is giving a type mismatch error on two identical types.
+ Of course we should give Java a break, as it is a young experimental language.
+
+ Yes, you're absolutely right! The generic bounds at the top of the class declaration guarantee that both GraphType and SiblingContext are tied to the same LabelType. Specifically:
+
+ SiblingContext extends Ariadne_TM_SR_NX_F<LabelType> ensures that SiblingContext is a subtype of Ariadne_TM_SR_NX_F<LabelType>.
+ GraphType extends Ariadne_Graph_FD<LabelType, NodeType> ensures that GraphType is a type of graph using the same LabelType.
+ Thus, conceptually, the cast should always be safe because graph.start() returns a type that satisfies the bounds of SiblingContext. The problem is that Java's type system is not sophisticated enough to understand this guarantee at runtime.
+
+
+ ```
+ public class
+ Ariadne_Graph_FD
+ < LabelType extends Ariadne_Label ,NodeType extends Ariadne_Node_FD<LabelType> >
+ extends Ariadne_Graph<LabelType ,NodeType>
+ {
+ ...
+ @Override public Ariadne_TM_SR_NX_F<LabelType> start(){
+ return Ariadne_TM_SR_NX_Array.make(start_list);
+ }
+
+ ```
+
+ ```
+ public class Ariadne_ContextStack
+ <
+ LabelType extends Ariadne_Label
+ ,NodeType extends Ariadne_Node_FD<LabelType>
+ ,SiblingContext extends Ariadne_TM_SR_NX_F<LabelType>
+ ,GraphType extends Ariadne_Graph_FD<LabelType, NodeType>
+ >
+ {
+ ...
+ protected Ariadne_ContextStack(GraphType graph){
+ this.graph = graph;
+ this.context_path = new ArrayList<>();
+ this.context_path.add( graph.start() ); // <--- type mismatch error this line
+ this.path_member_set = new HashSet<>();
+ }
+
+ ...
+
+ private final List<SiblingContext> context_path;
+
+ ```
+
+ Sure looks to me like graph.start() is said to return the same Ariadne_TM_SR_NX_F<LabelType>, as that accepted by context_path.add(). The two
+ 'LabelType' are tied together at the top of the class ContextStack declaration.
+ However the compiler says:
+
+ ```
+ javacđź–‰/Ariadne_ContextStack.java:72: error: incompatible types: Ariadne_TM_SR_NX_F<LabelType> cannot be converted to SiblingContext
+ this.context_path.add( graph.start() );
+ ^
+ where LabelType,SiblingContext are type-variables:
+ LabelType extends Ariadne_Label declared in class Ariadne_ContextStack
+ SiblingContext extends Ariadne_TM_SR_NX_F<LabelType> declared in class Ariadne_ContextStack
+ ```
+
+ This is only one of many type errors that appear to be the same sort of thins.
+ It is a scary proposition to be start correcting the compiler and inserting
+ a bunch of casts. And which of these casts would be a mistake?
+
+ small variation:
+
+ ```
+ javacđź–‰/Ariadne_ContextStack.java:74: error: incompatible types: Ariadne_TM_SR_NX_F<LabelType> cannot be converted to SiblingContext
+ SiblingContext s = t;
+ ```
+
+ add insult to injury, it gives a syntax error when a cast is added:
+ ```
+ this.context_path.add( (SiblingContext)graph.start() );
+ ```
+ ```
+ javacđź–‰/Ariadne_ContextStack.java:77: error: illegal start of type
+ this.context_path.add( (SiblingContext)graph.start() );
+ ^
+ ```
+
+ I thought I was going to be doing graph research, instead I am using
+ my time to learn the quirks of Java. Is it a more valuable activity?
+
+ This works, but issues a warning, which can be surpressed. Great, a
+ language made to patch the main language. Very useful of the main
+ language needs patching:
+
+ ```
+ @SuppressWarnings("unchecked")
+ SiblingContext sc = (SiblingContext) graph.start();
+ this.context_path.add( sc );
+ ```
+
+2025-01-31T07:43:30Z[]
+
+ Suppose class A parent, class B child type. Java does not allow
+ class B to have static methods with the same type signature as
+ static methods in class A.
+
+ This clobbers the factory method pattern because the factory is
+ always called `make`.
+
+ The 'cure' is to require each class to have a unique factory
+ method name. Perhaps make_<type>. So basically like a constructor
+ with 'make_' prepended. However, statics are already called
+ with their type name, so then a call to make would look like:
+
+ T x = T.make_T();
+
+ Type names tend to be long in Java and there is no type
+ alias facility, so that will surely span more than one line.
+
+ How many times can a person write type the same thing without
+ making an error? It is a game of 'Simon Says'.
+
+
+++ /dev/null
-/*
-
-Each member of a `path` list is a node label. A path is created by traversing the graph.
-
-Imagine expanding each member of a path into a sibling list tm, with the cell under
-the head being the label on the path. This is the context_path.
-
-Because a context path holds the siblings, it can be used as the state variable during
-a tree traversal.
-
-*/
-
-import java.util.HashSet;
-import java.util.ArrayList;
-import java.util.List;
-
-import com.ReasoningTechnology.Ariadne.Ariadne_TM_SR_NX;
-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_NX_Array;
-import com.ReasoningTechnology.Ariadne.Ariadne_TM_SR_NX_List;
-
-class TM_SR_NX_Depth extends Ariadne_TM_SR_NX<Label>{
-
- // ----------------------------------------
- // static
- //
-
- TM_SR_NX_Depth make(Ariadne_Graph graph){
- if(graph == null) return null;
- TM_SR_NX_Depth depth = new TM_SR_NX_Depth();
- depth.graph = graph;
- depth.context_path.add( graph.start() );
- depth.context_path_tm = Ariadne_TM_SR_NX_Array.make(context_path);
- initialize i = initialize.f(depth.context_path_tm ,depth.path_member_set);
- if( !i.success() ) return null;
- first_in_path_cycle_node_label = i.first_in_path_cycle_node_label;
- return depth;
- }
-
- // ----------------------------------------
- // instance data
- //
-
- protected Graph graph = null;
- protected List<Ariadne_TM_SR_NX<Label>> context_path = new ArrayList<>();
- protected Ariadne_TM_SR_NX_Array<Ariadne_TM_SR_NX> context_path_tm = null;
- protected Label first_in_path_cycle_node_label = null;
-
- // Used for cycle detection.
- HashSet<Ariadne_Label> path_member_set = new HashSet<>();
-
- // ----------------------------------------
- // constructor
- //
-
- protected TM_SR_NX_Depth(){
- set_topology(topo_null);
- }
-
-
- // ----------------------------------------
- // instance interface implementation
- //
-
- // Given a context_path_tm and path_member_set.
- // Initializes the path_member_set. Leaves head on last cell of context_path_tm.
- // Returns a successful initlaization flag and possibly not null cycle_node_label
- public class initialize{
- static public initialize f(context_path_tm ,path_member_set){
- initialize instance = new initialize();
- instance.g(context_path_tm ,path_member_set);
- return instance;
- }
- public Label first_in_path_cycle_node_label = null;
- public boolean success = false;
-
- protected void g(context_path_tm ,path_member_set){
-
- if( context_path.isEmpty() ){
- System.out.println("TM_SR_NX_Depth::initialize required context_path is empty.");
- success = false;
- return;
- }
-
- boolean is_cycle_node = false;
- Ariadne_TM_SR_NX sibling_tm = null;
- Ariadne_Label path_node_label = null;
-
- do{
- sibling_tm = context_path_tm.read();
- path_node_label = sibling_tm.read();
- if(path_node_label == null){
- System.out.println("TM_SR_NX_Depth::complete_context_path hit null path label on path");
- success = false;
- return;
- }
-
- is_cycle_node = path_member_set.contains(path_node_label);
- if( is_cycle_node ) break;
-
- path_member_set.add( path_node_label );
-
- if( !context_path_tm.can_step() ) break;
- context_path_tm.step();
-
- }while(true);
-
- if( is_cycle_node && context_path_tm.can_step() ){
- System.out.println
- (
- "TM_SR_NX_Depth::initialize_path_member_set: cycle found in initial context_path."
- );
- first_in_path_cycle_node_label = path_node_label;
- success = false;
- return;
- }
-
- success = true;
- return;
- }
- }
-
- public boolean path_has_cycle(){
- return first_in_path_cycle_node_label != null;
- }
-
-
- // Upon stepping on a cycle node, we must go back and pick the next start node.
- // The context path that stepped on the cycle node is saved to document the cycle.
- // A path is terminated by a cycle being found, or a leaf node, or all the children having been visited. The terminating node (label) becomes the read value. Upon entering `step()`
- // the head is on the prior leaf node.
- public void step(){
-
- boolean is_cycle_node = false;
- Ariadne_Node path_node = null;
- boolean is_leaf_node = false;
- Ariadne_TM_SR_NX sibling_tm = null;
- Ariadne_Label path_node_label = null;
-
- sibling_tm = context_path_tm.read();
- path_node_label = sibling_tm.read();
-
- do{
- path_node = graph.node(path_node_label);
- if(path_node == null){
- System.out.println
- (
- "TM_SR_NX_Depth::complete_context_path internal algorithm error, node on path not found in graph for: label(\""
- + path_node_label
- + "\")"
- );
- return false;
- }
-
- // attempt to extend downward
- sibling_tm = path_node.neighbor();
- is_leaf_node = sibling_tm == null || !sibling_tm.can_read();
- if(is_leaf_node){
-
- // add the sibling_tm to the context_path
- context_path.add(sibling_tm);
-
- // exit if path_node cycles back
- path_node_label = sibling_tm.read();
- is_cycle_node = path_member_set.contains(path_node_label);
- if( is_cycle_node ){
- // caller needs to check for cycle found before each new step
- first_in_path_cycle_node_label = path_node_label;
- return true;
- }
-
- // path_node_label has now been visited
- path_member_set.add(path_node_label);
-
- }while(true);
- }
-
- // being a good object citizen
- //
-
-
-}
import com.ReasoningTechnology.Ariadne.Ariadne_Label;
import com.ReasoningTechnology.Ariadne.Ariadne_Node;
-import com.ReasoningTechnology.Ariadne.Ariadne_Graph_FD;
+import com.ReasoningTechnology.Ariadne.Ariadne_Graph;
-public class Graph extends Ariadne_Graph_FD<Label ,Node>{
+public class Graph extends Ariadne_Graph<Label ,Node>{
@SuppressWarnings("unchecked")
public static Graph make(){
+++ /dev/null
-package com.ReasoningTechnology.Ariadne;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-
-// SiblingContext a tm of graph node labels, that are siblings to a path node, in a tree search
-// LT == Label Type
-public class Ariadne_ContextPath_FD
- <
- SiblingContext extends Ariadne_TM_SR_NX<LT>
- ,LT extends Ariadne_Label
- >
-{
-
- //----------------------------------------
- // Static
-
- public static
- <
- SiblingContext extends Ariadne_TM_SR_NX<LT>
- ,LT extends Ariadne_Label
- >
- Ariadne_ContextPath_FD<SiblingContext ,LT>
- make()
- {
- return new Ariadne_ContextPath_FD<>();
- }
-
- public static
- <
- SiblingContext extends Ariadne_TM_SR_NX<LT>
- ,LT extends Ariadne_Label
- >
- Ariadne_ContextPath_FD<SiblingContext ,LT>
- make(Ariadne_ContextPath_FD<SiblingContext ,LT> other)
- {
- return new Ariadne_ContextPath_FD<>();
- }
-
-
- //----------------------------------------
- // Instance data
-
- private final List<SiblingContext> context_path_list;
- private final HashSet<LT> path_member_set;
- private LT cycle_node_label;
-
- //----------------------------------------
- // Constructors
-
- public Ariadne_ContextPath_FD(){
- this.context_path_list = new ArrayList<>();
- this.path_member_set = new HashSet<>();
- }
-
- public Ariadne_ContextPath_FD(Ariadne_ContextPath_FD<SiblingContext ,LT> other){
- this.context_path_list = new ArrayList<>( other.context_path_list );
- this.path_member_set = new HashSet<>( other.path_member_set );
- }
-
- //----------------------------------------
- // Instance methods
-
- /**
- * Adds a traversal state to the context path.
- *
- * @param sibling_context The traversal state to add.
- * @return true if successfully added, false if it introduces a cycle.
- */
- public boolean push(SiblingContext sibling_context){
- if( sibling_context == null || !sibling_context.can_read() ){
- return false;
- }
-
- LT label = sibling_context.read();
- if( path_member_set.contains(label) ){
- cycle_node_label = label;
- return false; // Cycle detected
- }
-
- context_path_list.add( sibling_context );
- path_member_set.add(label);
- return true;
- }
-
- /**
- * Removes the last traversal state from the context path.
- *
- * @return The removed traversal state, or null if the path is empty.
- */
- public SiblingContext pop(){
- if( context_path_list.isEmpty() ){
- return null;
- }
-
- SiblingContext last = context_path_list.remove( context_path_list.size() - 1 );
- path_member_set.remove( last.read() );
- return last;
- }
-
- /**
- * Checks if the context path contains the given label.
- *
- * @param label The label to check.
- * @return true if the label is in the path, false otherwise.
- */
- public boolean contains(LT label){
- return path_member_set.contains(label);
- }
-
- /**
- * Returns the size of the context path.
- *
- * @return The number of traversal states in the path.
- */
- public int size(){
- return context_path_list.size();
- }
-
- /**
- * Provides a string representation of the context path for debugging.
- *
- * @return A string representing the context path.
- */
- @Override
- public String toString(){
- StringBuilder output = new StringBuilder("Ariadne_ContextPath_FD(");
- Ariadne_TM_SR_NX_F< SiblingContext > tm = Ariadne_TM_SR_NX_Array.make(context_path_list);
- if( tm.can_read() ){
- do{
- output.append("Sibling( ");
- output.append( tm.toString() );
- output.append(" )");
- if( !tm.can_step() ) break;
- tm.step();
- output.append(" ,");
- }while(true);
- }
- output.append(")");
- return output.toString();
- }
-
-}
-
--- /dev/null
+/*
+ Node.neighbor() returns a tm full of labels to neighbor nodes. For a node in a tree neighbors are called 'siblings'.
+
+ Each path node (node in a traversal path) comes from either the start list, or a neighbor list. This is the path node's 'sibling context'.
+
+ The sibling context is important in both breadth first and depth first traversals.
+
+ When the context for each node along a path is put on a stack, the result is the ContextStack.
+
+*/
+
+package com.ReasoningTechnology.Ariadne;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+
+public class Ariadne_ContextStack
+ <
+ Label extends Ariadne_Label
+ ,Node extends Ariadne_Node_FD<Label>
+ ,SiblingContext extends Ariadne_TM_SR_NX_F<Label>
+ >
+{
+
+ //----------------------------------------
+ // Static
+
+ public static
+ <
+ Label extends Ariadne_Label
+ ,Node extends Ariadne_Node_FD<Label>
+ ,SiblingContext extends Ariadne_TM_SR_NX_F<Label>
+ >
+ Ariadne_ContextStack<Label ,Node ,SiblingContext>
+ make()
+ {
+ return new Ariadne_ContextStack<>();
+ }
+
+ public static
+ <
+ Label extends Ariadne_Label
+ ,Node extends Ariadne_Node_FD<Label>
+ ,SiblingContext extends Ariadne_TM_SR_NX_F<Label>
+ ,Graph extends Ariadne_Graph_FD<Label, Node>
+ >
+ Ariadne_ContextStack<Label ,Node ,SiblingContext>
+ make(Ariadne_ContextStack<Label ,Node ,SiblingContext> other)
+ {
+ // full form required by the compiler
+ return new Ariadne_ContextStack<Label, Node, SiblingContext, Graph>(other);
+ }
+
+
+ //----------------------------------------
+ // Instance data
+
+ private final List<SiblingContext> context_stack;
+ private final HashSet<Label> path_member_set; // speed up cycle checks
+ private Label cycle_node_label;
+
+ //----------------------------------------
+ // Constructors
+
+ protected Ariadne_ContextStack(){
+ this.context_stack = new ArrayList<>();
+ this.path_member_set = new HashSet<>();
+ }
+
+ protected Ariadne_ContextStack(
+ Ariadne_ContextStack<Label ,Node ,SiblingContext> other
+ ){
+ this.context_stack = new ArrayList<>( other.context_stack );
+ this.path_member_set = new HashSet<>( other.path_member_set );
+ }
+
+ //----------------------------------------
+ // Instance methods
+
+ public enum PushResult{
+ NO_CONTEXT
+ ,CYCLE
+ ,SUCCESS
+ }
+ public boolean push(SiblingContext sibling_context){
+ if( sibling_context == null || !sibling_context.can_read() ){
+ return PushResult.NO_CONTEXT;
+ }
+
+ Label label = sibling_context.read();
+ if( path_member_set.contains(label) ){
+ cycle_node_label = label;
+ return PushResult.CYCLE;
+ }
+
+ context_stack.add( sibling_context );
+ path_member_set.add(label);
+ return PushResult.SUCCESS;
+ }
+
+ public SiblingContext top(){
+ return context_stack.get( context_stack.size() - 1 );
+ }
+
+ public SiblingContext pop(){
+ if( context_stack.isEmpty() ){
+ return null;
+ }
+ SiblingContext popped_top = context_stack.remove( context_stack.size() - 1 );
+ path_member_set.remove( popped_top.read() );
+ return popped_top;
+ }
+
+ public boolean in_path(Label label){
+ return path_member_set.contains(label);
+ }
+
+ /**
+ * Checks if the context path contains the given label.
+ *
+ * @param label The label to check.
+ * @return true if the label is in the path, false otherwise.
+ */
+ public boolean contains(Label label){
+ return path_member_set.contains(label);
+ }
+
+ /**
+ * Returns the size of the context path.
+ *
+ * @return The number of traversal states in the path.
+ */
+ public int size(){
+ return context_stack.size();
+ }
+
+ public enum StepResult{
+ NOT_CANSTEP
+ ,CYCLE
+ ,SUCCESS
+ }
+ StepResult top_step(){
+ if( top() == null || !top().can_step() ) return StepResult.NOT_CANSTEP;
+ top().step();
+ Label node_label = top().read();
+ if( path_member_set.contains(node_label) ){ // cycle found
+ cycle_node_label = node_label;
+ return StepResult.CYCLE;
+ }
+ path_member_set.add(node_label);
+ context_stack.push(s);
+ return StepResult.SUCCESS;
+ }
+
+ //----------------------------------------
+ // Good Citizen
+
+ @Override public boolean isEmpty(){
+ return context_stack.isEmpty();
+ }
+
+ /**
+ * Provides a string representation of the context path for debugging.
+ *
+ * @return A string representing the context path.
+ */
+ @Override public String toString(){
+ StringBuilder output = new StringBuilder("Ariadne_ContextStack(");
+ Ariadne_TM_SR_NX_F< SiblingContext > tm = Ariadne_TM_SR_NX_Array.make(context_stack);
+ if( tm.can_read() ){
+ do{
+ output.append("Sibling( ");
+ output.append( tm.toString() );
+ output.append(" )");
+ if( !tm.can_step() ) break;
+ tm.step();
+ output.append(" ,");
+ }while(true);
+ }
+ output.append(")");
+ return output.toString();
+ }
+
+}
+
,UNKNOWN
}
- public static < T extends Ariadne_Label, N extends Ariadne_Node<T> > Ariadne_Graph<T, N> make() {
+ public static
+ < T extends Ariadne_Label, N extends Ariadne_Node<T> >
+ Ariadne_Graph<T, N> make() {
return new Ariadne_Graph<>();
}
- public static <T extends Ariadne_Label, N extends Ariadne_Node<T>> Ariadne_Graph<T, N> make(String name) {
+ public static
+ <T extends Ariadne_Label, N extends Ariadne_Node<T>>
+ Ariadne_Graph<T, N> make(String name) {
return new Ariadne_Graph<>(name);
}
import java.util.ArrayList;
import java.util.HashMap;
-// LT == Label Type, NT == Node Type
-public class Ariadne_Graph_FD<LT extends Ariadne_Label ,NT extends Ariadne_Node<LT>> extends Ariadne_Graph<LT ,NT>{
+public class Ariadne_Graph_FD
+ <
+ LabelType extends Ariadne_Label
+ ,NodeType extends Ariadne_Node_FD<LabelType>
+ >
+ extends Ariadne_Graph<LabelType ,NodeType>
+{
// Static
//
- public static <T extends Ariadne_Label ,N extends Ariadne_Node<T>> Ariadne_Graph_FD<T ,N> make(){
+ // Java does not allow 'make' in the type extended from a type that has 'make',
+ // so these become 'make_FD'. Why? Because it is a game of Simon Says, and
+ // I got caught here, I didn't add the _FD initially.
+
+ public static
+ < T extends Ariadne_Label ,N extends Ariadne_Node_FD<T> >
+ Ariadne_Graph_FD<T ,N> make_FD(){
return new Ariadne_Graph_FD<>();
}
- public static <T extends Ariadne_Label ,N extends Ariadne_Node<T>> Ariadne_Graph_FD<T ,N> make(String name){
+ public static
+ < T extends Ariadne_Label ,N extends Ariadne_Node_FD<T> >
+ Ariadne_Graph_FD<T ,N> make_FD(String name){
return new Ariadne_Graph_FD<>(name);
}
// Instance data
//
- private final HashMap<LT ,NT> node_db = new HashMap<>();
- private final HashMap< Ariadne_Pair<LT ,LT> ,Ariadne_Edge<LT> > edge_db = new HashMap<>();
- private final ArrayList<LT> start_list = new ArrayList<>();
+ private final
+ HashMap<LabelType ,NodeType>
+ node_db = new HashMap<>();
+
+ private final
+ HashMap< Ariadne_Pair<LabelType ,LabelType> ,Ariadne_Edge<LabelType> >
+ edge_db = new HashMap<>();
+
+ private final
+ ArrayList<LabelType>
+ start_list = new ArrayList<>();
// Constructor(s)
//
// Nodes are distinct due to the use of the HashMap
// Check that start nodes are in the graph
- Ariadne_TM_SR_NX_Array<LT> tm = Ariadne_TM_SR_NX_Array.make(start_list);
+ Ariadne_TM_SR_NX_Array<LabelType> tm = Ariadne_TM_SR_NX_Array.make(start_list);
if( tm.can_read() ){
do{
start_flag = this.node( tm.read() ) != null;
return distinct_flag && start_flag;
}
- @Override public Ariadne_TM_SR_NX<LT> start(){
+ @Override public Ariadne_TM_SR_NX_F<LabelType> start(){
return Ariadne_TM_SR_NX_Array.make(start_list);
}
// Lookup a node on the graph by label
- @Override public NT node(LT label){
+ @Override public NodeType node(LabelType label){
return node_db.get(label);
}
// A tm of all nodes
- public Ariadne_TM_SR_NX<NT> node(){
+ public Ariadne_TM_SR_NX_F<NodeType> node(){
return Ariadne_TM_SR_NX_Array.make( new ArrayList<>(node_db.values()) );
}
// Lookup an edge by two labels. For a directed graph, label0 is the origin node label.
- @Override public Ariadne_Edge<LT> edge(LT label0 ,LT label1){
+ @Override public Ariadne_Edge<LabelType> edge(LabelType label0 ,LabelType label1){
return edge_db.get( Ariadne_Pair.make(label0 ,label1) );
}
// A tm of all edges
- public Ariadne_TM_SR_NX<Ariadne_Edge<LT>> edge(){
+ public Ariadne_TM_SR_NX_F<Ariadne_Edge<LabelType>> edge(){
return Ariadne_TM_SR_NX_Array.make( new ArrayList<>(edge_db.values()) );
}
output.append("Graph_FD( ");
{
- Ariadne_TM_SR_NX<NT> tm = this.node();
+ Ariadne_TM_SR_NX_F<NodeType> tm = this.node();
if( !tm.can_read() ){
output.append( "Node_list()" );
}else{
}
{
- Ariadne_TM_SR_NX<Ariadne_Edge<LT>> tm = this.edge();
+ Ariadne_TM_SR_NX_F<Ariadne_Edge<LabelType>> tm = this.edge();
if( !tm.can_read() ){
output.append( "Edge_list()" );
}else{
A Node potentially has an infinite number of neighbors, in which case its
neighbor set is defined using a function. See the IndexTree example.
+A node extends from HashMap so to facilitate the user in adding his or
+her own properties.
*/
// Owned by the class
//
- public static <T extends Ariadne_Label> Ariadne_Node<T> make(T label){
+ public static
+ <T extends Ariadne_Label>
+ Ariadne_Node<T> make(T label){
return new Ariadne_Node<>(label);
}
return this.label;
}
+ // the returned machine should have the head on leftmost
public Ariadne_TM_SR_NX<LT> neighbor(){
throw new UnsupportedOperationException("Ariadne_Node::neighbor not implemented in the base class.");
}
/*
A node with a finite fixed set of neighbors.
-
*/
package com.ReasoningTechnology.Ariadne;
import java.util.HashSet;
import java.util.Arrays;
+import java.util.List;
// LT == Label Type
public class Ariadne_Node_FD<LT extends Ariadne_Label> extends Ariadne_Node<LT>{
// Owned by the class
//
- @SafeVarargs
- public static <T extends Ariadne_Label> Ariadne_Node_FD<T> make(T label ,T... neighbors){
- return new Ariadne_Node_FD<>(label ,neighbors);
- }
-
// Data owned by the instance
//
- private final HashSet<LT> neighbor_set;
-
// Constructors
//
- @SafeVarargs
- protected Ariadne_Node_FD(LT label ,LT... neighbors){
+ protected Ariadne_Node_FD(LT label){
super(label);
- this.neighbor_set = new HashSet<>();
- if( neighbors != null ){
- this.neighbor_set.addAll(Arrays.asList(neighbors));
- }
}
// Instance interface
//
- @Override public Ariadne_TM_SR_NX<LT> neighbor(){
- return Ariadne_TM_SR_NX_Set.make(neighbor_set);
+ @Override public Ariadne_TM_SR_NX_F<LT> neighbor(){
+ throw new UnsupportedOperationException("Ariadne_Node_F::neighbor not implemented in the base class.");
}
// Good citizen
//
@Override public String toString(){
- Ariadne_TM_SR_NX_Set<LT> tm = Ariadne_TM_SR_NX_Set.make(neighbor_set);
+
boolean has_label = label() != null;
+
+ Ariadne_TM_SR_NX_F<LT> tm = neighbor();
boolean has_neighbor = tm.can_read();
if( !has_label && !has_neighbor ){
--- /dev/null
+/*
+A node with a finite fixed set of neighbors.
+
+
+*/
+
+package com.ReasoningTechnology.Ariadne;
+
+import java.util.HashSet;
+import java.util.Arrays;
+
+// LT == Label Type
+public class Ariadne_Node_Set<LT extends Ariadne_Label> extends Ariadne_Node_FD<LT>{
+
+ // Owned by the class
+ //
+
+ @SafeVarargs
+ public static <T extends Ariadne_Label> Ariadne_Node_Set<T> make(T label ,T... neighbors){
+ return new Ariadne_Node_Set<>(label ,neighbors);
+ }
+
+ // Data owned by the instance
+ //
+
+ private final HashSet<LT> neighbor_set;
+
+ // Constructors
+ //
+
+ @SafeVarargs
+ protected Ariadne_Node_Set(LT label ,LT... neighbors){
+ super( label );
+ this.neighbor_set = new HashSet<>();
+ if( neighbors != null ){
+ this.neighbor_set.addAll(Arrays.asList(neighbors));
+ }
+ }
+
+ // Instance interface
+ //
+
+ @Override public Ariadne_TM_SR_NX_F<LT> neighbor(){
+ // return Ariadne_TM_SR_NX_Set.make(neighbor_set);
+ return Ariadne_TM_SR_NX_Set.<LT>make(neighbor_set);
+ }
+
+ // Good citizen
+ //
+
+
+}
--- /dev/null
+/*
+Depth first traversal of a graph.
+
+Descent ends when reaching a cycle or a leaf node.
+
+*/
+package com.ReasoningTechnology.Ariadne;
+
+import java.util.HashSet;
+import java.util.ArrayList;
+import java.util.List;
+
+
+
+// ,SiblingContext extends Ariadne_TM_SR_NX_Set< HashSet<Label> >
+class TM_SR_NX_Depth
+ <
+ Label extends Ariadne_Label
+ ,Node extends Ariadne_Node_FD<Label>
+ ,Graph extends Ariadne_Graph_FD<Label ,Node>
+ >
+ extends Ariadne_TM_SR_NX_F<Ariadne_Label>
+{
+
+ // ----------------------------------------
+ // static
+ //
+ <
+ Label extends Ariadne_Label
+ ,Node extends Ariadne_Node_FD<Label>
+ ,Graph extends Ariadne_Graph_FD<Label ,Node>
+ >
+ TM_SR_NX_Depth<Label ,Node ,Graph>
+ make(Graph graph){
+ if(graph == null) return null;
+ if(graph.start() == null) return null;
+ TM_SR_NX_Depth depth = new TM_SR_NX_Depth(graph);
+ return depth;
+ }
+
+ // ----------------------------------------
+ // instance data
+ //
+
+ protected Graph graph;
+ protected Ariadne_ContextStack<SiblingContext ,Label> context_stack;
+ protected Ariadne_ContextStac
+ <
+
+ SiblingContext
+
+ > context_stack_tm;
+ protected Label cycle_node_label;
+
+ // ----------------------------------------
+ // constructor
+ //
+
+ protected TM_SR_NX_Depth(Graph graph){
+ graph = graph;
+ context_stack = Ariadne_ContextStack.make();
+ context_stack.push( graph.start() );
+ context_stack_tm = Ariadne_TM_SR_NX_Array.make(context_stack);
+ cycle_node_label = null;
+ extend_down();
+ set_topology(topo_segment);
+ }
+
+ // ----------------------------------------
+ // instance interface implementation
+ //
+
+ public enum BacktrackResult{
+ NO_CONTEXT
+ ,CYCLE
+ ,SUCCESS
+ ,DEPLETED
+ }
+ public BacktrackResult backtrack(){
+ if( isEmpty() ){
+ return BacktrackResult.NO_CONTEXT;
+ }
+
+ do{
+ pop();
+ if( isEmpty() ) return BacktrackResult.DEPLETED;
+ StepResult step_result = top_step();
+ switch( step_result ){
+ case NOT_CANSTEP:
+ continue;
+ case CYCLE:
+ return BacktrackResult.CYCLE;
+ case SUCCESS:
+ return BacktrackResult.SUCCESS;
+ default:
+ throw new UnsupportedOperationException(
+ "Ariadne_ContextStack::backtrack: Unknown result from top_step."
+ );
+ }
+ }while(true);
+ }
+
+ // Typically called after backtracking.
+ // The base node, that the function extends down from, will already be in the path.
+ // Returns true upon finding new read value, false upon finding a cycle.
+ public enum DescendResult{
+ NO_CONTEXT
+ ,LEAF
+ ,CYCLE
+ }
+ public DescendResult descend(){
+ if( isEmpty() ){
+ return DescendResult.NO_CONTEXT;
+ }
+
+ Label node_label = top().read();
+ Node node;
+
+ do{
+ node = graph.node(node_label);
+ if( node == null ){
+ throw new UnsupportedOperationException(
+ "Ariadne_ContextStack::descend: SiblingContext node label not found in the graph."
+ );
+ }
+
+ @SuppressWarnings("unchecked")
+ SiblingContext s = (SiblingContext)node.neighbor(); // this is a downward extension
+ PushResult result = push(s);
+ switch( result ){
+ case CYCLE:
+ return DescendResult.CYCLE;
+ case NO_CONTEXT:
+ return DescendResult.LEAF;
+ case SUCCESS:
+ node_label = s.read();
+ break; // from the switch statement
+ default:
+ throw new UnsupportedOperationException("Ariadne_ContextStack::descend result from push not known to descend.");
+ }
+ }while(true);
+ }
+
+
+ // being a good object citizen
+ //
+ 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 = null;
+ }
+ @Override public Topology topology(){ return Topology.SEGMENT; }
+ }
+ protected final TopoIface<RT> topo_segment = new SegmentTopo();
+
+ 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; }
+ }
+ protected final TopoIface<RT> topo_rightmost = new RightmostTopo();
+
+}
import java.util.Set;
import java.util.Iterator;
-public class Ariadne_TM_SR_NX_Set<RT> extends Ariadne_TM_SR_NX<RT>{
+public class Ariadne_TM_SR_NX_Set<RT> extends Ariadne_TM_SR_NX_F<RT>{
// Static methods
public static <RT> Ariadne_TM_SR_NX_Set<RT> make(Set<RT> set){