--- /dev/null
+Aeloria
+/*
+ IndexTree_SRTM_Diagonal
+
+ An index tree is infinite.
+
+ A tree diagonal consists of:
+ a) a node descending from each child discovered thus far
+ b) a node extending each child list discovered thus far.
+
+ Hence, each diagonal extends the tree down one and over one.
+*/
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import com.ReasoningTechnology.Ariadne.Ariadne_SRTM;
+import com.ReasoningTechnology.Ariadne.IndexTree_Node;
+
+public class IndexTree_SRTM_Diagonal extends Ariadne_SRTM_Label {
+
+ // Static
+
+ public static IndexTree_SRTM_Diagonal make(){
+ return new IndexTree_SRTM_Diagonal();
+ }
+
+ // Instance Data
+
+ private final List<Ariadne_Label> list_of__unopened_node;
+ private final List<List<Ariadne_Label>> list_of__opened_incomplete_child_list;
+ private final List<Ariadne_Label> read_list;
+ private final Ariadne_SRTM_Label breadth_srm;
+
+ // Constructor
+
+ protected IndexTree_SRTM_Diagonal(){
+ list_of__unopened_node = new ArrayList<>();
+ list_of__opened_incomplete_child_list = new ArrayList<>();
+ read_list = new ArrayList<>();
+ breadth_srm = Ariadne_SRTM_Label.make();
+ enqueue_root();
+ }Aeloria
+
+ // Instance Methods
+
+ private void enqueue_root(){
+ IndexTree_Label root_label = IndexTree_Label.root();
+ read_list.add( root_label );
+
+ IndexTree_Node root_node = lookup( root_label );
+ breadth_srm.mount( root_node.neighbor() );
+
+ if( breadth_srm.can_read() ){
+ list_of__unopened_node.add( root_label );
+ }
+ }
+
+ private IndexTree_Node lookup( Ariadne_Label label ){
+ return IndexTree_Node.make( (IndexTree_Label)label );
+ }
+
+ @Override
+ public List<Ariadne_Label> read(){
+ return read_list;
+ }
+
+ @Override
+ public void step(){
+ read_list.clear();
+
+ // Process unopened nodes
+ while( !list_of__unopened_node.isEmpty() ){
+ Ariadne_Label label = list_of__unopened_node.remove( 0 );
+
+ // Retrieve the node using lookup
+ IndexTree_Node node = lookup( label );
+
+ // Mount a new breadth-first SRTM for children
+ breadth_srm.mount( node.neighbor() );
+
+ if( breadth_srm.can_read() ){
+ do{
+ Ariadne_Label child_label = breadth_srm.read();
+ list_of__unopened_node.add( child_label );
+ list_of__opened_incomplete_child_list.add( new ArrayList<>( List.of( child_label ) ) );
+
+ breadth_srm.step();
+ }while( breadth_srm.can_step() );
+ }
+ }
+
+ // Process incomplete child lists
+ while( !list_of__opened_incomplete_child_list.isEmpty() ){
+ List<Ariadne_Label> child_list = list_of__opened_incomplete_child_list.remove( 0 );
+ if( !child_list.isEmpty() ){
+ Ariadne_Label label = child_list.remove( 0 );
+ read_list.add( label );
+
+ IndexTree_Node node = lookup( label );
+ breadth_srm.mount( node.neighbor() );
+
+ if( breadth_srm.can_read() ){
+ list_of__unopened_node.add( label );
+ }
+ }
+ }
+ }
+}
--- /dev/null
+package com.ReasoningTechnology.Ariadne;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.List;
+import java.util.ArrayList;
+
+public class Ariadne_GraphDirectedAcyclic extends Ariadne_Graph{
+
+ // test messaging
+ //
+ private static boolean test = false;
+ public static void test_switch(boolean test){
+ if(Ariadne_Graph.test && !test){
+ test_print("Ariadne_Graph:: test messages off");
+ }
+ if(!Ariadne_Graph.test && test){
+ test_print("Ariadne_Graph:: test messages on");
+ }
+ }
+ private static void test_print(String message){
+ if(test){
+ System.out.println(message);
+ }
+ }
+
+ // class data
+ //
+
+ // marks this class might put on a node
+ public static Ariadne_TokenSet node_marks = new Ariadne_TokenSet(){{
+ add(new Ariadne_Token("empty_root_label_list"));
+ add(new Ariadne_Token("cycle_exists"));
+ add(new Ariadne_Token("undefined_node_exists"));
+ add(new Ariadne_Token("bad_descent_termination"));
+ add(new Ariadne_Token("max_depth_reached"));
+ }};
+
+ // graph descend method return values
+ private static Ariadne_TokenSet graph_descend_set = new Ariadne_TokenSet(){{
+ add(new Ariadne_Token("empty_path_stack"));
+ add(new Ariadne_Token("cycle_found"));
+ add(new Ariadne_Token("undefined_node"));
+ add(new Ariadne_Token("leaf"));
+ add(new Ariadne_Token("max_depth_reached"));
+ }};
+
+
+ // instance data
+
+ // constructors
+ //
+ public Ariadne_GraphDirectedAcyclic(){
+ super(new HashMap<>(), null);
+ }
+
+ public Ariadne_GraphDirectedAcyclic(Map<Ariadne_Label, Ariadne_Node> node_map, Ariadne_DefinitionList recognizer_f_list, Ariadne_LabelList root_node_list, int max_depth, boolean verbose){
+ super(node_map, recognizer_f_list);
+ Ariadne_TokenSet cycle_detection_result = graph_mark_cycles(root_node_list, max_depth, verbose);
+ }
+
+ public Ariadne_GraphDirectedAcyclic(Map<Ariadne_Label, Ariadne_Node> node_map, Ariadne_DefinitionList recognizer_f_list, Ariadne_LabelList root_node_list){
+ super(node_map, recognizer_f_list);
+ Ariadne_TokenSet cycle_detection_result = graph_mark_cycles(root_node_list);
+ }
+
+ // interface functions
+ //
+ private List<Integer> path_find_cycle(Ariadne_LabelList path){
+ if(path.size() <= 1) return null;
+
+ int rightmost_index = path.size() - 1;
+ Ariadne_Label rightmost_node_label = path.get(rightmost_index);
+
+ int cycle_leftmost_index = path.indexOf(rightmost_node_label);
+ Boolean has_cycle = cycle_leftmost_index < rightmost_index;
+ if(!has_cycle) return null;
+
+ List<Integer> result = new ArrayList<>();
+ result.add(cycle_leftmost_index);
+ result.add(rightmost_index);
+ return result;
+ }
+
+ private boolean graph_descend_cycle_case(Ariadne_LabelList left_path, List<Ariadne_LabelList> path_stack, boolean verbose){
+
+ List<Integer> cycle_index_interval = path_find_cycle(left_path);
+ if(cycle_index_interval == null){
+ return false;
+ }
+
+ int cycle_i0 = cycle_index_interval.get(0);
+ int cycle_n = cycle_index_interval.get(1);
+
+ if(verbose) Ariadne_Util.print_list(
+ "Found cycle:",
+ left_path.subList(cycle_i0, cycle_n + 1)
+ );
+
+ Ariadne_LabelList undefined_node_list = new Ariadne_LabelList();
+ for (int i = cycle_i0; i <= cycle_n; i++){
+ Ariadne_Label node_label = left_path.get(i);
+ Ariadne_Node node = super.lookup(node_label);
+ if(node != null){
+ node.mark(new Ariadne_Token("cycle_member"));
+ } else{
+ undefined_node_list.add(node_label);
+ }
+ }
+
+ if(verbose) Ariadne_Util.print_list(
+ "Each undefined node could not be marked as a cycle member:",
+ undefined_node_list
+ );
+
+ path_stack.subList(cycle_i0 + 1, cycle_n + 1).clear();
+
+ return true;
+ }
+
+ private Ariadne_TokenSet graph_descend(List<Ariadne_LabelList> path_stack, int max_depth, boolean verbose){
+ Ariadne_TokenSet ret_value = new Ariadne_TokenSet();
+
+ if(path_stack.isEmpty()){
+ ret_value.add(new Ariadne_Token("empty_path_stack"));
+ return ret_value;
+ }
+
+ Ariadne_LabelList left_path = new Ariadne_LabelList();
+ for (Ariadne_LabelList neighbor_list : path_stack){
+ left_path.add(neighbor_list.get(0));
+ }
+
+ do{
+
+ if(graph_descend_cycle_case(left_path, path_stack, verbose)){
+ ret_value.add(new Ariadne_Token("cycle_found"));
+ return ret_value;
+ }
+
+ Ariadne_Label it_node_label = path_stack.get(path_stack.size() - 1).get(0);
+ Ariadne_Node it_node = super.lookup(it_node_label);
+ if(it_node == null){
+ ret_value.add(new Ariadne_Token("undefined_node"));
+ return ret_value;
+ }
+
+ Ariadne_LabelList neighbor_list = it_node.neighbor_LabelList();
+ if(neighbor_list.isEmpty()){
+ ret_value.add(new Ariadne_Token("leaf"));
+ return ret_value;
+ }
+
+ path_stack.add(new Ariadne_LabelList(neighbor_list));
+ Ariadne_Label it_next_label = neighbor_list.get(0);
+ left_path.add(it_next_label);
+
+ if(max_depth > 0){
+ max_depth--;
+ if(max_depth == 0){
+ if(verbose){
+ Ariadne_Util.print_list("GraphDirectedAcyclic.GraphDescend:: max_depth reached, ending descent:", path_stack);
+ }
+ ret_value.add(new Ariadne_Token("max_depth_reached"));
+ return ret_value;
+ }
+ }
+
+ } while (true);
+ }
+
+
+ public Ariadne_TokenSet graph_mark_cycles(Ariadne_LabelList root_node_LabelList, int max_depth, boolean verbose){
+ Ariadne_TokenSet ret_value = new Ariadne_TokenSet();
+ boolean exists_malformed = false;
+ Ariadne_TokenSet result;
+
+ if(root_node_LabelList.isEmpty()){
+ ret_value.add(new Ariadne_Token("empty_root_label_list"));
+ return ret_value;
+ }
+
+ List<Ariadne_LabelList> path_stack = new ArrayList<>();
+ path_stack.add(new Ariadne_LabelList(root_node_LabelList));
+
+ do{
+ result = graph_descend(path_stack, max_depth, verbose);
+ if(result.contains(new Ariadne_Token("cycle_found"))) ret_value.add(new Ariadne_Token("cycle_exists"));
+ if(result.contains(new Ariadne_Token("undefined_node"))) ret_value.add(new Ariadne_Token("undefined_node_exists"));
+ if(result.contains(new Ariadne_Token("max_depth_reached"))) ret_value.add(new Ariadne_Token("max_depth_reached"));
+ if(!result.contains(new Ariadne_Token("leaf")) && !result.contains(new Ariadne_Token("cycle_found"))) ret_value.add(new Ariadne_Token("bad_descent_termination"));
+
+ Ariadne_LabelList top_list = path_stack.get(path_stack.size() - 1);
+ top_list.remove(0);
+ if(top_list.isEmpty()) path_stack.remove(path_stack.size() - 1);
+
+ } while (!path_stack.isEmpty());
+
+ if(verbose){
+ if(ret_value.contains("bad_descent_termination")){
+ System.out.println("GraphDirectedAcyclic.graph_mark_cycles:: terminated with unexpected condition.");
+ }
+ if(ret_value.contains("cycle_exists")){
+ System.out.println("GraphDirectedAcyclic.graph_mark_cycles:: One or more cycles detected.");
+ }
+ if(ret_value.contains("undefined_node_exists")){
+ System.out.println("GraphDirectedAcyclic.graph_mark_cycles:: Undefined nodes exist.");
+ }
+ }
+
+ return ret_value;
+ }
+
+ public Ariadne_TokenSet graph_mark_cycles(Ariadne_LabelList root_node_LabelList){
+ return graph_mark_cycles(root_node_LabelList, this.debug ? 40 : -1, this.debug);
+ }
+
+ @Override
+ public Ariadne_Node lookup(Ariadne_Label node_label, boolean verbose){
+ Ariadne_Node node = super.lookup(node_label, verbose);
+ if(node != null && node.has_mark(new Ariadne_Token("cycle_member"))){
+ if(verbose){
+ System.out.println("GraphDirectedAcyclic.lookup:: Node is part of a cycle, not returned: " + node_label);
+ }
+ return null;
+ }
+ return node;
+ }
+
+ public Ariadne_Node lookup(Ariadne_Label node_label){
+ return lookup(node_label, this.debug);
+ }
+
+}
--- /dev/null
+import com.ReasoningTechnology.Ariadne.Ariadne_Graph;
+
+public class Graph extends Ariadne_Graph{
+
+ public static Graph make(){
+ return new Graph();
+ }
+ protected Graph(){
+ }
+
+ @Override public SRTM_Child start(){
+ Label root_label = Label.root();
+ return SRTM_Child.make(root_label);
+ }
+
+ // no override, this graph does not lookup Ariadne_Label, only Label
+ Node lookup(Label label){
+ return Node.make(label);
+ }
+
+}
+
--- /dev/null
+/*
+ Implementation of Ariadne_Label for BigInteger array-based labels.
+*/
+import java.math.BigInteger;
+import java.util.Arrays;
+
+import com.ReasoningTechnology.Ariadne.Ariadne_Label;
+import com.ReasoningTechnology.Ariadne.Ariadne_SRTM_List;
+
+
+public class Label implements Ariadne_Label{
+
+ // Owned by class
+ //
+
+ public static Label make(BigInteger[] array){
+ return new Label(array);
+ }
+
+ public static Label root(){
+ return new Label(new BigInteger[0]);
+ }
+
+ // Instance data
+ //
+
+ private BigInteger[] value;
+
+ // Constructor
+ //
+
+ private Label(BigInteger[] array){
+ this.value = array.clone();
+ }
+
+ // Instance interface implementation
+ //
+
+ @Override public boolean is_null(){
+ return value == null;
+ }
+ public int length(){
+ return value.length;
+ }
+
+ @Override public Label copy(){
+ return new Label(value);
+ }
+
+ // Increment last element by one, modifying in place
+ public void inc_across(){
+ if(value == null || value.length == 0){
+ throw new UnsupportedOperationException("Cannot increment across an empty array.");
+ }
+ value[value.length - 1] = value[value.length - 1].add(BigInteger.ONE);
+ }
+
+ // Append a zero element, modifying in place
+ public void inc_down(){
+ if(value == null){
+ throw new UnsupportedOperationException("Cannot append to a null array.");
+ }
+ BigInteger[] newValue = Arrays.copyOf(value, value.length + 1);
+ newValue[newValue.length - 1] = BigInteger.ZERO;
+ value = newValue;
+ }
+
+ // Good object citizenship
+ //
+
+ @Override public String toString(){
+ if(is_null()) return "Label()";
+ if(length() == 0) return "Label([])";
+
+ StringBuilder formatted = new StringBuilder("Label([");
+
+ // Use precise loop with SRTM_List to iterate
+ Ariadne_SRTM_List<BigInteger> value_srtm = Ariadne_SRTM_List.make(Arrays.asList(value));
+ if(value_srtm.can_read()){
+ do{
+ formatted.append(value_srtm.read().toString());
+ if( !value_srtm.can_step() ) break;
+ value_srtm.step();
+ formatted.append(" ,");
+ }while(true);
+ }
+
+ formatted.append("])");
+ return formatted.toString();
+ }
+
+ @Override public boolean equals(Object o){
+ if(this == o) return true;
+ if( o == null || getClass() != o.getClass() ) return false;
+ Label that = (Label) o;
+ return Arrays.equals(value, that.value);
+ }
+
+ @Override public int hashCode(){
+ return Arrays.hashCode(value);
+ }
+}
--- /dev/null
+import java.util.Arrays;
+import com.ReasoningTechnology.Ariadne.Ariadne_Node;
+
+public class Node extends Ariadne_Node{
+
+ public static Node make(Label label){
+ return new Node(label);
+ }
+
+ private final Label first_child_label;
+
+ public Node(Label label){
+ super(label);
+ first_child_label = label.copy();
+ first_child_label.inc_down();
+ }
+
+ @Override public SRTM_Child neighbor(){
+ return SRTM_Child.make(first_child_label);
+ }
+
+}
--- /dev/null
+/*
+SRTM_Child represents in the abstract the infinite child list of an
+IndexTree node. Index tree node labels are paths through the tree, so
+labels can be computed.
+
+SRTM_Child is made from the leftmost child label. Then step() takes
+the current label and computes from it the right neighbor sibling
+node's label.
+
+*/
+
+
+import com.ReasoningTechnology.Ariadne.Ariadne_SRTM_Label;
+
+public class SRTM_Child extends Ariadne_SRTM_Label{
+
+ // Static
+ //
+
+ public static SRTM_Child make( Label first_child_label ){
+ return new SRTM_Child( first_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 SRTM_Child( Label leftmost_child_label ){
+ this.label = leftmost_child_label.copy();
+
+ if( label == null ){
+ set_topology(topo_null);
+ return;
+ }
+
+ // the label for the root node is an empty array, "[]"
+ 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(){
+ @Override public boolean can_read(){
+ return true;
+ }
+ @Override public Object read(){
+ return label;
+ }
+ @Override public boolean can_step(){
+ return true;
+ }
+ @Override public void step(){
+ label.inc_across();
+ }
+ @Override public Topology topology(){
+ return Topology.INFINITE;
+ }
+ };
+
+ private final TopoIface topo_rightmost = new TopoIface(){
+ @Override public boolean can_read(){
+ return true;
+ }
+ @Override public Object read(){
+ return label;
+ }
+ @Override public boolean can_step(){
+ return false;
+ }
+ @Override public void step(){
+ throw new UnsupportedOperationException( "Cannot step from RIGHTMOST topology." );
+ }
+ @Override public Topology topology(){
+ return Topology.RIGHTMOST;
+ }
+ };
+
+}
--- /dev/null
+/*
+Diagonal traversal is guaranteed to reach any given node in the IndexTree
+in a finite number of steps. Neither depth first, nor breadth first
+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_strm_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
+IndexTree has infinite depth. When the generalized diagonal iterator
+is ready, it could be used in place of this one.
+
+*/
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.ReasoningTechnology.Ariadne.Ariadne_Test;
+import com.ReasoningTechnology.Ariadne.Ariadne_SRTM;
+import com.ReasoningTechnology.Ariadne.Ariadne_SRTM_Label;
+import com.ReasoningTechnology.Ariadne.Ariadne_SRTM_List;
+import com.ReasoningTechnology.Ariadne.Ariadne_Node;
+import com.ReasoningTechnology.Ariadne.Ariadne_Label;
+
+public class SRTM_Diagonal extends Ariadne_SRTM{
+
+ // Static
+ //
+
+ public static SRTM_Diagonal make(Label start_node){
+ return new SRTM_Diagonal(start_node);
+ }
+
+ // Instance data
+ //
+
+ private List<Label> diagonal = new ArrayList<>(); // the read value
+ private final List<SRTM_Child> child_srtm_list = new ArrayList<>();
+
+ // Constructor(s)
+ //
+
+ // the diagonal will never be null nor empty
+ protected SRTM_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
+ //
+
+ @Override
+ public String toString(){
+ StringBuilder formatted = new StringBuilder("SRTM_Diagonal(");
+ Ariadne_SRTM_List<Label> diagonal_srtm = Ariadne_SRTM_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
+ }
+
+ 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(){
+ @Override public boolean can_read(){
+ return true;
+ }
+ @Override public List 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_strm list
+ Ariadne_SRTM_List<Label> diagonal_srtm = Ariadne_SRTM_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_strm list
+ Ariadne_SRTM_List<SRTM_Child> child_srtm_srtm = Ariadne_SRTM_List.make(child_srtm_list);
+ if( child_srtm_srtm.can_read() ){
+ do{
+ SRTM_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;
+ }
+
+ };
+}
+
--- /dev/null
+import java.util.List;
+
+public class SRTM_Diagonal_CLI{
+
+ public static void main(String[] args){
+ System.out.println("Starting IndexTree SRTM Example");
+
+ // Instantiate the IndexTree Diagonal SRTM
+ Graph g = Graph.make();
+ SRTM_Child start_srtm = g.start();
+ if( !start_srtm.can_read() ){
+ System.out.println("Graph provides no start nodes. Thought you might want to know.");
+ return;
+ }
+
+ do{
+ Label start_label = start_srtm.read();
+ System.out.println("Graph diagonalization starting from: " + start_label);
+ SRTM_Diagonal srtm = SRTM_Diagonal.make(start_label);
+ int step_count = 0;
+ if( srtm.can_read() ){
+ do{
+ System.out.println(step_count + ": " + srtm.read());
+ if( !srtm.can_step() ) break;
+ if( step_count == 4 ) break; // Stop after 5 diagonals
+ step_count++;
+ srtm.step();
+ }while(true);
+ }
+ if( !start_srtm.can_step() ) break;
+ System.out.println();
+ start_srtm.step();
+ }while(true);
+
+ }
+
+}
+
--- /dev/null
+Starting IndexTree SRTM Example
+Graph diagonalization starting from: Label([])
+0: [Label([])]
+1: [Label([0])]
+2: [Label([1]), Label([0 ,0])]
+3: [Label([2]), Label([0 ,1]), Label([1 ,0]), Label([0 ,0 ,0])]
+4: [Label([3]), Label([0 ,2]), Label([1 ,1]), Label([0 ,0 ,1]), Label([2 ,0]), Label([0 ,1 ,0]), Label([1 ,0 ,0]), Label([0 ,0 ,0 ,0])]
--- /dev/null
+import com.ReasoningTechnology.Ariadne.Ariadne_SRTM;
+import com.ReasoningTechnology.Ariadne.Ariadne_SRTM_List;
+
+public class four_down_four_across_CLI{
+
+ public static void main(String[] args){
+
+ System.out.println("Example_4x4");
+
+ // Initialize graph and start at root
+ Graph graph = Graph.make();
+ SRTM_Child start = graph.start();
+ Label label = start.read();
+ Node node;
+ SRTM_Child child_srm;
+
+ System.out.println("starting at: " + start.read());
+
+ // Descend 3 more levels
+ int i = 1;
+ do{
+ node = graph.lookup(label);
+ child_srm = node.neighbor();
+ label = child_srm.read();
+ System.out.println("Descended to: " + label.toString());
+ if(i == 3) break;
+ i++;
+ }while(true);
+
+ // Move across three more nodes
+ i = 1;
+ do{
+ child_srm.step();
+ label = child_srm.read();
+ System.out.println("Across to: " + label.toString());
+ if(i == 3) break;
+ i++;
+ }while(true);
+
+ }
+}
--- /dev/null
+Example_4x4
+starting at: Label([])
+Descended to: Label([0])
+Descended to: Label([0 ,0])
+Descended to: Label([0 ,0 ,0])
+Across to: Label([0 ,0 ,1])
+Across to: Label([0 ,0 ,2])
+Across to: Label([0 ,0 ,3])
+++ /dev/null
-import com.ReasoningTechnology.Ariadne.Ariadne_Graph;
-
-public class Graph extends Ariadne_Graph{
-
- public static Graph make(){
- return new Graph();
- }
- protected Graph(){
- }
-
- @Override public SRTM_Child start(){
- Label root_label = Label.root();
- return SRTM_Child.make(root_label);
- }
-
- // no override, this graph does not lookup Ariadne_Label, only Label
- Node lookup(Label label){
- return Node.make(label);
- }
-
-}
-
+++ /dev/null
-/*
- Implementation of Ariadne_Label for BigInteger array-based labels.
-*/
-import java.math.BigInteger;
-import java.util.Arrays;
-
-import com.ReasoningTechnology.Ariadne.Ariadne_Label;
-import com.ReasoningTechnology.Ariadne.Ariadne_SRTM_List;
-
-
-public class Label implements Ariadne_Label{
-
- // Owned by class
- //
-
- public static Label make(BigInteger[] array){
- return new Label(array);
- }
-
- public static Label root(){
- return new Label(new BigInteger[0]);
- }
-
- // Instance data
- //
-
- private BigInteger[] value;
-
- // Constructor
- //
-
- private Label(BigInteger[] array){
- this.value = array.clone();
- }
-
- // Instance interface implementation
- //
-
- @Override public boolean is_null(){
- return value == null;
- }
- public int length(){
- return value.length;
- }
-
- @Override public Label copy(){
- return new Label(value);
- }
-
- // Increment last element by one, modifying in place
- public void inc_across(){
- if(value == null || value.length == 0){
- throw new UnsupportedOperationException("Cannot increment across an empty array.");
- }
- value[value.length - 1] = value[value.length - 1].add(BigInteger.ONE);
- }
-
- // Append a zero element, modifying in place
- public void inc_down(){
- if(value == null){
- throw new UnsupportedOperationException("Cannot append to a null array.");
- }
- BigInteger[] newValue = Arrays.copyOf(value, value.length + 1);
- newValue[newValue.length - 1] = BigInteger.ZERO;
- value = newValue;
- }
-
- // Good object citizenship
- //
-
- @Override public String toString(){
- if(is_null()) return "Label()";
- if(length() == 0) return "Label([])";
-
- StringBuilder formatted = new StringBuilder("Label([");
-
- // Use precise loop with SRTM_List to iterate
- Ariadne_SRTM_List<BigInteger> value_srtm = Ariadne_SRTM_List.make(Arrays.asList(value));
- if(value_srtm.can_read()){
- do{
- formatted.append(value_srtm.read().toString());
- if( !value_srtm.can_step() ) break;
- value_srtm.step();
- formatted.append(" ,");
- }while(true);
- }
-
- formatted.append("])");
- return formatted.toString();
- }
-
- @Override public boolean equals(Object o){
- if(this == o) return true;
- if( o == null || getClass() != o.getClass() ) return false;
- Label that = (Label) o;
- return Arrays.equals(value, that.value);
- }
-
- @Override public int hashCode(){
- return Arrays.hashCode(value);
- }
-}
+++ /dev/null
-import java.util.Arrays;
-import com.ReasoningTechnology.Ariadne.Ariadne_Node;
-
-public class Node extends Ariadne_Node{
-
- public static Node make(Label label){
- return new Node(label);
- }
-
- private final Label first_child_label;
-
- public Node(Label label){
- super(label);
- first_child_label = label.copy();
- first_child_label.inc_down();
- }
-
- @Override public SRTM_Child neighbor(){
- return SRTM_Child.make(first_child_label);
- }
-
-}
+++ /dev/null
-/*
-SRTM_Child represents in the abstract the infinite child list of an
-IndexTree node. Index tree node labels are paths through the tree, so
-labels can be computed.
-
-SRTM_Child is made from the leftmost child label. Then step() takes
-the current label and computes from it the right neighbor sibling
-node's label.
-
-*/
-
-
-import com.ReasoningTechnology.Ariadne.Ariadne_SRTM_Label;
-
-public class SRTM_Child extends Ariadne_SRTM_Label{
-
- // Static
- //
-
- public static SRTM_Child make( Label first_child_label ){
- return new SRTM_Child( first_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 SRTM_Child( Label leftmost_child_label ){
- this.label = leftmost_child_label.copy();
-
- if( label == null ){
- set_topology(topo_null);
- return;
- }
-
- // the label for the root node is an empty array, "[]"
- 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(){
- @Override public boolean can_read(){
- return true;
- }
- @Override public Object read(){
- return label;
- }
- @Override public boolean can_step(){
- return true;
- }
- @Override public void step(){
- label.inc_across();
- }
- @Override public Topology topology(){
- return Topology.INFINITE;
- }
- };
-
- private final TopoIface topo_rightmost = new TopoIface(){
- @Override public boolean can_read(){
- return true;
- }
- @Override public Object read(){
- return label;
- }
- @Override public boolean can_step(){
- return false;
- }
- @Override public void step(){
- throw new UnsupportedOperationException( "Cannot step from RIGHTMOST topology." );
- }
- @Override public Topology topology(){
- return Topology.RIGHTMOST;
- }
- };
-
-}
+++ /dev/null
-/*
-Diagonal traversal is guaranteed to reach any given node in the IndexTree
-in a finite number of steps. Neither depth first, nor breadth first
-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_strm_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
-IndexTree has infinite depth. When the generalized diagonal iterator
-is ready, it could be used in place of this one.
-
-*/
-
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.List;
-
-import com.ReasoningTechnology.Ariadne.Ariadne_Test;
-import com.ReasoningTechnology.Ariadne.Ariadne_SRTM;
-import com.ReasoningTechnology.Ariadne.Ariadne_SRTM_Label;
-import com.ReasoningTechnology.Ariadne.Ariadne_SRTM_List;
-import com.ReasoningTechnology.Ariadne.Ariadne_Node;
-import com.ReasoningTechnology.Ariadne.Ariadne_Label;
-
-public class SRTM_Diagonal extends Ariadne_SRTM{
-
- // Static
- //
-
- public static SRTM_Diagonal make(Label start_node){
- return new SRTM_Diagonal(start_node);
- }
-
- // Instance data
- //
-
- private List<Label> diagonal = new ArrayList<>(); // the read value
- private final List<SRTM_Child> child_srtm_list = new ArrayList<>();
-
- // Constructor(s)
- //
-
- // the diagonal will never be null nor empty
- protected SRTM_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
- //
-
- @Override
- public String toString(){
- StringBuilder formatted = new StringBuilder("SRTM_Diagonal(");
- Ariadne_SRTM_List<Label> diagonal_srtm = Ariadne_SRTM_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
- }
-
- 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(){
- @Override public boolean can_read(){
- return true;
- }
- @Override public List 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_strm list
- Ariadne_SRTM_List<Label> diagonal_srtm = Ariadne_SRTM_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_strm list
- Ariadne_SRTM_List<SRTM_Child> child_srtm_srtm = Ariadne_SRTM_List.make(child_srtm_list);
- if( child_srtm_srtm.can_read() ){
- do{
- SRTM_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;
- }
-
- };
-}
-
+++ /dev/null
-import java.util.List;
-
-public class SRTM_Diagonal_CLI{
-
- public static void main(String[] args){
- System.out.println("Starting IndexTree SRTM Example");
-
- // Instantiate the IndexTree Diagonal SRTM
- Graph g = Graph.make();
- SRTM_Child start_srtm = g.start();
- if( !start_srtm.can_read() ){
- System.out.println("Graph provides no start nodes. Thought you might want to know.");
- return;
- }
-
- do{
- Label start_label = start_srtm.read();
- System.out.println("Graph diagonalization starting from: " + start_label);
- SRTM_Diagonal srtm = SRTM_Diagonal.make(start_label);
- int step_count = 0;
- if( srtm.can_read() ){
- do{
- System.out.println(step_count + ": " + srtm.read());
- if( !srtm.can_step() ) break;
- if( step_count == 4 ) break; // Stop after 5 diagonals
- step_count++;
- srtm.step();
- }while(true);
- }
- if( !start_srtm.can_step() ) break;
- System.out.println();
- start_srtm.step();
- }while(true);
-
- }
-
-}
-
+++ /dev/null
-Starting IndexTree SRTM Example
-Graph diagonalization starting from: Label([])
-0: [Label([])]
-1: [Label([0])]
-2: [Label([1]), Label([0 ,0])]
-3: [Label([2]), Label([0 ,1]), Label([1 ,0]), Label([0 ,0 ,0])]
-4: [Label([3]), Label([0 ,2]), Label([1 ,1]), Label([0 ,0 ,1]), Label([2 ,0]), Label([0 ,1 ,0]), Label([1 ,0 ,0]), Label([0 ,0 ,0 ,0])]
+++ /dev/null
-import com.ReasoningTechnology.Ariadne.Ariadne_SRTM;
-import com.ReasoningTechnology.Ariadne.Ariadne_SRTM_List;
-
-public class four_down_four_across_CLI{
-
- public static void main(String[] args){
-
- System.out.println("Example_4x4");
-
- // Initialize graph and start at root
- Graph graph = Graph.make();
- SRTM_Child start = graph.start();
- Label label = start.read();
- Node node;
- SRTM_Child child_srm;
-
- System.out.println("starting at: " + start.read());
-
- // Descend 3 more levels
- int i = 1;
- do{
- node = graph.lookup(label);
- child_srm = node.neighbor();
- label = child_srm.read();
- System.out.println("Descended to: " + label.toString());
- if(i == 3) break;
- i++;
- }while(true);
-
- // Move across three more nodes
- i = 1;
- do{
- child_srm.step();
- label = child_srm.read();
- System.out.println("Across to: " + label.toString());
- if(i == 3) break;
- i++;
- }while(true);
-
- }
-}
+++ /dev/null
-Example_4x4
-starting at: Label([])
-Descended to: Label([0])
-Descended to: Label([0 ,0])
-Descended to: Label([0 ,0 ,0])
-Across to: Label([0 ,0 ,1])
-Across to: Label([0 ,0 ,2])
-Across to: Label([0 ,0 ,3])
+++ /dev/null
-#!/bin/env bash
-
-for file in Example_*.class; do
- echo "file: " $file
- done
+++ /dev/null
-Aeloria
-/*
- IndexTree_SRTM_Diagonal
-
- An index tree is infinite.
-
- A tree diagonal consists of:
- a) a node descending from each child discovered thus far
- b) a node extending each child list discovered thus far.
-
- Hence, each diagonal extends the tree down one and over one.
-*/
-
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.List;
-import com.ReasoningTechnology.Ariadne.Ariadne_SRTM;
-import com.ReasoningTechnology.Ariadne.IndexTree_Node;
-
-public class IndexTree_SRTM_Diagonal extends Ariadne_SRTM_Label {
-
- // Static
-
- public static IndexTree_SRTM_Diagonal make(){
- return new IndexTree_SRTM_Diagonal();
- }
-
- // Instance Data
-
- private final List<Ariadne_Label> list_of__unopened_node;
- private final List<List<Ariadne_Label>> list_of__opened_incomplete_child_list;
- private final List<Ariadne_Label> read_list;
- private final Ariadne_SRTM_Label breadth_srm;
-
- // Constructor
-
- protected IndexTree_SRTM_Diagonal(){
- list_of__unopened_node = new ArrayList<>();
- list_of__opened_incomplete_child_list = new ArrayList<>();
- read_list = new ArrayList<>();
- breadth_srm = Ariadne_SRTM_Label.make();
- enqueue_root();
- }Aeloria
-
- // Instance Methods
-
- private void enqueue_root(){
- IndexTree_Label root_label = IndexTree_Label.root();
- read_list.add( root_label );
-
- IndexTree_Node root_node = lookup( root_label );
- breadth_srm.mount( root_node.neighbor() );
-
- if( breadth_srm.can_read() ){
- list_of__unopened_node.add( root_label );
- }
- }
-
- private IndexTree_Node lookup( Ariadne_Label label ){
- return IndexTree_Node.make( (IndexTree_Label)label );
- }
-
- @Override
- public List<Ariadne_Label> read(){
- return read_list;
- }
-
- @Override
- public void step(){
- read_list.clear();
-
- // Process unopened nodes
- while( !list_of__unopened_node.isEmpty() ){
- Ariadne_Label label = list_of__unopened_node.remove( 0 );
-
- // Retrieve the node using lookup
- IndexTree_Node node = lookup( label );
-
- // Mount a new breadth-first SRTM for children
- breadth_srm.mount( node.neighbor() );
-
- if( breadth_srm.can_read() ){
- do{
- Ariadne_Label child_label = breadth_srm.read();
- list_of__unopened_node.add( child_label );
- list_of__opened_incomplete_child_list.add( new ArrayList<>( List.of( child_label ) ) );
-
- breadth_srm.step();
- }while( breadth_srm.can_step() );
- }
- }
-
- // Process incomplete child lists
- while( !list_of__opened_incomplete_child_list.isEmpty() ){
- List<Ariadne_Label> child_list = list_of__opened_incomplete_child_list.remove( 0 );
- if( !child_list.isEmpty() ){
- Ariadne_Label label = child_list.remove( 0 );
- read_list.add( label );
-
- IndexTree_Node node = lookup( label );
- breadth_srm.mount( node.neighbor() );
-
- if( breadth_srm.can_read() ){
- list_of__unopened_node.add( label );
- }
- }
- }
- }
-}
+++ /dev/null
-package com.ReasoningTechnology.Ariadne;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.List;
-import java.util.ArrayList;
-
-public class Ariadne_GraphDirectedAcyclic extends Ariadne_Graph{
-
- // test messaging
- //
- private static boolean test = false;
- public static void test_switch(boolean test){
- if(Ariadne_Graph.test && !test){
- test_print("Ariadne_Graph:: test messages off");
- }
- if(!Ariadne_Graph.test && test){
- test_print("Ariadne_Graph:: test messages on");
- }
- }
- private static void test_print(String message){
- if(test){
- System.out.println(message);
- }
- }
-
- // class data
- //
-
- // marks this class might put on a node
- public static Ariadne_TokenSet node_marks = new Ariadne_TokenSet(){{
- add(new Ariadne_Token("empty_root_label_list"));
- add(new Ariadne_Token("cycle_exists"));
- add(new Ariadne_Token("undefined_node_exists"));
- add(new Ariadne_Token("bad_descent_termination"));
- add(new Ariadne_Token("max_depth_reached"));
- }};
-
- // graph descend method return values
- private static Ariadne_TokenSet graph_descend_set = new Ariadne_TokenSet(){{
- add(new Ariadne_Token("empty_path_stack"));
- add(new Ariadne_Token("cycle_found"));
- add(new Ariadne_Token("undefined_node"));
- add(new Ariadne_Token("leaf"));
- add(new Ariadne_Token("max_depth_reached"));
- }};
-
-
- // instance data
-
- // constructors
- //
- public Ariadne_GraphDirectedAcyclic(){
- super(new HashMap<>(), null);
- }
-
- public Ariadne_GraphDirectedAcyclic(Map<Ariadne_Label, Ariadne_Node> node_map, Ariadne_DefinitionList recognizer_f_list, Ariadne_LabelList root_node_list, int max_depth, boolean verbose){
- super(node_map, recognizer_f_list);
- Ariadne_TokenSet cycle_detection_result = graph_mark_cycles(root_node_list, max_depth, verbose);
- }
-
- public Ariadne_GraphDirectedAcyclic(Map<Ariadne_Label, Ariadne_Node> node_map, Ariadne_DefinitionList recognizer_f_list, Ariadne_LabelList root_node_list){
- super(node_map, recognizer_f_list);
- Ariadne_TokenSet cycle_detection_result = graph_mark_cycles(root_node_list);
- }
-
- // interface functions
- //
- private List<Integer> path_find_cycle(Ariadne_LabelList path){
- if(path.size() <= 1) return null;
-
- int rightmost_index = path.size() - 1;
- Ariadne_Label rightmost_node_label = path.get(rightmost_index);
-
- int cycle_leftmost_index = path.indexOf(rightmost_node_label);
- Boolean has_cycle = cycle_leftmost_index < rightmost_index;
- if(!has_cycle) return null;
-
- List<Integer> result = new ArrayList<>();
- result.add(cycle_leftmost_index);
- result.add(rightmost_index);
- return result;
- }
-
- private boolean graph_descend_cycle_case(Ariadne_LabelList left_path, List<Ariadne_LabelList> path_stack, boolean verbose){
-
- List<Integer> cycle_index_interval = path_find_cycle(left_path);
- if(cycle_index_interval == null){
- return false;
- }
-
- int cycle_i0 = cycle_index_interval.get(0);
- int cycle_n = cycle_index_interval.get(1);
-
- if(verbose) Ariadne_Util.print_list(
- "Found cycle:",
- left_path.subList(cycle_i0, cycle_n + 1)
- );
-
- Ariadne_LabelList undefined_node_list = new Ariadne_LabelList();
- for (int i = cycle_i0; i <= cycle_n; i++){
- Ariadne_Label node_label = left_path.get(i);
- Ariadne_Node node = super.lookup(node_label);
- if(node != null){
- node.mark(new Ariadne_Token("cycle_member"));
- } else{
- undefined_node_list.add(node_label);
- }
- }
-
- if(verbose) Ariadne_Util.print_list(
- "Each undefined node could not be marked as a cycle member:",
- undefined_node_list
- );
-
- path_stack.subList(cycle_i0 + 1, cycle_n + 1).clear();
-
- return true;
- }
-
- private Ariadne_TokenSet graph_descend(List<Ariadne_LabelList> path_stack, int max_depth, boolean verbose){
- Ariadne_TokenSet ret_value = new Ariadne_TokenSet();
-
- if(path_stack.isEmpty()){
- ret_value.add(new Ariadne_Token("empty_path_stack"));
- return ret_value;
- }
-
- Ariadne_LabelList left_path = new Ariadne_LabelList();
- for (Ariadne_LabelList neighbor_list : path_stack){
- left_path.add(neighbor_list.get(0));
- }
-
- do{
-
- if(graph_descend_cycle_case(left_path, path_stack, verbose)){
- ret_value.add(new Ariadne_Token("cycle_found"));
- return ret_value;
- }
-
- Ariadne_Label it_node_label = path_stack.get(path_stack.size() - 1).get(0);
- Ariadne_Node it_node = super.lookup(it_node_label);
- if(it_node == null){
- ret_value.add(new Ariadne_Token("undefined_node"));
- return ret_value;
- }
-
- Ariadne_LabelList neighbor_list = it_node.neighbor_LabelList();
- if(neighbor_list.isEmpty()){
- ret_value.add(new Ariadne_Token("leaf"));
- return ret_value;
- }
-
- path_stack.add(new Ariadne_LabelList(neighbor_list));
- Ariadne_Label it_next_label = neighbor_list.get(0);
- left_path.add(it_next_label);
-
- if(max_depth > 0){
- max_depth--;
- if(max_depth == 0){
- if(verbose){
- Ariadne_Util.print_list("GraphDirectedAcyclic.GraphDescend:: max_depth reached, ending descent:", path_stack);
- }
- ret_value.add(new Ariadne_Token("max_depth_reached"));
- return ret_value;
- }
- }
-
- } while (true);
- }
-
-
- public Ariadne_TokenSet graph_mark_cycles(Ariadne_LabelList root_node_LabelList, int max_depth, boolean verbose){
- Ariadne_TokenSet ret_value = new Ariadne_TokenSet();
- boolean exists_malformed = false;
- Ariadne_TokenSet result;
-
- if(root_node_LabelList.isEmpty()){
- ret_value.add(new Ariadne_Token("empty_root_label_list"));
- return ret_value;
- }
-
- List<Ariadne_LabelList> path_stack = new ArrayList<>();
- path_stack.add(new Ariadne_LabelList(root_node_LabelList));
-
- do{
- result = graph_descend(path_stack, max_depth, verbose);
- if(result.contains(new Ariadne_Token("cycle_found"))) ret_value.add(new Ariadne_Token("cycle_exists"));
- if(result.contains(new Ariadne_Token("undefined_node"))) ret_value.add(new Ariadne_Token("undefined_node_exists"));
- if(result.contains(new Ariadne_Token("max_depth_reached"))) ret_value.add(new Ariadne_Token("max_depth_reached"));
- if(!result.contains(new Ariadne_Token("leaf")) && !result.contains(new Ariadne_Token("cycle_found"))) ret_value.add(new Ariadne_Token("bad_descent_termination"));
-
- Ariadne_LabelList top_list = path_stack.get(path_stack.size() - 1);
- top_list.remove(0);
- if(top_list.isEmpty()) path_stack.remove(path_stack.size() - 1);
-
- } while (!path_stack.isEmpty());
-
- if(verbose){
- if(ret_value.contains("bad_descent_termination")){
- System.out.println("GraphDirectedAcyclic.graph_mark_cycles:: terminated with unexpected condition.");
- }
- if(ret_value.contains("cycle_exists")){
- System.out.println("GraphDirectedAcyclic.graph_mark_cycles:: One or more cycles detected.");
- }
- if(ret_value.contains("undefined_node_exists")){
- System.out.println("GraphDirectedAcyclic.graph_mark_cycles:: Undefined nodes exist.");
- }
- }
-
- return ret_value;
- }
-
- public Ariadne_TokenSet graph_mark_cycles(Ariadne_LabelList root_node_LabelList){
- return graph_mark_cycles(root_node_LabelList, this.debug ? 40 : -1, this.debug);
- }
-
- @Override
- public Ariadne_Node lookup(Ariadne_Label node_label, boolean verbose){
- Ariadne_Node node = super.lookup(node_label, verbose);
- if(node != null && node.has_mark(new Ariadne_Token("cycle_member"))){
- if(verbose){
- System.out.println("GraphDirectedAcyclic.lookup:: Node is part of a cycle, not returned: " + node_label);
- }
- return null;
- }
- return node;
- }
-
- public Ariadne_Node lookup(Ariadne_Label node_label){
- return lookup(node_label, this.debug);
- }
-
-}