From: Thomas Walker Lynch
Date: Tue, 5 Nov 2024 15:19:13 +0000 (+0000)
Subject: adds tests for the utility classes, cleans up docs
X-Git-Url: https://git.reasoningtechnology.com/style/static/git-logo.png?a=commitdiff_plain;h=0d147f43f2c3f2d4a7917d8306453e0b8bb3cbcf;p=Ariadne
adds tests for the utility classes, cleans up docs
---
diff --git a/developer/document/GraphDirectedAcyclic.txt b/developer/document/GraphDirectedAcyclic.txt
new file mode 100644
index 0000000..3da0b12
--- /dev/null
+++ b/developer/document/GraphDirectedAcyclic.txt
@@ -0,0 +1,77 @@
+Comment that was on the cycle detector code. Was useful for defining
+the problem and limitations when defining the code. Might turn
+into a list of constraints the user needs to adhere for the algorithm
+to be guaranteed to function per spec. Has potential
+to be turned into a proof of the algorithm. Begins by laying
+out the assumptions the code is working under.
+
+
+/*
+Our build tool graph is directed from targets to dependencies.
+
+It must be cycle free. This class extends `Graph` by marking
+cycles that are found when descending from root nodes. Then
+`lookup` will not return these nodes.
+
+If:
+
+ 1. The production functions produce the same output given the
+ same input. (Which is a given for the map definition portion of
+ the graph).
+
+ 2. There are a finite number of states.
+
+ 3. Any input values that are used in the definition of the graph are not
+ changed after some point in time when the graph is said to have been 'defined'.
+
+ 4. No computed values are used for changing the graph definition.
+
+ 5. No computed values direct graph traversal.
+
+Then:
+
+ We can write an algorithm that in turn starts at each node
+ in the graph and searches for cycles, and will find all
+ cycles.
+
+ Our GraphDirectedAcyclic constructor would then not need
+ to know the root nodes of the traversal.
+
+However:
+
+ Had the graph definition been limited to the map object, and there is no
+ interaction with the build functions, we would meet the criteria.
+
+ However, our bestowed upon the user the ability to define 'production'
+ functions, which are used to build the graph dynamically at run time.
+
+ With such production functions is possible that a a graph definition would
+ emerge after a finite number of calls to the build function, and thus we still
+ meet the above criteria, and do not need to give a root node list to the
+ GraphDirectedAcyclic.
+
+ When a graph is to be used with the build tool, it is required that the graph
+ meet the criteria above ** when starting from the root nodes **. However, it
+ is not generally required. Hence, we provide the root nodes to this function.
+
+ It is possible that the user defines one or more production functions,
+ intentionally nor not, that results in building an unbounded graph definition.
+ Further it is possible for a user to define a production that has an unbounded
+ nature that results in the cycle marking method of this class from never
+ finishing.
+
+ As examples, suppose that the a production follows the digits of pi, giving
+ a different node definition each time it is fed a label to recognize. Or
+ suppose that a production returns an ever longer node label each time it
+ is called. Such a production would cause the graph definition to be open,
+ and potentially for this cycle detection algorithm to never complete.
+
+ A production for a conventional build environment will not do these things,
+ However, a buggy production for build environment, or an unconventional
+ build environment not imagined at this time, could.
+
+ A breadth first search combined programmed as a generator would be able
+ to handle such cases without hanging. Where as this algorithm plunges
+ down depth first, and returns when it has the answer.
+
+*/
diff --git a/developer/document/dependency_graph.html b/developer/document/dependency_graph.html
index 378c52d..a728d42 100644
--- a/developer/document/dependency_graph.html
+++ b/developer/document/dependency_graph.html
@@ -1,137 +1,151 @@
- Dependency Build Algorithm
+ Class and mature functions reference
+
- Cycle Detection in Dependency Graph
- Overview
-
- The is_acyclic_q function is designed to detect cycles in a dependency graph using a depth-first search (DFS) algorithm. It starts from a list of root node labels and traverses the graph to ensure that there are no cycles. If a cycle is detected, the function marks the nodes involved and continues to explore other parts of the graph.
-
- Key Concepts
-
- - Dependency Graph: A graph where nodes represent build targets and edges represent dependencies between these targets.
- - Depth-First Search (DFS): An algorithm for traversing or searching tree or graph data structures. It starts at the root and explores as far as possible along each branch before backtracking.
- - Cycle Detection: The process of identifying cycles (loops) in a graph, where a cycle is a path that starts and ends at the same node.
-
- Functions
- 1. is_acyclic_q
-
- Purpose: To determine if the dependency graph is acyclic (i.e., contains no cycles).
-
-
- Parameters:
-
- root_node_labels: A list of labels for the root nodes to start the cycle search.
- verbose: A boolean flag for enabling detailed output (default is true).
-
-
-
- Returns:
-
- 'acyclic' if no cycles are found.
- 'cycle_found' if cycles are detected.
-
-
-
- Process:
-
- - Initializes a stack for DFS traversal.
- - Iteratively calls the
is_acyclic_q_descend function to traverse the graph and detect cycles.
- - Updates the traversal state and continues exploring other paths until the stack is empty.
-
-
- 2. is_acyclic_q_descend
-
- Purpose: To perform the actual DFS traversal and cycle detection for a given path.
-
-
- Parameters:
-
- path_stack: A stack representing the current path in the graph.
- verbose: A boolean flag for enabling detailed output (default is true).
-
-
-
- Returns:
-
- 'leaf_node' if the current node has no children.
- 'cycle_found' if a cycle is detected.
-
-
-
- Process:
-
- - Collects the current path and node.
- - Checks for cycles by comparing the current node with nodes in the path.
- - Marks nodes involved in cycles and updates the stack to continue traversal.
-
-
- Usage
-
- The is_acyclic_q function is used to ensure that the dependency graph defined in the build file is free of cycles. This is crucial for preventing infinite loops and ensuring that the build process can proceed smoothly.
-
+
-
-
+ A very rough first draft of a reference to the classes.
+
+
Cycle Detection on a Dependency Graph
+
Overview
-
2. Run Build Scripts
-
- - Traverse the queue starting from the tail (the most recently added nodes).
- - For each node, attempt to build it by checking the file dates of the target node and its dependencies:
-
- - If the target file is older than any dependency, execute the nodeâs build function.
- - After building, recheck the file dates. If the file date has been updated, mark the node as successfully built.
- - If the build fails or the file date is not updated, mark the node with an error in its property list.
-
-
- - Nodes with dependencies marked with errors will not be built, and errors will propagate up the dependency tree.
-
+
A Dependency Graph: Is a directed acyclic graph
+ where non-leaf nodes are build targets, which are either symbolic, or
+ correspond to files in the file system. Leave nodes correspond to files
+ in the file system, and the only edge property is 'dependency'.
-
3. Final Reporting and Status
-
- - If the root node is successfully built, report the success and any other successfully built nodes.
- - If an error has propagated to the root, report the failure.
- - Keep a list of all successfully built nodes and provide a final summary of the build status.
-
+
Functions
-
4. Node Definitions
-
Each node in the dependency graph is defined by a property dictionary. A node is either a symbol or a path:
-
- - Symbol Nodes: These represent abstract concepts or commands and always trigger a build unless marked with an error.
- - Path Nodes: These represent file paths. A path node is considered built if its target file is newer than its dependencies.
-
-
Both node types are identified by a label, and their dependencies are stored as a list of node labels. The presence of an error property indicates that the node has failed to build or encountered a problem during processing.
+
1. is_acyclic_q
+
+ Purpose: To determine if the dependency graph is acyclovir.
+
+
+ Parameters:
+
+ root_node_labels: A list of labels for the root nodes to start the cycle search.
+ verbose: A boolean flag for enabling detailed output (default is true).
+
+
+
+ Returns:
+
+ 'acyclic' if no cycles are found.
+ 'cycle_found' if cycles are detected.
+
+
+
+ Process:
+
+ - Initializes a stack for DFS traversal.
+ - Iteratively calls the
is_acyclic_q_descend function to traverse the graph and detect cycles.
+ - Updates the traversal state and continues exploring other paths until the stack is empty.
+
+
+
2. is_acyclic_q_descend
+
+ Purpose: To perform the actual DFS traversal and cycle detection for a given path.
+
+
+ Parameters:
+
+ path_stack: A stack representing the current path in the graph.
+ verbose: A boolean flag for enabling detailed output (default is true).
+
+
+
+ Returns:
+
+ 'leaf_node' if the current node has no children.
+ 'cycle_found' if a cycle is detected.
+
+
+
+ Process:
+
+ - Collects the current path and node.
+ - Checks for cycles by comparing the current node with nodes in the path.
+ - Marks nodes involved in cycles and updates the stack to continue traversal.
+
+
+
Usage
+
+ The is_acyclic_q function is used to ensure that the dependency graph defined in the build file is free of cycles. This is crucial for preventing infinite loops and ensuring that the build process can proceed smoothly.
+
+