pencil updates
authorThomas Walker Lynch <eknp9n@reasoningtechnology.com>
Mon, 9 Dec 2024 11:11:55 +0000 (11:11 +0000)
committerThomas Walker Lynch <eknp9n@reasoningtechnology.com>
Mon, 9 Dec 2024 11:11:55 +0000 (11:11 +0000)
166 files changed:
LICENSE.txt [changed from symlink to file mode: 0644]
README.txt [changed from symlink to file mode: 0644]
developer/bash/.githolder [new file with mode: 0644]
developer/bash/Build [new file with mode: 0755]
developer/deprecated/Ariandne.groovy [deleted file]
developer/deprecated/Ariandne2.groovy [deleted file]
developer/deprecated/Graph.java [deleted file]
developer/deprecated/cycle_case.java [deleted file]
developer/deprecated/dependency_graph_definition.groovy [deleted file]
developer/deprecated/groovyc/#AriadneGraph.groovy# [deleted file]
developer/deprecated/groovyc/AriadneGraph.groovy [deleted file]
developer/deprecated/groovyc/BuildGraph.groovy [deleted file]
developer/document/#question_jan.txt# [deleted file]
developer/document/#variable_suffix_conventions.txt# [deleted file]
developer/document/GraphDirectedAcyclic.txt [deleted file]
developer/document/GraphDirectedAcyclic_1.txt [deleted file]
developer/document/dependency_graph.html [deleted file]
developer/document/nomenclature.txt [deleted file]
developer/document/see_also.txt [deleted file]
developer/documentđź–‰/#question_jan.txt# [new file with mode: 0644]
developer/documentđź–‰/#variable_suffix_conventions.txt# [new file with mode: 0644]
developer/documentđź–‰/GraphDirectedAcyclic.txt [new file with mode: 0644]
developer/documentđź–‰/GraphDirectedAcyclic_1.txt [new file with mode: 0644]
developer/documentđź–‰/build.txt [new file with mode: 0644]
developer/documentđź–‰/dependency_graph.html [new file with mode: 0644]
developer/documentđź–‰/nomenclature.txt [new file with mode: 0644]
developer/javac/Ariadne_File.java [deleted file]
developer/javac/Ariadne_Graph.java [deleted file]
developer/javac/Ariadne_GraphDirectedAcyclic.java [deleted file]
developer/javac/Ariadne_Label.java [deleted file]
developer/javac/Ariadne_LabelList.java [deleted file]
developer/javac/Ariadne_Node.java [deleted file]
developer/javac/Ariadne_NodeList.java [deleted file]
developer/javac/Ariadne_Production.java [deleted file]
developer/javac/Ariadne_ProductionList.java [deleted file]
developer/javac/Ariadne_Token.java [deleted file]
developer/javac/Ariadne_TokenSet.java [deleted file]
developer/javac/Ariadne_Util.java [deleted file]
developer/javac/Build.javax [deleted file]
developer/javac/GraphAriadne.javax [deleted file]
developer/javacđź–‰/Ariadne_File.java [new file with mode: 0644]
developer/javacđź–‰/Ariadne_Graph.java [new file with mode: 0644]
developer/javacđź–‰/Ariadne_GraphDirectedAcyclic.java [new file with mode: 0644]
developer/javacđź–‰/Ariadne_Label.java [new file with mode: 0644]
developer/javacđź–‰/Ariadne_LabelList.java [new file with mode: 0644]
developer/javacđź–‰/Ariadne_Node.java [new file with mode: 0644]
developer/javacđź–‰/Ariadne_NodeList.java [new file with mode: 0644]
developer/javacđź–‰/Ariadne_Production.java [new file with mode: 0644]
developer/javacđź–‰/Ariadne_ProductionList.java [new file with mode: 0644]
developer/javacđź–‰/Ariadne_Token.java [new file with mode: 0644]
developer/javacđź–‰/Ariadne_TokenSet.java [new file with mode: 0644]
developer/javacđź–‰/Ariadne_Util.java [new file with mode: 0644]
developer/javacđź–‰/Build.javax [new file with mode: 0644]
developer/javacđź–‰/GraphAriadne.javax [new file with mode: 0644]
developer/shell/.githolder [deleted file]
developer/shell/Build [deleted file]
developer/tool/clean_build_directories [deleted file]
developer/tool/clean_javac_output [deleted file]
developer/tool/clean_make_output [deleted file]
developer/tool/clean_release [deleted file]
developer/tool/distribute_source [deleted file]
developer/tool/env [deleted file]
developer/tool/make [deleted file]
developer/tool/release [deleted file]
developer/tool/shell_wrapper_list [deleted file]
developer/toolđź–‰/bash_wrapper_list [new file with mode: 0755]
developer/toolđź–‰/clean_build_directories [new file with mode: 0755]
developer/toolđź–‰/clean_javac_output [new file with mode: 0755]
developer/toolđź–‰/clean_make_output [new file with mode: 0755]
developer/toolđź–‰/clean_release [new file with mode: 0755]
developer/toolđź–‰/distribute_source [new file with mode: 0755]
developer/toolđź–‰/env [new file with mode: 0644]
developer/toolđź–‰/make [new file with mode: 0755]
developer/toolđź–‰/release [new file with mode: 0755]
document/Eclipse.txt [deleted file]
document/IntelliJ_IDEA.txt [deleted file]
document/license.txt [deleted file]
document/readme.txt [deleted file]
document/see_also [deleted symlink]
document/todo.txt [deleted file]
documentđź–‰/see_also [new symlink]
documentđź–‰/todo.txt [new file with mode: 0644]
env_administrator [deleted file]
env_administratorđź–‰ [new file with mode: 0644]
env_developer [changed from file to symlink]
env_run [changed from file to symlink]
env_tester [changed from file to symlink]
release/Ariadne.jar
tester/bash/.githolder [new file with mode: 0644]
tester/bash/Test_File_0 [new file with mode: 0755]
tester/bash/Test_Graph_0 [new file with mode: 0755]
tester/bash/Test_LabelList_0 [new file with mode: 0755]
tester/bash/Test_Label_0 [new file with mode: 0755]
tester/bash/Test_NodeList_0 [new file with mode: 0755]
tester/bash/Test_Node_0 [new file with mode: 0755]
tester/bash/Test_TokenSet_0 [new file with mode: 0755]
tester/bash/Test_Token_0 [new file with mode: 0755]
tester/bash/Test_Util_0 [new file with mode: 0755]
tester/bashđź–‰/TF0 [new file with mode: 0755]
tester/documentđź–‰/debug_with_sources.txt [new file with mode: 0644]
tester/javac/.gitignore [deleted file]
tester/javac/Test_File_0.java [deleted file]
tester/javac/Test_Graph_0.java [deleted file]
tester/javac/Test_LabelList_0.java [deleted file]
tester/javac/Test_Label_0.java [deleted file]
tester/javac/Test_NodeList_0.java [deleted file]
tester/javac/Test_Node_0.java [deleted file]
tester/javac/Test_TokenSet_0.java [deleted file]
tester/javac/Test_Token_0.java [deleted file]
tester/javac/Test_Util_0.java [deleted file]
tester/javacđź–‰/.gitignore [new file with mode: 0644]
tester/javacđź–‰/Test_File_0.java [new file with mode: 0644]
tester/javacđź–‰/Test_Graph_0.java [new file with mode: 0644]
tester/javacđź–‰/Test_LabelList_0.java [new file with mode: 0644]
tester/javacđź–‰/Test_Label_0.java [new file with mode: 0644]
tester/javacđź–‰/Test_NodeList_0.java [new file with mode: 0644]
tester/javacđź–‰/Test_Node_0.java [new file with mode: 0644]
tester/javacđź–‰/Test_TokenSet_0.java [new file with mode: 0644]
tester/javacđź–‰/Test_Token_0.java [new file with mode: 0644]
tester/javacđź–‰/Test_Util_0.java [new file with mode: 0644]
tester/javacđź–‰/test_log.txt [new file with mode: 0644]
tester/scratchpad/.gitignore
tester/shell-leaf/TF0 [deleted file]
tester/shell/.githolder [deleted file]
tester/shell/Test_File_0 [deleted file]
tester/shell/Test_Graph_0 [deleted file]
tester/shell/Test_LabelList_0 [deleted file]
tester/shell/Test_Label_0 [deleted file]
tester/shell/Test_NodeList_0 [deleted file]
tester/shell/Test_Node_0 [deleted file]
tester/shell/Test_TokenSet_0 [deleted file]
tester/shell/Test_Token_0 [deleted file]
tester/shell/Test_Util_0 [deleted file]
tester/test_log.txt
tester/tool/#make.sh# [deleted file]
tester/tool/clean_build_directories [deleted file]
tester/tool/env [deleted file]
tester/tool/make [deleted file]
tester/tool/run_jdb [deleted file]
tester/tool/run_tests [deleted file]
tester/tool/shell_wrapper_list [deleted file]
tester/toolđź–‰/bash_wrapper_list [new file with mode: 0755]
tester/toolđź–‰/clean_build_directories [new file with mode: 0755]
tester/toolđź–‰/env [new file with mode: 0644]
tester/toolđź–‰/make [new file with mode: 0755]
tester/toolđź–‰/run_jdb [new file with mode: 0755]
tester/toolđź–‰/run_tests [new file with mode: 0755]
tool/env [deleted file]
tool_shared/bespoke/bashrc [deleted file]
tool_shared/bespoke/cat_w_fn [deleted file]
tool_shared/bespoke/deprecate [deleted file]
tool_shared/bespoke/env [deleted file]
tool_shared/bespoke/githolder [deleted file]
tool_shared/bespoke/test_env [deleted file]
tool_shared/bespoke/version [deleted file]
tool_shared/bespoke/vl [deleted file]
tool_shared/bespoke/wipe_release [deleted file]
tool_shared/bespokeđź–‰/.githolder [new file with mode: 0755]
tool_shared/bespokeđź–‰/env [new file with mode: 0644]
tool_shared/bespokeđź–‰/version [new file with mode: 0755]
tool_shared/document/install.txt [deleted file]
tool_shared/documentđź–‰/Eclipse.txt [new file with mode: 0644]
tool_shared/documentđź–‰/Emacs.txt [new file with mode: 0644]
tool_shared/documentđź–‰/IntelliJ_IDEA.txt [new file with mode: 0644]
tool_shared/documentđź–‰/install.txt [new file with mode: 0644]
toolđź–‰/env [new file with mode: 0644]

deleted file mode 120000 (symlink)
index 98f0753c83742a278a8323fcc608377f5d90445c..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-document/license.txt
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..e177f6f1d54649a288b74a63a8796857f999e649
--- /dev/null
@@ -0,0 +1,152 @@
+Apache License
+Version 2.0, January 2004
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction, and
+distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by the copyright
+owner that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all other entities
+that control, are controlled by, or are under common control with that
+entity. For the purposes of this definition, "control" means (i) the power,
+direct or indirect, to cause the direction or management of such entity, whether
+by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of
+the outstanding shares, or (iii) beneficial ownership of such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity exercising
+permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications, including
+but not limited to software source code, documentation source, and configuration
+files.
+
+"Object" form shall mean any form resulting from mechanical transformation or
+translation of a Source form, including but not limited to compiled object code,
+generated documentation, and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form, made
+available under the License, as indicated by a copyright notice that is included
+in or attached to the work (an example is provided in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form, that
+is based on (or derived from) the Work and for which the editorial revisions,
+annotations, elaborations, or other modifications represent, as a whole, an
+original work of authorship. For the purposes of this License, Derivative Works
+shall not include works that remain separable from, or merely link (or bind by
+name) to the interfaces of, the Work and Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including the original version
+of the Work and any modifications or additions to that Work or Derivative Works
+thereof, that is intentionally submitted to Licensor for inclusion in the Work
+by the copyright owner or by an individual or Legal Entity authorized to submit
+on behalf of the copyright owner. For the purposes of this definition,
+"submitted" means any form of electronic, verbal, or written communication sent
+to the Licensor or its representatives, including but not limited to
+communication on electronic mailing lists, source code control systems, and
+issue tracking systems that are managed by, or on behalf of, the Licensor for
+the purpose of discussing and improving the Work, but excluding communication
+that is conspicuously marked or otherwise designated in writing by the copyright
+owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
+of whom a Contribution has been received by Licensor and subsequently
+incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of this
+License, each Contributor hereby grants to You a perpetual, worldwide,
+non-exclusive, no-charge, royalty-free, irrevocable copyright license to
+reproduce, prepare Derivative Works of, publicly display, publicly perform,
+sublicense, and distribute the Work and such Derivative Works in Source or
+Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of this License,
+each Contributor hereby grants to You a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable (except as stated in this section) patent
+license to make, have made, use, offer to sell, sell, import, and otherwise
+transfer the Work, where such license applies only to those patent claims
+licensable by such Contributor that are necessarily infringed by their
+Contribution(s) alone or by combination of their Contribution(s) with the Work
+to which such Contribution(s) was submitted. If You institute patent litigation
+against any entity (including a cross-claim or counterclaim in a lawsuit)
+alleging that the Work or a Contribution incorporated within the Work
+constitutes direct or contributory patent infringement, then any patent licenses
+granted to You under this License for that Work shall terminate as of the date
+such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the Work or
+Derivative Works thereof in any medium, with or without modifications, and in
+Source or Object form, provided that You meet the following conditions:
+
+You must give any other recipients of the Work or Derivative Works a copy of
+this License; and You must cause any modified files to carry prominent notices
+stating that You changed the files; and You must retain, in the Source form of
+any Derivative Works that You distribute, all copyright, patent, trademark, and
+attribution notices from the Source form of the Work, excluding those notices
+that do not pertain to any part of the Derivative Works; and If the Work
+includes a "NOTICE" text file as part of its distribution, then any Derivative
+Works that You distribute must include a readable copy of the attribution
+notices contained within such NOTICE file, excluding those notices that do not
+pertain to any part of the Derivative Works, in at least one of the following
+places: within a NOTICE text file distributed as part of the Derivative Works;
+within the Source form or documentation, if provided along with the Derivative
+Works; or, within a display generated by the Derivative Works, if and wherever
+such third-party notices normally appear. The contents of the NOTICE file are
+for informational purposes only and do not modify the License. You may add Your
+own attribution notices within Derivative Works that You distribute, alongside
+or as an addendum to the NOTICE text from the Work, provided that such
+additional attribution notices cannot be construed as modifying the License.
+You may add Your own copyright statement to Your modifications and may provide
+additional or different license terms and conditions for use, reproduction, or
+distribution of Your modifications, or for any such Derivative Works as a whole,
+provided Your use, reproduction, and distribution of the Work otherwise complies
+with the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise, any
+Contribution intentionally submitted for inclusion in the Work by You to the
+Licensor shall be under the terms and conditions of this License, without any
+additional terms or conditions. Notwithstanding the above, nothing herein shall
+supersede or modify the terms of any separate license agreement you may have
+executed with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade names,
+trademarks, service marks, or product names of the Licensor, except as required
+for reasonable and customary use in describing the origin of the Work and
+reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or agreed to in
+writing, Licensor provides the Work (and each Contributor provides its
+Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied, including, without limitation, any warranties
+or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+PARTICULAR PURPOSE. You are solely responsible for determining the
+appropriateness of using or redistributing the Work and assume any risks
+associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory, whether in
+tort (including negligence), contract, or otherwise, unless required by
+applicable law (such as deliberate and grossly negligent acts) or agreed to in
+writing, shall any Contributor be liable to You for damages, including any
+direct, indirect, special, incidental, or consequential damages of any character
+arising as a result of this License or out of the use or inability to use the
+Work (including but not limited to damages for loss of goodwill, work stoppage,
+computer failure or malfunction, or any and all other commercial damages or
+losses), even if such Contributor has been advised of the possibility of such
+damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing the Work or
+Derivative Works thereof, You may choose to offer, and charge a fee for,
+acceptance of support, warranty, indemnity, or other liability obligations
+and/or rights consistent with this License. However, in accepting such
+obligations, You may act only on Your own behalf and on Your sole
+responsibility, not on behalf of any other Contributor, and only if You agree to
+indemnify, defend, and hold each Contributor harmless for any liability incurred
+by, or claims asserted against, such Contributor by reason of your accepting any
+such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
deleted file mode 120000 (symlink)
index 06fa5f4ce2e7a9a7ecc18010f44433053a3c6f66..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-document/readme.txt
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..bf5978e7ffeee7e2e20dc0206755060b305df36e
--- /dev/null
@@ -0,0 +1,80 @@
+
+--------------------------------------------------------------------------------
+Ariadne
+
+Ariadne is a graph based build tool.
+
+Tying to build a project is a lot like trying to find your way out of
+Daedalus's impossible to solve maze. Ariadne hands you a ball of string.
+
+--------------------------------------------------------------------------------
+Documents
+
+Note the directories:  Ariadne/document, Ariadne/developer/document, 
+and Ariadne/tester/document.
+
+
+--------------------------------------------------------------------------------
+How It Works
+
+Everything is coded in Java, including the developers description of the
+dependency graph.
+
+A graph is made of nodes and edges.
+
+A node is dictionary. Each node has a 'label', a 'build' function, and a
+'neighbor' list.  The neighbor list holds the edges.
+
+Using Java, the developer puts the nodes in a map, keyed on the node label, or
+writes functions that when given a label, return either a node or null.
+
+A node map looks a lot like classic make file.  Each node label is a target file
+path, the neighbor list can be listed next, and then we have the build code.
+
+Function defined nodes are very flexible. They are more powerful, and more
+flexible than make's pattern rules.  If a developer wants a function to act like
+a pattern rule, the developer can use a regular expression match on the given
+label. However, unlike make, pattern rules defined in this manner, will
+backwards chain potentially through other pattern rules.
+
+The Build function is one of the graph traversal programs. It is given a graph
+and a list of top level market targets. It traverses the graph to find leaf
+while unwinding its proverbial ball of string. Upon finding leaf nodes, it then
+follows the string back until building the targets.
+
+It is possible to define other graph traversal functions.  In fact, Ariadne can
+be used to do anything where a directed graph of functions is useful.
+
+
+--------------------------------------------------------------------------------
+Entering the Project
+
+The project has three entry points, one for each project role: developer,
+tester, and administrator. To enter the project, source the environment
+appropriate for the role, either `env_developer`, `env_tester`, or
+`env_administrator`.
+
+For example, to work on the code as a developer, start a fresh shell and:
+
+> cd Ariadne
+> . env_developer
+>  <run your IDE, I run emacs>
+
+[do work]
+
+> make
+> release
+
+[change to tester role]
+
+The `make` command you see above is a bash script. Version 1.0 of Ariadne uses a
+direct 'build it all every time' approach. Perhaps in version 2.0 or so, we will
+use a prior version of Ariadne for the build environment.
+
+
+Using Ariadne
+-------------
+
+After it is built and released the tool will appear in the Ariadne/release
+directory where it can be tested or imported into another project.
+
diff --git a/developer/bash/.githolder b/developer/bash/.githolder
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/developer/bash/Build b/developer/bash/Build
new file mode 100755 (executable)
index 0000000..2a18026
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/bash
+java com.ReasoningTechnology."Ariadne".Build
diff --git a/developer/deprecated/Ariandne.groovy b/developer/deprecated/Ariandne.groovy
deleted file mode 100644 (file)
index a657f0d..0000000
+++ /dev/null
@@ -1,457 +0,0 @@
-/*
- Some terms:
-
- a node is either malformed or 'wellformed'.  A wellformed node meets
- the criteria set forth by `well_formed_node_q`.
-
- 'node': a dictionary, hopefully a wellformed one
- 'file node': a 'path' or 'leaf' type node.
- 'node file': for 'path' or 'leaf' nodes, path relative to the developer's directory.
-
- This code makes use of the following node properties:
- - label: Unique label string. Used to reference nodes.
- - type: The type of the node: 'leaf' ,'symbol' ,or 'path'.
- - neighbor: list of the neighbor nodes labels
- - must_have: list of node labels
- - build: Code that builds the node.
- - mark: a set of 'mark' tokens optionally placed on a node
-
- For 'path' and 'leaf' type nodes, the node label is a file path.  Relative paths
- are relative to the developer's directory.
-
- The dependency graph is defined by the `lookup` function. `lookup` when given
- a node label returns the node, if found, or null.
-
-*/
-
-/*--------------------------------------------------------------------------------
- file utility functions
-*/
-
-def unpack_file_path = { file_fp ->
-  def file = new File(file_fp)  // Renamed to 'file' to avoid overwriting 'file_fn'
-
-  // Get the parent directory path
-  def parent_dp = file.getParent()
-
-  // Get the file name (with extension)
-  def file_fn = file.getName()
-
-  // Split the file name into base and extension
-  def file_fn_base = file_fn.lastIndexOf('.') > 0 ? file_fn[0..file_fn.lastIndexOf('.') - 1] : file_fn
-  def file_fn_ext = file_fn.lastIndexOf('.') > 0 ? file_fn[file_fn.lastIndexOf('.') + 1..-1] : ''
-
-  // Return the components as a map for easier use
-  return [
-    parent_dp: parent_dp
-    ,file_fn: file_fn
-    ,file_fn_base: file_fn_base
-    ,file_fn_ext: file_fn_ext
-  ]
-}
-
-def file_exists_q(node_label) {
-  def node_path = Paths.get(node_label)
-  return Files.exists(node_path)
-}
-
-
-/*-------------------------------------------------------------------------------
-  DAG adjectives
-
-  node undefined for undefined node?
-*/
-
-// A node is type 'leaf' when the node file can not be deleted or replaced.
-// This type used to be called 'primary', which might be a better term.
-
-def all_node_type_set = ['symbol' ,'path' ,'leaf' ,'generator'] as Set
-
-def persistent_node_mark_set = ['cycle_member' ,'wellformed' ,'build_failed'] as Set
-def leaf_q = { node -> node && node.type && node.type == 'leaf' }
-
-// mark 
-def has_mark = { node -> node.mark && !node.mark.isEmpty() }
-def set_mark(node ,mark){
-  node.mark = node.mark ?: [] as Set
-  node.mark << mark
-}
-def clear_mark(node ,mark){
-  if( node.mark ) node.mark.remove(mark)
-}
-def marked_good_q(node){
-  return (
-    node 
-    && node.mark 
-    && ('wellformed' in node.mark) 
-    && !('cycle_member' in node.mark)
-    && !('build_failed' in node.mark)
-  )
-}
-
-
-
-/*--------------------------------------------------------------------------------
- Wellformed Node Check
-
- The developer defines the nodes, so their form needs to be checked.
-
- early bail on node not defined
- legal path in the build directory makedir -p ... not really a acquirement 
-
-*/
-def all_form_error_set = [
-  'no_node'
-  ,'node_must_have_label'
-  ,'label_must_be_string'
-  ,'node_must_have_type'
-  ,'bad_node_type'
-  ,'neighbor_value_must_be_list'
-  ,'neighbor_reference_must_be_string'
-  ,'mark_property_value_must_be_set'
-  ,'unregistered_mark'
-  ,'missing_required_build_code'
-  ,'leaf_given_neighbor_property'
-  ,'leaf_given_build_property'
-]
-def wellformed_q = { node -> 
-  def form_error_set = [] as Set
-
-  if( !node ){
-    form_error_set << 'no_node'
-    return form_error_set
-  }
-
-  if( !node.label )
-    form_error_set << 'node_must_have_label'
-  else if( !(node.label instanceof String) )
-    form_error_set << 'label_must_be_string'
-
-  if( !node.type )
-    form_error_set << 'node_must_have_type'
-  else if( !(node.type instanceof String) || !(node.type in all_node_type_set) )
-    form_error_set << 'bad_node_type'
-    
-  if( node.neighbor ){
-    if( !(node.neighbor instanceof List) )
-      form_error_set << 'neighbor_value_must_be_list'
-    else if( !(node.neighbor.every { it instanceof String }) )
-      form_error_set << 'neighbor_reference_must_be_string'
-  }
-
-  if( node.mark ){
-    if( !(node.mark instanceof Set) ) 
-      form_error_set << 'mark_property_value_must_be_set'
-    else if( !(node.mark.every { it in persistent_node_mark_set }) )
-      form_error_set << 'unregistered_mark'
-  }
-
-  // Removed test about symbol build needing neighbors
-
-  if( 
-    node.type == "path" 
-    && (!node.build || !(node.build instanceof Closure))
-  )
-    form_error_set << 'missing_required_build_code'
-
-  // Removed test about path needing neighbors
-
-  // Can a primary file have neighbors or a build script? Our build model
-  // has the node file as a target, the build script as a means of building
-  // the target (hence its name), and the dependencies as inputs to the build
-  // script. So in the spirit of this model, we will say "no".
-  if( node.type == "leaf" ){
-    if( node.neighbor ) form_error_set << 'leaf_given_neighbor_property'
-    if( node.build ) form_error_set << 'leaf_given_build_property'
-  }
-
-  return form_error_set
-}
-
-
-
-/*--------------------------------------------------------------------------------
- A well formed graph checker.  Traverses entire graph and marks nodes
- that are not well formed or that are part of a cycle.
-
-*/
-
-// given a node label list, adds the 'wellformed' mark to wellformed nodes.
-def mark_the_wellformed_f(node_label_list ,boolean verbose = true){
-  def all_wellformed = true
-
-  def neighbors = node_label_list.collect{ neighbor_label ->
-    def neighbor_node = lookup(neighbor_label)
-    def form_errors = wellformed_q(neighbor_node)
-    if(form_errors.isEmpty()){
-      neighbor_node.mark = neighbor_node.mark ?: [] as Set
-      neighbor_node.mark << 'wellformed'
-    } else {
-      all_wellformed = false
-      if(verbose){
-        if(neighbor_node.label && neighbor_node.label.length() > 0){
-          print("node ${neighbor_node.label} is malformed due to:")
-        } else {
-          print("anonymous node is malformed due to:")
-        }
-        form_errors.each { error -> print(" ${error}") }
-        println("")
-      }
-    }
-    neighbor_label
-  }
-
-  return all_wellformed ? 'all_wellformed' : 'exists_malformed'
-}
-
-// descends un-visited leftmost path, while marking nodes as wellformed and if
-// they are part of a cycle.
-def markup_graph_f_descend(path_stack ,boolean verbose = true){
-  def ret_value = [] as Set
-  def local_path = path_stack.collect{ it[0] }
-  def local_node_label = local_path[-1]
-  def cycle_start_index
-
-  do{
-    // Check for a cycle in the local path
-    cycle_start_index = local_path[0..-2].findIndexOf{ it == local_node_label }
-    if(cycle_start_index != -1){ // Cycle detected
-      ret_value << 'cycle_found'
-      if(verbose) print "markup_graph_f_descend:: dependency cycle found:"
-      local_path[cycle_start_index..-1].each{ cycle_node_label ->
-        def cycle_node = lookup(cycle_node_label)
-        if(verbose) print " ${cycle_node.label}"
-        cycle_node.mark = cycle_node.mark ?: [] as Set // Initialize mark set if needed
-        cycle_node.mark << 'cycle_member'
-      }
-      if(verbose) println ""
-      // we can not continue searching after the loop so ,we pop back to treat
-      // the first node in the loop as though a leaf node.
-      path_stack = path_stack[0..cycle_start_index]
-      return ret_value
-    }
-
-    // a 'de-facto' leaf node test subtleties here because we have not yet
-    // determined if the nodes we are wellformed. This is purposeful ,as
-    // this function does not know about the relationships between the 
-    // possible error marks.
-    def local_node = lookup(local_node_label)
-    if(local_node.neighbor.isEmpty()){
-      ret_value << 'defacto_leaf_node'
-      return ret_value
-    }
-
-    // Mark the wellformed nodes and get the result
-    def result = mark_the_wellformed_f(local_node.neighbor ,verbose)
-    if(result == 'exists_malformed'){
-      ret_value << 'exists_malformed'
-    }
-    
-    // Descend further into the tree.
-    path_stack << local_node.neighbor.clone()
-    local_node_label = local_node.neighbor[0]
-    local_path << local_node_label
-  }while(true)
-}
-
-
-
-/*--------------------------------------------------------------------------------
- This function defines the graph.
-
- Lookup attempts to lookup a node label in the node_map, and failing that, it
- tries each label pattern recognition function in order.
-
- lookup_marked_good can be run after `wellformed_graph_f` has marked up the
- graph.  It will only return a node if a) found b) that is 'good'.
- Note the `marked_good_q` adjective above.
-
-*/
-def lookup(node_label ,verbose = false){
-  def lookup_node = node_map[node_label]
-  if( lookup_node ){
-    lookup_node.label = node_label
-  } else {
-    def match_result
-    for(func in node_f_list){
-      match_result = func(node_label)
-      if(match_result.status == "matched"){
-        lookup_node = match_result
-        break
-      }
-    }
-  }
-  if( !lookup_node ){
-    if( verbose ) println "lookup:: Node ${node_label} could not be found."
-    return null
-  }
-  return lookup_node
-}
-
-// mark aware lookup function
-def lookup_marked_good(node_label ,verbose = false){
-  def node = lookup(node_label ,verbose)
-  if( node && marked_good_q(node) ) return node;
-  return null;
-}
-
-
-/*
- Given `root_node_labels` of a DAG. Applies `node_function` to each node in a
- depth-first traversal order.  Returns a set of error tokens encountered
- during traversal.
-
- `wellformed_graph_q` must be run on the DAG before this function is called ,or
- `lookup_marked_good` will not function correctly.
-*/
-def all_DAG_DF(root_node_labels ,node_function ,boolean verbose = true) {
-  def error_token_set = [] as Set
-
-  if (root_node_labels.isEmpty()) return error_token_set
-
-  def visited = [] as Set
-  def in_traversal_order = []
-  def stack = []
-
-  root_node_labels.each { root_label ->
-    stack << root_label
-  }
-
-  do {
-    def node_label = stack.pop()
-    
-    def node = lookup_marked_good(node_label ,verbose)
-    if (!node) {
-      error_token_set << 'lookup_fail'
-      continue
-    }
-
-    if (node.label in visited) continue
-    visited << node.label
-
-    in_traversal_order << node
-
-    node.neighbor.each { neighbor_label ->
-      stack << neighbor_label
-    }
-  } while (!stack.isEmpty())
-
-  in_traversal_order.reverse().each { node ->
-    node_function(node ,error_token_set ,verbose)
-  }
-
-  return error_token_set
-}
-
-
-/*--------------------------------------------------------------------------------
- run the build scripts
-   depends upon is_acyclic having already marked up the graph.
-*/
-
-import java.nio.file.Files
-import java.nio.file.Paths
-
-// a symbol dependency is good ,as long as it is built before the node in question
-def good_dependency_q(node_labels) {
-  return node_labels.every { node_label ->
-    def node = lookup_marked_good(node_label)
-    if (!node) return false
-    if (node.type in ['path' ,'leaf'] && !file_exists_q(node.label)) return false
-    return true
-  }
-}
-
-/* 
- Given a node label and a list of node labels ,returns true if the file at the
- node label in the first argument is newer than all the files at the
- corresponding node labels in the second list.
-*/
-def newer_than_all(node_label ,node_label_list) {
-  def node_path = Paths.get(node_label)
-  if (!Files.exists(node_path)) return false
-
-  def node_last_modified = Files.getLastModifiedTime(node_path).toMillis()
-
-  return node_label_list.every { label ->
-    def path = Paths.get(label)
-    if (!Files.exists(path)) return false
-    def last_modified = Files.getLastModifiedTime(path).toMillis()
-    return node_last_modified > last_modified
-  }
-}
-
-def can_be_built_q(node){
-  if( !marked_good_q(node) ) return false;
-  if( 
-    (node.type == 'symbol' || type == 'path')
-    && !good_dependency_q( node.neighbor )
-  ){
-    return false
-  }
-  if(
-    node.type == 'leaf'
-    && !file_exists_q(node.label)
-  ){ 
-    return false;
-  }
-  return true
-}
-
-// `can_be_build_q` must be true for this to be meaningful:
-def should_be_built_q(node ,verbose = true) {
-  if(node.type == 'leaf') return false
-  if(node.type == 'symbol') return true
-  if( node.type == 'path') return !newer_than_all(node.label ,node.neighbor)
-  println("should_be_build_q:: unrecognized node type ,so assuming it should not be built.")
-  return false
-}
-
-/*
- Runs build scripts for the given root_node_labels in a depth-first traversal order.
- Uses `all_DAG_DF` to traverse the graph and applies the build function to each node.
-
- Be sure that `wellformed_graph_q` has been run on DAG.
-
- Be sure that the 'build_failed' marks have been cleared if this is not the
- first build attempt.
-*/
-def run_build_scripts_f(root_node_labels ,boolean verbose = true){
-  if( root_node_labels.isEmpty() ) return
-
-  // Define the function to be applied to each node
-  def node_function = { node ,error_token_set ->
-
-    if( !can_be_built_q(node) ){
-      println("Skipping build for ${node.label} due to dependency problems or found leaf is missing")
-      return
-    }
-
-    if( !should_be_built_q(node) ){
-      if(verbose) println("${node.label} already up to date")
-      return
-    }
-
-    // if we get here, node can and should be built
-
-    println("Running build script for ${node.label}")
-    node.build(node ,node.neighbor)
-
-    // Check if the build updated the target file
-    if( should_be_built_q(node) ){
-      println("Build failed for ${node.label}")
-      set_mark(node ,'build_failed')
-    }
-
-  }
-
-  println("run_build_scripts_f:: running ...")
-  // Apply the function to all nodes in a depth-first manner
-  all_DAG_DF(root_node_labels ,node_function ,verbose)
-}
-
-
-// LocalWords:  FN FPL DN DNL RuleNameListRegx RuleNameList PrintVisitorMethod
-// LocalWords:  PrintVisitor SyntaxAnnotate wellformed defacto acyclic
-// LocalWords:  wellformed unvisited
diff --git a/developer/deprecated/Ariandne2.groovy b/developer/deprecated/Ariandne2.groovy
deleted file mode 100644 (file)
index 6c0cf17..0000000
+++ /dev/null
@@ -1,635 +0,0 @@
-class AriadneGraph {
-
-  // Instance variables for graph data if needed
-  Map node_map = [:]
-  List node_f_list = []
-
-  // Constructor to accept a graph definition (node_map and node_f_list)
-  AriadneGraph( Map node_map ,List node_f_list ){
-    this.node_map = node_map ?: [:]
-    this.node_f_list = node_f_list ?: []
-  }
-
-  /*--------------------------------------------------------------------------------
-   File utility functions
-  */
-
-  static Map unpack_file_path( String file_fp ){
-    def file = new File( file_fp )
-
-    def parent_dp = file.getParent()
-    def file_fn = file.getName()
-    def file_fn_base = file_fn.lastIndexOf('.') > 0 ? file_fn[ 0..file_fn.lastIndexOf('.') - 1 ] : file_fn
-    def file_fn_ext = file_fn.lastIndexOf('.') > 0 ? file_fn[ file_fn.lastIndexOf('.') + 1..-1 ] : ''
-
-    return [
-      parent_dp: parent_dp
-      ,file_fn: file_fn
-      ,file_fn_base: file_fn_base
-      ,file_fn_ext: file_fn_ext
-    ]
-  }
-
-  static boolean file_exists_q( String node_label ){
-    def node_path = Paths.get( node_label )
-    return Files.exists( node_path )
-  }
-
-  /*--------------------------------------------------------------------------------
-   Node type checks and marking
-  */
-
-  static Set all_node_type_set = ['symbol' ,'path' ,'leaf' ,'generator'] as Set
-  static Set persistent_node_mark_set = ['cycle_member' ,'wellformed' ,'build_failed'] as Set
-
-  static boolean leaf_q( Map node ){
-    return node && node.type == 'leaf'
-  }
-
-  static boolean has_mark( Map node ){
-    return node?.mark?.isNotEmpty()
-  }
-
-  static void set_mark( Map node ,String mark ){
-    node.mark = node.mark ?: [] as Set
-    node.mark << mark
-  }
-
-  static void clear_mark( Map node ,String mark ){
-    node?.mark?.remove( mark )
-  }
-
-  static boolean marked_good_q( Map node ){
-    return node && node.mark && ( 'wellformed' in node.mark ) && !( 'cycle_member' in node.mark ) && !( 'build_failed' in node.mark )
-  }
-
-  /*--------------------------------------------------------------------------------
-   Well-formed Node Check
-  */
-
-  static Set all_form_error_set = [
-    'no_node'
-    ,'node_must_have_label'
-    ,'label_must_be_string'
-    ,'node_must_have_type'
-    ,'bad_node_type'
-    ,'neighbor_value_must_be_list'
-    ,'neighbor_reference_must_be_string'
-    ,'mark_property_value_must_be_set'
-    ,'unregistered_mark'
-    ,'missing_required_build_code'
-    ,'leaf_given_neighbor_property'
-    ,'leaf_given_build_property'
-  ] as Set
-
-  static Set wellformed_q( Map node ){
-    def form_error_set = [] as Set
-
-    if( !node ){
-      form_error_set << 'no_node'
-      return form_error_set
-    }
-
-    if( !node.label )
-      form_error_set << 'node_must_have_label'
-    else if( !( node.label instanceof String ) )
-      form_error_set << 'label_must_be_string'
-
-    if( !node.type )
-      form_error_set << 'node_must_have_type'
-    else if( !( node.type instanceof String ) || !( node.type in all_node_type_set ) )
-      form_error_set << 'bad_node_type'
-
-    if( node.neighbor ){
-      if( !( node.neighbor instanceof List ) )
-        form_error_set << 'neighbor_value_must_be_list'
-      else if( !( node.neighbor.every { it instanceof String } ) )
-        form_error_set << 'neighbor_reference_must_be_string'
-    }
-
-    if( node.mark ){
-      if( !( node.mark instanceof Set ) )
-        form_error_set << 'mark_property_value_must_be_set'
-      else if( !( node.mark.every { it in persistent_node_mark_set } ) )
-        form_error_set << 'unregistered_mark'
-    }
-
-    if( node.type == 'path' && ( !node.build || !( node.build instanceof Closure ) ) )
-      form_error_set << 'missing_required_build_code'
-
-    if( node.type == 'leaf' ){
-      if( node.neighbor ) form_error_set << 'leaf_given_neighbor_property'
-      if( node.build ) form_error_set << 'leaf_given_build_property'
-    }
-
-    return form_error_set
-  }
-
-  /*--------------------------------------------------------------------------------
-   Graph traversal and build functions
-  */
-
-  def lookup( String node_label ,boolean verbose = false ){
-    def lookup_node = node_map[ node_label ]
-    if( !lookup_node ){
-      def match_result
-      for( func in node_f_list ){
-        match_result = func( node_label )
-        if( match_result.status == "matched" ){
-          lookup_node = match_result
-          break
-        }
-      }
-    }
-
-    if( !lookup_node && verbose ) println "lookup:: Node ${node_label} could not be found."
-    return lookup_node
-  }
-
-  def run_build_scripts_f( List root_node_labels ,boolean verbose = true ){
-    if( root_node_labels.isEmpty() ) return
-
-    def node_function = { node ,error_token_set ->
-
-      if( !can_be_built_q( node ) ){
-        println( "Skipping build for ${node.label} due to dependency problems" )
-        return
-      }
-      if( !should_be_built_q( node ) ){
-        if( verbose ) println( "${node.label} already up to date" )
-        return
-      }
-
-      println( "Running build script for ${node.label}" )
-      node.build( node ,node.neighbor )
-
-      if( should_be_built_q( node ) ){
-        println( "Build failed for ${node.label}" )
-        set_mark( node ,'build_failed' )
-      }
-    }
-
-    println( "run_build_scripts_f:: running ..." )
-    all_DAG_DF( root_node_labels ,node_function ,verbose )
-  }
-
-  // Add the rest of your methods here as instance/static methods based on whether they depend on the graph instance
-
-}
-/*
- Some terms:
-
- a node is either malformed or 'wellformed'.  A wellformed node meets
- the criteria set forth by `well_formed_node_q`.
-
- 'node': a dictionary, hopefully a wellformed one
- 'file node': a 'path' or 'leaf' type node.
- 'node file': for 'path' or 'leaf' nodes, path relative to the developer's directory.
-
- This code makes use of the following node properties:
- - label: Unique label string. Used to reference nodes.
- - type: The type of the node: 'leaf' ,'symbol' ,or 'path'.
- - neighbor: list of the neighbor nodes labels
- - must_have: list of node labels
- - build: Code that builds the node.
- - mark: a set of 'mark' tokens optionally placed on a node
-
- For 'path' and 'leaf' type nodes, the node label is a file path.  Relative paths
- are relative to the developer's directory.
-
- The dependency graph is defined by the `lookup` function. `lookup` when given
- a node label returns the node, if found, or null.
-
-*/
-
-/*--------------------------------------------------------------------------------
- file utility functions
-*/
-
-def unpack_file_path = { file_fp ->
-  def file = new File(file_fp)
-
-  // Get the parent directory path
-  def parent_dp = file_fn.getParent()
-
-  // Get the file name (with extension)
-  def file_fn = file_fn.getName()
-
-  // Split the file name into base and extension
-  def file_fn_base = file_fn.lastIndexOf('.') > 0 ? file_fn[0..file_fn.lastIndexOf('.') - 1] : file_fn
-  def file_fn_ext = file_fn.lastIndexOf('.') > 0 ? file_fn[file_fn.lastIndexOf('.') + 1..-1] : ''
-
-  // Return the components as a map for easier use
-  return [
-    parent_dp: parent_dp
-    ,file_fn: file_fn
-    ,file_fn_base: file_fn_base
-    ,file_fn_ext: file_fn_ext
-  ]
-}
-
-def file_exists_q(node_label) {
-  def node_path = Paths.get(node_label)
-  return Files.exists(node_path)
-}
-
-
-/*-------------------------------------------------------------------------------
-  DAG adjectives
-
-  node undefined for undefined node?
-*/
-
-// A node is type 'leaf' when the node file can not be deleted or replaced.
-// This type used to be called 'primary', which might be a better term.
-
-def all_node_type_set = ['symbol' ,'path' ,'leaf' ,'generator'] as Set
-
-def persistent_node_mark_set = ['cycle_member' ,'wellformed' ,'build_failed'] as Set
-def leaf_q = { node -> node && node.type && node.type == 'leaf' }
-
-// mark 
-def has_mark = { node -> node.mark && !node.mark.isEmpty() }
-def set_mark(node ,mark){
-  node.mark = node.mark ?: [] as Set
-  node.mark << mark
-}
-def clear_mark(node ,mark){
-  if( node.mark ) node.mark.remove(mark)
-}
-def marked_good_q(node){
-  return (
-    node 
-    && node.mark 
-    && ('wellformed' in node.mark) 
-    && !('cycle_member' in node.mark)
-    && !('build_failed' in node.mark)
-  )
-}
-
-
-
-/*--------------------------------------------------------------------------------
- Wellformed Node Check
-
- The developer defines the nodes, so their form needs to be checked.
-
- early bail on node not defined
- legal path in the build directory makedir -p ... not really a acquirement 
-
-*/
-def all_form_error_set = [
-  'no_node'
-  ,'node_must_have_label'
-  ,'label_must_be_string'
-  ,'node_must_have_type'
-  ,'bad_node_type'
-  ,'neighbor_value_must_be_list'
-  ,'neighbor_reference_must_be_string'
-  ,'mark_property_value_must_be_set'
-  ,'unregistered_mark'
-  ,'missing_required_build_code'
-  ,'leaf_given_neighbor_property'
-  ,'leaf_given_build_property'
-]
-def wellformed_q = { node -> 
-  def form_error_set = [] as Set
-
-  if( !node ){
-    form_error_set << 'no_node'
-    return form_error_set
-  }
-
-  if( !node.label )
-    form_error_set << 'node_must_have_label'
-  else if( !(node.label instanceof String) )
-    form_error_set << 'label_must_be_string'
-
-  if( !node.type )
-    form_error_set << 'node_must_have_type'
-  else if( !(node.type instanceof String) || !(node.type in all_node_type_set) )
-    form_error_set << 'bad_node_type'
-    
-  if( node.neighbor ){
-    if( !(node.neighbor instanceof List) )
-      form_error_set << 'neighbor_value_must_be_list'
-    else if( !(node.neighbor.every { it instanceof String }) )
-      form_error_set << 'neighbor_reference_must_be_string'
-  }
-
-  if( node.mark ){
-    if( !(node.mark instanceof Set) ) 
-      form_error_set << 'mark_property_value_must_be_set'
-    else if( !(node.mark.every { it in persistent_node_mark_set }) )
-      form_error_set << 'unregistered_mark'
-  }
-
-  // Removed test about symbol build needing neighbors
-
-  if( 
-    node.type == "path" 
-    && (!node.build || !(node.build instanceof Closure))
-  )
-    form_error_set << 'missing_required_build_code'
-
-  // Removed test about path needing neighbors
-
-  // Can a primary file have neighbors or a build script? Our build model
-  // has the node file as a target, the build script as a means of building
-  // the target (hence its name), and the dependencies as inputs to the build
-  // script. So in the spirit of this model, we will say "no".
-  if( node.type == "leaf" ){
-    if( node.neighbor ) form_error_set << 'leaf_given_neighbor_property'
-    if( node.build ) form_error_set << 'leaf_given_build_property'
-  }
-
-  return form_error_set
-}
-
-
-
-/*--------------------------------------------------------------------------------
- A well formed graph checker.  Traverses entire graph and marks nodes
- that are not well formed or that are part of a cycle.
-
-*/
-
-// given a node label list, adds the 'wellformed' mark to wellformed nodes.
-def mark_the_wellformed_f(node_label_list ,boolean verbose = true){
-  def all_wellformed = true
-
-  def neighbors = node_label_list.collect{ neighbor_label ->
-    def neighbor_node = lookup(neighbor_label)
-    def form_errors = wellformed_q(neighbor_node)
-    if(form_errors.isEmpty()){
-      neighbor_node.mark = neighbor_node.mark ?: [] as Set
-      neighbor_node.mark << 'wellformed'
-    } else {
-      all_wellformed = false
-      if(verbose){
-        if(neighbor_node.label && neighbor_node.label.length() > 0){
-          print("node ${neighbor_node.label} is malformed due to:")
-        } else {
-          print("anonymous node is malformed due to:")
-        }
-        form_errors.each { error -> print(" ${error}") }
-        println("")
-      }
-    }
-    neighbor_label
-  }
-
-  return all_wellformed ? 'all_wellformed' : 'exists_malformed'
-}
-
-// descends un-visited leftmost path, while marking nodes as wellformed and if
-// they are part of a cycle.
-def markup_graph_f_descend(path_stack ,boolean verbose = true){
-  def ret_value = [] as Set
-  def local_path = path_stack.collect{ it[0] }
-  def local_node_label = local_path[-1]
-  def cycle_start_index
-
-  do{
-    // Check for a cycle in the local path
-    cycle_start_index = local_path[0..-2].findIndexOf{ it == local_node_label }
-    if(cycle_start_index != -1){ // Cycle detected
-      ret_value << 'cycle_found'
-      if(verbose) print "markup_graph_f_descend:: dependency cycle found:"
-      local_path[cycle_start_index..-1].each{ cycle_node_label ->
-        def cycle_node = lookup(cycle_node_label)
-        if(verbose) print " ${cycle_node.label}"
-        cycle_node.mark = cycle_node.mark ?: [] as Set // Initialize mark set if needed
-        cycle_node.mark << 'cycle_member'
-      }
-      if(verbose) println ""
-      // we can not continue searching after the loop so ,we pop back to treat
-      // the first node in the loop as though a leaf node.
-      path_stack = path_stack[0..cycle_start_index]
-      return ret_value
-    }
-
-    // a 'de-facto' leaf node test subtleties here because we have not yet
-    // determined if the nodes we are wellformed. This is purposeful ,as
-    // this function does not know about the relationships between the 
-    // possible error marks.
-    def local_node = lookup(local_node_label)
-    if(local_node.neighbor.isEmpty()){
-      ret_value << 'defacto_leaf_node'
-      return ret_value
-    }
-
-    // Mark the wellformed nodes and get the result
-    def result = mark_the_wellformed_f(local_node.neighbor ,verbose)
-    if(result == 'exists_malformed'){
-      ret_value << 'exists_malformed'
-    }
-    
-    // Descend further into the tree.
-    path_stack << local_node.neighbor.clone()
-    local_node_label = local_node.neighbor[0]
-    local_path << local_node_label
-  }while(true)
-}
-
-
-
-/*--------------------------------------------------------------------------------
- This function defines the graph.
-
- Lookup attempts to lookup a node label in the node_map, and failing that, it
- tries each label pattern recognition function in order.
-
- lookup_marked_good can be run after `wellformed_graph_f` has marked up the
- graph.  It will only return a node if a) found b) that is 'good'.
- Note the `marked_good_q` adjective above.
-
-*/
-def lookup(node_label ,verbose = false){
-  def lookup_node = node_map[node_label]
-  if( lookup_node ){
-    lookup_node.label = node_label
-  } else {
-    def match_result
-    for(func in node_f_list){
-      match_result = func(node_label)
-      if(match_result.status == "matched"){
-        lookup_node = match_result
-        break
-      }
-    }
-  }
-  if( !lookup_node ){
-    if( verbose ) println "lookup:: Node ${node_label} could not be found."
-    return null
-  }
-  return lookup_node
-}
-
-// mark aware lookup function
-def lookup_marked_good(node_label ,verbose = false){
-  def node = lookup(node_label ,verbose)
-  if( node && marked_good_q(node) ) return node;
-  return null;
-}
-
-
-/*
- Given `root_node_labels` of a DAG. Applies `node_function` to each node in a
- depth-first traversal order.  Returns a set of error tokens encountered
- during traversal.
-
- `wellformed_graph_q` must be run on the DAG before this function is called ,or
- `lookup_marked_good` will not function correctly.
-*/
-def all_DAG_DF(root_node_labels ,node_function ,boolean verbose = true) {
-  def error_token_set = [] as Set
-
-  if (root_node_labels.isEmpty()) return error_token_set
-
-  def visited = [] as Set
-  def in_traversal_order = []
-  def stack = []
-
-  root_node_labels.each { root_label ->
-    stack << root_label
-  }
-
-  do {
-    def node_label = stack.pop()
-    
-    def node = lookup_marked_good(node_label ,verbose)
-    if (!node) {
-      error_token_set << 'lookup_fail'
-      continue
-    }
-
-    if (node.label in visited) continue
-    visited << node.label
-
-    in_traversal_order << node
-
-    node.neighbor.each { neighbor_label ->
-      stack << neighbor_label
-    }
-  } while (!stack.isEmpty())
-
-  in_traversal_order.reverse().each { node ->
-    node_function(node ,error_token_set ,verbose)
-  }
-
-  return error_token_set
-}
-
-
-/*--------------------------------------------------------------------------------
- run the build scripts
-   depends upon is_acyclic having already marked up the graph.
-*/
-
-import java.nio.file.Files
-import java.nio.file.Paths
-
-// a symbol dependency is good ,as long as it is built before the node in question
-def good_dependency_q(node_labels) {
-  return node_labels.every { node_label ->
-    def node = lookup_marked_good(node_label)
-    if (!node) return false
-    if (node.type in ['path' ,'leaf'] && !file_exists_q(node.label)) return false
-    return true
-  }
-}
-
-/* 
- Given a node label and a list of node labels ,returns true if the file at the
- node label in the first argument is newer than all the files at the
- corresponding node labels in the second list.
-*/
-def newer_than_all(node_label ,node_label_list) {
-  def node_path = Paths.get(node_label)
-  if (!Files.exists(node_path)) return false
-
-  def node_last_modified = Files.getLastModifiedTime(node_path).toMillis()
-
-  return node_label_list.every { label ->
-    def path = Paths.get(label)
-    if (!Files.exists(path)) return false
-    def last_modified = Files.getLastModifiedTime(path).toMillis()
-    return node_last_modified > last_modified
-  }
-}
-
-def can_be_built_q(node){
-  if( !marked_good_q(node) ) return false;
-  if( 
-    (node.type == 'symbol' || type == 'path')
-    && !good_dependency_q( node.neighbor )
-  ){
-    return false
-  }
-  if(
-    node.type == 'leaf'
-    && !file_exists_q(node.label)
-  ){ 
-    return false;
-  }
-  return true
-}
-
-// `can_be_build_q` must be true for this to be meaningful:
-def should_be_built_q(node ,verbose = true) {
-  if(node.type == 'leaf') return false
-  if(node.type == 'symbol') return true
-  if( node.type == 'path') return !newer_than_all(node.label ,node.neighbor)
-  println("should_be_build_q:: unrecognized node type ,so assuming it should not be built.")
-  return false
-}
-
-/*
- Runs build scripts for the given root_node_labels in a depth-first traversal order.
- Uses `all_DAG_DF` to traverse the graph and applies the build function to each node.
-
- Be sure that `wellformed_graph_q` has been run on DAG.
-
- Be sure that the 'build_failed' marks have been cleared if this is not the
- first build attempt.
-*/
-def run_build_scripts_f(root_node_labels ,boolean verbose = true){
-  if( root_node_labels.isEmpty() ) return
-
-  // Define the function to be applied to each node
-  def node_function = { node ,error_token_set ->
-
-    if( !can_be_built_q(node) ){
-      println("Skipping build for ${node.label} due to dependency problems or found leaf is missing")
-      return
-    }
-
-    if( !should_be_built_q(node) ){
-      if(verbose) println("${node.label} already up to date")
-      return
-    }
-
-    // if we get here, node can and should be built
-
-    println("Running build script for ${node.label}")
-    node.build(node ,node.neighbor)
-
-    // Check if the build updated the target file
-    if( should_be_built_q(node) ){
-      println("Build failed for ${node.label}")
-      set_mark(node ,'build_failed')
-    }
-
-  }
-
-  println("run_build_scripts_f:: running ...")
-  // Apply the function to all nodes in a depth-first manner
-  all_DAG_DF(root_node_labels ,node_function ,verbose)
-}
-
-
-// LocalWords:  FN FPL DN DNL RuleNameListRegx RuleNameList PrintVisitorMethod
-// LocalWords:  PrintVisitor SyntaxAnnotate wellformed defacto acyclic
-// LocalWords:  wellformed unvisited
diff --git a/developer/deprecated/Graph.java b/developer/deprecated/Graph.java
deleted file mode 100644 (file)
index 3052338..0000000
+++ /dev/null
@@ -1,685 +0,0 @@
-package Ariadne;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Stack;
-import java.util.function.BiConsumer;
-import java.util.function.BiFunction;
-import java.util.function.Function;
-import java.util.function.Predicate;
-
-
-public class Graph {
-
-  /*--------------------------------------------------------------------------------
-   type aliases
-  */
-  public class TokenSet extends HashSet<Token>{}
-  public class LabelList extends ArrayList<Label> {}
-  public interface Node extends Map<Label ,Object>{}
-  public interface NodeList extends List<Node>{}
-  public interface RecognizerF extends Function<Label ,Node>{}
-  public class RecognizerFList extends ArrayList<RecognizerF> {}
-
-  /*--------------------------------------------------------------------------------
-   instance data 
-  */
-
-  private static boolean debug = true;
-  private Map<Label ,Node> node_map;
-  private RecognizerFList recognizer_f_list;
-
-  /*--------------------------------------------------------------------------------
-    constructors
-  */
-
-  public AriadneGraph(Map<Label ,Node> node_map ,RecognizerFList recognizer_f_list){
-    if (node_map == null && recognizer_f_list == null) {
-      System.err.println("AriadneGraph: At least one of 'node_map' (Map) or 'recognizer_f_list' (List) must be provided.");
-      System.exit(1);
-    }
-
-    // Initialize node_map and recognizer_f_list to empty collections if they are null
-    this.node_map = (node_map != null) ? node_map : new HashMap<Label ,Node>();
-
-    this.recognizer_f_list = (recognizer_f_list != null) ? recognizer_f_list : new RecognizerFList();
-  }
-
-  /*--------------------------------------------------------------------------------
-   file utilities
-  */
-
-  public static Map<String ,String> unpack_file_path(String file_fp){
-    if(debug) System.out.println("unpack_file_path::file_fp: " + file_fp);
-
-    File file = new File(file_fp);
-    String parent_dp = (file.getParent() != null) ? file.getParent() : "";
-
-    if( !parent_dp.isEmpty() && !parent_dp.endsWith(File.separator) ){
-      parent_dp += File.separator;
-    }
-
-    String file_fn = file.getName();
-    String file_fn_base = file_fn;
-    String file_fn_ext = "";
-
-    int last_index = file_fn.lastIndexOf('.');
-    if(last_index > 0){
-      file_fn_base = file_fn.substring(0 ,last_index);
-      if( last_index + 1 < file_fn.length() ){
-        file_fn_ext = file_fn.substring(last_index + 1);
-      }
-    }
-
-    Map<String ,String> ret_val = new HashMap<>();
-    ret_val.put("dp" ,parent_dp);
-    ret_val.put("fn" ,file_fn);
-    ret_val.put("fn_base" ,file_fn_base);
-    ret_val.put("fn_ext" ,file_fn_ext);
-
-    if(debug) System.out.println("unpack_file_path::ret_val: " + ret_val);
-
-    return ret_val;
-  }
-
-  public static boolean file_exists_q(Label node_label){
-    Path node_path = Paths.get(node_label);
-    return Files.exists(node_path);
-  }
-
-  /*--------------------------------------------------------------------------------
-    About nodes
-
-    A leaf type node specifies a path to a file that should not be deleted by
-    in clean operations. Typically this is the source code. We could add a
-    tool to lock permissions on these before a build, so that the build
-    scripts will also not mess with them (unless they change permissions).
-
-    If the user has multiple dependency graphs defined, a node with no
-    dependencies in one graph, might have dependencies in another.
-
-    An error type node, is one that was found to not have a type, or
-    was constructed by the tool to be a place older, perhaps for a
-    node label that was not found.
-
-  */
-  public static TokenSet all_node_type_set = new TokenSet();
-  static {
-    all_node_type_set.add(new Token("symbol"));
-    all_node_type_set.add(new Token("path"));
-    all_node_type_set.add(new Token("leaf"));
-    all_node_type_set.add(new Token("error"));
-  }
-
-  public static TokenSet persistent_node_mark_set = new TokenSet();
-  static {
-    persistent_node_mark_set.add(new Token("cycle_member"));
-    persistent_node_mark_set.add(new Token("wellformed"));
-    persistent_node_mark_set.add(new Token("build_failed"));
-    persistent_node_mark_set.add(new Token("null_node"));
-  }
-
-  public static boolean leaf_q(Node node){
-    return node != null && "leaf".equals(node.get("type"));
-  }
-
-  public static boolean has_mark(Node node){
-    return node != null && node.get("mark") != null && !( (TokenSet)node.get("mark") ).isEmpty();
-  }
-
-  public static void set_mark(Node node ,Token mark){
-    if( node.get("mark") == null ){
-      node.put("mark" ,new HashTokenSet());
-    }
-    ( (TokenSet)node.get("mark") ).add(mark);
-  }
-
-  public static void clear_mark(Node node ,Token mark){
-    if( node != null && node.get("mark") != null ){
-      ( (TokenSet) node.get("mark") ).remove(mark);
-    }
-  }
-
-  public static boolean marked_good_q(Node node){
-    return node != null && node.get("mark") != null
-      && ( (TokenSet)node.get("mark") ).contains("wellformed")
-      && !( (TokenSet)node.get("mark") ).contains("cycle_member")
-      && !( (TokenSet)node.get("mark") ).contains("build_failed");
-  }
-
-
-  /*--------------------------------------------------------------------------------
-   Well-formed Node Check
-  */
-
-  public static TokenSet form_condition_set = new TokenSet();
-  static {
-    form_condition_set.add(new Token("no_node"));
-    form_condition_set.add(new Token("node_must_have_label"));
-    form_condition_set.add(new Token("label_must_be_string"));
-    form_condition_set.add(new Token("node_must_have_type"));
-    form_condition_set.add(new Token("bad_node_type"));
-    form_condition_set.add(new Token("neighbor_value_must_be_list"));
-    form_condition_set.add(new Token("neighbor_reference_must_be_string"));
-    form_condition_set.add(new Token("neighbor_label_not_in_graph"));
-    form_condition_set.add(new Token("mark_property_value_must_be_set"));
-    form_condition_set.add(new Token("unregistered_mark"));
-    form_condition_set.add(new Token("missing_required_build_code"));
-    form_condition_set.add(new Token("leaf_given_neighbor_property"));
-    form_condition_set.add(new Token("leaf_given_build_property"));
-  }
-
-  // given a node, collects a description of its form, returns a set form condition tokens
-  public static TokenSet wellformed_node_q(Node node){
-    TokenSet form_error_set = new HashSet<>();
-
-    if(node == null){
-      form_error_set.add("null_node");
-      return form_error_set;
-    }
-
-    if( !node.containsKey("label") )
-      form_error_set.add("node_must_have_label");
-    else if( !(node.get("label") instanceof Label) )
-      form_error_set.add("label_must_be_string");
-
-    if( !node.containsKey("type") )
-      form_error_set.add("node_must_have_type");
-    else if( !(node.get("type") instanceof String) || !all_node_type_set.contains(node.get("type")) )
-      form_error_set.add("bad_node_type");
-
-    if( node.containsKey("neighbor") ){
-      if( !(node.get("neighbor") instanceof List) )
-        form_error_set.add("neighbor_value_must_be_list");
-      else if( !((List<?>) node.get("neighbor")).stream().allMatch(it -> it instanceof Label) )
-        form_error_set.add("neighbor_reference_must_be_string");
-    }
-
-    if( node.containsKey("mark") ){
-      if( !(node.get("mark") instanceof Set) )
-        form_error_set.add("mark_property_value_must_be_set");
-      else if( !((Set<?>) node.get("mark")).stream().allMatch(it -> persistent_node_mark_set.contains(it)) )
-        form_error_set.add("unregistered_mark");
-    }
-
-    if( "path".equals(node.get("type")) && (!node.containsKey("build") || !(node.get("build") instanceof Runnable)) )
-      form_error_set.add("missing_required_build_code");
-
-    if( "leaf".equals(node.get("type")) ){
-      if( node.containsKey("neighbor") ) form_error_set.add("leaf_given_neighbor_property");
-      if( node.containsKey("build") ) form_error_set.add("leaf_given_build_property");
-    }
-
-    return form_error_set;
-  }
-
-  // given a node, potentially marks it as wellformed, returns one of 'wellformed' or 'malformed'
-  public static Token wellformed_mark_node(Node node ,boolean verbose){
-    if(debug){
-      if(node != null){
-        System.out.println("wellformed_mark_node::node: " + node);
-      }else{
-        System.out.println("wellformed_mark_node given a null node");
-      }
-    }
-
-    TokenSet form_errors = wellformed_node_q(node);
-    if( form_errors.isEmpty() ){
-      set_mark( node ,"wellformed" );
-      return "wellformed";
-    }
-
-    // At this point we know that form_errors is not empty
-    if(verbose){
-      if( node != null && node.get("label") != null && ((Label)node.get("label")).length() > 0 ){
-        System.out.print( "node " + node.get("label") + " is malformed due to:" );
-      }else{
-        System.out.print("anonymous node is malformed due to:");
-      }
-      for(Token error : form_errors){
-        System.out.print(" " + error);
-      }
-      System.out.println("");
-    }
-
-    return "malformed";
-  }
-  public Token wellformed_mark_node(Node node){
-    return wellformed_mark_node(node ,true);
-  }
-
-  // given a node_label, potentially marks the corresponding node as 'wellformed', returns a token set.
-  // Tokens included "undefined_node", "malformed", and "defactor_leaf".
-  public TokenSet wellformed_mark_node_label(Label node_label ,boolean verbose){
-    TokenSet ret_value = new HashSet<>();
-    Node node = lookup(node_label);
-    if(node == null){
-      ret_value.add("undefined_node");
-      return ret_value;
-    }
-    if( "malformed".equals(wellformed_mark_node(node ,verbose)) ){
-      ret_value.add("malformed");
-    }
-    if( ((List<?>)node.get("neighbor")).isEmpty() ){
-      ret_value.add("defacto_leaf"); // might not be `type:leaf`
-    }
-    return ret_value;
-  }
-  public TokenSet wellformed_mark_node_label(Label node_label){
-    return wellformed_mark_node_label(node_label ,true);
-  }
-
-
-  /*--------------------------------------------------------------------------------
-   A well formed graph checker.  Traverses entire graph and marks nodes
-   that are not well formed or that are part of a cycle.
-
-   This must be run on the graph for `lookup_marked_good` to work.
-
-   Each node_label must be a string and not empty.
-
-   Subleties here because we have not yet determined if the nodes we are
-   wellformed (after all ,that is what we are determining here).
-
-   If we want to attempt to build 'islands' of things that might be located on
-   the far side of cycles ,then modify the cycle finder to return a list of
-   cycles (i.e. a list of lists) ,then use each of cycle definition (a list) as
-   the root nodes for further search.
-
-   `path_stack` is a stack of LabelList. The first entry is a clone of the list of
-   root nodes, referenced by label. Each subsequent list is a clone of the
-   neighbor list of the leftmost node of the prior entry.
-
-   `path` is a list of the left most nodes, referenced by label, of the entries
-   on the path stack. This is the path to our current location in the tree.
-  */
-
-
-  private boolean find_and_remove_cycle(List<LabelList> path_stack ,LabelList path ,boolean verbose){
-
-    if( path.size() <= 1 ) return false; // 0 or 1 length path can't have a cycle
-
-    // we want to know if the most recent node added to the path occurs at a point earlier
-    // in the path.
-    int rightmost_index = path.size() - 1;
-    Label recent_node_label = path.get( rightmost_index );
-    int cycle_start_index = path.indexOf(recent_node_label);
-    if( cycle_start_index == -1 ){
-      System.err.println("find_and_remove_cycle:: indexOf does not find index of known list member");
-      return false;
-    }
-    Boolean has_cycle =  cycle_start_index < rightmost_index;
-    if(!has_cycle) return false;
-
-    if(verbose) System.out.print("mark_form_graph_descend:: dependency cycle found:");
-    for( Label cycle_node_label : path.subList(cycle_start_index ,path.size()) ){
-      if(verbose) System.out.print(" " + cycle_node_label);
-      Node cycle_node = lookup(cycle_node_label);
-      if( cycle_node.get("mark") == null ){
-        cycle_node.put( "mark" ,new HashTokenSet() );
-      }
-      ( (TokenSet)cycle_node.get("mark") ).add("cycle_member");
-    }
-    if(verbose) System.out.println("");
-
-    // We cannot continue searching after the loop, so we pop back to treat
-    // the first node in the loop as though a leaf node.
-    path_stack.subList( cycle_start_index + 1 ,path_stack.size() ).clear();
-
-    return true;
-  }
-
-  private static TokenSet mark_form_graph_descend_set = new TokenSet();
-  static {
-    mark_form_graph_descend_set.add(new Token("empty_path_stack"));
-    mark_form_graph_descend_set.add(new Token("cycle_found"));
-    mark_form_graph_descend_set.add(new Token("undefined_node"));
-    mark_form_graph_descend_set.add(new Token("exists_malformed"));
-    mark_form_graph_descend_set.add(new Token("defacto_leaf"));
-  }
-
-  private TokenSet mark_form_graph_descend( List<LabelList> path_stack ,boolean verbose ){
-    TokenSet ret_value = new HashSet<>();
-    if(path_stack.isEmpty()){
-      if(verbose) System.out.println( "mark_form_graph_descend:: given empty path_stack to descend from" );
-      ret_value.add( "empty_path_stack" );
-      return ret_value;
-    }
-
-    LabelList local_path = new ArrayList<>();
-    for(LabelList path : path_stack){
-      local_path.add( path.get(0) );
-    }
-    Label local_node_label = local_path.get( local_path.size() - 1 );
-  
-    do{
-      
-      if( find_and_remove_cycle(path_stack ,local_path ,verbose) ){
-        ret_value.add("cycle_found");
-        return ret_value;
-      }
-
-      TokenSet wellformed_mark_node_label_result = wellformed_mark_node_label(local_node_label ,verbose);
-      ret_value.addAll( wellformed_mark_node_label_result );
-      if( 
-         wellformed_mark_node_label_result.contains("undefined_node") 
-         || wellformed_mark_node_label_result.contains("defacto_leaf") 
-      ){
-        return ret_value;
-      }
-
-      // Descend further into the tree.
-      path_stack.add( new ArrayList<>((LabelList) lookup(local_node_label).get("neighbor")) );
-      local_node_label = (LabelList)lookup(local_node_label).get("neighbor").get(0);
-      local_path.add(local_node_label);
-
-    }while(true);
-  }
-
-   
-  /*
-    Given root_node_label_list, marks up the graph and returns a set possibly
-    containing 'all_wellformed' and 'cycles_exist'.
-
-    Marks potentially added to each node include 'cycle_member' and 'wellformed'.
-    Note that these marks are independent.
-  */
-  public TokenSet mark_form_graph(LabelList root_node_label_list ,boolean verbose){
-    TokenSet ret_value = new HashSet<>();
-    boolean exists_malformed = false;
-    TokenSet result; // used variously
-
-    if( root_node_label_list.isEmpty() ) return ret_value;
-
-    // Initialize the DFS tree iterator.
-    List<LabelList> path_stack = new ArrayList<>();
-    path_stack.add( new ArrayList<>(root_node_label_list) );
-
-    // iterate over left side tree descent, not ideal as it starts at the
-    // root each time, but avoids complexity in the cycle detection logic.
-    do{
-      result = mark_form_graph_descend(path_stack ,verbose);
-      if( result.contains("cycle_found") ) ret_value.add("cycle_exists");
-      if( result.contains("undefined_node") ) exists_malformed = true;
-      if( result.contains("exists_malformed") ) exists_malformed = true;
-
-      // increment the iterator to the next leftmost path
-      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( !exists_malformed ) ret_value.add("all_wellformed");
-
-    if( verbose ){
-      if( exists_malformed ) System.out.println("one or more malformed nodes were found");
-      boolean exists_cycle = ret_value.contains("cycle_exists");
-      if( exists_cycle ) System.out.println("one or more cyclic dependency loop found");
-      if( exists_malformed || exists_cycle ) System.out.println("will attempt to build unaffected nodes");
-    }
-
-    return ret_value;
-  }
-  public TokenSet mark_form_graph(LabelList root_node_label_list){
-    return mark_form_graph(root_node_label_list ,true);
-  }
-
-
-  /*--------------------------------------------------------------------------------
-    Graph traversal
-  */
-
-  // Given a node label, looks it up in the dependency graph, returns the node or null
-  public Node lookup(Label node_label ,boolean verbose){
-    if(node_label == null || node_label.isEmpty()){
-      if(verbose) System.out.println("lookup:: given node_label is null or an empty string");
-      return null;
-    }
-
-    // Try the map
-    Node node = this.node_map.get(node_label);
-    if(node != null){
-      node.put("label" ,node_label);
-      if(verbose) System.out.println("lookup:: found from map: " + node);
-      return node;
-    }
-    // At this point, node will be null
-
-    // The map lookup failed, let's try the function recognizer list
-    Node match_result = null;
-    for (RecognizerF func : this.recognizer_f_list){
-      Node match_result = func.apply(node_label); 
-      if("matched".equals(match_result.get("status"))){
-        node = match_result;
-        break;
-      }
-    }
-
-    if(verbose){
-      if(node != null) System.out.println("lookup:: found from recognizer function: " + node);
-      else System.out.println("lookup:: failed to find label: " + node_label);
-    }
-
-    return node;
-  }
-  public Node lookup(Label node_label){
-    return lookup(node_label ,true);
-  }
-
-  // Mark aware lookup function
-  public Node lookup_marked_good(Label node_label ,boolean verbose){
-    Node node = lookup(node_label ,verbose);
-    if(node != null && marked_good_q(node)) return node;
-    return null;
-  }
-  public Node lookup_marked_good(Label node_label){
-    return lookup_marked_good(node_label ,true);
-  }
-
-  /*
-    Given `root_node_label_list` of a DAG, applies `node_function` to each node in a
-    depth-first traversal order. Returns a set of error tokens encountered
-    during traversal.
-
-    `mark_form_graph` must be run on the DAG before this function is called, or
-    `lookup_marked_good` will not function correctly.
-  */
-  public TokenSet all_DAG_DF(LabelList root_node_label_list ,BiConsumer<Node ,TokenSet> node_function ,boolean verbose){
-    if(verbose) System.out.println("all_DAG_DF::");
-
-    TokenSet error_token_set = new HashSet<>();
-
-    boolean accept_arg_list = true;
-    if(node_function == null){
-      error_token_set.add("null_node_function");
-      accept_arg_list = false;
-    }
-    if(!(node_function instanceof BiFunction)){
-      error_token_set.add("node_function_not_a_function");
-      accept_arg_list = false;
-    }
-    if(root_node_label_list == null){
-      error_token_set.add("null_root_node_label_list");
-      accept_arg_list = false;
-    }
-    if(root_node_label_list.isEmpty()){
-      error_token_set.add("empty_root_node_label_list");
-      accept_arg_list = false;
-    }
-    if(!accept_arg_list) return error_token_set;
-
-    TokenSet visited = new HashSet<>();
-    List<Node> in_traversal_order = new ArrayList<>();
-
-    Stack<Label> stack = new Stack<>();
-    root_node_label_list.forEach(stack::push);
-
-    while( !stack.isEmpty() ){
-      Label node_label = stack.pop();
-
-      Node node = lookup_marked_good(node_label ,verbose);
-      if(node == null){
-        error_token_set.add("lookup_fail");
-        continue;
-      }
-
-      if(visited.contains(node.get("label"))) continue;
-      visited.add((Label)node.get("label"));
-
-      in_traversal_order.add(node);
-
-      stack.addAll( (LabelList)node.get("neighbor") );
-    }
-
-    Collections.reverse(in_traversal_order);
-    for(Node node : in_traversal_order){
-      node_function.apply(node ,error_token_set);
-    }
-
-    return error_token_set;
-  }
-  public TokenSet all_DAG_DF(LabelList root_node_label_list ,BiConsumer<Node ,TokenSet> node_function){
-    return all_DAG_DF(root_node_label_list ,node_function ,true);
-  }
-
-  /*--------------------------------------------------------------------------------
-    run the build scripts
-    depends upon is_acyclic having already marked up the graph.
-  */
-
-  // A dependency is "good" if it is marked good, and for leaf or path, if the
-  // corresponding file exists
-  public boolean good_dependency_q(LabelList node_labels){
-    return node_labels.stream().allMatch(node_label -> {
-        Node node = lookup_marked_good(node_label);
-        if( node == null ) return false;
-        if(
-          ("path".equals(node.get("type")) || "leaf".equals(node.get("type")) )
-          && !file_exists_q( (Label) node.get("label") )
-        ){
-          return false;
-        }
-        return true;
-      });
-  }
-
-  /*
-    Given a node label and a list of node labels, returns true if the file at the
-    node label in the first argument is newer than all the files at the
-    corresponding node labels in the second list.
-  */
-  public boolean newer_than_all(Label node_label ,LabelList node_label_list) throws IOException {
-    Path node_path = Paths.get(node_label);
-    if (!Files.exists(node_path)) return false;
-
-    long node_last_modified = Files.getLastModifiedTime(node_path).toMillis();
-
-    return node_label_list.stream().allMatch(label -> {
-        try {
-          Path path = Paths.get(label);
-          if (!Files.exists(path)) return false;
-          long last_modified = Files.getLastModifiedTime(path).toMillis();
-          return node_last_modified > last_modified;
-        } catch (IOException e){
-          return false;
-        }
-      });
-  }
-
-  public boolean can_be_built_q(Node node){
-    if( !marked_good_q(node) ) return false;
-    if(
-       ( "symbol".equals(node.get("type")) || "path".equals(node.get("type")) )
-        && !good_dependency_q( (LabelList)node.get("neighbor") ) 
-    ){
-      return false;
-    }
-    if( 
-       "leaf".equals( node.get("type") ) 
-       && !file_exists_q( (Label)node.get("label") )
-    ){
-      return false;
-    }
-    return true;
-  }
-
-  // `can_be_build_q` must be true for this to be meaningful:
-  public boolean should_be_built_q(Node node ,boolean verbose) throws IOException {
-    if ("leaf".equals(node.get("type"))) return false;
-    if ("symbol".equals(node.get("type"))) return true;
-    if ("path".equals(node.get("type"))) return !newer_than_all((Label) node.get("label") ,(LabelList) node.get("neighbor"));
-    
-    if (verbose){
-      System.out.println("should_be_build_q:: unrecognized node type, so assuming it should not be built.");
-    }
-    return false;
-  }
-  public boolean should_be_built_q(Node node) throws IOException {
-    return should_be_built_q(node ,true);
-  }
-
-  /*
-    Runs the build scripts, assuming the graph has been marked up already.
-  */
-  public void run_build_scripts_f(LabelList root_node_label_list ,boolean verbose) throws IOException {
-
-    if(root_node_label_list.isEmpty()) return;
-
-    TokenSet error_token_set = new HashSet<>(); // used to catch return values
-
-    System.out.println("run_build_script:: Checking if graph is well formed.");
-    error_token_set = mark_form_graph(root_node_label_list);
-    if(error_token_set != null && !error_token_set.isEmpty()){
-      System.out.println("Graph is not well-formed. Expect build problems. Errors:");
-      error_token_set.forEach(token -> System.out.println("  - " + token));
-    } else {
-      System.out.println("Graph is well-formed. Proceeding with build.");
-    }
-
-    // Define the node function
-    BiConsumer<Node ,TokenSet> node_function = (node ,error_token_set_2) -> {
-      if(!can_be_built_q(node)){
-        System.out.println("run_build_scripts_f:: Skipping build for " + node.get("label") + " due to problems with dependencies.");
-        return;
-      }
-      if(!should_be_built_q(node)){
-        if(verbose) System.out.println("run_build_scripts_f:: " + node.get("label") + " already up to date");
-        return;
-      }
-
-      // Build the target
-      System.out.println("run_build_scripts_f:: Running build script for " + node.get("label"));
-      // Assuming node.build() is a method in the Map or a related object
-      // Replace this with the actual build function for the node
-      // node.build();
-
-      // For path nodes, check if the build updated the target path
-      if("path".equals(node.get("type")) && should_be_built_q(node)){
-        System.out.println("run_build_scripts_f:: Build failed for " + node.get("label"));
-        set_mark(node ,"build_failed");
-      }
-    };
-
-    System.out.println("run_build_scripts_f:: running ...");
-    error_token_set = all_DAG_DF(root_node_label_list ,node_function ,verbose);
-    if(error_token_set != null){
-      error_token_set.forEach(error -> System.out.println("run_build_scripts_f::all_DAG_DF:: " + error));
-    }
-  }
-  public void run_build_scripts_f(LabelList root_node_label_list) throws IOException {
-    run_build_scripts_f(root_node_label_list ,true);
-  }
-
-}
diff --git a/developer/deprecated/cycle_case.java b/developer/deprecated/cycle_case.java
deleted file mode 100644 (file)
index 040654b..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-      //----------------------------------------
-      // cycle case
-      //
-      
-      List<Integer>  cycle_index_interval;
-      if( cycle_index_interval=path_find_cycle(left_path ,verbose) ){
-        ret_value.add( "cycle_found" );
-
-        int cycle_i0 = cycle_index_interval.get(0); // cycle leftmost, inclusive
-        int cycle_n = cycle_index_interval.get(1);  // cycle rightmost, inclusive
-
-        if(verbose) Util.print_list(
-          "Found cycle:" 
-          ,left_path.subList( cycle_i0 ,n +1)
-        );
-
-        // mark cycle
-        LabelList undefined_node_list;
-        int i = cycle_i0;
-        do{
-          node_label = left_path.get(i);
-          node = super.lookup(node_label);
-          if(node){
-            if( node.get("mark") == null ){
-              node.put( "mark" ,new HashTokenSet() );
-            }
-            ( (TokenSet)node.get("mark") ).add("cycle_member");
-          }else{
-            undefined_node_list.add(node_label);
-            ret_value.add( "undefined_node" );
-          }
-          i++;
-          if( i > cycle_n ) break;
-        }while(true);
-
-        if(verbose) Util.print_list(
-          "Each undefined node could not be marked as a cycle member:" 
-          ,undefined_node_list
-        );
-
-        // Reset the graph iterator to immediately top of the cycle, then return
-        // as though we had hit a leaf node. (Upon return the the i0 node will
-        // be dropped as part of incrementing the iterator.)
-        path_stack.subList(cycle_i0 + 1 ,cycle_n + 1).clear();
-
-        return ret_value;
-      } 
-
diff --git a/developer/deprecated/dependency_graph_definition.groovy b/developer/deprecated/dependency_graph_definition.groovy
deleted file mode 100644 (file)
index 387283b..0000000
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- Here the developer describes the build environment and the graph of
- dependencies between files to be built.
-
- Each file is given a 'node'.  The node label is a path
- to the file, existing or not. Node's can also be 'symbolic'
- in that the label does not correspond to a file.
-
- File paths are relative to the developer's directory.  Also
- known as $DEVELOPER_HOME.
-
- The program that processes this file is
- `executor/build_from_dependency_graph.groovy`.  There are more notes and
- definitions there.
-*/
-
-
-/*--------------------------------------------------------------------------------
- The build environment
-
- Each tool has its '_IN' and '_OUT' directories that are referenced in
- their build scripts. This keeps references in the build script local.
- (Flow of files between tools can be seen in the overlapping definitions
- among the various _IN and _OUT directories.)
-
- These suffixes are sometimes used to eliminate ambiguity:
-
- _FN  = File Name
- _FP  = File Path (last element of the FP is the FN)
- _DN  = Directory Name
- _DP  = Directory path (last element of the DP is the DN)
-
- _FNL = File Name list
- _FPL = File Path List 
- _DNL = Directory path list
- _DPL = Directory path list
-
- Files in a _LEAF directory can not be built, and should never be deleted by the tools.
-
-*/
-
-def env = [:]
-
-// Required shell environment variables
-def varName_List = [
-  'REPO_HOME'
-  ,'PROJECT'
-  ,'ENV_BUILD_VERSION'
-  ,'DEVELOPER_HOME'
-]
-varName_List.each { varName ->
-  env[varName] = System.getenv(varName) ?: ""
-}
-
-// Optional shell environment variables
-def varNameOptional_List = [
-  'CLASSPATH'
-]
-varNameOptional_List.each { varName ->
-  env[varName] = System.getenv(varName) ?: ""
-}
-
-env.CLASSPATH += ":${env.ANTLR_JAR}"
-
-// tools used in build scripts
-def JAVA_COMP_FP = "${env.JAVA_HOME}/bin/javac"   // Java compiler path
-def JAVA_INTERP_FP = "${env.JAVA_HOME}/bin/java"  // Java interpreter path
-def JAVA_ARCHIVE_FP = "${env.JAVA_HOME}/bin/jar"  // Java archive tool path
-
-def dir_map = [
-  'ANTLR_IN_LEAF'       : 'ANTLR/'
-  ,'ANTLR_OUT'           : 'javac/ANTLR/'
-  ,'ANTLR_OUT_PARENT'    : 'javac/' // required by the antlr command to be a base for OUT
-  ,'EXECUTOR_IN'         : 'executor/'
-  ,'JAVA_COMP_IN'        : 'javac/'
-  ,'JAVA_COMP_IN_LEAF': 'javac/leaf/'
-  ,'JAVA_COMP_IN_ANTLR'  : 'javac/ANTLR/'
-  ,'JAVA_COMP_IN_SYN'    : 'javac/synthesized/'
-  ,'JAVA_COMP_OUT'       : 'jvm/'
-  ,'JVM_IN'              : 'jvm/'
-  ,'TEMP'                : 'scratch_pad/'
-]
-
-env.CLASSPATH += ":${dir_map.JVM_IN}"
-
-dir_map.JAVA_COMP_IN_LIST = 
-  "${dir_map.JAVA_COMP_IN_LEAF}" 
-  +":${dir_map.JAVA_COMP_IN_ANTLR}" 
-  +":${dir_map.JAVA_COMP_IN_SYN}"
-
-//--------------------------------------------------------------------------------
-// required environment variable check.  Will add additional preface checks here
-// should they become available.
-//
-
-// a helper function for `environment_check`
-def print_missing_var_list(missing_var_list){
-  if(missing_var_list.isEmpty()){
-    // Print nothing if the list is empty
-    return
-  } else if(missing_var_list.size() == 1){
-    println "This environment variable was not set: ${missing_var_list[0]}"
-  } else {
-    println "These environment variables were not set: ${missing_var_list.join(' ,')}"
-  }
-}
-
-task environment_check {
-  dependsOn ':installTools'
-  doFirst {
-
-    println "CLASSPATH: ${env.CLASSPATH}"
-    println "JAVA_COMP_IN_LIST: ${dir_map.JAVA_COMP_IN_LIST}"
-    
-    // did the required variables have definitions?
-    def error_missing = false
-    def error_project = false
-    def missing_var_list = [] // To collect missing environment variables
-    varName_List.each { varName ->
-      if(!env[varName]){
-        error_missing = true
-        missing_var_list << varName
-      }
-    }
-    print_missing_var_list(missing_var_list)
-    
-    // did the required variables have definitions?
-    if(env.PROJECT != "GQL_to_Cypher"){
-      error_project = true
-      println "Expected project 'GQL_to_Cypher' ,but found '${env.PROJECT}'."
-    }
-    if(error_missing || error_project){
-      throw new GradleException("Bailing due to missing environment variables.")
-    }
-  }
-  doLast {
-    println "================================================================================"
-    println "Building project .."
-  }
-}
-
-/*--------------------------------------------------------------------------------
-  Map keyed on label node definitions
-
-*/
-
-def node_map = [
-
-  "all" : [
-    ,type: "symbol"
-    ,neighbor: [
-      "ANTLR_OUT_FL"
-      ,"RuleNameList"
-      ,"RuleNameListRegx"
-      ,"Synthesize_SyntaxAnnotate"
-      ,"Synthesize_SyntaxAnnotate_PrintVisitor"
-      ,"Synthesize_SyntaxAnnotate_PrintVisitorMethod"
-    ]
-  ]
-
-  "ANTLR_OUT_FL" : [
-    ,type: "symbol"
-    ,neighbor: ["${dir_map.EXECUTOR_IN}/ANTLR_OUT_FL"]
-  ]
-
-  ,"RuleNameList" : [
-    ,type: "symbol"
-    ,neighbor: ["${dir_map.EXECUTOR_IN}/RuleNameList"]
-  ]
-
-  ,"RuleNameListRegx" : [
-    ,type: "symbol"
-    ,neighbor: ["${dir_map.EXECUTOR_IN}/RuleNameListRegx"]
-  ]
-
-  ,"Synthesize_SyntaxAnnotate" : [
-    ,type: "symbol"
-    ,neighbor: [
-      "${dir_map.JAVA_COMP_IN_LEAF}/StringUtils.java"
-      ,"${dir_map.EXECUTOR_IN}/Synthesize_SyntaxAnnotate"
-    ]
-  ]
-
-  "Synthesize_SyntaxAnnotate.class" : [
-    type: 'path' , // It's a path type node
-    ,neighbor: [
-      "${dir_map.JAVA_COMP_IN_LEAF}/Synthesize_SyntaxAnnotate.java" , // Dependency
-      "${dir_map.JAVA_COMP_IN_LEAF}/StringUtils.java"  // Dependency
-    ]
-    ,build: { node ,neighbor ->
-      def javac_cmd = "${JAVA_COMP_FP} -d ${dir_map.JAVA_COMP_OUT} ${neighbor.join(' ')}"
-      javac_cmd.execute().waitFor()
-    }
-  ]
-
-  ,"Synthesize_SyntaxAnnotate_PrintVisitor" : [
-    ,type: "symbol"
-    ,neighbor: [
-      "${dir_map.JAVA_COMP_IN_LEAF}/StringUtils.java"
-      ,"${dir_map.JAVA_COMP_IN_LEAF}/Synthesize_SyntaxAnnotate_PrintVisitorMethod.java"
-      ,"${dir_map.EXECUTOR_IN}/Synthesize_SyntaxAnnotate_PrintVisitor"
-    ]
-  ]
-
-  ,"Synthesize_SyntaxAnnotate_PrintVisitorMethod" : [
-    ,type: "symbol"
-    ,neighbor: [
-      "${dir_map.JAVA_COMP_IN_LEAF}/StringUtils.java"
-      ,"${dir_map.EXECUTOR_IN}/Synthesize_SyntaxAnnotate_PrintVisitorMethod"
-    ]
-  ]
-]
-
-
-
-//--------------------------------------------------------------------------------
-// node making functions
-//
-
-// javac/leaf/<x> returns leaf node for javac/leaf/<x>
-def node_leaf_f(node_label) {
-  def leafNodePattern = ~/${dir_map['JAVA_COMP_IN_LEAF']}(.*)/
-  def match = node_label =~ leafNodePattern
-  if (!match) {
-    return [status: "no_match"]
-  }
-  def baseName = match[0][1]
-
-  def leafFilePath = "${dir_map['JAVA_COMP_IN_LEAF']}${baseName}"
-  def leafFile = new File(leafFilePath)
-  if (!leafFile.exists()) {
-    return [status: "no_match"]
-  }
-
-  return [
-    status: "matched"
-    ,label: node_label
-    ,type: "leaf"
-    ,neighbor: []
-  ]
-}
-
-// given executor/<x> returns node to build script wrapping jvm/<x>.jar
-def node_executor_f(node) {
-
-  def match = node =~ /^(executor\/)(${base})$/
-  if (!match) {
-    return [status: "no_match"]
-  }
-  def baseName = match[0][2]
-
-  def jarFilePath = "${dir_map['JVM_IN']}${baseName}.jar"
-  def wrapperFilePath = "${dir_map['EXECUTOR_IN']}${baseName}"
-
-  def jarFile = new File(jarFilePath)
-  if (!jarFile.exists()) {
-    return [status: "no_match"]
-  }
-
-  return [
-    status: "matched"
-    ,label: node
-    ,type: "path"
-    ,neighbor: [jarFilePath]
-    ,must_have: [jarFilePath]
-    ,build: { node ,neighbor -> 
-
-      // The script for wrapping the jar file:
-      def wrapper =
-      """
-      #!/usr/bin/env bash
-      ${dir_map['JAVA_INTERP']} -cp \${CLASSPATH}:${dir_map['JVM_IN']}:${dir_map['JVM_IN']}/${baseName}.jar ${baseName} \\\$\\@
-      """
-      
-      new File(wrapperFilePath).withWriter('UTF-8') { writer ->
-        writer.write(wrapper)
-      }
-
-      println "Creating executable wrapper script for ${baseName} in executor directory."
-      "chmod +x ${wrapperFilePath}".execute().text
-    }
-  ]
-}
-
-// given javac/ANTLR/<x>.java, returns node to build grammar <x>.g4
-def node_grammar_f(node) {
-
-  def match = node =~ /^(${dir_map['ANTLR_OUT']})(${base})(Lexer|Parser|BaseListener|Listener|BaseVisitor|Visitor)\.java$/
-  if( !match ){
-    return [status: "no_match"]
-  }
-
-  def grammarName = match[0][2]
-  def outputType = match[0][3]
-
-  def grammarFilePath = "${dir_map['ANTLR_IN_LEAF']}${grammarName}.g4"
-  def grammarFile = new File(grammarFilePath)
-
-  if( !grammarFile.exists() ){
-    return [status: "no_match"]
-  }
-
-  return [
-    status: "matched"
-    ,label: node
-    ,type: "path"
-    ,neighbor: [grammarFilePath]
-  ]
-}
-
-// given <x>.class returns node to build <x>.class from <x>.java
-def node_class_f(node) {
-
-  def match = node =~ /^(${dir_map['JAVA_COMP_OUT']})(${base})\.class$/
-  if( !match ){
-    return [status: "no_match"]
-  }
-
-  def baseName = match[0][2]
-  def javaFilePath = "${dir_map['JAVA_COMP_IN_PRIMARY_DIR']}/${baseName}.java"
-  def javaFile = new File(javaFilePath)
-
-  if( !javaFile.exists() ){
-    return [status: "no_match"]
-  }
-
-  return [
-    status: "matched",
-    label: node,
-    type: "path",  // It's a path node since we're building the .class file
-    neighbor: [javaFilePath],  // The corresponding .java file
-    build: { node, neighbor ->
-        def javac_cmd = "${JAVA_COMP_FP} -d ${dir_map.JAVA_COMP_OUT} -sourcepath ${dir_map.JAVA_COMP_IN_DL} ${neighbor[0]}"
-        javac_cmd.execute().waitFor()
-    }
-  ]
-}
-
-// given <x>.jar returns node to build <x>.jar from <x>.class
-def node_jar_f(node) {
-
-  // Use the symbolic name and base patterns
-  def match = node =~ /^(${dir_map['JAVA_COMP_OUT']})(${base})\.jar$/
-
-  if( !match ){
-    return [status: "no_match"]
-  }
-
-  def baseName = match[0][2]
-  def classFilePath = "${dir_map['JAVA_COMP_OUT']}${baseName}.class"
-  def classFile = new File(classFilePath)
-
-  if( !classFile.exists() ){
-    return [status: "no_match"]
-  }
-
-  return [
-    status: "matched"
-    ,label: node
-    ,type: "path"
-    ,neighbor: [classFilePath]
-    ,build: { node ,neighbor ->
-      println "Building jar for ${baseName}"
-      def command = "${ext.javaHome}/bin/jar cf ${baseName}.jar -C ${dir_map['JAVA_COMP_OUT']} ${baseName}.class"
-      return command.execute().text;
-    }
-  ]
-}
-
-// list of the recognizer functions
-def node_f_list = [
-  node_leaf_f
-  ,node_executor_f
-  ,node_grammar_f
-  ,node_class_f
-  ,node_jar_f
-]
-
-// comprehensions to make regexprs more readable
-def base = "[a-zA-Z0-9_-]+"
-def ext = "[a-zA-Z0-9_-]+$"
-def name = "${base}\\.${ext}"
-def path = ".+/${name}"
-
-
-
-// LocalWords:  wellformed
diff --git a/developer/deprecated/groovyc/#AriadneGraph.groovy# b/developer/deprecated/groovyc/#AriadneGraph.groovy#
deleted file mode 100644 (file)
index e9d8f2b..0000000
+++ /dev/null
@@ -1,632 +0,0 @@
-import java.nio.file.Files
-import java.nio.file.Paths
-
-class AriadneGraph {
-
-  //--------------------------------------------------------------------------------
-  // instance data
-  //
-
-  static Boolean debug = true
-  Map node_map = [:]
-  List node_f_list = []
-
-
-  AriadneGraph(Map node_map ,List node_f_list){
-    def accept_arg_list = true;
-    if( !(node_map === null) && !(node_map instanceof Map) ) accept_arg_list = false
-    if( !(node_f_list === null) && !(node_f_list instanceof List) ) accept_arg_list = false
-    if(node_map === null && node_f_list === null) accept_arg_list = false
-    if(!accept_arg_list){
-      println "AriandreGraph: requiers one or both of 'node_map' as Map, and 'node_f_list as List.'"
-      System.exit(1)
-    }
-    this.node_map = node_map ?: [:]
-    this.node_f_list = node_f_list ?: []
-  }
-
-  //--------------------------------------------------------------------------------
-  // File utility functions
-
-  public static Map<String ,String> unpack_file_path(String file_fp){
-    if( debug ) System.out.println("unpack_file_path::file_fp: " + file_fp);
-
-    File file = new File(file_fp);
-    String parent_dp = (file.getParent() != null) ? file.getParent() : "";
-
-    if( !parent_dp.isEmpty() && !parent_dp.endsWith(File.separator) ){
-      parent_dp += File.separator;
-    }
-
-    String file_fn = file.getName();
-    String file_fn_base = file_fn;
-    String file_fn_ext = "";
-
-    int last_index = file_fn.lastIndexOf('.');
-    if( last_index > 0 ){
-      file_fn_base = file_fn.substring(0 ,last_index);
-      if( last_index + 1 < file_fn.length() ){
-        file_fn_ext = file_fn.substring(last_index + 1);
-      }
-    }
-
-    Map<String ,String> ret_val = new HashMap<>();
-    ret_val.put("dp" ,parent_dp);
-    ret_val.put("fn" ,file_fn);
-    ret_val.put("fn_base" ,file_fn_base);
-    ret_val.put("fn_ext" ,file_fn_ext);
-
-    if( debug ) System.out.println("unpack_file_path::ret_val: " + ret_val);
-
-    return ret_val;
-  }
-
-  public static boolean file_exists_q(String node_label){
-    Path node_path = Paths.get(node_label);
-    return Files.exists(node_path);
-  }
-}
-
-
-  /*--------------------------------------------------------------------------------
-   File utility functions
-  */
-  static Map unpack_file_path(String file_fp) {
-    if (debug) println("unpack_file_path::file_fp: ${file_fp}")
-
-    def file = new File(file_fp)
-    def parent_dp = file.getParent() ?: ""
-
-    if (parent_dp && !parent_dp.endsWith(File.separator)) {
-      parent_dp += File.separator
-    }
-
-    def file_fn = file.getName()
-    def file_fn_base = file_fn
-    def file_fn_ext = ''
-
-    if (file_fn.lastIndexOf('.') > 0) {
-      file_fn_base = file_fn[0..file_fn.lastIndexOf('.') - 1]
-      if (file_fn.lastIndexOf('.') + 1 < file_fn.length()) {
-        file_fn_ext = file_fn[file_fn.lastIndexOf('.') + 1..-1]
-      }
-    }
-
-    def ret_val = [
-      dp      : parent_dp,
-      fn      : file_fn,
-      fn_base : file_fn_base,
-      fn_ext  : file_fn_ext
-    ]
-    if (debug) println("unpack_file_path::ret_val: ${ret_val}")
-
-    return ret_val
-  }
-
-  static boolean file_exists_q( String node_label ){
-    def node_path = Paths.get( node_label )
-    return Files.exists( node_path )
-  }
-
-  /*--------------------------------------------------------------------------------
-   Node type checks and marking
-  */
-
-  static Set all_node_type_set = [
-    'symbol'  // label is a symbol
-    ,'path'   // label is a path to a file, though it might not exist
-    ,'leaf'   // label is a path to a file that has no dependencies
-    ,'generator' // label is a path, but node has no neighbors
-    ,'error'   // typically created by the system node has a message property
-  ] as Set
-
-  static Set persistent_node_mark_set = 
-    [
-    'cycle_member' 
-     ,'wellformed' 
-     ,'build_failed'
-     ,'null_node'
-     ] as Set
-
-  static boolean leaf_q( Map node ){
-    return node && node.type == 'leaf'
-  }
-
-  static boolean has_mark( Map node ){
-    return node?.mark?.isNotEmpty()
-  }
-
-  static void set_mark( Map node ,String mark ){
-    node.mark = node.mark ?: [] as Set
-    node.mark << mark
-  }
-
-  static void clear_mark( Map node ,String mark ){
-    node?.mark?.remove( mark )
-  }
-
-  static boolean marked_good_q( Map node ){
-    return node && node.mark && ( 'wellformed' in node.mark ) && !( 'cycle_member' in node.mark ) && !( 'build_failed' in node.mark )
-  }
-
-  /*--------------------------------------------------------------------------------
-   Well-formed Node Check
-  */
-
-  static Set all_form_error_set = [
-    'no_node'
-    ,'node_must_have_label'
-    ,'label_must_be_string'
-    ,'node_must_have_type'
-    ,'bad_node_type'
-    ,'neighbor_value_must_be_list'
-    ,'neighbor_reference_must_be_string'
-    ,'neighbor_label_not_in_graph'
-    ,'mark_property_value_must_be_set'
-    ,'unregistered_mark'
-    ,'missing_required_build_code'
-    ,'leaf_given_neighbor_property'
-    ,'leaf_given_build_property'
-  ] as Set
-
-  static Set wellformed_q( Map node ){
-    def form_error_set = [] as Set
-
-    if( !node ){
-      form_error_set << 'null_node'
-      return form_error_set
-    }
-
-    if( !node.label )
-      form_error_set << 'node_must_have_label'
-    else if( !( node.label instanceof String ) )
-      form_error_set << 'label_must_be_string'
-
-    if( !node.type )
-      form_error_set << 'node_must_have_type'
-    else if( !( node.type instanceof String ) || !( node.type in all_node_type_set ) )
-      form_error_set << 'bad_node_type'
-
-    if( node.neighbor ){
-      if( !( node.neighbor instanceof List ) )
-        form_error_set << 'neighbor_value_must_be_list'
-      else if( !( node.neighbor.every { it instanceof String } ) )
-        form_error_set << 'neighbor_reference_must_be_string'
-    }
-
-    if( node.mark ){
-      if( !( node.mark instanceof Set ) )
-        form_error_set << 'mark_property_value_must_be_set'
-      else if( !( node.mark.every { it in persistent_node_mark_set } ) )
-        form_error_set << 'unregistered_mark'
-    }
-
-    if( node.type == 'path' && ( !node.build || !( node.build instanceof Closure ) ) )
-      form_error_set << 'missing_required_build_code'
-
-    if( node.type == 'leaf' ){
-      if( node.neighbor ) form_error_set << 'leaf_given_neighbor_property'
-      if( node.build ) form_error_set << 'leaf_given_build_property'
-    }
-
-    return form_error_set
-  }
-
-  /*--------------------------------------------------------------------------------
-   A well formed graph checker.  Traverses entire graph and marks nodes
-   that are not well formed or that are part of a cycle.
-
-   This must be run on the graph for `lookup_marked_good` to work.
-  */
-
-  def mark_node_form(node ,verbose = true){
-    if(debug){
-      if(node)
-        println("mark_node_form::node: ${node}")
-      else
-        println("mark_node_form given a null node")
-    }
-    
-    def form_errors = wellformed_q(node)
-    if( form_errors.isEmpty() ){
-      set_mark(node ,'wellformed');
-      return 'wellformed'
-    }
-    // at this point we know that form_errors is not empty
-    
-    if(verbose){
-      if(node && node.label && node.label.length() > 0)
-        print("node ${neighbor_node.label} is malformed due to:")
-      else
-        print("anonymous node is malformed due to:")
-      form_errors.each { error -> print(" ${error}") }
-      println("")
-    }
-
-    return 'malformed'
-  }
-
-
-  /* 
-   Each node_label must be a string and not empty.
-
-   Subleties here because we have not yet determined if the nodes we are
-   wellformed (after all, that is what we are determining here).
-
-   Given a path stack initialized with the path root ,descends to a leaf node
-   while looking for cycles. Marks nodes as to their form.  Returns a set of
-   tokens.
-
-   If we want to attempt to build 'islands' of things that might be located on
-   the far side of cycles, then modify the cycle finder to return a list of
-   cycles (i.e. a list of lists), then use each of cycle definition (a list) as
-   the root nodes for further search.
-
-
-   */
-  static Set markup_graph_f_descend_set = [
-    'empty_path_stack'
-    ,'cycle_found'
-    ,'undefined_node'
-    ,'exists_malformed'
-    ,'defacto_leaf'
-  ] as Set
-
-  def markup_graph_f_descend(path_stack ,boolean verbose = true){
-    def ret_value = [] as Set
-    if( path_stack.isEmpty() ){
-      if(verbose) println( "markup_graph_f_descend:: given empty path_stack to descend from")
-      ret_value << 'empty_path_stack'
-      return ret_value
-    }
-    def local_path = path_stack.collect{ it[0] }
-    def local_node_label = local_path[-1]
-    def cycle_start_index
-
-    do{
-
-      // Check for a cycle in the local path, if found marks cycle members
-      if( local_path.size() > 1){
-        cycle_start_index = local_path[0..-2].findIndexOf{ it == local_node_label }
-        if(cycle_start_index != -1){ // Cycle detected
-          ret_value << 'cycle_found'
-          if(verbose) print "markup_graph_f_descend:: dependency cycle found:"
-          local_path[cycle_start_index..-1].each{ cycle_node_label ->
-            if(verbose) print " ${cycle_node_label}"
-            def cycle_node = lookup(cycle_node_label)
-            cycle_node.mark = cycle_node.mark ?: [] as Set // Initialize mark set if needed
-            cycle_node.mark << 'cycle_member'
-          }
-          if(verbose) println ""
-          // we can not continue searching after the loop so ,we pop back to treat
-          // the first node in the loop as though a leaf node.
-          path_stack = path_stack[0..cycle_start_index]
-          return ret_value
-        }
-      }
-
-      def local_node = lookup(local_node_label)
-      if( !local_node ){
-        ret_value << 'undefined_node' 
-        return ret_value
-      }
-      if( mark_node_form(local_node) == 'malformed' ){
-        ret_value << 'exists_malformed'
-      }
-      if( local_node.neighbor.isEmpty() ){
-        ret_value << 'defacto_leaf' // might not be `type:leaf`
-        return ret_value
-      }
-
-      // Descend further into the tree.
-      path_stack << local_node.neighbor.clone()
-      local_node_label = local_node.neighbor[0]
-      local_path << local_node_label
-    }while(true)
-  }
-
-  /*
-   Given root_node_label_list ,marks up the graph and returns a set possibly
-   containing 'all_wellformed' and 'cycles_exist'.
-
-   Marks potentially added to each node include  'cycle_member' ,'wellformed'.
-   Note that these marks are independent.
-  */
-  def wellformed_graph_q(root_node_label_list ,boolean verbose = true){
-    def ret_value = [] as Set
-    def exists_malformed = false;
-    def result // used variously
-
-    if( root_node_label_list.isEmpty() ) return ret_value
-    
-    // Initialize the DFS tree iterator.
-    def path_stack = []
-    path_stack << root_node_label_list.clone()
-
-    // iterate over left side tree descent ,not ideal as it starts at the
-    // root each time ,but avoids complexity in the cycle detection logic.
-    do{
-      result = markup_graph_f_descend(path_stack ,verbose)
-      if('cycle_found' in result) ret_value << 'cycle_exists'
-      if('undefined_node' in result) exists_malformed = true;
-      if('exists_malformed' in result) exists_malformed = true;
-
-      // increment the iterator to the next leftmost path
-      def top_list = path_stack[-1]
-      top_list.remove(0)
-      if(top_list.isEmpty()) path_stack.pop()
-
-    }while(!path_stack.isEmpty())
-
-    if(!exists_malformed) ret_value << 'all_wellformed'
-    if( verbose ){
-      if(exists_malformed) println("one or more malformed nodes were found")
-      def exists_cycle = 'cycle_found' in ret_value
-      if(exists_cycle) println("one or more cyclic dependency loop found")
-      if( exists_malformed || exists_cycle ) println("will attempt to build unaffected nodes")
-    }
-
-    return ret_value
-  }
-
-  /*--------------------------------------------------------------------------------
-     Graph traversal
-  */
-
-  // given a node label, looks it up on the dependency graph, returns the node or null
-  Map lookup(String node_label ,boolean verbose = true){
-
-    if(!node_label){
-      if(verbose) println("lookup:: given node_label is null or an empty string")
-      return null
-    }
-
-    // try the map
-    def node = this.node_map[node_label]
-    if(node){
-      node.label = node_label
-      if(verbose) println("lookup:: found from map: ${node}")
-      return node
-    }
-    // at this point node will be null
-
-    // The map lookup failed, lets try the function recognizer list ..
-    def match_result
-    for( func in this.node_f_list ){
-      match_result = func(node_label)
-      if( match_result.status == 'matched' ){
-        node = match_result
-        break
-      }
-    }
-
-    if(verbose)
-      if(node) println("lookup:: found from recognizer function: ${node}")
-      else println("lookup:: failed to find label: ${node_label}")
-
-    return node
-  }
-
-  // mark aware lookup function
-  def lookup_marked_good(node_label ,verbose = true){
-    def node = lookup(node_label ,verbose)
-    if( node && marked_good_q(node) ) return node;
-    return null;
-  }
-
-
-  /*
-   Given `root_node_label_list` of a DAG. Applies `node_function` to each node in a
-   depth-first traversal order.  Returns a set of error tokens encountered
-   during traversal.
-
-   `wellformed_graph_q` must be run on the DAG before this function is called ,or
-   `lookup_marked_good` will not function correctly.
-  */
-  def all_DAG_DF(root_node_label_list ,node_function ,boolean verbose = true) {
-    if(verbose) println("all_DAG_DF::")
-
-    def error_token_set = [] as Set
-
-    def accept_arg_list = true
-    if( !node_function ){
-      error_token_set << 'null_node_function'
-      accept_arg_list = false
-    }
-    if( !(node_function instanceof Closure) ){
-      error_token_set << 'nod_function_not_a_function'
-      accept_arg_list = false
-    }
-    if( !root_node_label_list  ){
-      error_token_set << 'null_root_node_label_list'
-      accept_arg_list = false
-    }
-    if( root_node_label_list.isEmpty() ){
-      error_token_set << 'empty_root_node_label_list'
-      accept_arg_list = false
-    }
-    if( !accept_arg_list ) return error_token_set
-
-    def visited = [] as Set
-    def in_traversal_order = []
-
-    def stack = []
-    root_node_label_list.each { root_label ->
-      stack << root_label
-    }
-
-    do {
-      if( stack.isEmpty() ) break
-      def node_label = stack.pop()
-
-      def node = lookup_marked_good(node_label ,verbose)
-      if(!node){
-        error_token_set << 'lookup_fail'
-        continue
-      }
-
-      if(node.label in visited) continue
-      visited << node.label
-
-      in_traversal_order << node
-
-      node.neighbor.each { neighbor_label ->
-        stack << neighbor_label
-      }
-    } while(true)
-
-    in_traversal_order.reverse().each { node ->
-      node_function(node ,error_token_set)
-    }
-
-    return error_token_set
-  }
-
-  /*--------------------------------------------------------------------------------
-   run the build scripts
-     depends upon is_acyclic having already marked up the graph.
-
-  import java.nio.file.Files
-  import java.nio.file.Paths
-  */
-
-  // a symbol dependency is good ,as long as it is built before the node in question
-  def good_dependency_q(node_labels) {
-    return node_labels.every { node_label ->
-      def node = lookup_marked_good(node_label)
-      if (!node) return false
-      if (node.type in ['path' ,'leaf'] && !file_exists_q(node.label)) return false
-      return true
-    }
-  }
-
-  /* 
-   Given a node label and a list of node labels ,returns true if the file at the
-   node label in the first argument is newer than all the files at the
-   corresponding node labels in the second list.
-  */
-  def newer_than_all(node_label ,node_label_list) {
-    def node_path = Paths.get(node_label)
-    if (!Files.exists(node_path)) return false
-
-    def node_last_modified = Files.getLastModifiedTime(node_path).toMillis()
-
-    return node_label_list.every { label ->
-      def path = Paths.get(label)
-      if (!Files.exists(path)) return false
-      def last_modified = Files.getLastModifiedTime(path).toMillis()
-      return node_last_modified > last_modified
-    }
-  }
-
-  def can_be_built_q(node){
-    if( !marked_good_q(node) ) return false;
-    if( 
-      (node.type == 'symbol' || type == 'path')
-      && !good_dependency_q( node.neighbor )
-    ){
-      return false
-    }
-    if(
-      node.type == 'leaf'
-      && !file_exists_q(node.label)
-    ){ 
-      return false;
-    }
-    return true
-  }
-
-  // `can_be_build_q` must be true for this to be meaningful:
-  def should_be_built_q(node ,verbose = true) {
-    if(node.type == 'leaf') return false
-    if(node.type == 'symbol') return true
-    if( node.type == 'path') return !newer_than_all(node.label ,node.neighbor)
-    println("should_be_build_q:: unrecognized node type ,so assuming it should not be built.")
-    return false
-  }
-
-  void run_build_scripts_f( List root_node_label_list ,boolean verbose = true ){
-
-    if( root_node_label_list.isEmpty() ) return
-    Set error_token_set // used to catch return values
-
-    println( "run_build_script:: Checking if graph is well formed." )
-    error_token_set = wellformed_graph_q(root_node_label_list)
-    if( error_token_set && !error_token_set.isEmpty() ){
-      println( "Graph is not well-formed. Expect build problems. Errors:" )
-      error_token_set.each { token ->
-        println( "  - ${token}" )
-      }
-    } else {
-      println( "Graph is well-formed. Proceeding with build." )
-    }
-
-    def node_function = { node ,error_token_set_2 ->
-
-      if( !can_be_built_q( node ) ){
-        println( "run_build_scripts_f:: Skipping build for ${node.label} due to problems with dependencies." )
-        return
-      }
-      if( !should_be_built_q( node ) ){
-        if( verbose ) println( "run_build_scripts_f:: ${node.label} already up to date" )
-        return
-      }
-
-      // build the target
-      println( "run_build_scripts_f:: Running build script for ${node.label}" )
-      node.build()
-
-      // for path nodes, check if the build updated the target at path
-      if( node.type == 'path' && should_be_built_q( node ) ){
-        println( "run_build_scripts_f:: Build failed for ${node.label}" )
-        set_mark(node ,'build_failed')
-      }
-
-    }
-
-    println("run_build_scripts_f:: running ...")
-    error_token_set = all_DAG_DF(root_node_label_list, node_function, verbose)
-    if( error_token_set ){
-      error_token_set.each { error ->
-        println("run_build_scripts_f::all_DAG_DF:: ${error}")
-      }
-   }
-
-  }
-
-
-}
-
-
-/*
- def clean(nodes_to_clean) {
-  def all_dependencies = this.node_map["all"].neighbor.clone()
-  nodes_to_clean.each { node ->
-    all_dependencies.remove(node)
-  }
-
-  def must_have_nodes = []
-  all_dependencies.each { node ->
-    def node_info = this.node_map[node]
-    if (node_info.must_have) {
-      must_have_nodes += node_info.must_have
-    }
-  }
-
-  def to_clean_list = []
-  nodes_to_clean.each { node ->
-    if (!must_have_nodes.contains(node) && this.node_map[node].type == "path") {
-      to_clean_list += node
-    }
-  }
-
-  to_clean_list.each { node ->
-    def file_path = this.node_map[node].label
-    def file = new File(file_path)
-    if (file.exists()) {
-      file.delete()
-      println "Deleted file: ${file_path}"
-    }
-  }
-}
-*/
diff --git a/developer/deprecated/groovyc/AriadneGraph.groovy b/developer/deprecated/groovyc/AriadneGraph.groovy
deleted file mode 100644 (file)
index e149d23..0000000
+++ /dev/null
@@ -1,566 +0,0 @@
-import java.nio.file.Files
-import java.nio.file.Paths
-
-class AriadneGraph {
-
-  static Boolean debug = true
-  Map node_map = [:]
-  List node_f_list = []
-
-  AriadneGraph(Map node_map ,List node_f_list){
-    def accept_arg_list = true;
-    if( !(node_map === null) && !(node_map instanceof Map) ) accept_arg_list = false
-    if( !(node_f_list === null) && !(node_f_list instanceof List) ) accept_arg_list = false
-    if(node_map === null && node_f_list === null) accept_arg_list = false
-    if(!accept_arg_list){
-      println "AriandreGraph: requiers one or both of 'node_map' as Map, and 'node_f_list as List.'"
-      System.exit(1)
-    }
-    this.node_map = node_map ?: [:]
-    this.node_f_list = node_f_list ?: []
-  }
-
-  /*--------------------------------------------------------------------------------
-   File utility functions
-  */
-  static Map unpack_file_path(String file_fp) {
-    if (debug) println("unpack_file_path::file_fp: ${file_fp}")
-
-    def file = new File(file_fp)
-    def parent_dp = file.getParent() ?: ""
-
-    if (parent_dp && !parent_dp.endsWith(File.separator)) {
-      parent_dp += File.separator
-    }
-
-    def file_fn = file.getName()
-    def file_fn_base = file_fn
-    def file_fn_ext = ''
-
-    if (file_fn.lastIndexOf('.') > 0) {
-      file_fn_base = file_fn[0..file_fn.lastIndexOf('.') - 1]
-      if (file_fn.lastIndexOf('.') + 1 < file_fn.length()) {
-        file_fn_ext = file_fn[file_fn.lastIndexOf('.') + 1..-1]
-      }
-    }
-
-    def ret_val = [
-      dp      : parent_dp,
-      fn      : file_fn,
-      fn_base : file_fn_base,
-      fn_ext  : file_fn_ext
-    ]
-    if (debug) println("unpack_file_path::ret_val: ${ret_val}")
-
-    return ret_val
-  }
-
-  static boolean file_exists_q( String node_label ){
-    def node_path = Paths.get( node_label )
-    return Files.exists( node_path )
-  }
-
-  /*--------------------------------------------------------------------------------
-   Node type checks and marking
-  */
-
-  static Set all_node_type_set = [
-    'symbol'  // label is a symbol
-    ,'path'   // label is a path to a file, though it might not exist
-    ,'leaf'   // label is a path to a file that has no dependencies
-    ,'generator' // label is a path, but node has no neighbors
-    ,'error'   // typically created by the system node has a message property
-  ] as Set
-
-  static Set persistent_node_mark_set = 
-    [
-    'cycle_member' 
-     ,'wellformed' 
-     ,'build_failed'
-     ,'null_node'
-     ] as Set
-
-  static boolean leaf_q( Map node ){
-    return node && node.type == 'leaf'
-  }
-
-  static boolean has_mark( Map node ){
-    return node?.mark?.isNotEmpty()
-  }
-
-  static void set_mark( Map node ,String mark ){
-    node.mark = node.mark ?: [] as Set
-    node.mark << mark
-  }
-
-  static void clear_mark( Map node ,String mark ){
-    node?.mark?.remove( mark )
-  }
-
-  static boolean marked_good_q( Map node ){
-    return node && node.mark && ( 'wellformed' in node.mark ) && !( 'cycle_member' in node.mark ) && !( 'build_failed' in node.mark )
-  }
-
-  /*--------------------------------------------------------------------------------
-   Well-formed Node Check
-  */
-
-  static Set all_form_error_set = [
-    'no_node'
-    ,'node_must_have_label'
-    ,'label_must_be_string'
-    ,'node_must_have_type'
-    ,'bad_node_type'
-    ,'neighbor_value_must_be_list'
-    ,'neighbor_reference_must_be_string'
-    ,'neighbor_label_not_in_graph'
-    ,'mark_property_value_must_be_set'
-    ,'unregistered_mark'
-    ,'missing_required_build_code'
-    ,'leaf_given_neighbor_property'
-    ,'leaf_given_build_property'
-  ] as Set
-
-  static Set wellformed_q( Map node ){
-    def form_error_set = [] as Set
-
-    if( !node ){
-      form_error_set << 'null_node'
-      return form_error_set
-    }
-
-    if( !node.label )
-      form_error_set << 'node_must_have_label'
-    else if( !( node.label instanceof String ) )
-      form_error_set << 'label_must_be_string'
-
-    if( !node.type )
-      form_error_set << 'node_must_have_type'
-    else if( !( node.type instanceof String ) || !( node.type in all_node_type_set ) )
-      form_error_set << 'bad_node_type'
-
-    if( node.neighbor ){
-      if( !( node.neighbor instanceof List ) )
-        form_error_set << 'neighbor_value_must_be_list'
-      else if( !( node.neighbor.every { it instanceof String } ) )
-        form_error_set << 'neighbor_reference_must_be_string'
-    }
-
-    if( node.mark ){
-      if( !( node.mark instanceof Set ) )
-        form_error_set << 'mark_property_value_must_be_set'
-      else if( !( node.mark.every { it in persistent_node_mark_set } ) )
-        form_error_set << 'unregistered_mark'
-    }
-
-    if( node.type == 'path' && ( !node.build || !( node.build instanceof Closure ) ) )
-      form_error_set << 'missing_required_build_code'
-
-    if( node.type == 'leaf' ){
-      if( node.neighbor ) form_error_set << 'leaf_given_neighbor_property'
-      if( node.build ) form_error_set << 'leaf_given_build_property'
-    }
-
-    return form_error_set
-  }
-
-  /*--------------------------------------------------------------------------------
-   A well formed graph checker.  Traverses entire graph and marks nodes
-   that are not well formed or that are part of a cycle.
-
-   This must be run on the graph for `lookup_marked_good` to work.
-  */
-
-  def mark_node_form(node ,verbose = true){
-    if(debug){
-      if(node)
-        println("mark_node_form::node: ${node}")
-      else
-        println("mark_node_form given a null node")
-    }
-    
-    def form_errors = wellformed_q(node)
-    if( form_errors.isEmpty() ){
-      set_mark(node ,'wellformed');
-      return 'wellformed'
-    }
-    // at this point we know that form_errors is not empty
-    
-    if(verbose){
-      if(node && node.label && node.label.length() > 0)
-        print("node ${neighbor_node.label} is malformed due to:")
-      else
-        print("anonymous node is malformed due to:")
-      form_errors.each { error -> print(" ${error}") }
-      println("")
-    }
-
-    return 'malformed'
-  }
-
-
-  static Set markup_graph_f_descend_set = [
-    'empty_path_stack'
-    ,'cycle_found'
-    ,'undefined_node'
-    ,'exists_malformed'
-    ,'defacto_leaf'
-  ] as Set
-  def markup_graph_f_descend(path_stack ,boolean verbose = true){
-    def ret_value = [] as Set
-    if( path_stack.isEmpty() ){
-      if(verbose) println( "markup_graph_f_descend:: given empty path_stack to descend from")
-      ret_value << 'empty_path_stack'
-      return ret_value
-    }
-    def local_path = path_stack.collect{ it[0] }
-    def local_node_label = local_path[-1]
-    def cycle_start_index
-
-    do{
-
-      // Check for a cycle in the local path, if found marks cycle members
-      if( local_path.size() > 1){
-        cycle_start_index = local_path[0..-2].findIndexOf{ it == local_node_label }
-        if(cycle_start_index != -1){ // Cycle detected
-          ret_value << 'cycle_found'
-          if(verbose) print "markup_graph_f_descend:: dependency cycle found:"
-          local_path[cycle_start_index..-1].each{ cycle_node_label ->
-            if(verbose) print " ${cycle_node_label}"
-            def cycle_node = lookup(cycle_node_label)
-            cycle_node.mark = cycle_node.mark ?: [] as Set // Initialize mark set if needed
-            cycle_node.mark << 'cycle_member'
-          }
-          if(verbose) println ""
-          // we can not continue searching after the loop so ,we pop back to treat
-          // the first node in the loop as though a leaf node.
-          path_stack = path_stack[0..cycle_start_index]
-          return ret_value
-        }
-      }
-
-      def local_node = lookup(local_node_label)
-      if( !local_node ){
-        ret_value << 'undefined_node' 
-        return ret_value
-      }
-      if( mark_node_form(local_node) == 'malformed' ){
-        ret_value << 'exists_malformed'
-      }
-      if( local_node.neighbor.isEmpty() ){
-        ret_value << 'defacto_leaf' // might not be `type:leaf`
-        return ret_value
-      }
-
-      // Descend further into the tree.
-      path_stack << local_node.neighbor.clone()
-      local_node_label = local_node.neighbor[0]
-      local_path << local_node_label
-    }while(true)
-  }
-
-  /*
-   Given root_node_label_list ,marks up the graph and returns a set possibly
-   containing 'all_wellformed' and 'cycles_exist'.
-
-   Marks potentially added to each node include  'cycle_member' ,'wellformed'.
-   Note that these marks are independent.
-  */
-  def wellformed_graph_q(root_node_label_list ,boolean verbose = true){
-    def ret_value = [] as Set
-    def exists_malformed = false;
-    def result // used variously
-
-    if( root_node_label_list.isEmpty() ) return ret_value
-    
-    // Initialize the DFS tree iterator.
-    def path_stack = []
-    path_stack << root_node_label_list.clone()
-
-    // iterate over left side tree descent ,not ideal as it starts at the
-    // root each time ,but avoids complexity in the cycle detection logic.
-    do{
-      result = markup_graph_f_descend(path_stack ,verbose)
-      if('cycle_found' in result) ret_value << 'cycle_exists'
-      if('undefined_node' in result) exists_malformed = true;
-      if('exists_malformed' in result) exists_malformed = true;
-
-      // increment the iterator to the next leftmost path
-      def top_list = path_stack[-1]
-      top_list.remove(0)
-      if(top_list.isEmpty()) path_stack.pop()
-
-    }while(!path_stack.isEmpty())
-
-    if(!exists_malformed) ret_value << 'all_wellformed'
-    if( verbose ){
-      if(exists_malformed) println("one or more malformed nodes were found")
-      def exists_cycle = 'cycle_found' in ret_value
-      if(exists_cycle) println("one or more cyclic dependency loop found")
-      if( exists_malformed || exists_cycle ) println("will attempt to build unaffected nodes")
-    }
-
-    return ret_value
-  }
-
-  /*--------------------------------------------------------------------------------
-     Graph traversal
-  */
-
-  // given a node label, looks it up on the dependency graph, returns the node or null
-  Map lookup(String node_label ,boolean verbose = true){
-
-    if(!node_label){
-      if(verbose) println("lookup:: given node_label is null or an empty string")
-      return null
-    }
-
-    // try the map
-    def node = this.node_map[node_label]
-    if(node){
-      node.label = node_label
-      if(verbose) println("lookup:: found from map: ${node}")
-      return node
-    }
-    // at this point node will be null
-
-    // The map lookup failed, lets try the function recognizer list ..
-    def match_result
-    for( func in this.node_f_list ){
-      match_result = func(node_label)
-      if( match_result.status == 'matched' ){
-        node = match_result
-        break
-      }
-    }
-
-    if(verbose)
-      if(node) println("lookup:: found from recognizer function: ${node}")
-      else println("lookup:: failed to find label: ${node_label}")
-
-    return node
-  }
-
-  // mark aware lookup function
-  def lookup_marked_good(node_label ,verbose = true){
-    def node = lookup(node_label ,verbose)
-    if( node && marked_good_q(node) ) return node;
-    return null;
-  }
-
-
-  /*
-   Given `root_node_label_list` of a DAG. Applies `node_function` to each node in a
-   depth-first traversal order.  Returns a set of error tokens encountered
-   during traversal.
-
-   `wellformed_graph_q` must be run on the DAG before this function is called ,or
-   `lookup_marked_good` will not function correctly.
-  */
-  def all_DAG_DF(root_node_label_list ,node_function ,boolean verbose = true) {
-    if(verbose) println("all_DAG_DF::")
-
-    def error_token_set = [] as Set
-
-    def accept_arg_list = true
-    if( !node_function ){
-      error_token_set << 'null_node_function'
-      accept_arg_list = false
-    }
-    if( !(node_function instanceof Closure) ){
-      error_token_set << 'nod_function_not_a_function'
-      accept_arg_list = false
-    }
-    if( !root_node_label_list  ){
-      error_token_set << 'null_root_node_label_list'
-      accept_arg_list = false
-    }
-    if( root_node_label_list.isEmpty() ){
-      error_token_set << 'empty_root_node_label_list'
-      accept_arg_list = false
-    }
-    if( !accept_arg_list ) return error_token_set
-
-    def visited = [] as Set
-    def in_traversal_order = []
-
-    def stack = []
-    root_node_label_list.each { root_label ->
-      stack << root_label
-    }
-
-    do {
-      if( stack.isEmpty() ) break
-      def node_label = stack.pop()
-
-      def node = lookup_marked_good(node_label ,verbose)
-      if(!node){
-        error_token_set << 'lookup_fail'
-        continue
-      }
-
-      if(node.label in visited) continue
-      visited << node.label
-
-      in_traversal_order << node
-
-      node.neighbor.each { neighbor_label ->
-        stack << neighbor_label
-      }
-    } while(true)
-
-    in_traversal_order.reverse().each { node ->
-      node_function(node ,error_token_set)
-    }
-
-    return error_token_set
-  }
-
-  /*--------------------------------------------------------------------------------
-   run the build scripts
-     depends upon is_acyclic having already marked up the graph.
-
-  import java.nio.file.Files
-  import java.nio.file.Paths
-  */
-
-  // a symbol dependency is good ,as long as it is built before the node in question
-  def good_dependency_q(node_labels) {
-    return node_labels.every { node_label ->
-      def node = lookup_marked_good(node_label)
-      if (!node) return false
-      if (node.type in ['path' ,'leaf'] && !file_exists_q(node.label)) return false
-      return true
-    }
-  }
-
-  /* 
-   Given a node label and a list of node labels ,returns true if the file at the
-   node label in the first argument is newer than all the files at the
-   corresponding node labels in the second list.
-  */
-  def newer_than_all(node_label ,node_label_list) {
-    def node_path = Paths.get(node_label)
-    if (!Files.exists(node_path)) return false
-
-    def node_last_modified = Files.getLastModifiedTime(node_path).toMillis()
-
-    return node_label_list.every { label ->
-      def path = Paths.get(label)
-      if (!Files.exists(path)) return false
-      def last_modified = Files.getLastModifiedTime(path).toMillis()
-      return node_last_modified > last_modified
-    }
-  }
-
-  def can_be_built_q(node){
-    if( !marked_good_q(node) ) return false;
-    if( 
-      (node.type == 'symbol' || type == 'path')
-      && !good_dependency_q( node.neighbor )
-    ){
-      return false
-    }
-    if(
-      node.type == 'leaf'
-      && !file_exists_q(node.label)
-    ){ 
-      return false;
-    }
-    return true
-  }
-
-  // `can_be_build_q` must be true for this to be meaningful:
-  def should_be_built_q(node ,verbose = true) {
-    if(node.type == 'leaf') return false
-    if(node.type == 'symbol') return true
-    if( node.type == 'path') return !newer_than_all(node.label ,node.neighbor)
-    println("should_be_build_q:: unrecognized node type ,so assuming it should not be built.")
-    return false
-  }
-
-  void run_build_scripts_f( List root_node_label_list ,boolean verbose = true ){
-
-    if( root_node_label_list.isEmpty() ) return
-    Set error_token_set // used to catch return values
-
-    println( "run_build_script:: Checking if graph is well formed." )
-    error_token_set = wellformed_graph_q(root_node_label_list)
-    if( error_token_set && !error_token_set.isEmpty() ){
-      println( "Graph is not well-formed. Expect build problems. Errors:" )
-      error_token_set.each { token ->
-        println( "  - ${token}" )
-      }
-    } else {
-      println( "Graph is well-formed. Proceeding with build." )
-    }
-
-    def node_function = { node ,error_token_set_2 ->
-
-      if( !can_be_built_q( node ) ){
-        println( "run_build_scripts_f:: Skipping build for ${node.label} due to problems with dependencies." )
-        return
-      }
-      if( !should_be_built_q( node ) ){
-        if( verbose ) println( "run_build_scripts_f:: ${node.label} already up to date" )
-        return
-      }
-
-      // build the target
-      println( "run_build_scripts_f:: Running build script for ${node.label}" )
-      node.build()
-
-      // for path nodes, check if the build updated the target at path
-      if( node.type == 'path' && should_be_built_q( node ) ){
-        println( "run_build_scripts_f:: Build failed for ${node.label}" )
-        set_mark(node ,'build_failed')
-      }
-
-    }
-
-    println("run_build_scripts_f:: running ...")
-    error_token_set = all_DAG_DF(root_node_label_list, node_function, verbose)
-    if( error_token_set ){
-      error_token_set.each { error ->
-        println("run_build_scripts_f::all_DAG_DF:: ${error}")
-      }
-   }
-
-  }
-
-
-}
-
-
-/*
- def clean(nodes_to_clean) {
-  def all_dependencies = this.node_map["all"].neighbor.clone()
-  nodes_to_clean.each { node ->
-    all_dependencies.remove(node)
-  }
-
-  def must_have_nodes = []
-  all_dependencies.each { node ->
-    def node_info = this.node_map[node]
-    if (node_info.must_have) {
-      must_have_nodes += node_info.must_have
-    }
-  }
-
-  def to_clean_list = []
-  nodes_to_clean.each { node ->
-    if (!must_have_nodes.contains(node) && this.node_map[node].type == "path") {
-      to_clean_list += node
-    }
-  }
-
-  to_clean_list.each { node ->
-    def file_path = this.node_map[node].label
-    def file = new File(file_path)
-    if (file.exists()) {
-      file.delete()
-      println "Deleted file: ${file_path}"
-    }
-  }
-}
-*/
diff --git a/developer/deprecated/groovyc/BuildGraph.groovy b/developer/deprecated/groovyc/BuildGraph.groovy
deleted file mode 100644 (file)
index c68fa43..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-class BuildGraph {
-
-  // Function to load the graph class dynamically
-  static def include_a_class(String a_class_fp) {
-    def class_loader = BuildGraph.class.classLoader
-    def class_name = a_class_fp.replace('/', '.').replace('.class', '')
-    try {
-      return class_loader.loadClass(class_name)
-    } catch (Exception e) {
-      println "Error loading class '${class_name}': ${e.message}"
-      return null
-    }
-  }
-
-  // Build function
-  static def build(String graph_definition_fp, List<String> root_node_labels) {
-
-    // Print summary of what we are doing
-    println "build:: Building targets for graph '${graph_definition_fp}.class'"
-    if (root_node_labels.isEmpty()) {
-      println "No build targets specified. Please provide root node labels to build."
-      System.exit(0)
-    }
-    println "Building targets: ${root_node_labels.join(', ')}"
-
-    // Load the dependency graph class from arg[1]
-    def graph_definition_class = include_a_class(graph_definition_fp)
-    if (graph_definition_class) {
-      println "build:: loaded ${graph_definition_fp}.class"
-    } else {
-      println "build:: failed to load ${graph_definition_fp}.class"
-      System.exit(1)
-    }
-
-    // Get the node_map and node_f_list from the graph class
-    def node_map = graph_definition_class.get_node_map()
-    def node_f_list = graph_definition_class.get_node_f_list()
-    println "node_map: ${node_map}"
-    println "node_f_list: ${node_f_list}"
-
-    // Create an instance of AriadneGraph, and run the build scripts
-    def graph = new AriadneGraph(node_map, node_f_list)
-    graph.run_build_scripts_f(root_node_labels)
-  }
-
-  // Entry point when run as a script
-  static void main(String[] args) {
-    if (args.length == 0) {
-      println "Usage: ./build <graph_definition.class> [root_node_labels...]"
-      System.exit(1)
-    }
-
-    // Get graph definition file and root node labels
-    def graph_definition_fp = args[0]
-    def root_node_labels = args.length > 1 ? args[1..-1] : []
-    build(graph_definition_fp, root_node_labels)
-  }
-}
diff --git a/developer/document/#question_jan.txt# b/developer/document/#question_jan.txt#
deleted file mode 100644 (file)
index 9b0715c..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-
-On a directed acyclic graph, is it 
\ No newline at end of file
diff --git a/developer/document/#variable_suffix_conventions.txt# b/developer/document/#variable_suffix_conventions.txt#
deleted file mode 100644 (file)
index 8aca090..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-# Suffix Conventions
-
-## Specify interface used with variable when clarification is useful:
-
-- `_set`: Indicates that the variable holds a set of items.
-
-- `_list`: Used for variables that represent a list of items.
-
-- `_f`: Refers to a function.
-
-Instead of making a variable name plural, add the interface qualifier:
-
-   e.g. names ->  name_set  or name_list
-
-## Always a good idea to use these when working with files:
-
-- `_fp`: Refers to a file path. The part after the last slash is a file name.
-  
-- `_dp`: Refers to a directory path. By convention, the value ends in a slash.
-
-- `_fn`: Refers to a file name. Value has no slashes.
-
-- `_dn`: Refers to a directory name. Value has no slashes.
-  
-- `_fn_base`: The file name without the last dot and subsequent characters.
-  
-- `_fn_ext`: The subsequent characters after the last dot in a file name.
diff --git a/developer/document/GraphDirectedAcyclic.txt b/developer/document/GraphDirectedAcyclic.txt
deleted file mode 100644 (file)
index 3da0b12..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-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/GraphDirectedAcyclic_1.txt b/developer/document/GraphDirectedAcyclic_1.txt
deleted file mode 100644 (file)
index 7a202e2..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-  /*--------------------------------------------------------------------------------
-    Interface
-
-    1. nodes are referenced by label.
-
-    2. A list is a kind of sequence. It consists of a leftmost item, subsequent
-    items, and a rightmost item.
-
-    3. A node list consists of a leftmost node, subsequent nodes, and a rightmost node.
-
-    4. `path_stack`
-        
-        The `path_stack` is a list. Each item in the stack is a node list.
-
-        The rightmost items is the top of the stack.
-
-        The leftmost item is a list of root nodes, where traversal of the graph
-        starts.
-
-        Given two adjacent items on the path stack, say e0 and e1:
-
-            Say k0 is the leftmost node on the node list e0.
-            
-            The e1 will be the neighbor (child) list from node k0.
-
-            Hence, the path stack consists of the child lists of nodes along
-            a traversal. We chose a leftmost traversal.
-
-                e0:   k_0       k_1    ... k_2  
-
-                e1:   k_0_0    k_0_1   ... k_0_2   ; children of k_0
-
-                e2:   K_0_0_0  k_0_0_1 ... k_0_0_2 ; children of k_0_0
-                
-
-    5. `path`
-
-        A list of the leftmost nodes from a path stack.  
-
-        Given that e0 is a root node, `path` will consist of 
-
-            k_0, k_0_0, k_0_0_0 ... k_0_0..._0
-
-        Within the context of a path, k_0 is the leftmost item, and k_n is the
-        rightmost item.
-
-
-    6. removing a cycle
-
-       This is a build tool. Each node corresponds to a build objective, and the
-       neighbor nodes are dependencies. A neighbor node is a child node in our
-       tree descent, and is a dependency to our build tool.
-
-       This routine is called as part of the analysis phase. Nothing is
-       built here, rather we are merely marking dependency cycles that we
-       find when descending from the root nodes.
-
-       When we find a cycle, we remove those nodes from the current traversal
-       path, because we do not went the analysis to do in circles.  It is
-       possible that there are spurs that emanate from the cycle, and following
-       these might lead to finding more cycles.
-
-       Our build tool (which is not in this file) will stop descending through
-       the graph upon finding a cycle, and the effects of this will cause
-       upstream nodes to also not be built. Hence, the cycles hidden behind
-       other cycles are irrelevant.  
-
-       However, if we want to make routine of more general use, then the
-       discovered cycles should be pushed on to a cycle stack, and then each
-       item on the cycle stack would be used as root nodes for a new cycle
-       search. Note the leftmost cycle on each recursive search on the leftmost
-       node, will be the original cycle.
-  */
-
-  /*
-    Given a path to a node in the graph, `left_path`.
-
-    Checks if the rightmost node (referenced by label) recurs earlier in the path.
-    Presumably the rightmost node has been recently appended to the path.
-
-    If there is no cycle, returns null, otherwise returns the interval [i ,n],
-    of indexes into the path where the cycle is found. `n` will always be
-    the index of the rightmost node in the path list.
-  */
diff --git a/developer/document/dependency_graph.html b/developer/document/dependency_graph.html
deleted file mode 100644 (file)
index a728d42..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <title>Class and mature functions reference</title>
-  <style>
-    body {
-      font-family: 'Noto Sans JP', Arial, sans-serif;
-      background-color: hsl(0, 0%, 0%);
-      color: hsl(42, 100%, 80%);
-      padding: 2rem;
-    }
-    .page {
-      padding: 3rem; /* 20px */
-      margin: 1.25rem auto; /* 20px */
-      max-width: 46.875rem; /* 750px */
-      background-color: hsl(0, 0%, 0%);
-      box-shadow: 0 0 0.625rem hsl(42, 100%, 50%); /* 10px */
-    }
-    h1 {
-      font-size: 1.5rem;
-      text-align: center;
-      color: hsl(42, 100%, 84%);
-      text-transform: uppercase;
-      margin-top: 1.5rem;
-    }
-    h2 {
-      font-size: 1.25rem;
-      color: hsl(42, 100%, 84%);
-      text-align: center;
-      margin-top: 2rem;
-    }
-    h3 {
-      font-size: 1.125rem;
-      color: hsl(42, 100%, 75%);
-      margin-top: 1.5rem;
-    }
-    p, li {
-      color: hsl(42, 100%, 90%);
-      text-align: justify;
-      margin-bottom: 1rem;
-    }
-    .term {
-      font-family: 'Courier New', Courier, monospace;
-/*      background-color: hsl(0, 0%, 19%); */
-      padding: 0.125rem 0.25rem;
-      border-radius: 0.125rem;
-      text-decoration: underline;
-/*      font-style: italic;*/
-      color: hsl(42, 100%, 95%);
-    }
-    code {
-      font-family: 'Courier New', Courier, monospace;
-      background-color: hsl(0, 0%, 25%);
-      padding: 0.125rem 0.25rem;
-      color: hsl(42, 100%, 90%);
-    }
-
-    table {
-      border-collapse: collapse;
-      width: 100%;
-    }
-
-    tr {
-      page-break-inside: avoid;
-      page-break-after: auto;
-    }
-
-    th, td {
-      padding: 0.125rem;;
-/*      hsl(0, 0%, 86.7%) */
-      text-align: left;
-    }
-
-  </style>
-
-</head>
-<body>
-  <div class="page">
-
-    A very rough first draft of a reference to the classes.  
-
-    <h1>Cycle Detection on a Dependency Graph</h1>
-    <h2>Overview</h2>
-
-    <p>A <span class="term">Dependency Graph</span>: 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'.</p>
-
-    <h2>Functions</h2>
-
-    <h3>1. is_acyclic_q</h3>
-    <p>
-      <strong>Purpose</strong>: To determine if the dependency graph is acyclovir.
-    </p>
-    <p>
-      <strong>Parameters</strong>: 
-      <ul>
-        <li><code>root_node_labels</code>: A list of labels for the root nodes to start the cycle search.</li>
-        <li><code>verbose</code>: A boolean flag for enabling detailed output (default is <code>true</code>).</li>
-      </ul>
-    </p>
-    <p>
-      <strong>Returns</strong>: 
-      <ul>
-        <li><code>'acyclic'</code> if no cycles are found.</li>
-        <li><code>'cycle_found'</code> if cycles are detected.</li>
-      </ul>
-    </p>
-    <p>
-      <strong>Process</strong>:
-      <ul>
-        <li>Initializes a stack for DFS traversal.</li>
-        <li>Iteratively calls the <code>is_acyclic_q_descend</code> function to traverse the graph and detect cycles.</li>
-        <li>Updates the traversal state and continues exploring other paths until the stack is empty.</li>
-      </ul>
-    </p>
-    <h3>2. is_acyclic_q_descend</h3>
-    <p>
-      <strong>Purpose</strong>: To perform the actual DFS traversal and cycle detection for a given path.
-    </p>
-    <p>
-      <strong>Parameters</strong>: 
-      <ul>
-        <li><code>path_stack</code>: A stack representing the current path in the graph.</li>
-        <li><code>verbose</code>: A boolean flag for enabling detailed output (default is <code>true</code>).</li>
-      </ul>
-    </p>
-    <p>
-      <strong>Returns</strong>: 
-      <ul>
-        <li><code>'leaf_node'</code> if the current node has no children.</li>
-        <li><code>'cycle_found'</code> if a cycle is detected.</li>
-      </ul>
-    </p>
-    <p>
-      <strong>Process</strong>:
-      <ul>
-        <li>Collects the current path and node.</li>
-        <li>Checks for cycles by comparing the current node with nodes in the path.</li>
-        <li>Marks nodes involved in cycles and updates the stack to continue traversal.</li>
-      </ul>
-    </p>
-    <h2>Usage</h2>
-    <p>
-      The <code>is_acyclic_q</code> 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.
-    </p>
-  </div>
-
-</body>
-</html>
diff --git a/developer/document/nomenclature.txt b/developer/document/nomenclature.txt
deleted file mode 100644 (file)
index 633dc4a..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-
-wellformed is a single word. Its antonym is 'malformed'. Wellformed syntax
-parses without errors.
diff --git a/developer/document/see_also.txt b/developer/document/see_also.txt
deleted file mode 100644 (file)
index a8eed19..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-
-See also these documents located at a single point of maintenance:
-
-  https://git.reasoningtechnology.com/proem/home/?p=Mosaic;a=tree;f=developer/document;h=dcf38055fa575b40c4c1527558368aa266899ac2;hb=refs/heads/core_developer_branch
-
-  https://github.com/Thomas-Walker-Lynch/Mosaic/blob/release_v1.0/developer/document
-
-      RT_code_format.txt
-      variable_suffix_conventions.txt
-  
diff --git a/developer/documentđź–‰/#question_jan.txt# b/developer/documentđź–‰/#question_jan.txt#
new file mode 100644 (file)
index 0000000..9b0715c
--- /dev/null
@@ -0,0 +1,2 @@
+
+On a directed acyclic graph, is it 
\ No newline at end of file
diff --git a/developer/documentđź–‰/#variable_suffix_conventions.txt# b/developer/documentđź–‰/#variable_suffix_conventions.txt#
new file mode 100644 (file)
index 0000000..8aca090
--- /dev/null
@@ -0,0 +1,27 @@
+# Suffix Conventions
+
+## Specify interface used with variable when clarification is useful:
+
+- `_set`: Indicates that the variable holds a set of items.
+
+- `_list`: Used for variables that represent a list of items.
+
+- `_f`: Refers to a function.
+
+Instead of making a variable name plural, add the interface qualifier:
+
+   e.g. names ->  name_set  or name_list
+
+## Always a good idea to use these when working with files:
+
+- `_fp`: Refers to a file path. The part after the last slash is a file name.
+  
+- `_dp`: Refers to a directory path. By convention, the value ends in a slash.
+
+- `_fn`: Refers to a file name. Value has no slashes.
+
+- `_dn`: Refers to a directory name. Value has no slashes.
+  
+- `_fn_base`: The file name without the last dot and subsequent characters.
+  
+- `_fn_ext`: The subsequent characters after the last dot in a file name.
diff --git a/developer/documentđź–‰/GraphDirectedAcyclic.txt b/developer/documentđź–‰/GraphDirectedAcyclic.txt
new file mode 100644 (file)
index 0000000..3da0b12
--- /dev/null
@@ -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đź–‰/GraphDirectedAcyclic_1.txt b/developer/documentđź–‰/GraphDirectedAcyclic_1.txt
new file mode 100644 (file)
index 0000000..7a202e2
--- /dev/null
@@ -0,0 +1,84 @@
+  /*--------------------------------------------------------------------------------
+    Interface
+
+    1. nodes are referenced by label.
+
+    2. A list is a kind of sequence. It consists of a leftmost item, subsequent
+    items, and a rightmost item.
+
+    3. A node list consists of a leftmost node, subsequent nodes, and a rightmost node.
+
+    4. `path_stack`
+        
+        The `path_stack` is a list. Each item in the stack is a node list.
+
+        The rightmost items is the top of the stack.
+
+        The leftmost item is a list of root nodes, where traversal of the graph
+        starts.
+
+        Given two adjacent items on the path stack, say e0 and e1:
+
+            Say k0 is the leftmost node on the node list e0.
+            
+            The e1 will be the neighbor (child) list from node k0.
+
+            Hence, the path stack consists of the child lists of nodes along
+            a traversal. We chose a leftmost traversal.
+
+                e0:   k_0       k_1    ... k_2  
+
+                e1:   k_0_0    k_0_1   ... k_0_2   ; children of k_0
+
+                e2:   K_0_0_0  k_0_0_1 ... k_0_0_2 ; children of k_0_0
+                
+
+    5. `path`
+
+        A list of the leftmost nodes from a path stack.  
+
+        Given that e0 is a root node, `path` will consist of 
+
+            k_0, k_0_0, k_0_0_0 ... k_0_0..._0
+
+        Within the context of a path, k_0 is the leftmost item, and k_n is the
+        rightmost item.
+
+
+    6. removing a cycle
+
+       This is a build tool. Each node corresponds to a build objective, and the
+       neighbor nodes are dependencies. A neighbor node is a child node in our
+       tree descent, and is a dependency to our build tool.
+
+       This routine is called as part of the analysis phase. Nothing is
+       built here, rather we are merely marking dependency cycles that we
+       find when descending from the root nodes.
+
+       When we find a cycle, we remove those nodes from the current traversal
+       path, because we do not went the analysis to do in circles.  It is
+       possible that there are spurs that emanate from the cycle, and following
+       these might lead to finding more cycles.
+
+       Our build tool (which is not in this file) will stop descending through
+       the graph upon finding a cycle, and the effects of this will cause
+       upstream nodes to also not be built. Hence, the cycles hidden behind
+       other cycles are irrelevant.  
+
+       However, if we want to make routine of more general use, then the
+       discovered cycles should be pushed on to a cycle stack, and then each
+       item on the cycle stack would be used as root nodes for a new cycle
+       search. Note the leftmost cycle on each recursive search on the leftmost
+       node, will be the original cycle.
+  */
+
+  /*
+    Given a path to a node in the graph, `left_path`.
+
+    Checks if the rightmost node (referenced by label) recurs earlier in the path.
+    Presumably the rightmost node has been recently appended to the path.
+
+    If there is no cycle, returns null, otherwise returns the interval [i ,n],
+    of indexes into the path where the cycle is found. `n` will always be
+    the index of the rightmost node in the path list.
+  */
diff --git a/developer/documentđź–‰/build.txt b/developer/documentđź–‰/build.txt
new file mode 100644 (file)
index 0000000..fa1fc0b
--- /dev/null
@@ -0,0 +1,23 @@
+
+1. start with a clean release directory
+
+  wipe_release 
+
+2a. if including sources in the .jar:
+
+  clean_build_directories
+  distribute_source
+  make
+  release
+
+
+2b. if not including the sources:
+
+  clean_build_directories
+  make
+  release
+
+3. check
+
+   jar -tf ../release/Ariadne.jar
+
diff --git a/developer/documentđź–‰/dependency_graph.html b/developer/documentđź–‰/dependency_graph.html
new file mode 100644 (file)
index 0000000..a728d42
--- /dev/null
@@ -0,0 +1,151 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>Class and mature functions reference</title>
+  <style>
+    body {
+      font-family: 'Noto Sans JP', Arial, sans-serif;
+      background-color: hsl(0, 0%, 0%);
+      color: hsl(42, 100%, 80%);
+      padding: 2rem;
+    }
+    .page {
+      padding: 3rem; /* 20px */
+      margin: 1.25rem auto; /* 20px */
+      max-width: 46.875rem; /* 750px */
+      background-color: hsl(0, 0%, 0%);
+      box-shadow: 0 0 0.625rem hsl(42, 100%, 50%); /* 10px */
+    }
+    h1 {
+      font-size: 1.5rem;
+      text-align: center;
+      color: hsl(42, 100%, 84%);
+      text-transform: uppercase;
+      margin-top: 1.5rem;
+    }
+    h2 {
+      font-size: 1.25rem;
+      color: hsl(42, 100%, 84%);
+      text-align: center;
+      margin-top: 2rem;
+    }
+    h3 {
+      font-size: 1.125rem;
+      color: hsl(42, 100%, 75%);
+      margin-top: 1.5rem;
+    }
+    p, li {
+      color: hsl(42, 100%, 90%);
+      text-align: justify;
+      margin-bottom: 1rem;
+    }
+    .term {
+      font-family: 'Courier New', Courier, monospace;
+/*      background-color: hsl(0, 0%, 19%); */
+      padding: 0.125rem 0.25rem;
+      border-radius: 0.125rem;
+      text-decoration: underline;
+/*      font-style: italic;*/
+      color: hsl(42, 100%, 95%);
+    }
+    code {
+      font-family: 'Courier New', Courier, monospace;
+      background-color: hsl(0, 0%, 25%);
+      padding: 0.125rem 0.25rem;
+      color: hsl(42, 100%, 90%);
+    }
+
+    table {
+      border-collapse: collapse;
+      width: 100%;
+    }
+
+    tr {
+      page-break-inside: avoid;
+      page-break-after: auto;
+    }
+
+    th, td {
+      padding: 0.125rem;;
+/*      hsl(0, 0%, 86.7%) */
+      text-align: left;
+    }
+
+  </style>
+
+</head>
+<body>
+  <div class="page">
+
+    A very rough first draft of a reference to the classes.  
+
+    <h1>Cycle Detection on a Dependency Graph</h1>
+    <h2>Overview</h2>
+
+    <p>A <span class="term">Dependency Graph</span>: 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'.</p>
+
+    <h2>Functions</h2>
+
+    <h3>1. is_acyclic_q</h3>
+    <p>
+      <strong>Purpose</strong>: To determine if the dependency graph is acyclovir.
+    </p>
+    <p>
+      <strong>Parameters</strong>: 
+      <ul>
+        <li><code>root_node_labels</code>: A list of labels for the root nodes to start the cycle search.</li>
+        <li><code>verbose</code>: A boolean flag for enabling detailed output (default is <code>true</code>).</li>
+      </ul>
+    </p>
+    <p>
+      <strong>Returns</strong>: 
+      <ul>
+        <li><code>'acyclic'</code> if no cycles are found.</li>
+        <li><code>'cycle_found'</code> if cycles are detected.</li>
+      </ul>
+    </p>
+    <p>
+      <strong>Process</strong>:
+      <ul>
+        <li>Initializes a stack for DFS traversal.</li>
+        <li>Iteratively calls the <code>is_acyclic_q_descend</code> function to traverse the graph and detect cycles.</li>
+        <li>Updates the traversal state and continues exploring other paths until the stack is empty.</li>
+      </ul>
+    </p>
+    <h3>2. is_acyclic_q_descend</h3>
+    <p>
+      <strong>Purpose</strong>: To perform the actual DFS traversal and cycle detection for a given path.
+    </p>
+    <p>
+      <strong>Parameters</strong>: 
+      <ul>
+        <li><code>path_stack</code>: A stack representing the current path in the graph.</li>
+        <li><code>verbose</code>: A boolean flag for enabling detailed output (default is <code>true</code>).</li>
+      </ul>
+    </p>
+    <p>
+      <strong>Returns</strong>: 
+      <ul>
+        <li><code>'leaf_node'</code> if the current node has no children.</li>
+        <li><code>'cycle_found'</code> if a cycle is detected.</li>
+      </ul>
+    </p>
+    <p>
+      <strong>Process</strong>:
+      <ul>
+        <li>Collects the current path and node.</li>
+        <li>Checks for cycles by comparing the current node with nodes in the path.</li>
+        <li>Marks nodes involved in cycles and updates the stack to continue traversal.</li>
+      </ul>
+    </p>
+    <h2>Usage</h2>
+    <p>
+      The <code>is_acyclic_q</code> 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.
+    </p>
+  </div>
+
+</body>
+</html>
diff --git a/developer/documentđź–‰/nomenclature.txt b/developer/documentđź–‰/nomenclature.txt
new file mode 100644 (file)
index 0000000..633dc4a
--- /dev/null
@@ -0,0 +1,3 @@
+
+wellformed is a single word. Its antonym is 'malformed'. Wellformed syntax
+parses without errors.
diff --git a/developer/javac/Ariadne_File.java b/developer/javac/Ariadne_File.java
deleted file mode 100644 (file)
index 825b499..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-package com.ReasoningTechnology.Ariadne;
-
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class Ariadne_File {
-  static boolean debug = false;
-
-  public static Map<String, String> unpack_file_path(String file_fp) {
-    if (debug) System.out.println("unpack_file_path::file_fp: " + file_fp);
-
-    // Use java.io.File explicitly to avoid conflict with the custom Ariadne_File class
-    java.io.File file = new java.io.File(file_fp);
-    String parent_dp = (file.getParent() != null) ? file.getParent() : "";
-
-    if (!parent_dp.isEmpty() && !parent_dp.endsWith(java.io.File.separator)) {
-      parent_dp += java.io.File.separator;
-    }
-
-    String file_fn = file.getName();
-    String file_fn_base = file_fn;
-    String file_fn_ext = "";
-
-    int last_index = file_fn.lastIndexOf('.');
-    if (last_index > 0) {
-      file_fn_base = file_fn.substring(0, last_index);
-      if (last_index + 1 < file_fn.length()) {
-        file_fn_ext = file_fn.substring(last_index + 1);
-      }
-    }
-
-    Map<String, String> ret_val = new HashMap<>();
-    ret_val.put("dp", parent_dp);
-    ret_val.put("fn", file_fn);
-    ret_val.put("fn_base", file_fn_base);
-    ret_val.put("fn_ext", file_fn_ext);
-
-    if (debug) System.out.println("unpack_file_path::ret_val: " + ret_val);
-
-    return ret_val;
-  }
-
-  public static boolean file_exists_q(String fp_string) {
-    Path fp_object = Paths.get(fp_string);
-    return Files.exists(fp_object);
-  }
-
-  /*
-    Given a target_fp and a list of dependency_fp.
-
-    Returns false if the target is newer than all dependencies or if a file is missing;
-    otherwise, returns true.
-  */
-  public static boolean newer_than_all(String target_fp_string, List<String> dependency_fp_list) throws IOException {
-    Path target_fp_object = Paths.get(target_fp_string);
-    if (!Files.exists(target_fp_object)) return false;
-
-    long target_last_modified_time = Files.getLastModifiedTime(target_fp_object).toMillis();
-
-    return dependency_fp_list.stream().allMatch(dependency_fp -> {
-      try {
-        Path dependency_fp_object = Paths.get(dependency_fp);
-        if (!Files.exists(dependency_fp_object)) return false;
-        long dependency_last_modified_time = Files.getLastModifiedTime(dependency_fp_object).toMillis();
-        return target_last_modified_time > dependency_last_modified_time;
-      } catch (IOException e) {
-        return false;
-      }
-    });
-  }
-}
diff --git a/developer/javac/Ariadne_Graph.java b/developer/javac/Ariadne_Graph.java
deleted file mode 100644 (file)
index 2dd28b6..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-package com.ReasoningTechnology.Ariadne;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class Ariadne_Graph {
-
-  /*--------------------------------------------------------------------------------
-    constructors
-  */
-
-  public Ariadne_Graph(Map<Ariadne_Label, Ariadne_Node> node_map, Ariadne_ProductionList recognizer_f_list) {
-    if (node_map == null && recognizer_f_list == null) {
-      System.err.println("Ariadne_Graph: At least one of 'node_map' (Map) or 'recognizer_f_list' (List) must be provided.");
-      System.exit(1);
-    }
-
-    // Initialize each of node_map and recognizer_f_list to empty collections if null
-    this.node_map = (node_map != null) ? node_map : new HashMap<>();
-    this.recognizer_f_list = (recognizer_f_list != null) ? recognizer_f_list : new Ariadne_ProductionList();
-  }
-
-  /*--------------------------------------------------------------------------------
-   instance data 
-  */
-
-  private static boolean debug = true;
-  private Map<Ariadne_Label, Ariadne_Node> node_map;
-  private Ariadne_ProductionList recognizer_f_list;
-
-  /*--------------------------------------------------------------------------------
-   interface
-  */
-
-  // Lookup method to find a node by its label
-  public Ariadne_Node lookup(Ariadne_Label node_label, boolean verbose) {
-    if (node_label == null || node_label.isEmpty()) {
-      if (verbose) {
-        System.out.println("lookup:: given node_label is null or empty.");
-      }
-      return null;
-    }
-
-    // Try to retrieve the node from the map
-    Ariadne_Node node = this.node_map.get(node_label);
-
-    if (verbose) {
-      if (node != null) {
-        System.out.println("lookup:: found node: " + node);
-      } else {
-        System.out.println("lookup:: node not found for label: " + node_label);
-      }
-    }
-
-    return node;
-  }
-
-  // Overloaded lookup method with default verbosity (true)
-  public Ariadne_Node lookup(Ariadne_Label node_label) {
-    return lookup(node_label, true);
-  }
-}
diff --git a/developer/javac/Ariadne_GraphDirectedAcyclic.java b/developer/javac/Ariadne_GraphDirectedAcyclic.java
deleted file mode 100644 (file)
index 3a8e9e2..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-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 {
-
-  /*--------------------------------------------------------------------------------
-    Constructors
-  */
-
-  public Ariadne_GraphDirectedAcyclic(Map<Ariadne_Label, Ariadne_Node> node_map, Ariadne_ProductionList 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_ProductionList 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);
-  }
-
-  /*--------------------------------------------------------------------------------
-    Instance Data Extension
-  */
-
-  private static boolean debug = true;
-
-  /*--------------------------------------------------------------------------------
-    Interface
-  */
-
-  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 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"));
-  }};
-
-  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 static Ariadne_TokenSet graph_mark_cycles_set = 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"));
-  }};
-
-  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);
-  }
-
-}
diff --git a/developer/javac/Ariadne_Label.java b/developer/javac/Ariadne_Label.java
deleted file mode 100644 (file)
index 9f10fcb..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.ReasoningTechnology.Ariadne;
-
-/*
-  A value for the node.label property.
-
-  This is a wrapper for a String. We can't instead use an alias by extending
-  String, because String is a JavaScript 'final' type.
-
-*/
-public class Ariadne_Label{
-  private final String value;
-
-  public Ariadne_Label(String value){
-    this.value = value;
-  }
-
-  public boolean isEmpty(){
-    return value.isEmpty();
-  }
-
-  public String get(){
-    return value;
-  }
-
-  @Override
-  public String toString(){
-    return value;
-  }
-
-  @Override
-  public boolean equals(Object o){
-    if(this == o) return true;
-    if( o == null || getClass() != o.getClass() ) return false;
-    Ariadne_Label label = (Ariadne_Label)o;
-    return value.equals( label.value );
-  }
-
-  @Override
-  public int hashCode(){
-    return value.hashCode();
-  }
-}
diff --git a/developer/javac/Ariadne_LabelList.java b/developer/javac/Ariadne_LabelList.java
deleted file mode 100644 (file)
index ae2dd0b..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// LabelList.java
-package com.ReasoningTechnology.Ariadne;
-import java.util.List; 
-import java.util.ArrayList;
-
-public class Ariadne_LabelList extends ArrayList<Ariadne_Label>{
-  // Constructor
-  public Ariadne_LabelList(){
-    super();
-  }
-  public Ariadne_LabelList(List<Ariadne_Label> labels){
-    super();  // Initialize the parent class
-    if(labels != null){
-      this.addAll(labels);  // Copy all elements from the provided list
-    }
-  }
-
-}
diff --git a/developer/javac/Ariadne_Node.java b/developer/javac/Ariadne_Node.java
deleted file mode 100644 (file)
index 41d8ccd..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.ReasoningTechnology.Ariadne;
-import java.util.HashMap;
-
-public class Ariadne_Node extends HashMap<String, Object> {
-
-  private static String mark_property_name = "mark";
-  private static String neighbor_property_name = "neighbor";
-
-  public Ariadne_Node() {
-    super();
-    this.put(neighbor_property_name, new Ariadne_LabelList());
-  }
-
-  public void mark(Ariadne_Token token) {
-    if (this.get(mark_property_name) == null) {
-      this.put(mark_property_name, new Ariadne_TokenSet());
-    }
-    ((Ariadne_TokenSet) this.get(mark_property_name)).add(token);
-  }
-
-  public boolean has_mark(Ariadne_Token token) {
-    Ariadne_TokenSet mark = (Ariadne_TokenSet) this.get(mark_property_name);
-    return mark != null && mark.contains(token);
-  }
-
-  public Ariadne_LabelList neighbor_LabelList() {
-    return (Ariadne_LabelList) this.get(neighbor_property_name);
-  }
-
-}
diff --git a/developer/javac/Ariadne_NodeList.java b/developer/javac/Ariadne_NodeList.java
deleted file mode 100644 (file)
index 69e4284..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// NodeList.java
-package com.ReasoningTechnology.Ariadne;
-import java.util.ArrayList;
-
-public class Ariadne_NodeList extends ArrayList<Ariadne_Node> {
-  // Constructor
-  public Ariadne_NodeList(){
-    super();
-  }
-}
diff --git a/developer/javac/Ariadne_Production.java b/developer/javac/Ariadne_Production.java
deleted file mode 100644 (file)
index ab6aed9..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-// Production.java
-package com.ReasoningTechnology.Ariadne;
-import java.util.function.Function;
-
-public interface Ariadne_Production extends Function<Ariadne_Label, Ariadne_Node> {}
diff --git a/developer/javac/Ariadne_ProductionList.java b/developer/javac/Ariadne_ProductionList.java
deleted file mode 100644 (file)
index 03b2461..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// ProductionList.java
-package com.ReasoningTechnology.Ariadne;
-import java.util.ArrayList;
-
-public class Ariadne_ProductionList extends ArrayList<Ariadne_Production> {
-  // Constructor
-  public Ariadne_ProductionList(){
-    super();
-  }
-}
diff --git a/developer/javac/Ariadne_Token.java b/developer/javac/Ariadne_Token.java
deleted file mode 100644 (file)
index 98e3863..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.ReasoningTechnology.Ariadne;
-
-/*
-An error token.
-
-*/
-public class Ariadne_Token {
-  private final String value;
-
-  public Ariadne_Token(String value){
-    this.value = value;
-  }
-
-  public String get(){
-    return value;
-  }
-
-  @Override
-  public String toString(){
-    return value;
-  }
-
-  @Override
-  public boolean equals(Object o){
-    if(this == o) return true;  // No padding, not nested
-    if( o == null || getClass() != o.getClass() ) return false;  // Padded, because it's nested
-    Ariadne_Token token = (Ariadne_Token)o;
-    return value.equals( token.value );
-  }
-
-  @Override
-  public int hashCode(){
-    return value.hashCode();
-  }
-}
diff --git a/developer/javac/Ariadne_TokenSet.java b/developer/javac/Ariadne_TokenSet.java
deleted file mode 100644 (file)
index 9ec671c..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// TokenSet.java
-package com.ReasoningTechnology.Ariadne;
-import java.util.HashSet;
-
-public class Ariadne_TokenSet extends HashSet<Ariadne_Token> {
-  // Constructor
-  public Ariadne_TokenSet(){
-    super();
-  }
-}
diff --git a/developer/javac/Ariadne_Util.java b/developer/javac/Ariadne_Util.java
deleted file mode 100644 (file)
index 28009b3..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.ReasoningTechnology.Ariadne;
-import java.util.List; 
-
-public class Ariadne_Util{
-  static boolean debug = false;
-
-  public static void print_list(String prefix ,List<?> item_list){
-    if( item_list == null || item_list.isEmpty() ){
-      return;
-    }
-    if( prefix != null && !prefix.isEmpty() ){
-      System.out.print(prefix);
-    }
-    int i = 0;
-    int n = item_list.size() - 1;
-    System.out.print( " '" + item_list.get(i) + "'" );
-    do{
-      i++;
-      if( i > n ) break;
-      System.out.print(", " +  "'" + item_list.get(i) + "'");
-    }while( true );
-    System.out.println(".");
-  }
-
-}
diff --git a/developer/javac/Build.javax b/developer/javac/Build.javax
deleted file mode 100644 (file)
index b0cdab3..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-import java.util.List;
-
-public class Build {
-
-    // Function to load the graph class dynamically
-    public static Class<?> includeAClass(String aClassFp) {
-        ClassLoader classLoader = Build.class.getClassLoader();
-        String className = aClassFp.replace('/', '.').replace(".class", "");
-        try {
-            return classLoader.loadClass(className);
-        } catch (Exception e) {
-            System.out.println("Error loading class '" + className + "': " + e.getMessage());
-            return null;
-        }
-    }
-
-    // Build function
-    public static void build(String graphDefinitionFp, List<String> rootNodeLabels) {
-        // Print summary of what we are doing
-        System.out.println("build:: Building targets for graph '" + graphDefinitionFp + ".class'");
-        if (rootNodeLabels.isEmpty()) {
-            System.out.println("No build targets specified. Please provide root node labels to build.");
-            System.exit(0);
-        }
-        System.out.println("Building targets: " + String.join(", ", rootNodeLabels));
-
-        // Load the dependency graph class from arg[1]
-        Class<?> graphDefinitionClass = includeAClass(graphDefinitionFp);
-        if (graphDefinitionClass != null) {
-            System.out.println("build:: loaded " + graphDefinitionFp + ".class");
-        } else {
-            System.out.println("build:: failed to load " + graphDefinitionFp + ".class");
-            System.exit(1);
-        }
-
-        // Get the node_map and node_f_list from the graph class
-        // Assuming these methods are static and return the appropriate types
-        // Replace with actual method calls if they are different
-        Object nodeMap = null;
-        Object nodeFList = null;
-        try {
-            nodeMap = graphDefinitionClass.getMethod("getNodeMap").invoke(null);
-            nodeFList = graphDefinitionClass.getMethod("getNodeFList").invoke(null);
-        } catch (Exception e) {
-            System.out.println("Error invoking methods on graphDefinitionClass: " + e.getMessage());
-            System.exit(1);
-        }
-        System.out.println("node_map: " + nodeMap);
-        System.out.println("node_f_list: " + nodeFList);
-
-        // Create an instance of AriadneGraph, and run the build scripts
-        // Assuming AriadneGraph has a constructor that takes nodeMap and nodeFList
-        // Replace with actual constructor call if it is different
-        try {
-            Class<?> ariadneGraphClass = Class.forName("AriadneGraph");
-            Object graph = ariadneGraphClass.getConstructor(nodeMap.getClass(), nodeFList.getClass()).newInstance(nodeMap, nodeFList);
-            ariadneGraphClass.getMethod("runBuildScriptsF", List.class).invoke(graph, rootNodeLabels);
-        } catch (Exception e) {
-            System.out.println("Error creating or invoking AriadneGraph: " + e.getMessage());
-            System.exit(1);
-        }
-    }
-
-    // Entry point when run as a script
-    public static void main(String[] args) {
-        if (args.length == 0) {
-            System.out.println("Usage: ./build <graph_definition.class> [root_node_labels...]");
-            System.exit(1);
-        }
-
-        // Get graph definition file and root node labels
-        String graphDefinitionFp = args[0];
-        List<String> rootNodeLabels = args.length > 1 ? List.of(args).subList(1, args.length) : List.of();
-        build(graphDefinitionFp, rootNodeLabels);
-    }
-}
diff --git a/developer/javac/GraphAriadne.javax b/developer/javac/GraphAriadne.javax
deleted file mode 100644 (file)
index a5949fe..0000000
+++ /dev/null
@@ -1,376 +0,0 @@
-package com.ReasoningTechnology.Ariadne;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class AriadnaGraph extends Graph{
-
-  /*--------------------------------------------------------------------------------
-    constructors
-  */
-
-  public Graph(Map<Label ,Node> node_map ,ProductionList recognizer_f_list){
-
-  }
-
-  /*--------------------------------------------------------------------------------
-   instance data 
-  */
-
-  private static boolean debug = true;
-
-  /*--------------------------------------------------------------------------------
-    About nodes
-
-    A leaf type node specifies a path to a file that should not be deleted by
-    in clean operations. Typically this is the source code. We could add a
-    tool to lock permissions on these before a build, so that the build
-    scripts will also not mess with them (unless they change permissions).
-
-    If the user has multiple dependency graphs defined, a node with no
-    dependencies in one graph, might have dependencies in another.
-
-    An error type node, is one that was found to not have a type, or
-    was constructed by the tool to be a place older, perhaps for a
-    node label that was not found.
-
-  */
-  public static TokenSet all_node_type_set = new TokenSet();
-  static {
-    all_node_type_set.add(new Token("symbol"));
-    all_node_type_set.add(new Token("path"));
-    all_node_type_set.add(new Token("leaf"));
-    all_node_type_set.add(new Token("error"));
-  }
-
-  public static TokenSet persistent_node_mark_set = new TokenSet();
-  static {
-    persistent_node_mark_set.add(new Token("cycle_member"));
-    persistent_node_mark_set.add(new Token("wellformed"));
-    persistent_node_mark_set.add(new Token("build_failed"));
-    persistent_node_mark_set.add(new Token("null_node"));
-  }
-
-  public static boolean leaf_q(Node node){
-    return node != null && "leaf".equals(node.get("type"));
-  }
-
-  public static boolean has_mark(Node node){
-    return node != null && node.get("mark") != null && !( (TokenSet)node.get("mark") ).isEmpty();
-  }
-
-  public static void set_mark(Node node ,Token mark){
-    if( node.get("mark") == null ){
-      node.put("mark" ,new HashTokenSet());
-    }
-    ( (TokenSet)node.get("mark") ).add(mark);
-  }
-
-  public static void clear_mark(Node node ,Token mark){
-    if( node != null && node.get("mark") != null ){
-      ( (TokenSet) node.get("mark") ).remove(mark);
-    }
-  }
-
-  public static boolean marked_good_q(Node node){
-    return node != null && node.get("mark") != null
-      && ( (TokenSet)node.get("mark") ).contains("wellformed")
-      && !( (TokenSet)node.get("mark") ).contains("cycle_member")
-      && !( (TokenSet)node.get("mark") ).contains("build_failed");
-  }
-
-  /*--------------------------------------------------------------------------------
-   Well-formed Node Check
-  */
-
-  public static TokenSet form_condition_set = new TokenSet();
-  static {
-    form_condition_set.add(new Token("no_node"));
-    form_condition_set.add(new Token("node_must_have_label"));
-    form_condition_set.add(new Token("label_must_be_string"));
-    form_condition_set.add(new Token("node_must_have_type"));
-    form_condition_set.add(new Token("bad_node_type"));
-    form_condition_set.add(new Token("neighbor_value_must_be_list"));
-    form_condition_set.add(new Token("neighbor_reference_must_be_string"));
-    form_condition_set.add(new Token("neighbor_label_not_in_graph"));
-    form_condition_set.add(new Token("mark_property_value_must_be_set"));
-    form_condition_set.add(new Token("unregistered_mark"));
-    form_condition_set.add(new Token("missing_required_build_code"));
-    form_condition_set.add(new Token("leaf_given_neighbor_property"));
-    form_condition_set.add(new Token("leaf_given_build_property"));
-  }
-
-  // given a node, collects a description of its form, returns a set form condition tokens
-  public static TokenSet wellformed_node_q(Node node){
-    TokenSet form_error_set = new HashSet<>();
-
-    if(node == null){
-      form_error_set.add("null_node");
-      return form_error_set;
-    }
-
-    if( !node.containsKey("label") )
-      form_error_set.add("node_must_have_label");
-    else if( !(node.get("label") instanceof Label) )
-      form_error_set.add("label_must_be_string");
-
-    if( !node.containsKey("type") )
-      form_error_set.add("node_must_have_type");
-    else if( !(node.get("type") instanceof String) || !all_node_type_set.contains(node.get("type")) )
-      form_error_set.add("bad_node_type");
-
-    if( node.containsKey("neighbor") ){
-      if( !(node.get("neighbor") instanceof List) )
-        form_error_set.add("neighbor_value_must_be_list");
-      else if( !((List<?>) node.get("neighbor")).stream().allMatch(it -> it instanceof Label) )
-        form_error_set.add("neighbor_reference_must_be_string");
-    }
-
-    if( node.containsKey("mark") ){
-      if( !(node.get("mark") instanceof Set) )
-        form_error_set.add("mark_property_value_must_be_set");
-      else if( !((Set<?>) node.get("mark")).stream().allMatch(it -> persistent_node_mark_set.contains(it)) )
-        form_error_set.add("unregistered_mark");
-    }
-
-    if( "path".equals(node.get("type")) && (!node.containsKey("build") || !(node.get("build") instanceof Runnable)) )
-      form_error_set.add("missing_required_build_code");
-
-    if( "leaf".equals(node.get("type")) ){
-      if( node.containsKey("neighbor") ) form_error_set.add("leaf_given_neighbor_property");
-      if( node.containsKey("build") ) form_error_set.add("leaf_given_build_property");
-    }
-
-    return form_error_set;
-  }
-
-  // given a node, potentially marks it as wellformed, returns one of 'wellformed' or 'malformed'
-  public static Token wellformed_mark_node(Node node ,boolean verbose){
-    if(debug){
-      if(node != null){
-        System.out.println("wellformed_mark_node::node: " + node);
-      }else{
-        System.out.println("wellformed_mark_node given a null node");
-      }
-    }
-
-    TokenSet form_errors = wellformed_node_q(node);
-    if( form_errors.isEmpty() ){
-      set_mark( node ,"wellformed" );
-      return "wellformed";
-    }
-
-    // At this point we know that form_errors is not empty
-    if(verbose){
-      if( node != null && node.get("label") != null && ((Label)node.get("label")).length() > 0 ){
-        System.out.print( "node " + node.get("label") + " is malformed due to:" );
-      }else{
-        System.out.print("anonymous node is malformed due to:");
-      }
-      for(Token error : form_errors){
-        System.out.print(" " + error);
-      }
-      System.out.println("");
-    }
-
-    return "malformed";
-  }
-  public Token wellformed_mark_node(Node node){
-    return wellformed_mark_node(node ,true);
-  }
-
-  // given a node_label, potentially marks the corresponding node as 'wellformed', returns a token set.
-  // Tokens included "undefined_node", "malformed", and "defactor_leaf".
-  public TokenSet wellformed_mark_node_label(Label node_label ,boolean verbose){
-    TokenSet ret_value = new HashSet<>();
-    Node node = super.lookup(node_label);
-    if(node == null){
-      ret_value.add("undefined_node");
-      return ret_value;
-    }
-    if( "malformed".equals(wellformed_mark_node(node ,verbose)) ){
-      ret_value.add("malformed");
-    }
-    if( ((List<?>)node.get("neighbor")).isEmpty() ){
-      ret_value.add("defacto_leaf"); // might not be `type:leaf`
-    }
-    return ret_value;
-  }
-  public TokenSet wellformed_mark_node_label(Label node_label){
-    return wellformed_mark_node_label(node_label ,true);
-  }
-
-  /*--------------------------------------------------------------------------------
-   A well formed graph checker.  Traverses entire graph and marks nodes
-   that are not well formed or that are part of a cycle.
-
-   This must be run on the graph for `lookup_marked_good` to work.
-
-   Each node_label must be a string and not empty.
-
-   Subleties here because we have not yet determined if the nodes we are
-   wellformed (after all ,that is what we are determining here).
-
-   If we want to attempt to build 'islands' of things that might be located on
-   the far side of cycles ,then modify the cycle finder to return a list of
-   cycles (i.e. a list of lists) ,then use each of cycle definition (a list) as
-   the root nodes for further search.
-
-   `path_stack` is a stack of LabelList. The first entry is a clone of the list of
-   root nodes, referenced by label. Each subsequent list is a clone of the
-   neighbor list of the leftmost node of the prior entry.
-
-   `path` is a list of the left most nodes, referenced by label, of the entries
-   on the path stack. This is the path to our current location in the tree.
-  */
-
-
-  private boolean find_and_remove_cycle(List<LabelList> path_stack ,LabelList path ,boolean verbose){
-
-    if( path.size() <= 1 ) return false; // 0 or 1 length path can't have a cycle
-
-    // we want to know if the most recent node added to the path occurs at a point earlier
-    // in the path.
-    int rightmost_index = path.size() - 1;
-    Label recent_node_label = path.get( rightmost_index );
-    int cycle_start_index = path.indexOf(recent_node_label);
-    if( cycle_start_index == -1 ){
-      System.err.println("find_and_remove_cycle:: indexOf does not find index of known list member");
-      return false;
-    }
-    Boolean has_cycle =  cycle_start_index < rightmost_index;
-    if(!has_cycle) return false;
-
-    if(verbose) System.out.print("mark_form_graph_descend:: dependency cycle found:");
-    for( Label cycle_node_label : path.subList(cycle_start_index ,path.size()) ){
-      if(verbose) System.out.print(" " + cycle_node_label);
-      Node cycle_node = super.lookup(cycle_node_label);
-      if( cycle_node.get("mark") == null ){
-        cycle_node.put( "mark" ,new HashTokenSet() );
-      }
-      ( (TokenSet)cycle_node.get("mark") ).add("cycle_member");
-    }
-    if(verbose) System.out.println("");
-
-    // We cannot continue searching after the loop, so we pop back to treat
-    // the first node in the loop as though a leaf node.
-    path_stack.subList( cycle_start_index + 1 ,path_stack.size() ).clear();
-
-    return true;
-  }
-
-  private static TokenSet mark_form_graph_descend_set = new TokenSet();
-  static {
-    mark_form_graph_descend_set.add(new Token("empty_path_stack"));
-    mark_form_graph_descend_set.add(new Token("cycle_found"));
-    mark_form_graph_descend_set.add(new Token("undefined_node"));
-    mark_form_graph_descend_set.add(new Token("exists_malformed"));
-    mark_form_graph_descend_set.add(new Token("defacto_leaf"));
-  }
-
-  private TokenSet mark_form_graph_descend( List<LabelList> path_stack ,boolean verbose ){
-    TokenSet ret_value = new HashSet<>();
-    if(path_stack.isEmpty()){
-      if(verbose) System.out.println( "mark_form_graph_descend:: given empty path_stack to descend from" );
-      ret_value.add( "empty_path_stack" );
-      return ret_value;
-    }
-
-    LabelList local_path = new ArrayList<>();
-    for(LabelList path : path_stack){
-      local_path.add( path.get(0) );
-    }
-    Label local_node_label = local_path.get( local_path.size() - 1 );
-  
-    do{
-      
-      if( find_and_remove_cycle(path_stack ,local_path ,verbose) ){
-        ret_value.add("cycle_found");
-        return ret_value;
-      }
-
-      TokenSet wellformed_mark_node_label_result = wellformed_mark_node_label(local_node_label ,verbose);
-      ret_value.addAll( wellformed_mark_node_label_result );
-      if( 
-         wellformed_mark_node_label_result.contains("undefined_node") 
-         || wellformed_mark_node_label_result.contains("defacto_leaf") 
-      ){
-        return ret_value;
-      }
-
-      // Descend further into the tree.
-      path_stack.add( new ArrayList<>((LabelList) super.lookup(local_node_label).get("neighbor")) );
-      local_node_label = (LabelList)super.lookup(local_node_label).get("neighbor").get(0);
-      local_path.add(local_node_label);
-
-    }while(true);
-  }
-
-   
-  /*
-    Given root_node_label_list, marks up the graph and returns a set possibly
-    containing 'all_wellformed' and 'cycles_exist'.
-
-    Marks potentially added to each node include 'cycle_member' and 'wellformed'.
-    Note that these marks are independent.
-  */
-  public TokenSet mark_form_graph(LabelList root_node_label_list ,boolean verbose){
-    TokenSet ret_value = new HashSet<>();
-    boolean exists_malformed = false;
-    TokenSet result; // used variously
-
-    if( root_node_label_list.isEmpty() ) return ret_value;
-
-    // Initialize the DFS tree iterator.
-    List<LabelList> path_stack = new ArrayList<>();
-    path_stack.add( new ArrayList<>(root_node_label_list) );
-
-    // iterate over left side tree descent, not ideal as it starts at the
-    // root each time, but avoids complexity in the cycle detection logic.
-    do{
-      result = mark_form_graph_descend(path_stack ,verbose);
-      if( result.contains("cycle_found") ) ret_value.add("cycle_exists");
-      if( result.contains("undefined_node") ) exists_malformed = true;
-      if( result.contains("exists_malformed") ) exists_malformed = true;
-
-      // increment the iterator to the next leftmost path
-      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( !exists_malformed ) ret_value.add("all_wellformed");
-
-    if( verbose ){
-      if( exists_malformed ) System.out.println("one or more malformed nodes were found");
-      boolean exists_cycle = ret_value.contains("cycle_exists");
-      if( exists_cycle ) System.out.println("one or more cyclic dependency loop found");
-      if( exists_malformed || exists_cycle ) System.out.println("will attempt to build unaffected nodes");
-    }
-
-    return ret_value;
-  }
-  public TokenSet mark_form_graph(LabelList root_node_label_list){
-    return mark_form_graph(root_node_label_list ,true);
-  }
-
-  /*--------------------------------------------------------------------------------
-    Graph traversal
-  */
-
-  // Lookup method to find a node by its label
-  public Node lookup(Label node_label ,boolean verbose){
-    Node node = super.lookup(node_label ,verbose);
-    if(node != null && marked_good_q(node)) return node;
-    return null;
-  }
-
-  // Overloaded lookup method with default verbosity (true)
-  public Node lookup(Label node_label){
-    return lookup(node_label ,true);
-  }
-
-
-
-}
diff --git a/developer/javacđź–‰/Ariadne_File.java b/developer/javacđź–‰/Ariadne_File.java
new file mode 100644 (file)
index 0000000..825b499
--- /dev/null
@@ -0,0 +1,76 @@
+package com.ReasoningTechnology.Ariadne;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class Ariadne_File {
+  static boolean debug = false;
+
+  public static Map<String, String> unpack_file_path(String file_fp) {
+    if (debug) System.out.println("unpack_file_path::file_fp: " + file_fp);
+
+    // Use java.io.File explicitly to avoid conflict with the custom Ariadne_File class
+    java.io.File file = new java.io.File(file_fp);
+    String parent_dp = (file.getParent() != null) ? file.getParent() : "";
+
+    if (!parent_dp.isEmpty() && !parent_dp.endsWith(java.io.File.separator)) {
+      parent_dp += java.io.File.separator;
+    }
+
+    String file_fn = file.getName();
+    String file_fn_base = file_fn;
+    String file_fn_ext = "";
+
+    int last_index = file_fn.lastIndexOf('.');
+    if (last_index > 0) {
+      file_fn_base = file_fn.substring(0, last_index);
+      if (last_index + 1 < file_fn.length()) {
+        file_fn_ext = file_fn.substring(last_index + 1);
+      }
+    }
+
+    Map<String, String> ret_val = new HashMap<>();
+    ret_val.put("dp", parent_dp);
+    ret_val.put("fn", file_fn);
+    ret_val.put("fn_base", file_fn_base);
+    ret_val.put("fn_ext", file_fn_ext);
+
+    if (debug) System.out.println("unpack_file_path::ret_val: " + ret_val);
+
+    return ret_val;
+  }
+
+  public static boolean file_exists_q(String fp_string) {
+    Path fp_object = Paths.get(fp_string);
+    return Files.exists(fp_object);
+  }
+
+  /*
+    Given a target_fp and a list of dependency_fp.
+
+    Returns false if the target is newer than all dependencies or if a file is missing;
+    otherwise, returns true.
+  */
+  public static boolean newer_than_all(String target_fp_string, List<String> dependency_fp_list) throws IOException {
+    Path target_fp_object = Paths.get(target_fp_string);
+    if (!Files.exists(target_fp_object)) return false;
+
+    long target_last_modified_time = Files.getLastModifiedTime(target_fp_object).toMillis();
+
+    return dependency_fp_list.stream().allMatch(dependency_fp -> {
+      try {
+        Path dependency_fp_object = Paths.get(dependency_fp);
+        if (!Files.exists(dependency_fp_object)) return false;
+        long dependency_last_modified_time = Files.getLastModifiedTime(dependency_fp_object).toMillis();
+        return target_last_modified_time > dependency_last_modified_time;
+      } catch (IOException e) {
+        return false;
+      }
+    });
+  }
+}
diff --git a/developer/javacđź–‰/Ariadne_Graph.java b/developer/javacđź–‰/Ariadne_Graph.java
new file mode 100644 (file)
index 0000000..2dd28b6
--- /dev/null
@@ -0,0 +1,62 @@
+package com.ReasoningTechnology.Ariadne;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class Ariadne_Graph {
+
+  /*--------------------------------------------------------------------------------
+    constructors
+  */
+
+  public Ariadne_Graph(Map<Ariadne_Label, Ariadne_Node> node_map, Ariadne_ProductionList recognizer_f_list) {
+    if (node_map == null && recognizer_f_list == null) {
+      System.err.println("Ariadne_Graph: At least one of 'node_map' (Map) or 'recognizer_f_list' (List) must be provided.");
+      System.exit(1);
+    }
+
+    // Initialize each of node_map and recognizer_f_list to empty collections if null
+    this.node_map = (node_map != null) ? node_map : new HashMap<>();
+    this.recognizer_f_list = (recognizer_f_list != null) ? recognizer_f_list : new Ariadne_ProductionList();
+  }
+
+  /*--------------------------------------------------------------------------------
+   instance data 
+  */
+
+  private static boolean debug = true;
+  private Map<Ariadne_Label, Ariadne_Node> node_map;
+  private Ariadne_ProductionList recognizer_f_list;
+
+  /*--------------------------------------------------------------------------------
+   interface
+  */
+
+  // Lookup method to find a node by its label
+  public Ariadne_Node lookup(Ariadne_Label node_label, boolean verbose) {
+    if (node_label == null || node_label.isEmpty()) {
+      if (verbose) {
+        System.out.println("lookup:: given node_label is null or empty.");
+      }
+      return null;
+    }
+
+    // Try to retrieve the node from the map
+    Ariadne_Node node = this.node_map.get(node_label);
+
+    if (verbose) {
+      if (node != null) {
+        System.out.println("lookup:: found node: " + node);
+      } else {
+        System.out.println("lookup:: node not found for label: " + node_label);
+      }
+    }
+
+    return node;
+  }
+
+  // Overloaded lookup method with default verbosity (true)
+  public Ariadne_Node lookup(Ariadne_Label node_label) {
+    return lookup(node_label, true);
+  }
+}
diff --git a/developer/javacđź–‰/Ariadne_GraphDirectedAcyclic.java b/developer/javacđź–‰/Ariadne_GraphDirectedAcyclic.java
new file mode 100644 (file)
index 0000000..3a8e9e2
--- /dev/null
@@ -0,0 +1,214 @@
+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 {
+
+  /*--------------------------------------------------------------------------------
+    Constructors
+  */
+
+  public Ariadne_GraphDirectedAcyclic(Map<Ariadne_Label, Ariadne_Node> node_map, Ariadne_ProductionList 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_ProductionList 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);
+  }
+
+  /*--------------------------------------------------------------------------------
+    Instance Data Extension
+  */
+
+  private static boolean debug = true;
+
+  /*--------------------------------------------------------------------------------
+    Interface
+  */
+
+  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 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"));
+  }};
+
+  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 static Ariadne_TokenSet graph_mark_cycles_set = 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"));
+  }};
+
+  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);
+  }
+
+}
diff --git a/developer/javacđź–‰/Ariadne_Label.java b/developer/javacđź–‰/Ariadne_Label.java
new file mode 100644 (file)
index 0000000..9f10fcb
--- /dev/null
@@ -0,0 +1,42 @@
+package com.ReasoningTechnology.Ariadne;
+
+/*
+  A value for the node.label property.
+
+  This is a wrapper for a String. We can't instead use an alias by extending
+  String, because String is a JavaScript 'final' type.
+
+*/
+public class Ariadne_Label{
+  private final String value;
+
+  public Ariadne_Label(String value){
+    this.value = value;
+  }
+
+  public boolean isEmpty(){
+    return value.isEmpty();
+  }
+
+  public String get(){
+    return value;
+  }
+
+  @Override
+  public String toString(){
+    return value;
+  }
+
+  @Override
+  public boolean equals(Object o){
+    if(this == o) return true;
+    if( o == null || getClass() != o.getClass() ) return false;
+    Ariadne_Label label = (Ariadne_Label)o;
+    return value.equals( label.value );
+  }
+
+  @Override
+  public int hashCode(){
+    return value.hashCode();
+  }
+}
diff --git a/developer/javacđź–‰/Ariadne_LabelList.java b/developer/javacđź–‰/Ariadne_LabelList.java
new file mode 100644 (file)
index 0000000..ae2dd0b
--- /dev/null
@@ -0,0 +1,18 @@
+// LabelList.java
+package com.ReasoningTechnology.Ariadne;
+import java.util.List; 
+import java.util.ArrayList;
+
+public class Ariadne_LabelList extends ArrayList<Ariadne_Label>{
+  // Constructor
+  public Ariadne_LabelList(){
+    super();
+  }
+  public Ariadne_LabelList(List<Ariadne_Label> labels){
+    super();  // Initialize the parent class
+    if(labels != null){
+      this.addAll(labels);  // Copy all elements from the provided list
+    }
+  }
+
+}
diff --git a/developer/javacđź–‰/Ariadne_Node.java b/developer/javacđź–‰/Ariadne_Node.java
new file mode 100644 (file)
index 0000000..41d8ccd
--- /dev/null
@@ -0,0 +1,30 @@
+package com.ReasoningTechnology.Ariadne;
+import java.util.HashMap;
+
+public class Ariadne_Node extends HashMap<String, Object> {
+
+  private static String mark_property_name = "mark";
+  private static String neighbor_property_name = "neighbor";
+
+  public Ariadne_Node() {
+    super();
+    this.put(neighbor_property_name, new Ariadne_LabelList());
+  }
+
+  public void mark(Ariadne_Token token) {
+    if (this.get(mark_property_name) == null) {
+      this.put(mark_property_name, new Ariadne_TokenSet());
+    }
+    ((Ariadne_TokenSet) this.get(mark_property_name)).add(token);
+  }
+
+  public boolean has_mark(Ariadne_Token token) {
+    Ariadne_TokenSet mark = (Ariadne_TokenSet) this.get(mark_property_name);
+    return mark != null && mark.contains(token);
+  }
+
+  public Ariadne_LabelList neighbor_LabelList() {
+    return (Ariadne_LabelList) this.get(neighbor_property_name);
+  }
+
+}
diff --git a/developer/javacđź–‰/Ariadne_NodeList.java b/developer/javacđź–‰/Ariadne_NodeList.java
new file mode 100644 (file)
index 0000000..69e4284
--- /dev/null
@@ -0,0 +1,10 @@
+// NodeList.java
+package com.ReasoningTechnology.Ariadne;
+import java.util.ArrayList;
+
+public class Ariadne_NodeList extends ArrayList<Ariadne_Node> {
+  // Constructor
+  public Ariadne_NodeList(){
+    super();
+  }
+}
diff --git a/developer/javacđź–‰/Ariadne_Production.java b/developer/javacđź–‰/Ariadne_Production.java
new file mode 100644 (file)
index 0000000..ab6aed9
--- /dev/null
@@ -0,0 +1,5 @@
+// Production.java
+package com.ReasoningTechnology.Ariadne;
+import java.util.function.Function;
+
+public interface Ariadne_Production extends Function<Ariadne_Label, Ariadne_Node> {}
diff --git a/developer/javacđź–‰/Ariadne_ProductionList.java b/developer/javacđź–‰/Ariadne_ProductionList.java
new file mode 100644 (file)
index 0000000..03b2461
--- /dev/null
@@ -0,0 +1,10 @@
+// ProductionList.java
+package com.ReasoningTechnology.Ariadne;
+import java.util.ArrayList;
+
+public class Ariadne_ProductionList extends ArrayList<Ariadne_Production> {
+  // Constructor
+  public Ariadne_ProductionList(){
+    super();
+  }
+}
diff --git a/developer/javacđź–‰/Ariadne_Token.java b/developer/javacđź–‰/Ariadne_Token.java
new file mode 100644 (file)
index 0000000..98e3863
--- /dev/null
@@ -0,0 +1,35 @@
+package com.ReasoningTechnology.Ariadne;
+
+/*
+An error token.
+
+*/
+public class Ariadne_Token {
+  private final String value;
+
+  public Ariadne_Token(String value){
+    this.value = value;
+  }
+
+  public String get(){
+    return value;
+  }
+
+  @Override
+  public String toString(){
+    return value;
+  }
+
+  @Override
+  public boolean equals(Object o){
+    if(this == o) return true;  // No padding, not nested
+    if( o == null || getClass() != o.getClass() ) return false;  // Padded, because it's nested
+    Ariadne_Token token = (Ariadne_Token)o;
+    return value.equals( token.value );
+  }
+
+  @Override
+  public int hashCode(){
+    return value.hashCode();
+  }
+}
diff --git a/developer/javacđź–‰/Ariadne_TokenSet.java b/developer/javacđź–‰/Ariadne_TokenSet.java
new file mode 100644 (file)
index 0000000..9ec671c
--- /dev/null
@@ -0,0 +1,10 @@
+// TokenSet.java
+package com.ReasoningTechnology.Ariadne;
+import java.util.HashSet;
+
+public class Ariadne_TokenSet extends HashSet<Ariadne_Token> {
+  // Constructor
+  public Ariadne_TokenSet(){
+    super();
+  }
+}
diff --git a/developer/javacđź–‰/Ariadne_Util.java b/developer/javacđź–‰/Ariadne_Util.java
new file mode 100644 (file)
index 0000000..28009b3
--- /dev/null
@@ -0,0 +1,25 @@
+package com.ReasoningTechnology.Ariadne;
+import java.util.List; 
+
+public class Ariadne_Util{
+  static boolean debug = false;
+
+  public static void print_list(String prefix ,List<?> item_list){
+    if( item_list == null || item_list.isEmpty() ){
+      return;
+    }
+    if( prefix != null && !prefix.isEmpty() ){
+      System.out.print(prefix);
+    }
+    int i = 0;
+    int n = item_list.size() - 1;
+    System.out.print( " '" + item_list.get(i) + "'" );
+    do{
+      i++;
+      if( i > n ) break;
+      System.out.print(", " +  "'" + item_list.get(i) + "'");
+    }while( true );
+    System.out.println(".");
+  }
+
+}
diff --git a/developer/javacđź–‰/Build.javax b/developer/javacđź–‰/Build.javax
new file mode 100644 (file)
index 0000000..b0cdab3
--- /dev/null
@@ -0,0 +1,76 @@
+import java.util.List;
+
+public class Build {
+
+    // Function to load the graph class dynamically
+    public static Class<?> includeAClass(String aClassFp) {
+        ClassLoader classLoader = Build.class.getClassLoader();
+        String className = aClassFp.replace('/', '.').replace(".class", "");
+        try {
+            return classLoader.loadClass(className);
+        } catch (Exception e) {
+            System.out.println("Error loading class '" + className + "': " + e.getMessage());
+            return null;
+        }
+    }
+
+    // Build function
+    public static void build(String graphDefinitionFp, List<String> rootNodeLabels) {
+        // Print summary of what we are doing
+        System.out.println("build:: Building targets for graph '" + graphDefinitionFp + ".class'");
+        if (rootNodeLabels.isEmpty()) {
+            System.out.println("No build targets specified. Please provide root node labels to build.");
+            System.exit(0);
+        }
+        System.out.println("Building targets: " + String.join(", ", rootNodeLabels));
+
+        // Load the dependency graph class from arg[1]
+        Class<?> graphDefinitionClass = includeAClass(graphDefinitionFp);
+        if (graphDefinitionClass != null) {
+            System.out.println("build:: loaded " + graphDefinitionFp + ".class");
+        } else {
+            System.out.println("build:: failed to load " + graphDefinitionFp + ".class");
+            System.exit(1);
+        }
+
+        // Get the node_map and node_f_list from the graph class
+        // Assuming these methods are static and return the appropriate types
+        // Replace with actual method calls if they are different
+        Object nodeMap = null;
+        Object nodeFList = null;
+        try {
+            nodeMap = graphDefinitionClass.getMethod("getNodeMap").invoke(null);
+            nodeFList = graphDefinitionClass.getMethod("getNodeFList").invoke(null);
+        } catch (Exception e) {
+            System.out.println("Error invoking methods on graphDefinitionClass: " + e.getMessage());
+            System.exit(1);
+        }
+        System.out.println("node_map: " + nodeMap);
+        System.out.println("node_f_list: " + nodeFList);
+
+        // Create an instance of AriadneGraph, and run the build scripts
+        // Assuming AriadneGraph has a constructor that takes nodeMap and nodeFList
+        // Replace with actual constructor call if it is different
+        try {
+            Class<?> ariadneGraphClass = Class.forName("AriadneGraph");
+            Object graph = ariadneGraphClass.getConstructor(nodeMap.getClass(), nodeFList.getClass()).newInstance(nodeMap, nodeFList);
+            ariadneGraphClass.getMethod("runBuildScriptsF", List.class).invoke(graph, rootNodeLabels);
+        } catch (Exception e) {
+            System.out.println("Error creating or invoking AriadneGraph: " + e.getMessage());
+            System.exit(1);
+        }
+    }
+
+    // Entry point when run as a script
+    public static void main(String[] args) {
+        if (args.length == 0) {
+            System.out.println("Usage: ./build <graph_definition.class> [root_node_labels...]");
+            System.exit(1);
+        }
+
+        // Get graph definition file and root node labels
+        String graphDefinitionFp = args[0];
+        List<String> rootNodeLabels = args.length > 1 ? List.of(args).subList(1, args.length) : List.of();
+        build(graphDefinitionFp, rootNodeLabels);
+    }
+}
diff --git a/developer/javacđź–‰/GraphAriadne.javax b/developer/javacđź–‰/GraphAriadne.javax
new file mode 100644 (file)
index 0000000..a5949fe
--- /dev/null
@@ -0,0 +1,376 @@
+package com.ReasoningTechnology.Ariadne;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class AriadnaGraph extends Graph{
+
+  /*--------------------------------------------------------------------------------
+    constructors
+  */
+
+  public Graph(Map<Label ,Node> node_map ,ProductionList recognizer_f_list){
+
+  }
+
+  /*--------------------------------------------------------------------------------
+   instance data 
+  */
+
+  private static boolean debug = true;
+
+  /*--------------------------------------------------------------------------------
+    About nodes
+
+    A leaf type node specifies a path to a file that should not be deleted by
+    in clean operations. Typically this is the source code. We could add a
+    tool to lock permissions on these before a build, so that the build
+    scripts will also not mess with them (unless they change permissions).
+
+    If the user has multiple dependency graphs defined, a node with no
+    dependencies in one graph, might have dependencies in another.
+
+    An error type node, is one that was found to not have a type, or
+    was constructed by the tool to be a place older, perhaps for a
+    node label that was not found.
+
+  */
+  public static TokenSet all_node_type_set = new TokenSet();
+  static {
+    all_node_type_set.add(new Token("symbol"));
+    all_node_type_set.add(new Token("path"));
+    all_node_type_set.add(new Token("leaf"));
+    all_node_type_set.add(new Token("error"));
+  }
+
+  public static TokenSet persistent_node_mark_set = new TokenSet();
+  static {
+    persistent_node_mark_set.add(new Token("cycle_member"));
+    persistent_node_mark_set.add(new Token("wellformed"));
+    persistent_node_mark_set.add(new Token("build_failed"));
+    persistent_node_mark_set.add(new Token("null_node"));
+  }
+
+  public static boolean leaf_q(Node node){
+    return node != null && "leaf".equals(node.get("type"));
+  }
+
+  public static boolean has_mark(Node node){
+    return node != null && node.get("mark") != null && !( (TokenSet)node.get("mark") ).isEmpty();
+  }
+
+  public static void set_mark(Node node ,Token mark){
+    if( node.get("mark") == null ){
+      node.put("mark" ,new HashTokenSet());
+    }
+    ( (TokenSet)node.get("mark") ).add(mark);
+  }
+
+  public static void clear_mark(Node node ,Token mark){
+    if( node != null && node.get("mark") != null ){
+      ( (TokenSet) node.get("mark") ).remove(mark);
+    }
+  }
+
+  public static boolean marked_good_q(Node node){
+    return node != null && node.get("mark") != null
+      && ( (TokenSet)node.get("mark") ).contains("wellformed")
+      && !( (TokenSet)node.get("mark") ).contains("cycle_member")
+      && !( (TokenSet)node.get("mark") ).contains("build_failed");
+  }
+
+  /*--------------------------------------------------------------------------------
+   Well-formed Node Check
+  */
+
+  public static TokenSet form_condition_set = new TokenSet();
+  static {
+    form_condition_set.add(new Token("no_node"));
+    form_condition_set.add(new Token("node_must_have_label"));
+    form_condition_set.add(new Token("label_must_be_string"));
+    form_condition_set.add(new Token("node_must_have_type"));
+    form_condition_set.add(new Token("bad_node_type"));
+    form_condition_set.add(new Token("neighbor_value_must_be_list"));
+    form_condition_set.add(new Token("neighbor_reference_must_be_string"));
+    form_condition_set.add(new Token("neighbor_label_not_in_graph"));
+    form_condition_set.add(new Token("mark_property_value_must_be_set"));
+    form_condition_set.add(new Token("unregistered_mark"));
+    form_condition_set.add(new Token("missing_required_build_code"));
+    form_condition_set.add(new Token("leaf_given_neighbor_property"));
+    form_condition_set.add(new Token("leaf_given_build_property"));
+  }
+
+  // given a node, collects a description of its form, returns a set form condition tokens
+  public static TokenSet wellformed_node_q(Node node){
+    TokenSet form_error_set = new HashSet<>();
+
+    if(node == null){
+      form_error_set.add("null_node");
+      return form_error_set;
+    }
+
+    if( !node.containsKey("label") )
+      form_error_set.add("node_must_have_label");
+    else if( !(node.get("label") instanceof Label) )
+      form_error_set.add("label_must_be_string");
+
+    if( !node.containsKey("type") )
+      form_error_set.add("node_must_have_type");
+    else if( !(node.get("type") instanceof String) || !all_node_type_set.contains(node.get("type")) )
+      form_error_set.add("bad_node_type");
+
+    if( node.containsKey("neighbor") ){
+      if( !(node.get("neighbor") instanceof List) )
+        form_error_set.add("neighbor_value_must_be_list");
+      else if( !((List<?>) node.get("neighbor")).stream().allMatch(it -> it instanceof Label) )
+        form_error_set.add("neighbor_reference_must_be_string");
+    }
+
+    if( node.containsKey("mark") ){
+      if( !(node.get("mark") instanceof Set) )
+        form_error_set.add("mark_property_value_must_be_set");
+      else if( !((Set<?>) node.get("mark")).stream().allMatch(it -> persistent_node_mark_set.contains(it)) )
+        form_error_set.add("unregistered_mark");
+    }
+
+    if( "path".equals(node.get("type")) && (!node.containsKey("build") || !(node.get("build") instanceof Runnable)) )
+      form_error_set.add("missing_required_build_code");
+
+    if( "leaf".equals(node.get("type")) ){
+      if( node.containsKey("neighbor") ) form_error_set.add("leaf_given_neighbor_property");
+      if( node.containsKey("build") ) form_error_set.add("leaf_given_build_property");
+    }
+
+    return form_error_set;
+  }
+
+  // given a node, potentially marks it as wellformed, returns one of 'wellformed' or 'malformed'
+  public static Token wellformed_mark_node(Node node ,boolean verbose){
+    if(debug){
+      if(node != null){
+        System.out.println("wellformed_mark_node::node: " + node);
+      }else{
+        System.out.println("wellformed_mark_node given a null node");
+      }
+    }
+
+    TokenSet form_errors = wellformed_node_q(node);
+    if( form_errors.isEmpty() ){
+      set_mark( node ,"wellformed" );
+      return "wellformed";
+    }
+
+    // At this point we know that form_errors is not empty
+    if(verbose){
+      if( node != null && node.get("label") != null && ((Label)node.get("label")).length() > 0 ){
+        System.out.print( "node " + node.get("label") + " is malformed due to:" );
+      }else{
+        System.out.print("anonymous node is malformed due to:");
+      }
+      for(Token error : form_errors){
+        System.out.print(" " + error);
+      }
+      System.out.println("");
+    }
+
+    return "malformed";
+  }
+  public Token wellformed_mark_node(Node node){
+    return wellformed_mark_node(node ,true);
+  }
+
+  // given a node_label, potentially marks the corresponding node as 'wellformed', returns a token set.
+  // Tokens included "undefined_node", "malformed", and "defactor_leaf".
+  public TokenSet wellformed_mark_node_label(Label node_label ,boolean verbose){
+    TokenSet ret_value = new HashSet<>();
+    Node node = super.lookup(node_label);
+    if(node == null){
+      ret_value.add("undefined_node");
+      return ret_value;
+    }
+    if( "malformed".equals(wellformed_mark_node(node ,verbose)) ){
+      ret_value.add("malformed");
+    }
+    if( ((List<?>)node.get("neighbor")).isEmpty() ){
+      ret_value.add("defacto_leaf"); // might not be `type:leaf`
+    }
+    return ret_value;
+  }
+  public TokenSet wellformed_mark_node_label(Label node_label){
+    return wellformed_mark_node_label(node_label ,true);
+  }
+
+  /*--------------------------------------------------------------------------------
+   A well formed graph checker.  Traverses entire graph and marks nodes
+   that are not well formed or that are part of a cycle.
+
+   This must be run on the graph for `lookup_marked_good` to work.
+
+   Each node_label must be a string and not empty.
+
+   Subleties here because we have not yet determined if the nodes we are
+   wellformed (after all ,that is what we are determining here).
+
+   If we want to attempt to build 'islands' of things that might be located on
+   the far side of cycles ,then modify the cycle finder to return a list of
+   cycles (i.e. a list of lists) ,then use each of cycle definition (a list) as
+   the root nodes for further search.
+
+   `path_stack` is a stack of LabelList. The first entry is a clone of the list of
+   root nodes, referenced by label. Each subsequent list is a clone of the
+   neighbor list of the leftmost node of the prior entry.
+
+   `path` is a list of the left most nodes, referenced by label, of the entries
+   on the path stack. This is the path to our current location in the tree.
+  */
+
+
+  private boolean find_and_remove_cycle(List<LabelList> path_stack ,LabelList path ,boolean verbose){
+
+    if( path.size() <= 1 ) return false; // 0 or 1 length path can't have a cycle
+
+    // we want to know if the most recent node added to the path occurs at a point earlier
+    // in the path.
+    int rightmost_index = path.size() - 1;
+    Label recent_node_label = path.get( rightmost_index );
+    int cycle_start_index = path.indexOf(recent_node_label);
+    if( cycle_start_index == -1 ){
+      System.err.println("find_and_remove_cycle:: indexOf does not find index of known list member");
+      return false;
+    }
+    Boolean has_cycle =  cycle_start_index < rightmost_index;
+    if(!has_cycle) return false;
+
+    if(verbose) System.out.print("mark_form_graph_descend:: dependency cycle found:");
+    for( Label cycle_node_label : path.subList(cycle_start_index ,path.size()) ){
+      if(verbose) System.out.print(" " + cycle_node_label);
+      Node cycle_node = super.lookup(cycle_node_label);
+      if( cycle_node.get("mark") == null ){
+        cycle_node.put( "mark" ,new HashTokenSet() );
+      }
+      ( (TokenSet)cycle_node.get("mark") ).add("cycle_member");
+    }
+    if(verbose) System.out.println("");
+
+    // We cannot continue searching after the loop, so we pop back to treat
+    // the first node in the loop as though a leaf node.
+    path_stack.subList( cycle_start_index + 1 ,path_stack.size() ).clear();
+
+    return true;
+  }
+
+  private static TokenSet mark_form_graph_descend_set = new TokenSet();
+  static {
+    mark_form_graph_descend_set.add(new Token("empty_path_stack"));
+    mark_form_graph_descend_set.add(new Token("cycle_found"));
+    mark_form_graph_descend_set.add(new Token("undefined_node"));
+    mark_form_graph_descend_set.add(new Token("exists_malformed"));
+    mark_form_graph_descend_set.add(new Token("defacto_leaf"));
+  }
+
+  private TokenSet mark_form_graph_descend( List<LabelList> path_stack ,boolean verbose ){
+    TokenSet ret_value = new HashSet<>();
+    if(path_stack.isEmpty()){
+      if(verbose) System.out.println( "mark_form_graph_descend:: given empty path_stack to descend from" );
+      ret_value.add( "empty_path_stack" );
+      return ret_value;
+    }
+
+    LabelList local_path = new ArrayList<>();
+    for(LabelList path : path_stack){
+      local_path.add( path.get(0) );
+    }
+    Label local_node_label = local_path.get( local_path.size() - 1 );
+  
+    do{
+      
+      if( find_and_remove_cycle(path_stack ,local_path ,verbose) ){
+        ret_value.add("cycle_found");
+        return ret_value;
+      }
+
+      TokenSet wellformed_mark_node_label_result = wellformed_mark_node_label(local_node_label ,verbose);
+      ret_value.addAll( wellformed_mark_node_label_result );
+      if( 
+         wellformed_mark_node_label_result.contains("undefined_node") 
+         || wellformed_mark_node_label_result.contains("defacto_leaf") 
+      ){
+        return ret_value;
+      }
+
+      // Descend further into the tree.
+      path_stack.add( new ArrayList<>((LabelList) super.lookup(local_node_label).get("neighbor")) );
+      local_node_label = (LabelList)super.lookup(local_node_label).get("neighbor").get(0);
+      local_path.add(local_node_label);
+
+    }while(true);
+  }
+
+   
+  /*
+    Given root_node_label_list, marks up the graph and returns a set possibly
+    containing 'all_wellformed' and 'cycles_exist'.
+
+    Marks potentially added to each node include 'cycle_member' and 'wellformed'.
+    Note that these marks are independent.
+  */
+  public TokenSet mark_form_graph(LabelList root_node_label_list ,boolean verbose){
+    TokenSet ret_value = new HashSet<>();
+    boolean exists_malformed = false;
+    TokenSet result; // used variously
+
+    if( root_node_label_list.isEmpty() ) return ret_value;
+
+    // Initialize the DFS tree iterator.
+    List<LabelList> path_stack = new ArrayList<>();
+    path_stack.add( new ArrayList<>(root_node_label_list) );
+
+    // iterate over left side tree descent, not ideal as it starts at the
+    // root each time, but avoids complexity in the cycle detection logic.
+    do{
+      result = mark_form_graph_descend(path_stack ,verbose);
+      if( result.contains("cycle_found") ) ret_value.add("cycle_exists");
+      if( result.contains("undefined_node") ) exists_malformed = true;
+      if( result.contains("exists_malformed") ) exists_malformed = true;
+
+      // increment the iterator to the next leftmost path
+      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( !exists_malformed ) ret_value.add("all_wellformed");
+
+    if( verbose ){
+      if( exists_malformed ) System.out.println("one or more malformed nodes were found");
+      boolean exists_cycle = ret_value.contains("cycle_exists");
+      if( exists_cycle ) System.out.println("one or more cyclic dependency loop found");
+      if( exists_malformed || exists_cycle ) System.out.println("will attempt to build unaffected nodes");
+    }
+
+    return ret_value;
+  }
+  public TokenSet mark_form_graph(LabelList root_node_label_list){
+    return mark_form_graph(root_node_label_list ,true);
+  }
+
+  /*--------------------------------------------------------------------------------
+    Graph traversal
+  */
+
+  // Lookup method to find a node by its label
+  public Node lookup(Label node_label ,boolean verbose){
+    Node node = super.lookup(node_label ,verbose);
+    if(node != null && marked_good_q(node)) return node;
+    return null;
+  }
+
+  // Overloaded lookup method with default verbosity (true)
+  public Node lookup(Label node_label){
+    return lookup(node_label ,true);
+  }
+
+
+
+}
diff --git a/developer/shell/.githolder b/developer/shell/.githolder
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/developer/shell/Build b/developer/shell/Build
deleted file mode 100755 (executable)
index 2a18026..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-java com.ReasoningTechnology."Ariadne".Build
diff --git a/developer/tool/clean_build_directories b/developer/tool/clean_build_directories
deleted file mode 100755 (executable)
index 7091d81..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-
-# Removes all files found in the build directories. It asks no questions as to
-# how or why the files got there. Be especially careful with the 'shell'
-# directory if you have authored scripts for release, add a `shell-leaf`
-# directory instead of putting them in `shell`.
-
-# input guards
-  env_must_be="developer/tool/env"
-  if [ "$ENV" != "$env_must_be" ]; then
-    echo "$(script_fp):: error: must be run in the $env_must_be environment"
-    exit 1
-  fi
-
-# remove files
-  set -x
-  cd "$REPO_HOME"/developer
-  rm -r scratchpad/*
-  rm jvm/*
-  rm shell/*
-  set +x
-
-echo "$(script_fn) done."
-
diff --git a/developer/tool/clean_javac_output b/developer/tool/clean_javac_output
deleted file mode 100755 (executable)
index 5ebeb51..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-# remove  all files created by make's call to `javac`
-
-# input guards
-  env_must_be="developer/tool/env"
-  if [ "$ENV" != "$env_must_be" ]; then
-    echo "$(script_fp):: error: must be run in the $env_must_be environment"
-    exit 1
-  fi
-
-# remove files
-  set -x
-  cd "$REPO_HOME"/developer
-  rm -r scratchpad/com/ReasoningTechnology/"$PROJECT"
-  set +x
-
-echo "$(script_fn) done."
diff --git a/developer/tool/clean_make_output b/developer/tool/clean_make_output
deleted file mode 100755 (executable)
index a7c6ebf..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-# remove all files made by `make`
-
-# input guards
-
-  env_must_be="developer/tool/env"
-  if [ "$ENV" != "$env_must_be" ]; then
-    echo "$(script_fp):: error: must be run in the $env_must_be environment"
-    exit 1
-  fi
-
-# wrappers to clean (this list space separated list will grow)
-
-  wrapper=$(shell_wrapper_list)
-
-# remove files
-
-  set -x
-  cd "$REPO_HOME"/developer
-  rm -r scratchpad/com/ReasoningTechnology/"$PROJECT"
-  rm jvm/"$PROJECT".jar
-  rm shell/{$wrapper}
-  set +x
-
-echo "$(script_fn) done."
diff --git a/developer/tool/clean_release b/developer/tool/clean_release
deleted file mode 100755 (executable)
index a33f19a..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-# remove files made by `make` and by `release`
-
-# input guards
-
-  env_must_be="developer/tool/env"
-  if [ "$ENV" != "$env_must_be" ]; then
-    echo "$(script_fp):: error: must be run in the $env_must_be environment"
-    exit 1
-  fi
-
-# things to clean
-
-  release_dir="$REPO_HOME"/release
-  wrapper=$(shell_wrapper_list)
-
-# remove files
-  set -x
-  cd "$REPO_HOME"/developer
-  rm -r scratchpad/com/ReasoningTechnology/"$PROJECT"
-  rm jvm/"$PROJECT".jar
-  rm shell/{$wrapper}
-  rm -f "$release_dir"/"$PROJECT".jar
-  rm -f "$release_dir"/{$wrapper}
-  set +x
-
-echo "$(script_fn) done."
-
diff --git a/developer/tool/distribute_source b/developer/tool/distribute_source
deleted file mode 100755 (executable)
index 6629cdc..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-
-# This script links the sources in javac into the directory tree that parallels
-# the package name in scratch_pad.  If the `-nolink` option is specified,
-# it makes a copy instead of a link.
-
-# Input guards
-env_must_be="developer/tool/env"
-if [ "$ENV" != "$env_must_be" ]; then
-  echo "$script_afp:: error: must be run in the $env_must_be environment"
-  exit 1
-fi
-
-cd "$REPO_HOME"/developer || exit 1
-
-# Parse options
-nolink=false
-while [[ "$1" == -* ]]; do
-  case "$1" in
-    -nolink) nolink=true ;;
-    *) echo "$script_afp:: error: unknown option $1" && exit 1 ;;
-  esac
-  shift
-done
-
-# Set up package tree
-package_tree="scratchpad/com/ReasoningTechnology/$PROJECT"
-mkdir -p "$package_tree"
-echo "Package: $package_tree"
-
-# Process files
-echo -n "$([[ $nolink == true ]] && echo "Copying" || echo "Linking"):"
-for source_file in javac/*.java; do
-  echo -n " $(basename "$source_file")"
-  link_target="$package_tree/$(basename "$source_file")"
-  # Copy the file if -nolink option is provided, otherwise create a link
-  if [[ $nolink == true ]]; then
-   # Remove link if present, otherwise copy will try to overwrite the link target (and fail).
-    rm -f "$link_target"
-    cp "$source_file" "$link_target"
-  else
-    # Create a symbolic link if -nolink is not provided
-    if [ ! -L "$link_target" ]; then
-      ln -s "$(realpath --relative-to="$package_tree" "$source_file")" "$link_target"
-    fi
-  fi
-done
-echo "."
-
-echo "$script_afp done."
-
-
diff --git a/developer/tool/env b/developer/tool/env
deleted file mode 100644 (file)
index 66446d4..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/usr/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-
-# input guards
-
-  env_must_be="tool_shared/bespoke/env"
-  error=false
-  if [ "$ENV" != "$env_must_be" ]; then
-    echo "$(script_fp):: error: must be run in the $env_must_be environment"
-    error=true
-  fi
-  if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
-    echo "$script_afp:: This script must be sourced, not executed."
-    error=true
-  fi
-  if $error; then exit 1; fi
-
-# so we can do the build
-
-export PATH=\
-"$REPO_HOME"/developer/tool/\
-:"$REPO_HOME"/tool_shared/bespoke/\
-:"$JAVA_HOME"/bin\
-:"$PATH"
-
-# so we can run the stuff we built locally.
-
-export CLASSPATH=\
-"$REPO_HOME"/developer/jvm\
-:"$REPO_HOME"/developer/jvm/"$PROJECT".jar\
-:"$JAVA_HOME"/lib\
-:"$CLASSPATH"
-
-export PATH=\
-"$REPO_HOME"/developer/shell\
-:"$PATH"
-
-# misc
-
-  # make .githolder and .gitignore visible
-  alias ls="ls -a"
-
-# some feedback to show all went well
-
-  export PROMPT_DECOR="$PROJECT"_developer
-  export ENV=$(script_fp)
-  echo ENV "$ENV"
-  cd "$REPO_HOME"/developer/
-
-
-
diff --git a/developer/tool/make b/developer/tool/make
deleted file mode 100755 (executable)
index be84a0e..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-
-# input guards
-
-  env_must_be="developer/tool/env"
-  if [ "$ENV" != "$env_must_be" ]; then
-    echo "$(script_fp):: error: must be run in the $env_must_be environment"
-    exit 1
-  fi
-
-  cd "$REPO_HOME"/developer
-
-echo "Compiling files..."
-  set -x
-  javac -g -d scratchpad javac/*.java
-  set +x
-  if [ $? -ne 0 ]; then
-    echo "Compilation failed."
-    exit 1
-  fi
-
-echo "Creating JAR file..."
-  set -x
-  jar_file=jvm/"$PROJECT".jar
-  mkdir -p jvm
-  jar cf $jar_file -C scratchpad .
-  set +x
-  if [ $? -eq 0 ]; then
-    echo "JAR file created successfully: $jar_file"
-  else
-    echo "Failed to create JAR file."
-    exit 1
-  fi
-
-echo "Creating shell wrappers..."
-  mkdir -p shell
-  # wrapper is a space separated list
-  wrapper=$(shell_wrapper_list)
-  for file in $wrapper;do
-    cat > shell/$file << EOL
-#!/bin/bash
-java com.ReasoningTechnology."$PROJECT".$file
-EOL
-    chmod +x shell/$file
-  done
-
-echo "$(script_fp) done."
-
diff --git a/developer/tool/release b/developer/tool/release
deleted file mode 100755 (executable)
index bcf4686..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/usr/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-
-# input guards
-
-  if [ -z "$REPO_HOME" ]; then
-    echo "$(script_fp):: REPO_HOME is not set."
-    exit 1
-  fi
-
-  env_must_be="developer/tool/env"
-  if [ "$ENV" != "$env_must_be" ]; then
-    echo "$(script_fp):: error: must be run in the $env_must_be environment"
-    exit 1
-  fi
-
-# script local environment
-
-  release_dir="$REPO_HOME/release"
-  shell_dir="$REPO_HOME/developer/shell"
-  project_jar_fp="$REPO_HOME/developer/jvm/"$PROJECT".jar"
-  wrapper=$(shell_wrapper_list)
-
-
-  if [ ! -d "$release_dir" ]; then
-    mkdir -p "$release_dir"
-  fi
-
-  # Function to copy and set permissions
-  install_file() {
-    source_fp="$1"
-    target_dp="$2"
-    perms="$3"
-
-    target_file="$target_dp/$(basename "$source_fp")"
-
-    if [ ! -f "$source_fp" ]; then
-      echo "install_file:: Source file '$source_fp' does not exist."
-      return 1
-    fi
-
-    if ! install -m "$perms" "$source_fp" "$target_file"; then
-      echo "Error: Failed to install $(basename "$source_fp") to $target_dp"
-      exit 1
-    else
-      echo "Installed $(basename "$source_fp") to $target_dp with permissions $perms"
-    fi
-  }
-# do the release
-
-  echo "Starting release process..."
-
-  # Install the JAR file
-  install_file "$project_jar_fp" "$release_dir" "ug+r"
-
-  # Install shell wrappers
-  for wrapper in $wrapper; do
-    install_file "$shell_dir/$wrapper" "$release_dir" "ug+r+x"
-  done
-
-echo "$(script_fp) done."
diff --git a/developer/tool/shell_wrapper_list b/developer/tool/shell_wrapper_list
deleted file mode 100755 (executable)
index 9130bde..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-
-# input guards
-
-  env_must_be="developer/tool/env"
-  if [ "$ENV" != "$env_must_be" ]; then
-    echo "$(script_fp):: error: must be run in the $env_must_be environment"
-    exit 1
-  fi
-
-  cd "$REPO_HOME"/developer
-
-# list of classes that have main calls and get shell wrappers
-echo Build
diff --git a/developer/toolđź–‰/bash_wrapper_list b/developer/toolđź–‰/bash_wrapper_list
new file mode 100755 (executable)
index 0000000..d4c620b
--- /dev/null
@@ -0,0 +1,15 @@
+#!/bin/env bash
+script_afp=$(realpath "${BASH_SOURCE[0]}")
+
+# input guards
+
+  env_must_be="developer/toolđź–‰/env"
+  if [ "$ENV" != "$env_must_be" ]; then
+    echo "$(script_fp):: error: must be run in the $env_must_be environment"
+    exit 1
+  fi
+
+  cd "$REPO_HOME"/developer
+
+# list of classes that have main calls and get bash wrappers
+echo Build
diff --git a/developer/toolđź–‰/clean_build_directories b/developer/toolđź–‰/clean_build_directories
new file mode 100755 (executable)
index 0000000..2414a1c
--- /dev/null
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+script_afp=$(realpath "${BASH_SOURCE[0]}")
+
+# Removes all files found in the build directories. It asks no questions as to
+# how or why the files got there. Be especially careful with the 'bash'
+# directory if you have authored scripts for release, add a `bashđź–‰`
+# directory instead of putting them in `bash`.
+
+# input guards
+  env_must_be="developer/toolđź–‰/env"
+  if [ "$ENV" != "$env_must_be" ]; then
+    echo "$(script_fp):: error: must be run in the $env_must_be environment"
+    exit 1
+  fi
+
+# remove files
+  set -x
+  cd "$REPO_HOME"/developer
+  rm -r scratchpad/*
+  rm jvm/*
+  rm bash/*
+  set +x
+
+echo "$(script_fn) done."
+
diff --git a/developer/toolđź–‰/clean_javac_output b/developer/toolđź–‰/clean_javac_output
new file mode 100755 (executable)
index 0000000..82835c7
--- /dev/null
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+script_afp=$(realpath "${BASH_SOURCE[0]}")
+# remove  all files created by make's call to `javac`
+
+# input guards
+  env_must_be="developer/toolđź–‰/env"
+  if [ "$ENV" != "$env_must_be" ]; then
+    echo "$(script_fp):: error: must be run in the $env_must_be environment"
+    exit 1
+  fi
+
+# remove files
+  set -x
+  cd "$REPO_HOME"/developer
+  rm -r scratchpad/com/ReasoningTechnology/"$PROJECT"
+  set +x
+
+echo "$(script_fn) done."
diff --git a/developer/toolđź–‰/clean_make_output b/developer/toolđź–‰/clean_make_output
new file mode 100755 (executable)
index 0000000..094552b
--- /dev/null
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+script_afp=$(realpath "${BASH_SOURCE[0]}")
+# remove all files made by `make`
+
+# input guards
+
+  env_must_be="developer/toolđź–‰/env"
+  if [ "$ENV" != "$env_must_be" ]; then
+    echo "$(script_fp):: error: must be run in the $env_must_be environment"
+    exit 1
+  fi
+
+# wrappers to clean (this list space separated list will grow)
+
+  wrapper=$(bash_wrapper_list)
+
+# remove files
+
+  set -x
+  cd "$REPO_HOME"/developer
+  rm -r scratchpad/com/ReasoningTechnology/"$PROJECT"
+  rm jvm/"$PROJECT".jar
+  rm bash/{$wrapper}
+  set +x
+
+echo "$(script_fn) done."
diff --git a/developer/toolđź–‰/clean_release b/developer/toolđź–‰/clean_release
new file mode 100755 (executable)
index 0000000..8744730
--- /dev/null
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+script_afp=$(realpath "${BASH_SOURCE[0]}")
+# remove files made by `make` and by `release`
+
+# input guards
+
+  env_must_be="developer/toolđź–‰/env"
+  if [ "$ENV" != "$env_must_be" ]; then
+    echo "$(script_fp):: error: must be run in the $env_must_be environment"
+    exit 1
+  fi
+
+# things to clean
+
+  release_dir="$REPO_HOME"/release
+  wrapper=$(bash_wrapper_list)
+
+# remove files
+  set -x
+  cd "$REPO_HOME"/developer
+  rm -r scratchpad/com/ReasoningTechnology/"$PROJECT"
+  rm jvm/"$PROJECT".jar
+  rm bash/{$wrapper}
+  rm -f "$release_dir"/"$PROJECT".jar
+  rm -f "$release_dir"/{$wrapper}
+  set +x
+
+echo "$(script_fn) done."
+
diff --git a/developer/toolđź–‰/distribute_source b/developer/toolđź–‰/distribute_source
new file mode 100755 (executable)
index 0000000..c0a9874
--- /dev/null
@@ -0,0 +1,53 @@
+#!/bin/env bash
+script_afp=$(realpath "${BASH_SOURCE[0]}")
+
+# This script links the sources in javacđź–‰ into the directory tree that parallels
+# the package name in scratch_pad.  If the `-nolink` option is specified,
+# it makes a copy instead of a link.
+
+# Input guards
+env_must_be="developer/toolđź–‰/env"
+if [ "$ENV" != "$env_must_be" ]; then
+  echo "$script_afp:: error: must be run in the $env_must_be environment"
+  exit 1
+fi
+
+cd "$REPO_HOME"/developer || exit 1
+
+# Parse options
+nolink=false
+while [[ "$1" == -* ]]; do
+  case "$1" in
+    -nolink) nolink=true ;;
+    *) echo "$script_afp:: error: unknown option $1" && exit 1 ;;
+  esac
+  shift
+done
+
+# Set up package tree
+package_tree="scratchpad/com/ReasoningTechnology/$PROJECT"
+mkdir -p "$package_tree"
+echo "Package: $package_tree"
+
+# Process files
+echo -n "$([[ $nolink == true ]] && echo "Copying" || echo "Linking"):"
+for source_file in javacđź–‰/*.java; do
+  echo -n " $(basename "$source_file")"
+  link_target="$package_tree/$(basename "$source_file")"
+  # Copy the file if -nolink option is provided, otherwise create a link
+  if [[ $nolink == true ]]; then
+   # Remove link if present, otherwise copy will try to overwrite the link target (and fail).
+    rm -f "$link_target"
+    cp "$source_file" "$link_target"
+  else
+    # Create a symbolic link if -nolink is not provided
+    if [ ! -L "$link_target" ]; then
+      ln -s "$(realpath --relative-to="$package_tree" "$source_file")" "$link_target"
+    fi
+  fi
+done
+echo "."
+
+echo "$script_afp done."
+
+
diff --git a/developer/toolđź–‰/env b/developer/toolđź–‰/env
new file mode 100644 (file)
index 0000000..630b7f6
--- /dev/null
@@ -0,0 +1,52 @@
+#!/usr/bin/env bash
+script_afp=$(realpath "${BASH_SOURCE[0]}")
+
+# input guards
+
+  env_must_be="tool_shared/bespokeđź–‰/env"
+  error_bad_env=false
+  error_not_sourced=false
+  if [ "$ENV" != "$env_must_be" ]; then
+    echo "$(script_fp):: error: must be run in the $env_must_be environment"
+    error_bad_env=true
+  fi
+  if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
+    echo "$script_afp:: This script must be sourced, not executed."
+    error_not_sourced=true
+  fi
+  if $error_not_sourced; then exit 1; fi
+  if $error_bad_env; then return 1; fi
+
+# so we can do the build
+
+export PATH=\
+"$REPO_HOME"/developer/toolđź–‰/\
+:"$JAVA_HOME"/bin\
+:"$PATH"
+
+# so we can run the stuff we built locally.
+
+export CLASSPATH=\
+"$REPO_HOME"/developer/jvm\
+:"$REPO_HOME"/developer/jvm/"$PROJECT".jar\
+:"$JAVA_HOME"/lib\
+:"$CLASSPATH"
+
+export PATH=\
+"$REPO_HOME"/developer/bash\
+:"$PATH"
+
+# misc
+
+  # make .githolder and .gitignore visible
+  alias ls="ls -a"
+
+# some feedback to show all went well
+
+  export PROMPT_DECOR="$PROJECT"_developer
+  export ENV=$(script_fp)
+  echo ENV "$ENV"
+  cd "$REPO_HOME"/developer/
+
+
+
diff --git a/developer/toolđź–‰/make b/developer/toolđź–‰/make
new file mode 100755 (executable)
index 0000000..64602b6
--- /dev/null
@@ -0,0 +1,49 @@
+#!/bin/env bash
+script_afp=$(realpath "${BASH_SOURCE[0]}")
+
+# input guards
+
+  env_must_be="developer/toolđź–‰/env"
+  if [ "$ENV" != "$env_must_be" ]; then
+    echo "$(script_fp):: error: must be run in the $env_must_be environment"
+    exit 1
+  fi
+
+  cd "$REPO_HOME"/developer
+
+echo "Compiling files..."
+  set -x
+  javac -g -d scratchpad javacđź–‰/*.java
+  set +x
+  if [ $? -ne 0 ]; then
+    echo "Compilation failed."
+    exit 1
+  fi
+
+echo "Creating JAR file..."
+  set -x
+  jar_file=jvm/"$PROJECT".jar
+  mkdir -p jvm
+  jar cf $jar_file -C scratchpad .
+  set +x
+  if [ $? -eq 0 ]; then
+    echo "JAR file created successfully: $jar_file"
+  else
+    echo "Failed to create JAR file."
+    exit 1
+  fi
+
+echo "Creating bash wrappers..."
+  mkdir -p bash
+  # wrapper is a space separated list
+  wrapper=$(bash_wrapper_list)
+  for file in $wrapper;do
+    cat > bash/$file << EOL
+#!/bin/bash
+java com.ReasoningTechnology."$PROJECT".$file
+EOL
+    chmod +x bash/$file
+  done
+
+echo "$(script_fp) done."
+
diff --git a/developer/toolđź–‰/release b/developer/toolđź–‰/release
new file mode 100755 (executable)
index 0000000..81966ad
--- /dev/null
@@ -0,0 +1,62 @@
+#!/usr/bin/env bash
+script_afp=$(realpath "${BASH_SOURCE[0]}")
+
+# input guards
+
+  if [ -z "$REPO_HOME" ]; then
+    echo "$(script_fp):: REPO_HOME is not set."
+    exit 1
+  fi
+
+  env_must_be="developer/toolđź–‰/env"
+  if [ "$ENV" != "$env_must_be" ]; then
+    echo "$(script_fp):: error: must be run in the $env_must_be environment"
+    exit 1
+  fi
+
+# script local environment
+
+  release_dir="$REPO_HOME/release"
+  bash_dir="$REPO_HOME/developer/bash"
+  project_jar_fp="$REPO_HOME/developer/jvm/"$PROJECT".jar"
+  wrapper=$(bash_wrapper_list)
+
+
+  if [ ! -d "$release_dir" ]; then
+    mkdir -p "$release_dir"
+  fi
+
+  # Function to copy and set permissions
+  install_file() {
+    source_fp="$1"
+    target_dp="$2"
+    perms="$3"
+
+    target_file="$target_dp/$(basename "$source_fp")"
+
+    if [ ! -f "$source_fp" ]; then
+      echo "install_file:: Source file '$source_fp' does not exist."
+      return 1
+    fi
+
+    if ! install -m "$perms" "$source_fp" "$target_file"; then
+      echo "Error: Failed to install $(basename "$source_fp") to $target_dp"
+      exit 1
+    else
+      echo "Installed $(basename "$source_fp") to $target_dp with permissions $perms"
+    fi
+  }
+# do the release
+
+  echo "Starting release process..."
+
+  # Install the JAR file
+  install_file "$project_jar_fp" "$release_dir" "ug+r"
+
+  # Install bash wrappers
+  for wrapper in $wrapper; do
+    install_file "$bash_dir/$wrapper" "$release_dir" "ug+r+x"
+  done
+
+echo "$(script_fp) done."
diff --git a/document/Eclipse.txt b/document/Eclipse.txt
deleted file mode 100644 (file)
index 167d14e..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-
-The project is originally configured to be used with Emacs as an IDE. The tools
-can all be run from a shell inside of emacs. Even when using an IDE what the
-shell environment scripts and tools do should be understood.
-
-I have added a working IntelliJ IDEA configuration, so if you want a modern IDE
-it is probably best to go with this. See ItelliJ_IDEA.txt in this directory.
-
-I've not run Eclipse on the project, if you do, perhaps you can update the notes
-here.  These things will probably increase your odds of making it work:
-  1. open a shell
-  2. cd to Ariadne, and source the env_developer
-  3. run the tool 'distribute_source'
-  3. run eclipse from the command line
-  4. give eclipse the 'scratchpad' directory as its source
-
-Be sure to run `release` after development to update what the tester sees.
-
-Do the analogous steps if you contribute as a 'tester'.  I.e. from
-the shell source env_tester instead. Also, you will need to add
-distribute_source to tester/tool, as it is currently not there.
-
diff --git a/document/IntelliJ_IDEA.txt b/document/IntelliJ_IDEA.txt
deleted file mode 100644 (file)
index 82b21cc..0000000
+++ /dev/null
@@ -1,252 +0,0 @@
-This file describes the local install and configuration of IntelliJ_IDEA for
-the Ariadne project.
-
-The project was/is originally configured to be used with Emacs as an IDE. The tools
-can all be run from a shell inside of emacs. Even when using an IDE what the
-shell environment scripts and tools do should be understood.
-
---------------------------------------------------------------------------------
-Some notes
-
-'project directory' - the directory with the .git file in it. Called $REPO_HOME in
-  RT scripts. Called $PROJECT_DIR$ (doesn't seem to be reliable) in IntelliJ
-  file paths.
-
-'module directory' - for RT projects examples include `~/Ariadne/developer' 
-  `~/Ariadne/tester`.  These are independent build environments.
-
-  Careful, if Intellij scans directories it will not hesitate to pull things
-  from `tool_shared`/third_party or wherever else it finds things, and it will
-  make a big mess.
-
-IntelliJ paths on forms:
-
-  I tried using $PROJECT_DIR$ as a variable standing for the project directory,
-  as this was suggested by an AI.  However IntelliJ simply made a directory
-  with the literal variable name. 
-
-  Also tried using $REPO_HOME, as that was defined in the environment IntelliJ was run from.
-  It had the same effect as $PROJECT_DIR$.
-
-  It will work with `~` for the home directory. So I have been using
-  `~/Ariadne/...` when typing out paths.
-
-  There will be a browser icon at the right of a form entry boxes that take
-  paths.  The browser tool starts from either /home or at / rather than at the
-  project.  It inserts absolute path names.
-
-A GUI bug:
-
-  There is a Gnome Linux bug where the drop down menu can stay on top no matter
-  what other window, application, or what virtual desktop a person is on.  You
-  must go back to the IDEA application window and hit <escape> to make it go
-  away.
-
-The [OK] button at the bottom of dialogs:
-
-   This closes the dialog.
-
-   To apply changes hit [Apply].
-
-   [OK] will not save what is on the dialog if [Apply] would fail, but
-   it still closes it.
-
---------------------------------------------------------------------------------
-To install ItelliJ
-
-  Download the tar file from 
-    `https://www.jetbrains.com/idea/download/?section=linux` 
-  into the
-    `$REPO_HOME/tool_shared/third_party/upstream`
-   directory.
-
-  Expand it into 
-    `$REPO_HOME/tool_shared/third_party` 
-  
-  cd into the expanded directory, into `bin`, then `chmod u+x` and run `idea_inst`.
-
-  set the env path to include 
-    `$REPO_HOME/tool_shared/third_party/idea-IC*/bin`
-
-  The executable is called `idea`.
-
-  Consider setting a desktop short cut. Consider instead installing it in your
-  own bin directory. Easily done, just move the directory created by the tar
-  file expansion there.
-
-  I prefer a user mode install, as there is no reason this tool should need
-  admin privileges.
-
---------------------------------------------------------------------------------
-Startup
-
-  ./tool_shared/third_party/idea-IC-243.21565.193/bin/idea &
-
-  Shows: Welcome screen
-    select "Open" as Ariadne already exists
-
-  Shows: Open File or Project Browser
-    In top dialog box put full path to project directory.
-
-    Hit [OK] at the bottom. Unlikely, but might be scrolled off the bottom of the screen.
-
-  Shows: main window
-     Appears after hitting OK from the "Open File or Project" [ok].
-
-     Has a tool bar at the top. There is a double meat hamburger menu icon
-     at the left. Hitting this will replace the top bar with a vertical
-     menu for drop down menus.
-
-     Careful, after the hamburger icon is pressed, the first drop down
-     menu instantly appears. Slide over to get the other drop downs.
-     Don't click, slide!
-
-     Under tool bar:
-       Far left is an icon bar.  Then a file browser.  And then a big box
-       describing hot keys.
-
---------------------------------------------------------------------------------
-Configuration
-
-If you cloned the Ariadne project, the modules will already be configured, and
-also probably some of the run configuration will already be configured.
-
-  -------------
-  Setup Project
-  Hamburger icon > File dop-down > Project Structure > Project
-
-    select project SDK from disk:
-      ~/Ariadne/tool_shared/third_party/jdk-11
-
-  -------------
-  Setup Modules
-
-    Hamburger icon > File dop-down > Project Structure > Modules
-
-      Shows: "Project Structure" dialog
-
-       Hit the '+' option that shows at the top of the second panel.
-
-       New Module.
-
-       Dialog pop-up
-
-          Name: developer
-
-          Location: (browse to the developer directory)
-
-            alternatively enter the full path, ~/Ariadne, e.g.
-
-            $PROJECT_DIR$ instead of, ~/Ariadne, worked when
-            entering the first module, but not the second. 
-
-          Dependencies:
-            Select the "Project SDK" from the drop down.
-
-          Careful, the module won't be made until hitting [Create] at the bottom.
-
-          As far as I can tell you can't get this panel again, rather delete and add
-          a new module if you need to change the entries.
-
-      Shows: "Project Structure" dialog, again, now the third panel with information about the
-      developer module.
-          Third panel shows three choices:  [Source] [Paths] [Dependencies]
-
-          [Sources] is already selected.
-
-              With Sources there are two panels.
-
-              In second panel, on right side, the module root should show at the top.
-              Under if it lists any sources, use the button at the far right of the
-              listing to x it out.
-
-              The first panel now shows a file browser for the module.
-
-                Select the `javac` directory with a single click. Then, and only
-                after, look immediately the directory lists and click on [Sources] 
-
-                "Source Folders" will now appear in the second panel. The
-                javac folder will be listed.
-
-              hit: [apply] at the bottom (or the form will reset to defaults next time)
-
-
-          Slide over to [Paths]      
-              Copmiler Output
-                select [Use Module Compile Output Path]
-                   Output Path: $PROJECT_DIR$/developer/scratchpad
-                   Test Path: $PROJECT_DIR$/developer/test
-
-                   leave the exclude output checkbox, that means to exclude from repo
-                   and from indexing for search
-
-              hit: [apply] at the bottom
-
-  -------------
-  To add an external tool, for example tester/tool/make:
-
-  This is how we integrate the local tools.
-
-  Note, even if a shell script runs then runs a java program, that jave program
-  was compiled with debug flags, and run in debug mode, it can't be debugged.  It
-  won't stop at break points, etc. For that an 'application' must be added see
-  the next section.
-
-  Hamburger> Run > edit configurations
-  Shows Run/Debug configurations dialog
-     Upper left hit '+'
-     Shows drop down
-       chose [Shell Script] second from bottom
-       Shows dialog, for example:
-         Name: tester make
-         Script Path: ~/Ariadne/tester/tool/make  (better to chose with the browser tool)
-         Script Options: tester make
-         Working Directory: ~/Ariadne  (location of the env source scripts that env_run uses)
-         Environment variabls:  (none, env_run will source env_tester)
-         Interpreter: /bin/bash  (left to default)
-
-  -------------
-  To add a program for debugging.
-
-    Humburger > Run > edit configurations
-    Shows Run/Debug configurations dialog
-       Upper left hit '+'
-       Shows drop down
-         chose [Application] first choice
-         Shows dialog, for example:
-         Name: Test_Graph_0
-
-         next line are two boxes, they are not labeled, the defaults show:
-         [ module not specified ] [ -cp no module ]
-           I selected::
-           [ java 11 SDk of 'tester' module]  [ -cp tester ]
-             This can be confusing, as the modules are 'tester' and 'developer', but
-             here it asks for an SDK! Then the next box says it wants a class path,
-             but it wants a module name!
-
-         next line one box, not labeled
-         [ main class [] ]
-           Note icon at right, it will give a list of class names, here in the tester module,
-           that have main calls, select one.
-
-         next line, again not labeled
-         [ Program Arguments ]
-           Test_Graph_0 has no arguments so I left it blank.
-
-         Working Directory: ~/Ariadne
-
-         Environment Variables:
-           Left blank because the executable itself does not make use of any. I do
-           know at this point if variables set in the environment IDEA ran in are
-           inherited.
-
-         'Modify Options' with a drop down menu. (At the top right of the configuration dialog)
-           Scan down for the `Java` section.
-           Check: 'Do not build before run'
-             (To build this example, go to the Run menu and run `tester make'. Or run make directly
-             from a console prompt. Be sure to source env_tester first.)
-
-    Next go to main window file browser, click on the file you want to debug, click on the line
-    to set a break point. Right click to get a menu, and 
-
diff --git a/document/license.txt b/document/license.txt
deleted file mode 100644 (file)
index e177f6f..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-Apache License
-Version 2.0, January 2004
-http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
-"License" shall mean the terms and conditions for use, reproduction, and
-distribution as defined by Sections 1 through 9 of this document.
-
-"Licensor" shall mean the copyright owner or entity authorized by the copyright
-owner that is granting the License.
-
-"Legal Entity" shall mean the union of the acting entity and all other entities
-that control, are controlled by, or are under common control with that
-entity. For the purposes of this definition, "control" means (i) the power,
-direct or indirect, to cause the direction or management of such entity, whether
-by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of
-the outstanding shares, or (iii) beneficial ownership of such entity.
-
-"You" (or "Your") shall mean an individual or Legal Entity exercising
-permissions granted by this License.
-
-"Source" form shall mean the preferred form for making modifications, including
-but not limited to software source code, documentation source, and configuration
-files.
-
-"Object" form shall mean any form resulting from mechanical transformation or
-translation of a Source form, including but not limited to compiled object code,
-generated documentation, and conversions to other media types.
-
-"Work" shall mean the work of authorship, whether in Source or Object form, made
-available under the License, as indicated by a copyright notice that is included
-in or attached to the work (an example is provided in the Appendix below).
-
-"Derivative Works" shall mean any work, whether in Source or Object form, that
-is based on (or derived from) the Work and for which the editorial revisions,
-annotations, elaborations, or other modifications represent, as a whole, an
-original work of authorship. For the purposes of this License, Derivative Works
-shall not include works that remain separable from, or merely link (or bind by
-name) to the interfaces of, the Work and Derivative Works thereof.
-
-"Contribution" shall mean any work of authorship, including the original version
-of the Work and any modifications or additions to that Work or Derivative Works
-thereof, that is intentionally submitted to Licensor for inclusion in the Work
-by the copyright owner or by an individual or Legal Entity authorized to submit
-on behalf of the copyright owner. For the purposes of this definition,
-"submitted" means any form of electronic, verbal, or written communication sent
-to the Licensor or its representatives, including but not limited to
-communication on electronic mailing lists, source code control systems, and
-issue tracking systems that are managed by, or on behalf of, the Licensor for
-the purpose of discussing and improving the Work, but excluding communication
-that is conspicuously marked or otherwise designated in writing by the copyright
-owner as "Not a Contribution."
-
-"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
-of whom a Contribution has been received by Licensor and subsequently
-incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of this
-License, each Contributor hereby grants to You a perpetual, worldwide,
-non-exclusive, no-charge, royalty-free, irrevocable copyright license to
-reproduce, prepare Derivative Works of, publicly display, publicly perform,
-sublicense, and distribute the Work and such Derivative Works in Source or
-Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of this License,
-each Contributor hereby grants to You a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable (except as stated in this section) patent
-license to make, have made, use, offer to sell, sell, import, and otherwise
-transfer the Work, where such license applies only to those patent claims
-licensable by such Contributor that are necessarily infringed by their
-Contribution(s) alone or by combination of their Contribution(s) with the Work
-to which such Contribution(s) was submitted. If You institute patent litigation
-against any entity (including a cross-claim or counterclaim in a lawsuit)
-alleging that the Work or a Contribution incorporated within the Work
-constitutes direct or contributory patent infringement, then any patent licenses
-granted to You under this License for that Work shall terminate as of the date
-such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the Work or
-Derivative Works thereof in any medium, with or without modifications, and in
-Source or Object form, provided that You meet the following conditions:
-
-You must give any other recipients of the Work or Derivative Works a copy of
-this License; and You must cause any modified files to carry prominent notices
-stating that You changed the files; and You must retain, in the Source form of
-any Derivative Works that You distribute, all copyright, patent, trademark, and
-attribution notices from the Source form of the Work, excluding those notices
-that do not pertain to any part of the Derivative Works; and If the Work
-includes a "NOTICE" text file as part of its distribution, then any Derivative
-Works that You distribute must include a readable copy of the attribution
-notices contained within such NOTICE file, excluding those notices that do not
-pertain to any part of the Derivative Works, in at least one of the following
-places: within a NOTICE text file distributed as part of the Derivative Works;
-within the Source form or documentation, if provided along with the Derivative
-Works; or, within a display generated by the Derivative Works, if and wherever
-such third-party notices normally appear. The contents of the NOTICE file are
-for informational purposes only and do not modify the License. You may add Your
-own attribution notices within Derivative Works that You distribute, alongside
-or as an addendum to the NOTICE text from the Work, provided that such
-additional attribution notices cannot be construed as modifying the License.
-You may add Your own copyright statement to Your modifications and may provide
-additional or different license terms and conditions for use, reproduction, or
-distribution of Your modifications, or for any such Derivative Works as a whole,
-provided Your use, reproduction, and distribution of the Work otherwise complies
-with the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise, any
-Contribution intentionally submitted for inclusion in the Work by You to the
-Licensor shall be under the terms and conditions of this License, without any
-additional terms or conditions. Notwithstanding the above, nothing herein shall
-supersede or modify the terms of any separate license agreement you may have
-executed with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade names,
-trademarks, service marks, or product names of the Licensor, except as required
-for reasonable and customary use in describing the origin of the Work and
-reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or agreed to in
-writing, Licensor provides the Work (and each Contributor provides its
-Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied, including, without limitation, any warranties
-or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-PARTICULAR PURPOSE. You are solely responsible for determining the
-appropriateness of using or redistributing the Work and assume any risks
-associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory, whether in
-tort (including negligence), contract, or otherwise, unless required by
-applicable law (such as deliberate and grossly negligent acts) or agreed to in
-writing, shall any Contributor be liable to You for damages, including any
-direct, indirect, special, incidental, or consequential damages of any character
-arising as a result of this License or out of the use or inability to use the
-Work (including but not limited to damages for loss of goodwill, work stoppage,
-computer failure or malfunction, or any and all other commercial damages or
-losses), even if such Contributor has been advised of the possibility of such
-damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing the Work or
-Derivative Works thereof, You may choose to offer, and charge a fee for,
-acceptance of support, warranty, indemnity, or other liability obligations
-and/or rights consistent with this License. However, in accepting such
-obligations, You may act only on Your own behalf and on Your sole
-responsibility, not on behalf of any other Contributor, and only if You agree to
-indemnify, defend, and hold each Contributor harmless for any liability incurred
-by, or claims asserted against, such Contributor by reason of your accepting any
-such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
diff --git a/document/readme.txt b/document/readme.txt
deleted file mode 100644 (file)
index bf5978e..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-
---------------------------------------------------------------------------------
-Ariadne
-
-Ariadne is a graph based build tool.
-
-Tying to build a project is a lot like trying to find your way out of
-Daedalus's impossible to solve maze. Ariadne hands you a ball of string.
-
---------------------------------------------------------------------------------
-Documents
-
-Note the directories:  Ariadne/document, Ariadne/developer/document, 
-and Ariadne/tester/document.
-
-
---------------------------------------------------------------------------------
-How It Works
-
-Everything is coded in Java, including the developers description of the
-dependency graph.
-
-A graph is made of nodes and edges.
-
-A node is dictionary. Each node has a 'label', a 'build' function, and a
-'neighbor' list.  The neighbor list holds the edges.
-
-Using Java, the developer puts the nodes in a map, keyed on the node label, or
-writes functions that when given a label, return either a node or null.
-
-A node map looks a lot like classic make file.  Each node label is a target file
-path, the neighbor list can be listed next, and then we have the build code.
-
-Function defined nodes are very flexible. They are more powerful, and more
-flexible than make's pattern rules.  If a developer wants a function to act like
-a pattern rule, the developer can use a regular expression match on the given
-label. However, unlike make, pattern rules defined in this manner, will
-backwards chain potentially through other pattern rules.
-
-The Build function is one of the graph traversal programs. It is given a graph
-and a list of top level market targets. It traverses the graph to find leaf
-while unwinding its proverbial ball of string. Upon finding leaf nodes, it then
-follows the string back until building the targets.
-
-It is possible to define other graph traversal functions.  In fact, Ariadne can
-be used to do anything where a directed graph of functions is useful.
-
-
---------------------------------------------------------------------------------
-Entering the Project
-
-The project has three entry points, one for each project role: developer,
-tester, and administrator. To enter the project, source the environment
-appropriate for the role, either `env_developer`, `env_tester`, or
-`env_administrator`.
-
-For example, to work on the code as a developer, start a fresh shell and:
-
-> cd Ariadne
-> . env_developer
->  <run your IDE, I run emacs>
-
-[do work]
-
-> make
-> release
-
-[change to tester role]
-
-The `make` command you see above is a bash script. Version 1.0 of Ariadne uses a
-direct 'build it all every time' approach. Perhaps in version 2.0 or so, we will
-use a prior version of Ariadne for the build environment.
-
-
-Using Ariadne
--------------
-
-After it is built and released the tool will appear in the Ariadne/release
-directory where it can be tested or imported into another project.
-
diff --git a/document/see_also b/document/see_also
deleted file mode 120000 (symlink)
index 24e6315..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/var/user_data/Thomas-developer/Ariadne/tool_shared/third_party/resource/document
\ No newline at end of file
diff --git a/document/todo.txt b/document/todo.txt
deleted file mode 100644 (file)
index 1b081de..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-
-2024-10-16T07:12:41Z[Ariadne_tester]
-
-[done] 1. TestBench should be extracted as its own project. It holds the project independent
-part of the TestBench.
-
-2. Project skeleton.
-
-  PaintIt is the current project skeleton, it needs to be updated to match the
-  structure of this project.
-
-  [Will circle back to PaintIt when Ariadne is done.]
-
-3. Implementation in additional languges.
-
-  It is a one language build environment. Currently that language is Java.  The
-  graph definition is a Java map, the productions are Java functions, and the
-  triggered build functions are Java code.
-
-  The build code could build anything that can be built by running Java code, so
-  this could be projects in other languages. Still after doing everything else
-  in Java it feels natural to use the tool to build Java programs.
-
-  There is no reason this could not all be done in nodejs, for example, though
-  nodejs is not compiled, so there is no point in this.
-
-  I think it could be a C++ program, though there is a dynamic portion to it, as
-  the graph definition is read by the running program, and the running program
-  expects to read the map, and call the loaded production functions.
-
-  This would be an easy program to write to write in nodejs, or Lisp, but
-  development in those languages do not need this tool, as it already exists in
-  Java, it is not clear that benefits of having a 'cleaner' implementation would
-  justify the work.
-
diff --git a/documentđź–‰/see_also b/documentđź–‰/see_also
new file mode 120000 (symlink)
index 0000000..02eb81c
--- /dev/null
@@ -0,0 +1 @@
+../tool_shared/third_party/RT-project-share/documentđź–‰/
\ No newline at end of file
diff --git a/documentđź–‰/todo.txt b/documentđź–‰/todo.txt
new file mode 100644 (file)
index 0000000..1b081de
--- /dev/null
@@ -0,0 +1,35 @@
+
+2024-10-16T07:12:41Z[Ariadne_tester]
+
+[done] 1. TestBench should be extracted as its own project. It holds the project independent
+part of the TestBench.
+
+2. Project skeleton.
+
+  PaintIt is the current project skeleton, it needs to be updated to match the
+  structure of this project.
+
+  [Will circle back to PaintIt when Ariadne is done.]
+
+3. Implementation in additional languges.
+
+  It is a one language build environment. Currently that language is Java.  The
+  graph definition is a Java map, the productions are Java functions, and the
+  triggered build functions are Java code.
+
+  The build code could build anything that can be built by running Java code, so
+  this could be projects in other languages. Still after doing everything else
+  in Java it feels natural to use the tool to build Java programs.
+
+  There is no reason this could not all be done in nodejs, for example, though
+  nodejs is not compiled, so there is no point in this.
+
+  I think it could be a C++ program, though there is a dynamic portion to it, as
+  the graph definition is read by the running program, and the running program
+  expects to read the map, and call the loaded production functions.
+
+  This would be an easy program to write to write in nodejs, or Lisp, but
+  development in those languages do not need this tool, as it already exists in
+  Java, it is not clear that benefits of having a 'cleaner' implementation would
+  justify the work.
+
diff --git a/env_administrator b/env_administrator
deleted file mode 100644 (file)
index 0fc10de..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
-  echo "$script_afp:: This script must be sourced, not executed."
-  exit 1
-fi
-
-source tool_shared/bespoke/env
-
-
diff --git a/env_administratorđź–‰ b/env_administratorđź–‰
new file mode 100644 (file)
index 0000000..0fc10de
--- /dev/null
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+script_afp=$(realpath "${BASH_SOURCE[0]}")
+if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
+  echo "$script_afp:: This script must be sourced, not executed."
+  exit 1
+fi
+
+source tool_shared/bespoke/env
+
+
deleted file mode 100644 (file)
index 6240b202b1f07ba0a3d106e03f7f5873a79ca93a..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
-  echo "$script_afp:: This script must be sourced, not executed."
-  exit 1
-fi
-
-source tool_shared/bespoke/env
-source developer/tool/env
-
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..864cb5eff692ba72377c5cdcc98ad1a0724a6806
--- /dev/null
@@ -0,0 +1 @@
+tool_shared/third_party/RT-project-share/release/bash/env_developer
\ No newline at end of file
diff --git a/env_run b/env_run
deleted file mode 100755 (executable)
index 262bf14b1933d7b359f443f050cc6117e2fa96d2..0000000000000000000000000000000000000000
--- a/env_run
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/usr/bin/env bash
-
-# Centralized environment executor. Typically used by IDEs to run developer/tool
-# or tester/tool commands in the correct environment. Shell users are encouraged
-# to source the appropriate environment file into their shell instead of
-# running commands through this executor.
-
-if [ "$#" -lt 2 ]; then
-    echo "Usage: $0 <environment> <command> [args...]"
-    echo "Example: $0 developer make"
-    exit 1
-fi
-
-# extract the environment and the command
-environment=$1
-shift
-command=$1
-shift
-command_args="$@"
-
-# Determine the path to the environment script based on the environment
-case "$environment" in
-    developer)
-        env_script="env_developer"
-        ;;
-    tester)
-        env_script="env_tester"
-        ;;
-    *)
-        echo "Error: Unknown environment '$environment'. Supported environments are: developer, tester."
-        exit 1
-        ;;
-esac
-
-# check if the environment script exists and is readable
-if [ ! -f "$env_script" ] || [ ! -r "$env_script" ]; then
-    echo "Error: Environment script '$env_script' not found or not readable."
-    exit 1
-fi
-
-source "$env_script"
-exec "$command" "$command_args"
diff --git a/env_run b/env_run
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..c2bd0066851b87aaac395ec064d4001db0bda381
--- /dev/null
+++ b/env_run
@@ -0,0 +1 @@
+tool_shared/third_party/RT-project-share/release/bash/env_run
\ No newline at end of file
deleted file mode 100644 (file)
index 44aace3649ec7782cb9a8856e7858f51b755f33c..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/usr/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
-  echo "$script_afp:: This script must be sourced, not executed."
-  exit 1
-fi
-
-source tool_shared/bespoke/env
-source tester/tool/env
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..4dcdc19a32d0edd9ebc8f9f327b466c173053c15
--- /dev/null
@@ -0,0 +1 @@
+tool_shared/third_party/RT-project-share/release/bash/env_tester
\ No newline at end of file
index d1c93e1..b9fcac5 100644 (file)
Binary files a/release/Ariadne.jar and b/release/Ariadne.jar differ
diff --git a/tester/bash/.githolder b/tester/bash/.githolder
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tester/bash/Test_File_0 b/tester/bash/Test_File_0
new file mode 100755 (executable)
index 0000000..39c1f2a
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/env bash
+java Test_File_0
diff --git a/tester/bash/Test_Graph_0 b/tester/bash/Test_Graph_0
new file mode 100755 (executable)
index 0000000..7653d09
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/env bash
+java Test_Graph_0
diff --git a/tester/bash/Test_LabelList_0 b/tester/bash/Test_LabelList_0
new file mode 100755 (executable)
index 0000000..15a0da6
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/env bash
+java Test_LabelList_0
diff --git a/tester/bash/Test_Label_0 b/tester/bash/Test_Label_0
new file mode 100755 (executable)
index 0000000..6b61242
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/env bash
+java Test_Label_0
diff --git a/tester/bash/Test_NodeList_0 b/tester/bash/Test_NodeList_0
new file mode 100755 (executable)
index 0000000..8970446
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/env bash
+java Test_NodeList_0
diff --git a/tester/bash/Test_Node_0 b/tester/bash/Test_Node_0
new file mode 100755 (executable)
index 0000000..7901f30
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/env bash
+java Test_Node_0
diff --git a/tester/bash/Test_TokenSet_0 b/tester/bash/Test_TokenSet_0
new file mode 100755 (executable)
index 0000000..05d37d4
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/env bash
+java Test_TokenSet_0
diff --git a/tester/bash/Test_Token_0 b/tester/bash/Test_Token_0
new file mode 100755 (executable)
index 0000000..842f673
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/env bash
+java Test_Token_0
diff --git a/tester/bash/Test_Util_0 b/tester/bash/Test_Util_0
new file mode 100755 (executable)
index 0000000..6157abe
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/env bash
+java Test_Util_0
diff --git a/tester/bashđź–‰/TF0 b/tester/bashđź–‰/TF0
new file mode 100755 (executable)
index 0000000..af784e6
--- /dev/null
@@ -0,0 +1,10 @@
+#!/bin/env bash
+
+echo $ENV
+
+vl echo "CLASSPATH: $CLASSPATH"
+
+set -x
+java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005 Test_File_0
+     
+
diff --git a/tester/documentđź–‰/debug_with_sources.txt b/tester/documentđź–‰/debug_with_sources.txt
new file mode 100644 (file)
index 0000000..e2ee8e0
--- /dev/null
@@ -0,0 +1,78 @@
+
+How to tie sources into debugging
+
+<h3>Option 1: so sources can be edited then checked into the repo:</h3>
+
+  It is not typical to desire to be able edit upstream libraries, but maybe you
+  are developer on the upstream code, or want to leave the option open.  Who
+  knows?
+
+  1. distribute the source files into the package tree
+
+      cd $REPO_HOME/tool_shared/<project>/developer
+      . env_developer
+      distribute_source
+
+     This will put links into developer/scratchpad that point back into original
+     sources. Hence, after making changes they can be checked in.
+
+     If on a release branch, the sources will be in sync with the classes found
+     in the .jvm in the release directory, or at least they are supposed to be.
+
+     If not on a release branch, then follow the directions for making and
+     releasing the project, and spin up a new released `.jvm` file and they
+     will be in sync.
+
+
+  2. edit $REPO_HOME/tester/toolđź–‰/env and make sure the developer/scratchpad is
+  in the SOURCEPATH
+
+    export SOURCEPATH=\
+     ...
+     :"$REPO_HOME"/tool_shared/third_party/Mosaic/developer/scratchpad\
+     ...
+
+<h3>Option 2: you do not plan to edit the third party library:</h3>
+
+  This is more typical.
+
+  1. If your `<project>.jar` file has sources included, expand it into the tester/scratchapd
+
+       jar -xf <path to <project>.jar>  $REPO_HOME/tester/scratchpad.
+
+     The debugger should now have access to the sources.
+
+  2. If your `.jar` does not have sources included. Go build them, see the directions in
+     the first option.
+
+<h3>Option 3: don't debug a third party library.
+
+  This is the most typical.  Step over calls to the library. If results are not as expected,
+  read docs, discuss with others, make bug reports.
+
+--------------------------------------------------------------------------------
+
+Examples:
+
+export CLASSPATH=\
+"$JAVA_HOME"/lib\
+:"$MOSAIC_HOME"/developer/scratchpad\
+:"$REPO_HOME"/developer/scratchpad\
+:"$REPO_HOME"/tester/scratchpad\
+:"$CLASSPATH"
+
+First line gets the class files most recently built by Mosaic developer.
+Second line gets the class files most recently built by Ariadne developer.
+Third line gets class files most recently built by the tester.
+
+export SOURCEPATH=\
+"$JAVA_HOME"/lib\
+:"$MOSAIC_HOME"/developer/scratchpad\
+:"$REPO_HOME"/developer/scratchpad\
+:"$REPO_HOME"/tester/javacđź–‰\
+:"$SOURCEPATH"
+
+In each case the developer must run `distribute_source` before building the project.
+First line gets the source files most recently built by Mosaic developer.
+Second line gets the source files most recently built by Ariadne developer.
+Third line gets source files most recently built by the tester.
diff --git a/tester/javac/.gitignore b/tester/javac/.gitignore
deleted file mode 100644 (file)
index d396818..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/Test_File_0$TestSuite.class
-/Test_File_0.class
-/Test_Graph_0$TestSuite.class
-/Test_Graph_0.class
-/Test_LabelList_0$TestSuite.class
-/Test_LabelList_0.class
-/Test_Label_0$TestSuite.class
-/Test_Label_0.class
-/Test_NodeList_0$TestSuite.class
-/Test_NodeList_0.class
-/Test_Node_0$TestSuite.class
-/Test_Node_0.class
-/Test_TokenSet_0$TestSuite.class
-/Test_TokenSet_0.class
-/Test_Token_0$TestSuite.class
-/Test_Token_0.class
-/Test_Util_0$TestSuite.class
-/Test_Util_0.class
diff --git a/tester/javac/Test_File_0.java b/tester/javac/Test_File_0.java
deleted file mode 100644 (file)
index e3bb697..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.attribute.FileTime;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import com.ReasoningTechnology.Mosaic.Mosaic_IO;
-import com.ReasoningTechnology.Mosaic.Mosaic_Testbench;
-import com.ReasoningTechnology.Mosaic.Mosaic_Util;
-
-import com.ReasoningTechnology.Ariadne.Ariadne_File;
-
-
-public class Test_File_0 {
-
-    public class TestSuite {
-
-        public Boolean unpack_file_path_0(Mosaic_IO io) {
-            Boolean[] conditions = new Boolean[5];
-            int i = 0;
-
-            String test_fp = "/home/user/test.txt";
-            String expected_dp = "/home/user/";
-            String expected_fn = "test.txt";
-            String expected_fn_base = "test";
-            String expected_fn_ext = "txt";
-
-            try {
-                Map<String, String> result = Ariadne_File.unpack_file_path(test_fp);
-
-                conditions[i++] = result.get("dp").equals(expected_dp);
-                conditions[i++] = result.get("fn").equals(expected_fn);
-                conditions[i++] = result.get("fn_base").equals(expected_fn_base);
-                conditions[i++] = result.get("fn_ext").equals(expected_fn_ext);
-                conditions[i++] = result.size() == 4;
-
-                return Mosaic_Util.all(conditions);
-            } catch (Exception e) {
-                e.printStackTrace();
-                return false;
-            }
-        }
-
-        public Boolean file_exists_q_0(Mosaic_IO io) {
-            Boolean[] conditions = new Boolean[2];
-            int i = 0;
-
-            String repoHome = System.getenv("REPO_HOME");
-            String existingFilePath = repoHome + "/tester/data_Test_File_0/I_exist";
-            String nonExistentFilePath = repoHome + "/tester/data_Test_File_0/I_do_not_exist";
-
-            conditions[i++] = Ariadne_File.file_exists_q(existingFilePath);
-            conditions[i++] = !Ariadne_File.file_exists_q(nonExistentFilePath);
-
-            return Mosaic_Util.all(conditions);
-        }
-
-        public Boolean newer_than_all_0(Mosaic_IO io) throws IOException {
-            Boolean[] conditions = new Boolean[5];
-            int i = 0;
-
-            String repoHome = System.getenv("REPO_HOME");
-            String file_0 = repoHome + "/tester/data_Test_File_0/file_0";
-            String file_1 = repoHome + "/tester/data_Test_File_0/file_1";
-            String file_2 = repoHome + "/tester/data_Test_File_0/file_2";
-            String file_3 = repoHome + "/tester/data_Test_File_0/file_3";
-            String missing_file_0 = repoHome + "/tester/data_Test_File_0/missing_file_0";
-
-            // Setting modification times
-            Files.setLastModifiedTime(Path.of(file_3), FileTime.fromMillis(System.currentTimeMillis() - 20000));
-            Files.setLastModifiedTime(Path.of(file_2), FileTime.fromMillis(System.currentTimeMillis() - 15000));
-            Files.setLastModifiedTime(Path.of(file_1), FileTime.fromMillis(System.currentTimeMillis() - 10000));
-            Files.setLastModifiedTime(Path.of(file_0), FileTime.fromMillis(System.currentTimeMillis() - 5000));
-
-            conditions[i++] = Ariadne_File.newer_than_all(file_0, List.of(file_1, file_2, file_3));
-
-            // Updating times and repeating checks
-            Files.setLastModifiedTime(Path.of(file_2), FileTime.fromMillis(System.currentTimeMillis() + 10000));
-            conditions[i++] = !Ariadne_File.newer_than_all(file_0, List.of(file_1, file_2, file_3));
-
-            Files.setLastModifiedTime(Path.of(file_1), FileTime.fromMillis(System.currentTimeMillis() + 15000));
-            conditions[i++] = !Ariadne_File.newer_than_all(file_0, List.of(file_1, file_2, file_3));
-
-            conditions[i++] = !Ariadne_File.newer_than_all(missing_file_0, List.of(file_1, file_2, file_3));
-
-            conditions[i++] = !Ariadne_File.newer_than_all(file_0, List.of(file_1, missing_file_0));
-
-            return Mosaic_Util.all(conditions);
-        }
-    }
-
-    public static void main(String[] args) {
-        try {
-            TestSuite suite = new Test_File_0().new TestSuite();
-            int result = Mosaic_Testbench.run(suite);
-            System.exit(result);
-        } catch (Exception e) {
-            e.printStackTrace();
-            System.exit(1);
-        }
-    }
-}
diff --git a/tester/javac/Test_Graph_0.java b/tester/javac/Test_Graph_0.java
deleted file mode 100644 (file)
index cfab110..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-import java.util.HashMap;
-import java.util.Map;
-import java.util.List;
-import java.lang.reflect.Method;
-
-import com.ReasoningTechnology.Mosaic.Mosaic_IO;
-import com.ReasoningTechnology.Mosaic.Mosaic_Testbench;
-import com.ReasoningTechnology.Mosaic.Mosaic_Util;
-
-import com.ReasoningTechnology.Ariadne.Ariadne_Graph;
-import com.ReasoningTechnology.Ariadne.Ariadne_GraphDirectedAcyclic;
-import com.ReasoningTechnology.Ariadne.Ariadne_Label;
-import com.ReasoningTechnology.Ariadne.Ariadne_LabelList;
-import com.ReasoningTechnology.Ariadne.Ariadne_Node;
-import com.ReasoningTechnology.Ariadne.Ariadne_ProductionList;
-
-public class Test_Graph_0 {
-
-  public class TestSuite {
-    private final Object GraphDirectedAcyclic_proxy;
-
-    public TestSuite() {
-      this.GraphDirectedAcyclic_proxy =
-        Mosaic_Util.make_all_public_methods_proxy( Ariadne_GraphDirectedAcyclic.class );
-    }
-
-    public Boolean path_find_cycle_0( Mosaic_IO io ) {
-      System.out.println("path_find_cycle_0 method called");
-      Boolean[] conditions = new Boolean[1];
-      Mosaic_Util.all_set_false( conditions );
-      int i = 0;
-      try {
-        Ariadne_LabelList path = new Ariadne_LabelList(
-          List.of(
-            new Ariadne_Label( "A" )
-           ,new Ariadne_Label( "B" )
-           ,new Ariadne_Label( "A" )
-          )
-        );
- //       @SuppressWarnings("unchecked")
-        List<Integer> cycle_indices = (List<Integer>) GraphDirectedAcyclic_proxy.getClass().getMethod(
-          "path_find_cycle"
-         ,Ariadne_LabelList.class
-        ).invoke( GraphDirectedAcyclic_proxy ,path );
-        /*
-
-        conditions[i++] = cycle_indices != null && cycle_indices.size() == 2;
-        */
-      } catch (Exception e) {
-        Mosaic_Util.log_message("path_find_cycle_0", "Test logic error: " + e.getMessage());
-        return false;
-      }
-
-      return true;
-//      return Mosaic_Util.all( conditions );
-    }
-
-    public Boolean lookup_0( Mosaic_IO io ) {
-      Boolean[] conditions = new Boolean[1];
-      Mosaic_Util.all_set_false( conditions );
-      int i = 0;
-        return true;
-    }
-  }
-
-  public static void main(String[] args) {
-    // no command line arguments, nor options to be parsed.
-    TestSuite suite = new Test_Graph_0().new TestSuite();
-    int result = Mosaic_Testbench.run(suite); 
-    System.exit(result);
-  }
-}
diff --git a/tester/javac/Test_LabelList_0.java b/tester/javac/Test_LabelList_0.java
deleted file mode 100644 (file)
index 258362e..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-import java.util.Arrays;
-import java.util.List;
-
-import com.ReasoningTechnology.Mosaic.Mosaic_IO;
-import com.ReasoningTechnology.Mosaic.Mosaic_Util;
-import com.ReasoningTechnology.Mosaic.Mosaic_Testbench;
-
-import com.ReasoningTechnology.Ariadne.Ariadne_Label;
-import com.ReasoningTechnology.Ariadne.Ariadne_LabelList;
-
-public class Test_LabelList_0 {
-
-  public class TestSuite {
-
-    public Boolean labelList_creation_0(Mosaic_IO io) {
-      Boolean[] conditions = new Boolean[2];
-      int i = 0;
-
-      // Test the default constructor
-      Ariadne_LabelList emptyList = new Ariadne_LabelList();
-      conditions[i++] = emptyList.isEmpty(); // Expect true for an empty list
-
-      // Test the constructor with a list of labels
-      List<Ariadne_Label> labels = Arrays.asList(new Ariadne_Label("label1"), new Ariadne_Label("label2"));
-      Ariadne_LabelList labelList = new Ariadne_LabelList(labels);
-      conditions[i++] = labelList.size() == 2 && labelList.get(0).get().equals("label1") && labelList.get(1).get().equals("label2"); // Expect true for correct size and contents
-
-      // Return true if all conditions are met
-      return Mosaic_Util.all(conditions);
-    }
-
-  }
-
-  public static void main(String[] args) {
-    TestSuite suite = new Test_LabelList_0().new TestSuite();
-    int result = Mosaic_Testbench.run(suite); 
-    System.exit(result);
-  }
-}
diff --git a/tester/javac/Test_Label_0.java b/tester/javac/Test_Label_0.java
deleted file mode 100644 (file)
index e304150..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-
-import com.ReasoningTechnology.Mosaic.Mosaic_IO;
-import com.ReasoningTechnology.Mosaic.Mosaic_Util;
-import com.ReasoningTechnology.Mosaic.Mosaic_Testbench;
-
-import com.ReasoningTechnology.Ariadne.Ariadne_Label;
-
-
-public class Test_Label_0 {
-
-  public class TestSuite {
-
-    public Boolean label_creation_0(Mosaic_IO io) {
-      Boolean[] conditions = new Boolean[4];
-      int i = 0;
-
-      // Test input
-      Ariadne_Label label1 = new Ariadne_Label("test");
-      Ariadne_Label label2 = new Ariadne_Label("");
-      Ariadne_Label label3 = new Ariadne_Label("test");
-
-      // Check that the value is correctly set
-      conditions[i++] = label1.get().equals("test"); // Expect true
-      conditions[i++] = label2.isEmpty(); // Expect true
-      conditions[i++] = label1.equals(label3); // Expect true, as contents are identical
-      conditions[i++] = label1.hashCode() == label3.hashCode(); // Expect true, as hash should match for equal labels
-
-      // Return true if all conditions are met
-      return Mosaic_Util.all(conditions);
-    }
-
-  }
-
-  public static void main(String[] args) {
-    TestSuite suite = new Test_Label_0().new TestSuite();
-    int result = Mosaic_Testbench.run(suite); 
-    System.exit(result);
-  }
-
-}
diff --git a/tester/javac/Test_NodeList_0.java b/tester/javac/Test_NodeList_0.java
deleted file mode 100644 (file)
index cb7f5a6..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-import com.ReasoningTechnology.Mosaic.Mosaic_IO;
-import com.ReasoningTechnology.Mosaic.Mosaic_Util;
-import com.ReasoningTechnology.Mosaic.Mosaic_Testbench;
-
-import com.ReasoningTechnology.Ariadne.Ariadne_Node;
-import com.ReasoningTechnology.Ariadne.Ariadne_NodeList;
-
-public class Test_NodeList_0 {
-
-  public class TestSuite {
-
-    public Boolean nodeList_creation_0(Mosaic_IO io) {
-      Boolean[] conditions = new Boolean[2];
-      int i = 0;
-
-      // Test default constructor (expecting an empty NodeList)
-      Ariadne_NodeList nodeList = new Ariadne_NodeList();
-      conditions[i++] = nodeList.isEmpty(); // Expect true for empty list
-
-      // Add a node and verify presence
-      Ariadne_Node node = new Ariadne_Node();
-      nodeList.add(node);
-      conditions[i++] = nodeList.size() == 1 && nodeList.contains(node); // Expect true for correct size and content
-
-      // Return true if all conditions are met
-      return Mosaic_Util.all(conditions);
-    }
-  }
-
-  public static void main(String[] args) {
-    TestSuite suite = new Test_NodeList_0().new TestSuite();
-    int result = Mosaic_Testbench.run(suite); 
-    System.exit(result);
-  }
-}
diff --git a/tester/javac/Test_Node_0.java b/tester/javac/Test_Node_0.java
deleted file mode 100644 (file)
index ae85d64..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-
-import com.ReasoningTechnology.Mosaic.Mosaic_IO;
-import com.ReasoningTechnology.Mosaic.Mosaic_Util;
-import com.ReasoningTechnology.Mosaic.Mosaic_Testbench;
-
-import com.ReasoningTechnology.Ariadne.Ariadne_Node;
-import com.ReasoningTechnology.Ariadne.Ariadne_Label;
-import com.ReasoningTechnology.Ariadne.Ariadne_LabelList;
-import com.ReasoningTechnology.Ariadne.Ariadne_Token;
-import com.ReasoningTechnology.Ariadne.Ariadne_TokenSet;
-
-
-public class Test_Node_0 {
-
-  public class TestSuite {
-
-    public Boolean node_creation_0(Mosaic_IO io) {
-      Boolean[] conditions = new Boolean[2];
-      int i = 0;
-
-      // Test that neighbor list is initialized
-      Ariadne_Node node = new Ariadne_Node();
-      conditions[i++] = node.neighbor_LabelList() != null && node.neighbor_LabelList().isEmpty(); // Expect true
-
-      // Test that the mark property is not initialized until used
-      conditions[i++] = node.get("mark") == null; // Expect true
-
-      // Return true if all conditions are met
-      return Mosaic_Util.all(conditions);
-    }
-
-    public Boolean node_marking_0(Mosaic_IO io) {
-      Boolean[] conditions = new Boolean[3];
-      int i = 0;
-
-      Ariadne_Node node = new Ariadne_Node();
-      Ariadne_Token token1 = new Ariadne_Token("token1");
-      Ariadne_Token token2 = new Ariadne_Token("token2");
-
-      // Test marking the node with token1
-      node.mark(token1);
-      conditions[i++] = node.has_mark(token1); // Expect true
-      conditions[i++] = !node.has_mark(token2); // Expect false for unmarked token
-
-      // Test that mark property is now initialized and contains token1
-      Ariadne_TokenSet markSet = (Ariadne_TokenSet) node.get("mark");
-      conditions[i++] = markSet != null && markSet.contains(token1); // Expect true
-
-      // Return true if all conditions are met
-      return Mosaic_Util.all(conditions);
-    }
-
-    public Boolean node_neighbor_0(Mosaic_IO io) {
-      Boolean[] conditions = new Boolean[1];
-      int i = 0;
-
-      // Test adding and retrieving neighbors
-      Ariadne_Node node = new Ariadne_Node();
-      Ariadne_LabelList neighbors = node.neighbor_LabelList();
-      neighbors.add(new Ariadne_Label("neighbor1"));
-      neighbors.add(new Ariadne_Label("neighbor2"));
-      conditions[i++] = neighbors.size() == 2 && neighbors.get(0).get().equals("neighbor1") && neighbors.get(1).get().equals("neighbor2"); // Expect true
-
-      // Return true if all conditions are met
-      return Mosaic_Util.all(conditions);
-    }
-  }
-
-  public static void main(String[] args) {
-    TestSuite suite = new Test_Node_0().new TestSuite();
-    int result = Mosaic_Testbench.run(suite); 
-    System.exit(result);
-  }
-}
diff --git a/tester/javac/Test_TokenSet_0.java b/tester/javac/Test_TokenSet_0.java
deleted file mode 100644 (file)
index 53399e1..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-import com.ReasoningTechnology.Mosaic.Mosaic_IO;
-import com.ReasoningTechnology.Mosaic.Mosaic_Util;
-import com.ReasoningTechnology.Mosaic.Mosaic_Testbench;
-
-import com.ReasoningTechnology.Ariadne.Ariadne_Token;
-import com.ReasoningTechnology.Ariadne.Ariadne_TokenSet;
-
-public class Test_TokenSet_0 {
-
-  public class TestSuite {
-
-    public Boolean tokenSet_creation_0(Mosaic_IO io) {
-      Boolean[] conditions = new Boolean[2];
-      int i = 0;
-
-      // Test default constructor (expecting an empty TokenSet)
-      Ariadne_TokenSet tokenSet = new Ariadne_TokenSet();
-      conditions[i++] = tokenSet.isEmpty(); // Expect true for empty set
-
-      // Add a token and verify presence
-      Ariadne_Token token = new Ariadne_Token("error");
-      tokenSet.add(token);
-      conditions[i++] = tokenSet.size() == 1 && tokenSet.contains(token); // Expect true for correct size and content
-
-      // Return true if all conditions are met
-      return Mosaic_Util.all(conditions);
-    }
-
-    public Boolean tokenSet_uniqueness_0(Mosaic_IO io) {
-      Boolean[] conditions = new Boolean[1];
-      int i = 0;
-
-      Ariadne_TokenSet tokenSet = new Ariadne_TokenSet();
-      Ariadne_Token token1 = new Ariadne_Token("error");
-      Ariadne_Token token2 = new Ariadne_Token("error");
-
-      // Add two tokens with identical values and verify only one is stored
-      tokenSet.add(token1);
-      tokenSet.add(token2);
-      conditions[i++] = tokenSet.size() == 1 && tokenSet.contains(token1) && tokenSet.contains(token2); // Expect true for single entry despite duplicate addition
-
-      // Return true if all conditions are met
-      return Mosaic_Util.all(conditions);
-    }
-  }
-
-  public static void main(String[] args) {
-    TestSuite suite = new Test_TokenSet_0().new TestSuite();
-    int result = Mosaic_Testbench.run(suite); 
-    System.exit(result);
-  }
-}
diff --git a/tester/javac/Test_Token_0.java b/tester/javac/Test_Token_0.java
deleted file mode 100644 (file)
index 2fe9c48..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-import com.ReasoningTechnology.Mosaic.Mosaic_IO;
-import com.ReasoningTechnology.Mosaic.Mosaic_Util;
-import com.ReasoningTechnology.Mosaic.Mosaic_Testbench;
-
-import com.ReasoningTechnology.Ariadne.Ariadne_Token;
-
-public class Test_Token_0 {
-
-  public class TestSuite {
-
-    public Boolean token_creation_0(Mosaic_IO io) {
-      Boolean[] conditions = new Boolean[4];
-      int i = 0;
-
-      // Test input
-      Ariadne_Token token1 = new Ariadne_Token("error");
-      Ariadne_Token token2 = new Ariadne_Token("warning");
-      Ariadne_Token token3 = new Ariadne_Token("error");
-
-      // Check that the value is correctly set
-      conditions[i++] = token1.get().equals("error"); // Expect true
-      conditions[i++] = token1.toString().equals("error"); // Expect true (toString should match value)
-      conditions[i++] = token1.equals(token3); // Expect true, as contents are identical
-      conditions[i++] = !token1.equals(token2); // Expect false, as values differ
-
-      // Return true if all conditions are met
-      return Mosaic_Util.all(conditions);
-    }
-
-    public Boolean token_hashCode_0(Mosaic_IO io) {
-      Boolean[] conditions = new Boolean[1];
-      int i = 0;
-
-      Ariadne_Token token1 = new Ariadne_Token("error");
-      Ariadne_Token token2 = new Ariadne_Token("error");
-
-      // Check that two identical tokens have the same hashCode
-      conditions[i++] = token1.hashCode() == token2.hashCode(); // Expect true
-
-      // Return true if all conditions are met
-      return Mosaic_Util.all(conditions);
-    }
-  }
-
-  public static void main(String[] args) {
-    TestSuite suite = new Test_Token_0().new TestSuite();
-    int result = Mosaic_Testbench.run(suite); 
-    System.exit(result);
-  }
-}
diff --git a/tester/javac/Test_Util_0.java b/tester/javac/Test_Util_0.java
deleted file mode 100644 (file)
index 15d9821..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-import com.ReasoningTechnology.Mosaic.Mosaic_IO;
-import com.ReasoningTechnology.Mosaic.Mosaic_Util;
-import com.ReasoningTechnology.Mosaic.Mosaic_Testbench;
-
-import com.ReasoningTechnology.Ariadne.Ariadne_Label;
-import com.ReasoningTechnology.Ariadne.Ariadne_Util;
-
-import java.util.List;
-import java.util.Arrays;
-
-public class Test_Util_0 {
-
-  public class TestSuite {
-
-    public Boolean print_list_0(Mosaic_IO io) {
-      Boolean[] conditions = new Boolean[3];
-      int i = 0;
-
-      // Test with a non-empty list and a prefix
-      List<Ariadne_Label> itemList1 = Arrays.asList(new Ariadne_Label("first"), new Ariadne_Label("second"), new Ariadne_Label("third"));
-      Ariadne_Util.print_list("Items:", itemList1);
-
-      // Capture and check stdout content
-      String stdoutContent1 = io.get_out_content();
-      conditions[i++] = stdoutContent1.equals("Items: 'first', 'second', 'third'.\n"); // Expect correct format with prefix
-
-      // Clear streams for the next test
-      io.clear_buffers();
-
-      // Test with an empty list (no output expected)
-      List<Ariadne_Label> itemList2 = Arrays.asList();
-      Ariadne_Util.print_list("Empty:", itemList2);
-      String stdoutContent2 = io.get_out_content();
-      conditions[i++] = stdoutContent2.isEmpty(); // Expect no output for empty list
-
-      // Clear streams for the next test
-      io.clear_buffers();
-
-      // Test with a null list (no output expected)
-      Ariadne_Util.print_list("Null:", null);
-      String stdoutContent3 = io.get_out_content();
-      conditions[i++] = stdoutContent3.isEmpty(); // Expect no output for null list
-
-      // Return true if all conditions are met
-      return Mosaic_Util.all(conditions);
-    }
-  }
-
-  public static void main(String[] args) {
-    TestSuite suite = new Test_Util_0().new TestSuite();
-    int result = Mosaic_Testbench.run(suite); 
-    System.exit(result);
-  }
-
-}
diff --git a/tester/javacđź–‰/.gitignore b/tester/javacđź–‰/.gitignore
new file mode 100644 (file)
index 0000000..d396818
--- /dev/null
@@ -0,0 +1,18 @@
+/Test_File_0$TestSuite.class
+/Test_File_0.class
+/Test_Graph_0$TestSuite.class
+/Test_Graph_0.class
+/Test_LabelList_0$TestSuite.class
+/Test_LabelList_0.class
+/Test_Label_0$TestSuite.class
+/Test_Label_0.class
+/Test_NodeList_0$TestSuite.class
+/Test_NodeList_0.class
+/Test_Node_0$TestSuite.class
+/Test_Node_0.class
+/Test_TokenSet_0$TestSuite.class
+/Test_TokenSet_0.class
+/Test_Token_0$TestSuite.class
+/Test_Token_0.class
+/Test_Util_0$TestSuite.class
+/Test_Util_0.class
diff --git a/tester/javacđź–‰/Test_File_0.java b/tester/javacđź–‰/Test_File_0.java
new file mode 100644 (file)
index 0000000..e3bb697
--- /dev/null
@@ -0,0 +1,107 @@
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.attribute.FileTime;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.ReasoningTechnology.Mosaic.Mosaic_IO;
+import com.ReasoningTechnology.Mosaic.Mosaic_Testbench;
+import com.ReasoningTechnology.Mosaic.Mosaic_Util;
+
+import com.ReasoningTechnology.Ariadne.Ariadne_File;
+
+
+public class Test_File_0 {
+
+    public class TestSuite {
+
+        public Boolean unpack_file_path_0(Mosaic_IO io) {
+            Boolean[] conditions = new Boolean[5];
+            int i = 0;
+
+            String test_fp = "/home/user/test.txt";
+            String expected_dp = "/home/user/";
+            String expected_fn = "test.txt";
+            String expected_fn_base = "test";
+            String expected_fn_ext = "txt";
+
+            try {
+                Map<String, String> result = Ariadne_File.unpack_file_path(test_fp);
+
+                conditions[i++] = result.get("dp").equals(expected_dp);
+                conditions[i++] = result.get("fn").equals(expected_fn);
+                conditions[i++] = result.get("fn_base").equals(expected_fn_base);
+                conditions[i++] = result.get("fn_ext").equals(expected_fn_ext);
+                conditions[i++] = result.size() == 4;
+
+                return Mosaic_Util.all(conditions);
+            } catch (Exception e) {
+                e.printStackTrace();
+                return false;
+            }
+        }
+
+        public Boolean file_exists_q_0(Mosaic_IO io) {
+            Boolean[] conditions = new Boolean[2];
+            int i = 0;
+
+            String repoHome = System.getenv("REPO_HOME");
+            String existingFilePath = repoHome + "/tester/data_Test_File_0/I_exist";
+            String nonExistentFilePath = repoHome + "/tester/data_Test_File_0/I_do_not_exist";
+
+            conditions[i++] = Ariadne_File.file_exists_q(existingFilePath);
+            conditions[i++] = !Ariadne_File.file_exists_q(nonExistentFilePath);
+
+            return Mosaic_Util.all(conditions);
+        }
+
+        public Boolean newer_than_all_0(Mosaic_IO io) throws IOException {
+            Boolean[] conditions = new Boolean[5];
+            int i = 0;
+
+            String repoHome = System.getenv("REPO_HOME");
+            String file_0 = repoHome + "/tester/data_Test_File_0/file_0";
+            String file_1 = repoHome + "/tester/data_Test_File_0/file_1";
+            String file_2 = repoHome + "/tester/data_Test_File_0/file_2";
+            String file_3 = repoHome + "/tester/data_Test_File_0/file_3";
+            String missing_file_0 = repoHome + "/tester/data_Test_File_0/missing_file_0";
+
+            // Setting modification times
+            Files.setLastModifiedTime(Path.of(file_3), FileTime.fromMillis(System.currentTimeMillis() - 20000));
+            Files.setLastModifiedTime(Path.of(file_2), FileTime.fromMillis(System.currentTimeMillis() - 15000));
+            Files.setLastModifiedTime(Path.of(file_1), FileTime.fromMillis(System.currentTimeMillis() - 10000));
+            Files.setLastModifiedTime(Path.of(file_0), FileTime.fromMillis(System.currentTimeMillis() - 5000));
+
+            conditions[i++] = Ariadne_File.newer_than_all(file_0, List.of(file_1, file_2, file_3));
+
+            // Updating times and repeating checks
+            Files.setLastModifiedTime(Path.of(file_2), FileTime.fromMillis(System.currentTimeMillis() + 10000));
+            conditions[i++] = !Ariadne_File.newer_than_all(file_0, List.of(file_1, file_2, file_3));
+
+            Files.setLastModifiedTime(Path.of(file_1), FileTime.fromMillis(System.currentTimeMillis() + 15000));
+            conditions[i++] = !Ariadne_File.newer_than_all(file_0, List.of(file_1, file_2, file_3));
+
+            conditions[i++] = !Ariadne_File.newer_than_all(missing_file_0, List.of(file_1, file_2, file_3));
+
+            conditions[i++] = !Ariadne_File.newer_than_all(file_0, List.of(file_1, missing_file_0));
+
+            return Mosaic_Util.all(conditions);
+        }
+    }
+
+    public static void main(String[] args) {
+        try {
+            TestSuite suite = new Test_File_0().new TestSuite();
+            int result = Mosaic_Testbench.run(suite);
+            System.exit(result);
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+    }
+}
diff --git a/tester/javacđź–‰/Test_Graph_0.java b/tester/javacđź–‰/Test_Graph_0.java
new file mode 100644 (file)
index 0000000..ba28304
--- /dev/null
@@ -0,0 +1,71 @@
+import java.util.HashMap;
+import java.util.Map;
+import java.util.List;
+import java.lang.reflect.Method;
+
+import com.ReasoningTechnology.Mosaic.Mosaic_IO;
+import com.ReasoningTechnology.Mosaic.Mosaic_Testbench;
+import com.ReasoningTechnology.Mosaic.Mosaic_Util;
+
+import com.ReasoningTechnology.Ariadne.Ariadne_Graph;
+import com.ReasoningTechnology.Ariadne.Ariadne_GraphDirectedAcyclic;
+import com.ReasoningTechnology.Ariadne.Ariadne_Label;
+import com.ReasoningTechnology.Ariadne.Ariadne_LabelList;
+import com.ReasoningTechnology.Ariadne.Ariadne_Node;
+import com.ReasoningTechnology.Ariadne.Ariadne_ProductionList;
+
+public class Test_Graph_0 {
+
+  public class TestSuite {
+    private final Object GraphDirectedAcyclic_proxy;
+
+    public TestSuite() {
+      this.GraphDirectedAcyclic_proxy =
+        Mosaic_Util.make_all_public_methods_proxy( Ariadne_GraphDirectedAcyclic.class );
+    }
+
+    public Boolean path_find_cycle_0( Mosaic_IO io ) {
+      Boolean[] conditions = new Boolean[1];
+      Mosaic_Util.all_set_false( conditions );
+      int i = 0;
+      try {
+        Ariadne_LabelList path = new Ariadne_LabelList(
+          List.of(
+            new Ariadne_Label( "A" )
+           ,new Ariadne_Label( "B" )
+           ,new Ariadne_Label( "A" )
+          )
+        );
+ //       @SuppressWarnings("unchecked")
+        List<Integer> cycle_indices = (List<Integer>) GraphDirectedAcyclic_proxy.getClass().getMethod(
+          "path_find_cycle"
+         ,Ariadne_LabelList.class
+        ).invoke( GraphDirectedAcyclic_proxy ,path );
+        /*
+
+        conditions[i++] = cycle_indices != null && cycle_indices.size() == 2;
+        */
+      } catch (Exception e) {
+        Mosaic_Util.log_message("path_find_cycle_0", "Test logic error: " + e.getMessage());
+        return false;
+      }
+
+      return true;
+//      return Mosaic_Util.all( conditions );
+    }
+
+    public Boolean lookup_0( Mosaic_IO io ) {
+      Boolean[] conditions = new Boolean[1];
+      Mosaic_Util.all_set_false( conditions );
+      int i = 0;
+        return true;
+    }
+  }
+
+  public static void main(String[] args) {
+    // no command line arguments, nor options to be parsed.
+    TestSuite suite = new Test_Graph_0().new TestSuite();
+    int result = Mosaic_Testbench.run(suite); 
+    System.exit(result);
+  }
+}
diff --git a/tester/javacđź–‰/Test_LabelList_0.java b/tester/javacđź–‰/Test_LabelList_0.java
new file mode 100644 (file)
index 0000000..258362e
--- /dev/null
@@ -0,0 +1,39 @@
+import java.util.Arrays;
+import java.util.List;
+
+import com.ReasoningTechnology.Mosaic.Mosaic_IO;
+import com.ReasoningTechnology.Mosaic.Mosaic_Util;
+import com.ReasoningTechnology.Mosaic.Mosaic_Testbench;
+
+import com.ReasoningTechnology.Ariadne.Ariadne_Label;
+import com.ReasoningTechnology.Ariadne.Ariadne_LabelList;
+
+public class Test_LabelList_0 {
+
+  public class TestSuite {
+
+    public Boolean labelList_creation_0(Mosaic_IO io) {
+      Boolean[] conditions = new Boolean[2];
+      int i = 0;
+
+      // Test the default constructor
+      Ariadne_LabelList emptyList = new Ariadne_LabelList();
+      conditions[i++] = emptyList.isEmpty(); // Expect true for an empty list
+
+      // Test the constructor with a list of labels
+      List<Ariadne_Label> labels = Arrays.asList(new Ariadne_Label("label1"), new Ariadne_Label("label2"));
+      Ariadne_LabelList labelList = new Ariadne_LabelList(labels);
+      conditions[i++] = labelList.size() == 2 && labelList.get(0).get().equals("label1") && labelList.get(1).get().equals("label2"); // Expect true for correct size and contents
+
+      // Return true if all conditions are met
+      return Mosaic_Util.all(conditions);
+    }
+
+  }
+
+  public static void main(String[] args) {
+    TestSuite suite = new Test_LabelList_0().new TestSuite();
+    int result = Mosaic_Testbench.run(suite); 
+    System.exit(result);
+  }
+}
diff --git a/tester/javacđź–‰/Test_Label_0.java b/tester/javacđź–‰/Test_Label_0.java
new file mode 100644 (file)
index 0000000..e304150
--- /dev/null
@@ -0,0 +1,40 @@
+
+import com.ReasoningTechnology.Mosaic.Mosaic_IO;
+import com.ReasoningTechnology.Mosaic.Mosaic_Util;
+import com.ReasoningTechnology.Mosaic.Mosaic_Testbench;
+
+import com.ReasoningTechnology.Ariadne.Ariadne_Label;
+
+
+public class Test_Label_0 {
+
+  public class TestSuite {
+
+    public Boolean label_creation_0(Mosaic_IO io) {
+      Boolean[] conditions = new Boolean[4];
+      int i = 0;
+
+      // Test input
+      Ariadne_Label label1 = new Ariadne_Label("test");
+      Ariadne_Label label2 = new Ariadne_Label("");
+      Ariadne_Label label3 = new Ariadne_Label("test");
+
+      // Check that the value is correctly set
+      conditions[i++] = label1.get().equals("test"); // Expect true
+      conditions[i++] = label2.isEmpty(); // Expect true
+      conditions[i++] = label1.equals(label3); // Expect true, as contents are identical
+      conditions[i++] = label1.hashCode() == label3.hashCode(); // Expect true, as hash should match for equal labels
+
+      // Return true if all conditions are met
+      return Mosaic_Util.all(conditions);
+    }
+
+  }
+
+  public static void main(String[] args) {
+    TestSuite suite = new Test_Label_0().new TestSuite();
+    int result = Mosaic_Testbench.run(suite); 
+    System.exit(result);
+  }
+
+}
diff --git a/tester/javacđź–‰/Test_NodeList_0.java b/tester/javacđź–‰/Test_NodeList_0.java
new file mode 100644 (file)
index 0000000..cb7f5a6
--- /dev/null
@@ -0,0 +1,35 @@
+import com.ReasoningTechnology.Mosaic.Mosaic_IO;
+import com.ReasoningTechnology.Mosaic.Mosaic_Util;
+import com.ReasoningTechnology.Mosaic.Mosaic_Testbench;
+
+import com.ReasoningTechnology.Ariadne.Ariadne_Node;
+import com.ReasoningTechnology.Ariadne.Ariadne_NodeList;
+
+public class Test_NodeList_0 {
+
+  public class TestSuite {
+
+    public Boolean nodeList_creation_0(Mosaic_IO io) {
+      Boolean[] conditions = new Boolean[2];
+      int i = 0;
+
+      // Test default constructor (expecting an empty NodeList)
+      Ariadne_NodeList nodeList = new Ariadne_NodeList();
+      conditions[i++] = nodeList.isEmpty(); // Expect true for empty list
+
+      // Add a node and verify presence
+      Ariadne_Node node = new Ariadne_Node();
+      nodeList.add(node);
+      conditions[i++] = nodeList.size() == 1 && nodeList.contains(node); // Expect true for correct size and content
+
+      // Return true if all conditions are met
+      return Mosaic_Util.all(conditions);
+    }
+  }
+
+  public static void main(String[] args) {
+    TestSuite suite = new Test_NodeList_0().new TestSuite();
+    int result = Mosaic_Testbench.run(suite); 
+    System.exit(result);
+  }
+}
diff --git a/tester/javacđź–‰/Test_Node_0.java b/tester/javacđź–‰/Test_Node_0.java
new file mode 100644 (file)
index 0000000..ae85d64
--- /dev/null
@@ -0,0 +1,74 @@
+
+import com.ReasoningTechnology.Mosaic.Mosaic_IO;
+import com.ReasoningTechnology.Mosaic.Mosaic_Util;
+import com.ReasoningTechnology.Mosaic.Mosaic_Testbench;
+
+import com.ReasoningTechnology.Ariadne.Ariadne_Node;
+import com.ReasoningTechnology.Ariadne.Ariadne_Label;
+import com.ReasoningTechnology.Ariadne.Ariadne_LabelList;
+import com.ReasoningTechnology.Ariadne.Ariadne_Token;
+import com.ReasoningTechnology.Ariadne.Ariadne_TokenSet;
+
+
+public class Test_Node_0 {
+
+  public class TestSuite {
+
+    public Boolean node_creation_0(Mosaic_IO io) {
+      Boolean[] conditions = new Boolean[2];
+      int i = 0;
+
+      // Test that neighbor list is initialized
+      Ariadne_Node node = new Ariadne_Node();
+      conditions[i++] = node.neighbor_LabelList() != null && node.neighbor_LabelList().isEmpty(); // Expect true
+
+      // Test that the mark property is not initialized until used
+      conditions[i++] = node.get("mark") == null; // Expect true
+
+      // Return true if all conditions are met
+      return Mosaic_Util.all(conditions);
+    }
+
+    public Boolean node_marking_0(Mosaic_IO io) {
+      Boolean[] conditions = new Boolean[3];
+      int i = 0;
+
+      Ariadne_Node node = new Ariadne_Node();
+      Ariadne_Token token1 = new Ariadne_Token("token1");
+      Ariadne_Token token2 = new Ariadne_Token("token2");
+
+      // Test marking the node with token1
+      node.mark(token1);
+      conditions[i++] = node.has_mark(token1); // Expect true
+      conditions[i++] = !node.has_mark(token2); // Expect false for unmarked token
+
+      // Test that mark property is now initialized and contains token1
+      Ariadne_TokenSet markSet = (Ariadne_TokenSet) node.get("mark");
+      conditions[i++] = markSet != null && markSet.contains(token1); // Expect true
+
+      // Return true if all conditions are met
+      return Mosaic_Util.all(conditions);
+    }
+
+    public Boolean node_neighbor_0(Mosaic_IO io) {
+      Boolean[] conditions = new Boolean[1];
+      int i = 0;
+
+      // Test adding and retrieving neighbors
+      Ariadne_Node node = new Ariadne_Node();
+      Ariadne_LabelList neighbors = node.neighbor_LabelList();
+      neighbors.add(new Ariadne_Label("neighbor1"));
+      neighbors.add(new Ariadne_Label("neighbor2"));
+      conditions[i++] = neighbors.size() == 2 && neighbors.get(0).get().equals("neighbor1") && neighbors.get(1).get().equals("neighbor2"); // Expect true
+
+      // Return true if all conditions are met
+      return Mosaic_Util.all(conditions);
+    }
+  }
+
+  public static void main(String[] args) {
+    TestSuite suite = new Test_Node_0().new TestSuite();
+    int result = Mosaic_Testbench.run(suite); 
+    System.exit(result);
+  }
+}
diff --git a/tester/javacđź–‰/Test_TokenSet_0.java b/tester/javacđź–‰/Test_TokenSet_0.java
new file mode 100644 (file)
index 0000000..53399e1
--- /dev/null
@@ -0,0 +1,52 @@
+import com.ReasoningTechnology.Mosaic.Mosaic_IO;
+import com.ReasoningTechnology.Mosaic.Mosaic_Util;
+import com.ReasoningTechnology.Mosaic.Mosaic_Testbench;
+
+import com.ReasoningTechnology.Ariadne.Ariadne_Token;
+import com.ReasoningTechnology.Ariadne.Ariadne_TokenSet;
+
+public class Test_TokenSet_0 {
+
+  public class TestSuite {
+
+    public Boolean tokenSet_creation_0(Mosaic_IO io) {
+      Boolean[] conditions = new Boolean[2];
+      int i = 0;
+
+      // Test default constructor (expecting an empty TokenSet)
+      Ariadne_TokenSet tokenSet = new Ariadne_TokenSet();
+      conditions[i++] = tokenSet.isEmpty(); // Expect true for empty set
+
+      // Add a token and verify presence
+      Ariadne_Token token = new Ariadne_Token("error");
+      tokenSet.add(token);
+      conditions[i++] = tokenSet.size() == 1 && tokenSet.contains(token); // Expect true for correct size and content
+
+      // Return true if all conditions are met
+      return Mosaic_Util.all(conditions);
+    }
+
+    public Boolean tokenSet_uniqueness_0(Mosaic_IO io) {
+      Boolean[] conditions = new Boolean[1];
+      int i = 0;
+
+      Ariadne_TokenSet tokenSet = new Ariadne_TokenSet();
+      Ariadne_Token token1 = new Ariadne_Token("error");
+      Ariadne_Token token2 = new Ariadne_Token("error");
+
+      // Add two tokens with identical values and verify only one is stored
+      tokenSet.add(token1);
+      tokenSet.add(token2);
+      conditions[i++] = tokenSet.size() == 1 && tokenSet.contains(token1) && tokenSet.contains(token2); // Expect true for single entry despite duplicate addition
+
+      // Return true if all conditions are met
+      return Mosaic_Util.all(conditions);
+    }
+  }
+
+  public static void main(String[] args) {
+    TestSuite suite = new Test_TokenSet_0().new TestSuite();
+    int result = Mosaic_Testbench.run(suite); 
+    System.exit(result);
+  }
+}
diff --git a/tester/javacđź–‰/Test_Token_0.java b/tester/javacđź–‰/Test_Token_0.java
new file mode 100644 (file)
index 0000000..2fe9c48
--- /dev/null
@@ -0,0 +1,50 @@
+import com.ReasoningTechnology.Mosaic.Mosaic_IO;
+import com.ReasoningTechnology.Mosaic.Mosaic_Util;
+import com.ReasoningTechnology.Mosaic.Mosaic_Testbench;
+
+import com.ReasoningTechnology.Ariadne.Ariadne_Token;
+
+public class Test_Token_0 {
+
+  public class TestSuite {
+
+    public Boolean token_creation_0(Mosaic_IO io) {
+      Boolean[] conditions = new Boolean[4];
+      int i = 0;
+
+      // Test input
+      Ariadne_Token token1 = new Ariadne_Token("error");
+      Ariadne_Token token2 = new Ariadne_Token("warning");
+      Ariadne_Token token3 = new Ariadne_Token("error");
+
+      // Check that the value is correctly set
+      conditions[i++] = token1.get().equals("error"); // Expect true
+      conditions[i++] = token1.toString().equals("error"); // Expect true (toString should match value)
+      conditions[i++] = token1.equals(token3); // Expect true, as contents are identical
+      conditions[i++] = !token1.equals(token2); // Expect false, as values differ
+
+      // Return true if all conditions are met
+      return Mosaic_Util.all(conditions);
+    }
+
+    public Boolean token_hashCode_0(Mosaic_IO io) {
+      Boolean[] conditions = new Boolean[1];
+      int i = 0;
+
+      Ariadne_Token token1 = new Ariadne_Token("error");
+      Ariadne_Token token2 = new Ariadne_Token("error");
+
+      // Check that two identical tokens have the same hashCode
+      conditions[i++] = token1.hashCode() == token2.hashCode(); // Expect true
+
+      // Return true if all conditions are met
+      return Mosaic_Util.all(conditions);
+    }
+  }
+
+  public static void main(String[] args) {
+    TestSuite suite = new Test_Token_0().new TestSuite();
+    int result = Mosaic_Testbench.run(suite); 
+    System.exit(result);
+  }
+}
diff --git a/tester/javacđź–‰/Test_Util_0.java b/tester/javacđź–‰/Test_Util_0.java
new file mode 100644 (file)
index 0000000..15d9821
--- /dev/null
@@ -0,0 +1,55 @@
+import com.ReasoningTechnology.Mosaic.Mosaic_IO;
+import com.ReasoningTechnology.Mosaic.Mosaic_Util;
+import com.ReasoningTechnology.Mosaic.Mosaic_Testbench;
+
+import com.ReasoningTechnology.Ariadne.Ariadne_Label;
+import com.ReasoningTechnology.Ariadne.Ariadne_Util;
+
+import java.util.List;
+import java.util.Arrays;
+
+public class Test_Util_0 {
+
+  public class TestSuite {
+
+    public Boolean print_list_0(Mosaic_IO io) {
+      Boolean[] conditions = new Boolean[3];
+      int i = 0;
+
+      // Test with a non-empty list and a prefix
+      List<Ariadne_Label> itemList1 = Arrays.asList(new Ariadne_Label("first"), new Ariadne_Label("second"), new Ariadne_Label("third"));
+      Ariadne_Util.print_list("Items:", itemList1);
+
+      // Capture and check stdout content
+      String stdoutContent1 = io.get_out_content();
+      conditions[i++] = stdoutContent1.equals("Items: 'first', 'second', 'third'.\n"); // Expect correct format with prefix
+
+      // Clear streams for the next test
+      io.clear_buffers();
+
+      // Test with an empty list (no output expected)
+      List<Ariadne_Label> itemList2 = Arrays.asList();
+      Ariadne_Util.print_list("Empty:", itemList2);
+      String stdoutContent2 = io.get_out_content();
+      conditions[i++] = stdoutContent2.isEmpty(); // Expect no output for empty list
+
+      // Clear streams for the next test
+      io.clear_buffers();
+
+      // Test with a null list (no output expected)
+      Ariadne_Util.print_list("Null:", null);
+      String stdoutContent3 = io.get_out_content();
+      conditions[i++] = stdoutContent3.isEmpty(); // Expect no output for null list
+
+      // Return true if all conditions are met
+      return Mosaic_Util.all(conditions);
+    }
+  }
+
+  public static void main(String[] args) {
+    TestSuite suite = new Test_Util_0().new TestSuite();
+    int result = Mosaic_Testbench.run(suite); 
+    System.exit(result);
+  }
+
+}
diff --git a/tester/javacđź–‰/test_log.txt b/tester/javacđź–‰/test_log.txt
new file mode 100644 (file)
index 0000000..e2ec965
--- /dev/null
@@ -0,0 +1,12 @@
+
+2024-12-09T04:25:18.053085602Z -----------------------------------------------------------
+Test: path_find_cycle_0
+Message:
+Test logic error: jdk.proxy1.$Proxy0.path_find_cycle(com.ReasoningTechnology.Ariadne.Ariadne_LabelList)
+
+2024-12-09T04:25:18.061014789Z -----------------------------------------------------------
+Test: path_find_cycle_0
+Stream: stdout
+Output:
+path_find_cycle_0 method called
+
index d396818..120f485 100644 (file)
@@ -1,18 +1,2 @@
-/Test_File_0$TestSuite.class
-/Test_File_0.class
-/Test_Graph_0$TestSuite.class
-/Test_Graph_0.class
-/Test_LabelList_0$TestSuite.class
-/Test_LabelList_0.class
-/Test_Label_0$TestSuite.class
-/Test_Label_0.class
-/Test_NodeList_0$TestSuite.class
-/Test_NodeList_0.class
-/Test_Node_0$TestSuite.class
-/Test_Node_0.class
-/Test_TokenSet_0$TestSuite.class
-/Test_TokenSet_0.class
-/Test_Token_0$TestSuite.class
-/Test_Token_0.class
-/Test_Util_0$TestSuite.class
-/Test_Util_0.class
+*
+!/.gitignore
diff --git a/tester/shell-leaf/TF0 b/tester/shell-leaf/TF0
deleted file mode 100755 (executable)
index af784e6..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/env bash
-
-echo $ENV
-
-vl echo "CLASSPATH: $CLASSPATH"
-
-set -x
-java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005 Test_File_0
-     
-
diff --git a/tester/shell/.githolder b/tester/shell/.githolder
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/tester/shell/Test_File_0 b/tester/shell/Test_File_0
deleted file mode 100755 (executable)
index 39c1f2a..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/env bash
-java Test_File_0
diff --git a/tester/shell/Test_Graph_0 b/tester/shell/Test_Graph_0
deleted file mode 100755 (executable)
index 7653d09..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/env bash
-java Test_Graph_0
diff --git a/tester/shell/Test_LabelList_0 b/tester/shell/Test_LabelList_0
deleted file mode 100755 (executable)
index 15a0da6..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/env bash
-java Test_LabelList_0
diff --git a/tester/shell/Test_Label_0 b/tester/shell/Test_Label_0
deleted file mode 100755 (executable)
index 6b61242..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/env bash
-java Test_Label_0
diff --git a/tester/shell/Test_NodeList_0 b/tester/shell/Test_NodeList_0
deleted file mode 100755 (executable)
index 8970446..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/env bash
-java Test_NodeList_0
diff --git a/tester/shell/Test_Node_0 b/tester/shell/Test_Node_0
deleted file mode 100755 (executable)
index 7901f30..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/env bash
-java Test_Node_0
diff --git a/tester/shell/Test_TokenSet_0 b/tester/shell/Test_TokenSet_0
deleted file mode 100755 (executable)
index 05d37d4..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/env bash
-java Test_TokenSet_0
diff --git a/tester/shell/Test_Token_0 b/tester/shell/Test_Token_0
deleted file mode 100755 (executable)
index 842f673..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/env bash
-java Test_Token_0
diff --git a/tester/shell/Test_Util_0 b/tester/shell/Test_Util_0
deleted file mode 100755 (executable)
index 6157abe..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/env bash
-java Test_Util_0
index ce967e9..f9fe542 100644 (file)
@@ -196,3 +196,39 @@ Stream: stdout
 Output:
 path_find_cycle_0 method called
 
+
+2024-12-09T04:07:54.684532266Z -----------------------------------------------------------
+Test: path_find_cycle_0
+Message:
+Test logic error: jdk.proxy1.$Proxy0.path_find_cycle(com.ReasoningTechnology.Ariadne.Ariadne_LabelList)
+
+2024-12-09T04:07:54.695557006Z -----------------------------------------------------------
+Test: path_find_cycle_0
+Stream: stdout
+Output:
+path_find_cycle_0 method called
+
+
+2024-12-09T04:20:55.682148373Z -----------------------------------------------------------
+Test: path_find_cycle_0
+Message:
+Test logic error: jdk.proxy1.$Proxy0.path_find_cycle(com.ReasoningTechnology.Ariadne.Ariadne_LabelList)
+
+2024-12-09T04:24:22.045170508Z -----------------------------------------------------------
+Test: path_find_cycle_0
+Stream: stdout
+Output:
+path_find_cycle_0 method called
+
+
+2024-12-09T07:16:25.530710606Z -----------------------------------------------------------
+Test: path_find_cycle_0
+Message:
+Test logic error: jdk.proxy1.$Proxy0.path_find_cycle(com.ReasoningTechnology.Ariadne.Ariadne_LabelList)
+
+2024-12-09T07:16:25.539373169Z -----------------------------------------------------------
+Test: path_find_cycle_0
+Stream: stdout
+Output:
+path_find_cycle_0 method called
+
diff --git a/tester/tool/#make.sh# b/tester/tool/#make.sh#
deleted file mode 100755 (executable)
index d11729a..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/env bash
-
-# Ensure the script is sourced
-if [ -z "$ENV_TESTER" ]; then
-  echo "env_build:: script can only be run in the tester  environment"
-  return 1
-fi
-
-cd "$REPO_HOME"/tester/test0
-groovyc TestGraph.groovy
diff --git a/tester/tool/clean_build_directories b/tester/tool/clean_build_directories
deleted file mode 100755 (executable)
index 5b84fd0..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-
-# Caveat: the 'shell' directory is for built wrapper
-# functions. `clean_build_directories` will remove all the files in this
-# directory. For bespoke scripts used by the tester, put them in the `tool`
-# directory.
-
-# input guards
-  env_must_be="tester/tool/env"
-  if [ "$ENV" != "$env_must_be" ]; then
-    echo "$(script_fp):: error: must be run in the $env_must_be environment"
-    exit 1
-  fi
-
-# remove files
-  set -x
-  cd "$REPO_HOME"/tester
-  rm -r scratchpad/*
-  rm jvm/*
-  rm shell/*
-  set +x
-
-echo "$(script_fn) done."
diff --git a/tester/tool/env b/tester/tool/env
deleted file mode 100644 (file)
index fd66adb..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-
-# input guards
-
-  env_must_be="tool_shared/bespoke/env"
-  error=false
-  if [ "$ENV" != "$env_must_be" ]; then
-    echo "$(script_fp):: error: must be run in the $env_must_be environment"
-    error=true
-  fi
-  if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
-    echo "$script_afp:: This script must be sourced, not executed."
-    error=true
-  fi
-  if $error; then exit 1; fi
-
-# so we can do testing
-
-export PATH=\
-"$REPO_HOME"/tester/tool/\
-:"$REPO_HOME"/tool_shared/bespoke/\
-:"$JAVA_HOME"/bin\
-:"$MOSAIC_HOME"\
-:"$PATH"
-
-export CLASSPATH=\
-"$JAVA_HOME"/lib\
-:"$MOSAIC_HOME"/Mosaic.jar\
-:"$REPO_HOME"/release/"$PROJECT".jar\
-:"$REPO_HOME"/tester/jvm/Test_"$PROJECT".jar\
-:"$CLASSPATH"
-
-export SOURCEPATH=\
-"$REPO_HOME"/tester/javac/\
-:"$REPO_HOME"/developer/scratchpad/\
-
-
-# misc
-
-  # make .githolder and .gitignore visible
-  alias ls="ls -a --time-style=full-iso"
-
-# some feedback to show all went well
-
-  export PROMPT_DECOR="$PROJECT"_tester
-  export ENV=$(script_fp)
-  echo ENV "$ENV"
-  cd "$REPO_HOME"/tester/
diff --git a/tester/tool/make b/tester/tool/make
deleted file mode 100755 (executable)
index deae0a1..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-
-# input guards
-
-  env_must_be="tester/tool/env"
-  if [ "$ENV" != "$env_must_be" ]; then
-    echo "$(script_fp):: error: must be run in the $env_must_be environment"
-    exit 1
-  fi
-
-echo "Compiling files..."
-
-  set -x
-  cd $REPO_HOME/tester
-  javac -g -d scratchpad javac/*.java
-  jar cf jvm/Test_"$PROJECT".jar -C scratchpad .
-  set +x 
-
-echo "Creating shell wrappers..."
-  mkdir -p shell
-  # wrapper is a space separated list
-  wrapper=$(shell_wrapper_list)
-  for file in $wrapper;do
-    cat > shell/$file << EOL
-#!/bin/env bash
-java $file
-EOL
-    chmod +x shell/$file
-  done
-
-echo "$(script_fp) done."
diff --git a/tester/tool/run_jdb b/tester/tool/run_jdb
deleted file mode 100755 (executable)
index 9c472f4..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-
-# input guards
-env_must_be="tester/tool/env"
-if [ "$ENV" != "$env_must_be" ]; then
-  echo "$(script_fp):: error: must be run in the $env_must_be environment"
-  exit 1
-fi
-
-jdb -sourcepath "$SOURCEPATH" "$@"
-
diff --git a/tester/tool/run_tests b/tester/tool/run_tests
deleted file mode 100755 (executable)
index b26e9b1..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/env bash
-
-# Ensure REPO_HOME is set
-if [ -z "$REPO_HOME" ]; then
-  echo "Error: REPO_HOME is not set."
-  exit 1
-fi
-
-# Navigate to the shell directory
-cd "$REPO_HOME/tester/shell" || exit
-
-# Get the list of test scripts in the specific order from shell_wrapper_list
-test_list=$(shell_wrapper_list)
-
-# Execute each test in the specified order
-for file in $test_list; do
-  if [[ -x "$file" && ! -d "$file" ]]; then
-    echo
-    echo "Running $file..."
-    ./"$file"
-  else
-    echo "Skipping $file (not executable or is a directory)"
-  fi
-done
diff --git a/tester/tool/shell_wrapper_list b/tester/tool/shell_wrapper_list
deleted file mode 100755 (executable)
index c8a3926..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-
-# input guards
-env_must_be="tester/tool/env"
-if [ "$ENV" != "$env_must_be" ]; then
-  echo "$(script_fp):: error: must be run in the $env_must_be environment"
-  exit 1
-fi
-
-# space separated list of shell interface wrappers
-echo \
-  Test_File_0 \
-  Test_Label_0 \
-  Test_LabelList_0 \
-  Test_Node_0 \
-  Test_NodeList_0 \
-  Test_Token_0 \
-  Test_TokenSet_0 \
-  Test_Util_0 \
-  Test_Graph_0 \
-  ""
-
diff --git a/tester/toolđź–‰/bash_wrapper_list b/tester/toolđź–‰/bash_wrapper_list
new file mode 100755 (executable)
index 0000000..0fef9b2
--- /dev/null
@@ -0,0 +1,24 @@
+#!/bin/env bash
+script_afp=$(realpath "${BASH_SOURCE[0]}")
+
+# input guards
+env_must_be="tester/toolđź–‰/env"
+if [ "$ENV" != "$env_must_be" ]; then
+  echo "$(script_fp):: error: must be run in the $env_must_be environment"
+  exit 1
+fi
+
+# space separated list of bash interface wrappers
+echo \
+  Test_File_0 \
+  Test_Label_0 \
+  Test_LabelList_0 \
+  Test_Node_0 \
+  Test_NodeList_0 \
+  Test_Token_0 \
+  Test_TokenSet_0 \
+  Test_Util_0 \
+  Test_Graph_0 \
+  ""
+
diff --git a/tester/toolđź–‰/clean_build_directories b/tester/toolđź–‰/clean_build_directories
new file mode 100755 (executable)
index 0000000..cf16126
--- /dev/null
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+script_afp=$(realpath "${BASH_SOURCE[0]}")
+
+# Caveat: the 'bash' directory is for built wrapper
+# functions. `clean_build_directories` will remove all the files in this
+# directory. For bespoke scripts used by the tester, put them in the `tool`
+# directory.
+
+# input guards
+  env_must_be="tester/toolđź–‰/env"
+  if [ "$ENV" != "$env_must_be" ]; then
+    echo "$(script_fp):: error: must be run in the $env_must_be environment"
+    exit 1
+  fi
+
+# remove files
+  set -x
+  cd "$REPO_HOME"/tester
+  rm -r scratchpad/*
+  rm jvm/*
+  rm bash/*
+  set +x
+
+echo "$(script_fn) done."
diff --git a/tester/toolđź–‰/env b/tester/toolđź–‰/env
new file mode 100644 (file)
index 0000000..f9001da
--- /dev/null
@@ -0,0 +1,105 @@
+#!/usr/bin/env bash
+script_afp=$(realpath "${BASH_SOURCE[0]}")
+
+# input guards
+
+  env_must_be="tool_shared/bespokeđź–‰/env"
+  error_bad_env=false
+  error_not_sourced=false
+  if [ "$ENV" != "$env_must_be" ]; then
+    echo "$(script_fp):: error: must be run in the $env_must_be environment"
+    error_bad_env=true
+  fi
+  if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
+    echo "$script_afp:: This script must be sourced, not executed."
+    error_not_sourced=true
+  fi
+  if $error_not_sourced; then exit 1; fi
+  if $error_bad_env; then return 1; fi
+
+# so we can do testing
+
+export PATH=\
+"$REPO_HOME"/tester/toolđź–‰/\
+:"$JAVA_HOME"/bin\
+:"$MOSAIC_HOME"\
+:"$PATH"
+
+# Use this when leaving open the option to check in edits to the third party project
+#   sources.  (after cloning/pulling the project, build it with sources, the
+#   classes and sources will be in the scratchpad directory)
+#
+# And, when leaving open the option to edit Ariadne sources directly (some
+# development workflows might not accommodate this. Be sure that Ariadne was built
+# with sources and the scratchpad directory has not been cleaned)
+#
+export CLASSPATH=\
+"$JAVA_HOME"/lib\
+:"$MOSAIC_HOME"/developer/scratchpad\
+:"$REPO_HOME"/developer/scratchpad\
+:"$REPO_HOME"/tester/scratchpad\
+:"$CLASSPATH"
+
+export SOURCEPATH=\
+"$JAVA_HOME"/lib\
+:"$MOSAIC_HOME"/developer/scratchpad\
+:"$REPO_HOME"/developer/scratchpad\
+:"$REPO_HOME"/tester/javacđź–‰\
+:"$SOURCEPATH"
+
+# For projects who's sources are not be edited, directly expand the project into
+# $REPO_HOME/tester/scratchpad before testing.
+#
+#   When Mosaic sources are not to edited then checked back in.
+#     Be sure to use `Mosaic.jar` that has sources included.
+#       (cd tester/scratchpad && jar -xf $REPO_HOME/tool_shared/third_party/Mosaic.jar)
+#   When Ariadne developers source are not to be edited directly
+#     Be sure to use `release Ariadne.jar` has sources included.
+#        (cd scratchpad && jar xf $REPO_HOME/release/Ariadne.jar)
+#
+# export CLASSPATH=\
+# "$JAVA_HOME"/lib\
+# :"$REPO_HOME"/tester/javacđź–‰\
+# :"$REPO_HOME"/tester/scratchpad\
+# :"$CLASSPATH"
+
+# export SOURCEPATH=\
+# "$JAVA_HOME"/lib\
+# :"$REPO_HOME"/tester/javacđź–‰\
+# :"$REPO_HOME"/tester/scratchpad\
+# :"$SOURCEPATH"
+
+# The 'normal' case When outside sources are not viewed in the debugger. This is
+# common when the tester's responsibility is to find failed tests, and the
+# tester is not debugging anything but the test code.
+#
+# export CLASSPATH=\
+# "$JAVA_HOME"/lib\
+# :"$MOSAIC_HOME"/Mosaic.jar\
+# :"$REPO_HOME"/release/"$PROJECT".jar\
+# :"$REPO_HOME"/tester/jvm/Test_"$PROJECT".jar\
+# :"$CLASSPATH"
+
+# export SOURCEPATH=\
+# "$REPO_HOME"/tester/javacđź–‰\ 
+# :"$SOURCEPATH"
+
+
+# so we can run individual built test wrappers
+export PATH=\
+"$REPO_HOME"/tester/bashđź–‰\
+"$REPO_HOME"/tester/bash\
+:"$PATH"
+
+
+# misc
+
+  # make .githolder and .gitignore visible
+  alias ls="ls -a --time-style=full-iso"
+
+# some feedback to show all went well
+
+  export PROMPT_DECOR="$PROJECT"_tester
+  export ENV=$(script_fp)
+  echo ENV "$ENV"
+  cd "$REPO_HOME"/tester/
diff --git a/tester/toolđź–‰/make b/tester/toolđź–‰/make
new file mode 100755 (executable)
index 0000000..15f469a
--- /dev/null
@@ -0,0 +1,32 @@
+#!/bin/env bash
+script_afp=$(realpath "${BASH_SOURCE[0]}")
+
+# input guards
+
+  env_must_be="tester/toolđź–‰/env"
+  if [ "$ENV" != "$env_must_be" ]; then
+    echo "$(script_fp):: error: must be run in the $env_must_be environment"
+    exit 1
+  fi
+
+echo "Compiling files..."
+
+  set -x
+  cd $REPO_HOME/tester
+  javac -g -d scratchpad javac/*.java
+  jar cf jvm/Test_"$PROJECT".jar -C scratchpad .
+  set +x 
+
+echo "Creating bash wrappers..."
+  mkdir -p bash
+  # wrapper is a space separated list
+  wrapper=$(bash_wrapper_list)
+  for file in $wrapper;do
+    cat > bash/$file << EOL
+#!/bin/env bash
+java $file
+EOL
+    chmod +x bash/$file
+  done
+
+echo "$(script_fp) done."
diff --git a/tester/toolđź–‰/run_jdb b/tester/toolđź–‰/run_jdb
new file mode 100755 (executable)
index 0000000..8334c1b
--- /dev/null
@@ -0,0 +1,12 @@
+#!/bin/env bash
+script_afp=$(realpath "${BASH_SOURCE[0]}")
+
+# input guards
+env_must_be="tester/toolđź–‰/env"
+if [ "$ENV" != "$env_must_be" ]; then
+  echo "$(script_fp):: error: must be run in the $env_must_be environment"
+  exit 1
+fi
+
+jdb -sourcepath "$SOURCEPATH" "$@"
+
diff --git a/tester/toolđź–‰/run_tests b/tester/toolđź–‰/run_tests
new file mode 100755 (executable)
index 0000000..a27f28a
--- /dev/null
@@ -0,0 +1,24 @@
+#!/bin/env bash
+
+# Ensure REPO_HOME is set
+if [ -z "$REPO_HOME" ]; then
+  echo "Error: REPO_HOME is not set."
+  exit 1
+fi
+
+# Navigate to the bash directory
+cd "$REPO_HOME/tester/bash" || exit
+
+# Get the list of test scripts in the specific order from bash_wrapper_list
+test_list=$(bash_wrapper_list)
+
+# Execute each test in the specified order
+for file in $test_list; do
+  if [[ -x "$file" && ! -d "$file" ]]; then
+    echo
+    echo "Running $file..."
+    ./"$file"
+  else
+    echo "Skipping $file (not executable or is a directory)"
+  fi
+done
diff --git a/tool/env b/tool/env
deleted file mode 100644 (file)
index 4f0c70f..0000000
--- a/tool/env
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-
-# input guards
-
-  env_must_be="tool_shared/bespoke/env"
-  error=false
-  if [ "$ENV" != "$env_must_be" ]; then
-    echo "$(script_fp):: error: must be run in the $env_must_be environment"
-    error=true
-  fi
-  if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
-    echo "$script_afp:: This script must be sourced, not executed."
-    error=true
-  fi
-  if $error; then exit 1; fi
-
-export PATH=\
-"$REPO_HOME"/tool_shared/bespoke/\
-:"$PATH"
-
-# expose sneaky hidden files
-alias ls="ls -a"
-
-# some feedback to show all went well
-
-  export PROMPT_DECOR="$PROJECT"_administrator
-  export ENV=$(script_fp)
-  echo ENV "$ENV"
diff --git a/tool_shared/bespoke/bashrc b/tool_shared/bespoke/bashrc
deleted file mode 100644 (file)
index 0914cfc..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-# ssh login will fail if .bashrc writes to stdout, so we write to "bash_error.txt"
-# set -x
-# in F37 something seems to be caching PATH, which can be annoying
-
-# If not running interactively, don't do anything
-  case $- in
-      *i*) ;;
-        *) return;;
-  esac
-
-# This should also be the default from login.defs, because gnome ignores 
-# .login, .profile, etc. and uses systemd to launch applications from the desktop,
-  umask 0077
-
-# - note the variable $PROMPT_DECOR, that is how the project name ends up in the prompt.
-# - without -i bash will clear PS1, just because, so we set PPS1, ,PPS2 to not lose the profit.
-# - use $(pwd) instead of \w or it will prefix '~' which confuses dirtrack when the
-#   user is changed using su
-  export PPS1='\n$($iseq/Z)[$PROMPT_DECOR]\n\u@\h§$(pwd)§\n> '
-  export PPS2='>> '
-  export PS1="$PPS1"
-  export PS2="$PPS2"
-
-# sort the output of printenv, show newlines as environment variable values as \n
-  alias printenv='printenv | awk '\''{gsub(/\n/, "\\n")}1'\'' | sort'
-
-# iso time in ls -l, show hidden files, human readable sizes
-  alias ls='ls -a -h --time-style=long-iso' 
-
-# iso time for all Linux programs, which they will all ignore, but at least we
-# tried, perhaps someday ...
-  export TZ=UTC
-  export TIME_STYLE=long-iso
-  export LC_ALL=en_DK.UTF-8
-
-# -l don't truncate long lins
-# -p show pids
-  alias pstree='pstree -lp'
-
-# - make bash gp to sleep, revealing the calling shell
-# - useful for job control of multiple bash shells from a controlling shell
-  alias zzz="kill -STOP \$\$"
-
-# The one true operating system.
-# Proof that an OS can be as small as an editor.
-  export EDITOR=emacs
-
-# check the window size after each command and, if necessary, update the values
-# of LINES and COLUMNS.
-  shopt -s checkwinsize
-
diff --git a/tool_shared/bespoke/cat_w_fn b/tool_shared/bespoke/cat_w_fn
deleted file mode 100755 (executable)
index 3308525..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-
-# Check if at least one file is provided
-if [ $# -eq 0 ]; then
-  echo "Usage: $(script_fp) <filename1> [filename2] ..."
-  exit 1
-fi
-
-# Loop through all the provided files
-for file in "$@"; do
-  # Check if the file exists
-  if [ ! -f "$file" ]; then
-    echo "Error: File '$file' not found!"
-    continue
-  fi
-
-  # Print 80 dashes
-  printf '%.0s-' {1..80}
-  echo
-
-  # Print the filename and a colon
-  echo "$file:"
-
-  # Print the contents of the file
-  cat "$file"
-
-  # Print a newline for spacing between files
-  echo
-done
diff --git a/tool_shared/bespoke/deprecate b/tool_shared/bespoke/deprecate
deleted file mode 100755 (executable)
index 4713db5..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-
-# cp subtree at <source> under file path <destination>, and make all the copied
-# files read-only. The intended use case is for moving files to a `deprecated`
-# directory. This helps prevent subsequent accidental editing.
-
-if [ "$#" -lt 2 ]; then
-  echo "Usage: $script_afp <source> <destination>"
-  exit 1
-fi
-SRC="$1"
-DEST="$2"
-
-mkdir -p "$DEST"
-mv "$SRC" "$DEST"
-
-# make stuff readonly
-cd "$DEST" || exit
-chmod -R u-w,go-rwx "$DEST"
diff --git a/tool_shared/bespoke/env b/tool_shared/bespoke/env
deleted file mode 100644 (file)
index 3951697..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/usr/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
-  echo "$script_afp:: This script must be sourced, not executed."
-  exit 1
-fi
-
-# --------------------------------------------------------------------------------
-# project definition
-
-# actual absolute director path for this script file
-
-  script_adp(){
-    dirname "$script_afp"
-  }
-
-# assume this script is located  $REPO_HOME/tools_shared/bespoke and work backwards
-# to get $REPO_HOME, etc.
-
-  REPO_HOME=$(dirname "$(dirname "$(script_adp)")")
-  echo REPO_HOME "$REPO_HOME"
-
-  PROJECT=$(basename "$REPO_HOME")
-  echo PROJECT "$PROJECT"
-
-  # set the prompt decoration to the name of the project
-  PROMPT_DECOR=$PROJECT
-
-# --------------------------------------------------------------------------------
-# The project administrator sets up the following tools for all roles to use:
-#
-#  export JAVA_HOME="$REPO_HOME/tool_shared/third_party/jdk-11"
- export JAVA_HOME="$REPO_HOME/tool_shared/third_party/jdk-23.0.1"
- export MOSAIC_HOME="$REPO_HOME/tool_shared/third_party/Mosaic/release"
-
-# --------------------------------------------------------------------------------
-# the following functions are provided for other scripts to use.
-# at the top of files that make use of these functions put the following line:
-#  script_afp=$(realpath "${BASH_SOURCE[0]}")
-#
-
-  ## script's filename
-  script_fn(){
-    basename "$script_afp"
-  }
-
-  ## script's dirpath relative to $REPO_HOME
-  script_fp(){
-    realpath --relative-to="${REPO_HOME}" "$script_afp"
-  }
-
-  ## script's dirpath relative to $REPO_HOME
-  script_dp(){
-    dirname "$(script_fp)"
-  }
-
-# --------------------------------------------------------------------------------
-# Exports
-# Bash has no 'closure' hence when exporting a function, one must also export all the pieces.
-# do not export script_afp
-
-  export REPO_HOME PROJECT PROMPT_DECOR
-  export -f script_adp script_fn script_dp script_fp
-
-  export ENV=$(script_fp)
-  echo ENV "$ENV"
-
diff --git a/tool_shared/bespoke/githolder b/tool_shared/bespoke/githolder
deleted file mode 100755 (executable)
index 49fb12b..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/bin/env /bin/bash
-
-# Description: Descends from $1, or pwd, looking for empty directories and adds a `.githolder` to them.
-# does not descend into hidden directories.
-
-# examples:
-#   > git_holder
-#   > git_holder --dry-run
-
-set -e
-
-find_empty_dirs() {
-  local dir="$1"
-  local dry_run="$2"
-
-  # Skip `.git` specifically
-  if [[ "$(basename "$dir")" == ".git" ]]; then
-    return
-  fi
-
-  # Check if the directory is empty (including hidden files, excluding `.` and `..`)
-  if [[ -z $(find "$dir" -mindepth 1 -maxdepth 1 -print -quit) ]]; then
-    if [[ "$dry_run" == "true" ]]; then
-      echo "Dry-run: Would add .githolder in $dir"
-    else
-      echo "Adding .githolder to $dir"
-      touch "$dir/.githolder"
-    fi
-  else
-    # Recurse into subdirectories
-    for subdir in "$dir"/*/ "$dir"/.[!.]/; do
-      if [[ -d "$subdir" && "$subdir" != "$dir/.[!.]/" ]]; then
-        find_empty_dirs "$subdir" "$dry_run"
-      fi
-    done
-  fi
-}
-
-# Default parameters
-dry_run="false"
-target_dir="."
-
-# Parse arguments
-while [[ $# -gt 0 ]]; do
-  case "$1" in
-    --dry-run)
-      dry_run="true"
-      shift
-      ;;
-    *)
-      if [[ -d "$1" ]]; then
-        target_dir="$1"
-        shift
-      else
-        echo "Invalid argument: $1 is not a directory"
-        exit 1
-      fi
-      ;;
-  esac
-done
-
-# Run the function
-find_empty_dirs "$target_dir" "$dry_run"
diff --git a/tool_shared/bespoke/test_env b/tool_shared/bespoke/test_env
deleted file mode 100755 (executable)
index 18d75f9..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-
-# try both running and sourcing this test
-
-echo
-echo "--------------------------------------------------------------------------------"
-echo "from within test_shared/bespoke/test_env:"
-echo
-echo "REPO_HOME:" "$REPO_HOME"
-echo "PROJECT:" "$PROJECT"
-echo "script_afp:" "$script_afp"
-echo "script_adp:" "$(script_adp)"
-echo "script_fn:" "$(script_fn)"
-echo "script_fp:" "$(script_fp)"
-echo "script_dp:" "$(script_dp)"
-echo "ENV:" "$ENV"
-echo "-----------------------"
-echo "the BASH_SOURCE stack:"
-
-         top_index=$(( ${#BASH_SOURCE[@]} - 1 ))
-         for (( i=0; i<=top_index; i++ )); do
-           echo "$i: ${BASH_SOURCE[$i]}"
-         done
diff --git a/tool_shared/bespoke/version b/tool_shared/bespoke/version
deleted file mode 100755 (executable)
index 51abf9f..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-
-# 0.1 pulled groovy files from GQL_to_Cypher build.gradle
-# 0.2 conversion to Java
-# 0.3 refactored, split into smaller pieces, made into package
-
-echo v0.3
-
diff --git a/tool_shared/bespoke/vl b/tool_shared/bespoke/vl
deleted file mode 100755 (executable)
index 2c968d3..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-# vl 'vertical list'
-
-# Check if the command is provided
-if [ -z "$1" ]; then
-  echo "Usage: vl <command> [args...]"
-  exit 1
-fi
-
-# Capture the command and its arguments
-cmd=$1
-shift
-
-# Run the command with the remaining arguments and replace colons or spaces with newlines
-"$cmd" "$@" | tr ' :' '\n'
-
-exit 0
diff --git a/tool_shared/bespoke/wipe_release b/tool_shared/bespoke/wipe_release
deleted file mode 100755 (executable)
index 5bac0e7..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-# remove all files in the release directory
-set -e
-
-script_name=$(basename ${BASH_SOURCE[0]})
-if [ -z "$REPO_HOME" ]; then
-  echo "$script_name:: REPO_HOME is not set."
-  exit 1
-fi
-
-set -x
-cd "$REPO_HOME"
-rm -rf release/*
-set +x
-
-echo "$script_name done."
-
diff --git a/tool_shared/bespokeđź–‰/.githolder b/tool_shared/bespokeđź–‰/.githolder
new file mode 100755 (executable)
index 0000000..49fb12b
--- /dev/null
@@ -0,0 +1,63 @@
+#!/bin/env /bin/bash
+
+# Description: Descends from $1, or pwd, looking for empty directories and adds a `.githolder` to them.
+# does not descend into hidden directories.
+
+# examples:
+#   > git_holder
+#   > git_holder --dry-run
+
+set -e
+
+find_empty_dirs() {
+  local dir="$1"
+  local dry_run="$2"
+
+  # Skip `.git` specifically
+  if [[ "$(basename "$dir")" == ".git" ]]; then
+    return
+  fi
+
+  # Check if the directory is empty (including hidden files, excluding `.` and `..`)
+  if [[ -z $(find "$dir" -mindepth 1 -maxdepth 1 -print -quit) ]]; then
+    if [[ "$dry_run" == "true" ]]; then
+      echo "Dry-run: Would add .githolder in $dir"
+    else
+      echo "Adding .githolder to $dir"
+      touch "$dir/.githolder"
+    fi
+  else
+    # Recurse into subdirectories
+    for subdir in "$dir"/*/ "$dir"/.[!.]/; do
+      if [[ -d "$subdir" && "$subdir" != "$dir/.[!.]/" ]]; then
+        find_empty_dirs "$subdir" "$dry_run"
+      fi
+    done
+  fi
+}
+
+# Default parameters
+dry_run="false"
+target_dir="."
+
+# Parse arguments
+while [[ $# -gt 0 ]]; do
+  case "$1" in
+    --dry-run)
+      dry_run="true"
+      shift
+      ;;
+    *)
+      if [[ -d "$1" ]]; then
+        target_dir="$1"
+        shift
+      else
+        echo "Invalid argument: $1 is not a directory"
+        exit 1
+      fi
+      ;;
+  esac
+done
+
+# Run the function
+find_empty_dirs "$target_dir" "$dry_run"
diff --git a/tool_shared/bespokeđź–‰/env b/tool_shared/bespokeđź–‰/env
new file mode 100644 (file)
index 0000000..c7829f1
--- /dev/null
@@ -0,0 +1,74 @@
+#!/usr/bin/env bash
+script_afp=$(realpath "${BASH_SOURCE[0]}")
+if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
+  echo "$script_afp:: This script must be sourced, not executed."
+  exit 1
+fi
+
+# --------------------------------------------------------------------------------
+# project definition
+
+# actual absolute director path for this script file
+
+  script_adp(){
+    dirname "$script_afp"
+  }
+
+# assume this script is located  $REPO_HOME/tools_shared/bespoke and work backwards
+# to get $REPO_HOME, etc.
+
+  REPO_HOME=$(dirname "$(dirname "$(script_adp)")")
+  echo REPO_HOME "$REPO_HOME"
+
+  PROJECT=$(basename "$REPO_HOME")
+  echo PROJECT "$PROJECT"
+
+  # set the prompt decoration to the name of the project
+  PROMPT_DECOR=$PROJECT
+
+  # include the project bespoke tools
+  PATH="$REPO_HOME"/tool_shared/bespokeđź–‰:"$PATH"
+
+  export REPO_HOME PROJECT PROMPT_DECOR PATH
+
+# --------------------------------------------------------------------------------
+# The project administrator sets up the following tools for all roles to use:
+#
+  PATH="$REPO_HOME/tool_shared/third_party/RT-project-share/release/bash:$PATH"
+  PATH="$REPO_HOME/tool_shared/third_party/RT-project-share/release/amd64:$PATH"
+  PATH="$REPO_HOME/tool_shared/third_party/emacs/bin:$PATH"
+  JAVA_HOME="$REPO_HOME/tool_shared/third_party/jdk-23.0.1"
+  MOSAIC_HOME="$REPO_HOME/tool_shared/third_party/Mosaic"
+
+  export PATH JAVA_HOME MOSAIC_HOME
+
+# --------------------------------------------------------------------------------
+# the following functions are provided for other scripts to use.
+# at the top of files that make use of these functions put the following line:
+#  script_afp=$(realpath "${BASH_SOURCE[0]}")
+#
+
+  ## script's filename
+  script_fn(){
+    basename "$script_afp"
+  }
+
+  ## script's dirpath relative to $REPO_HOME
+  script_fp(){
+    realpath --relative-to="${REPO_HOME}" "$script_afp"
+  }
+
+  ## script's dirpath relative to $REPO_HOME
+  script_dp(){
+    dirname "$(script_fp)"
+  }
+
+  export -f script_adp script_fn script_dp script_fp
+
+# --------------------------------------------------------------------------------
+# closing
+#
+
+  export ENV=$(script_fp)
+  echo ENV "$ENV"
+
diff --git a/tool_shared/bespokeđź–‰/version b/tool_shared/bespokeđź–‰/version
new file mode 100755 (executable)
index 0000000..51abf9f
--- /dev/null
@@ -0,0 +1,9 @@
+#!/bin/env bash
+script_afp=$(realpath "${BASH_SOURCE[0]}")
+
+# 0.1 pulled groovy files from GQL_to_Cypher build.gradle
+# 0.2 conversion to Java
+# 0.3 refactored, split into smaller pieces, made into package
+
+echo v0.3
+
diff --git a/tool_shared/document/install.txt b/tool_shared/document/install.txt
deleted file mode 100644 (file)
index a584d92..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-The Ariadne project uses these:
-
-1. resource - for additional docs and scripts
-
-  https://github.com/Thomas-Walker-Lynch/resource/tree/core_developer_branch/document
-  https://git.reasoningtechnology.com/?p=resource;a=tree;f=document;h=098de7aa481fa7950bd56a7a7858c616c6be9ea5;hb=refs/heads/core_developer_branch
-
-> cd "$REPO_HOME/tool_shared/third_party/"
-> git clone https://github.com/Thomas-Walker-Lynch/resource.git
-> ln -s "$REPO_HOME/tool_shared/third_party/resource/document" see_also
-
-additional documents: resource/documents
-emacs elisp files: resource/developer/emacs
-additional tools: resource/developer
-
-> cd $REPO_HOME/document
-> ln -s "$REPO_HOME/tool_shared/third_party/resource/document" see_also
-
-2. jdk - Ariadne is currently a Java project
-
-  > cd "$REPO_HOME/tool_shared/third_party/upstream"
-
-  # source for the 11 version, before upgrade to 23
-  #curl -C - -o OpenJDK11U-jdk_x64_linux_hotspot_11.0.16_8.tar.gz https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.16+8/OpenJDK11U-jdk_x64_linux_hotspot_11.0.16_8.tar.gz
-
-  I used a browser to download the 23 version:
-    https://www.oracle.com/java/technologies/downloads/ 
-    OpenJDK11U-jdk_x64_linux_hotspot_11.0.16_8.tar.gz 
-
-  > cd ..
-  > tar -xzf upstream/jdk-23_linux-x64_bin.tar.gz
-
-  edit $REPO_HOME/tool_shared/bespoke/env, and update JAVA_HOME:
-
-  export JAVA_HOME="$REPO_HOME/tool_shared/third_party/jdk-23.0.1"
-
-
-3. Mosaic - for testing
-
-  > cd $REPO_HOME/tool_shared/third_party
-  > git clone https://github.com/Thomas-Walker-Lynch/Mosaic.git
-
-  edit $REPO_HOME/tool_shared/bespoke/env, and add Mosaic:
-
-    export MOSAIC_HOME="$REPO_HOME/tool_shared/third_party/Mosaic/release"
-
-
-  edit $REPO_HOME/tester/tool/env, and add Mosaic
-
-    export PATH=\
-    "$REPO_HOME"/tester/tool/\
-    :"$REPO_HOME"/tool_shared/bespoke/\
-    :"$JAVA_HOME"/bin\
-    :"$MOSAIC_HOME"\
-    :"$PATH"
-
-    export CLASSPATH=\
-    "$JAVA_HOME"/lib\
-    :"$MOSAIC_HOME"/Mosaic.jar\
-    :"$REPO_HOME"/release/"$PROJECT".jar\
-    :"$REPO_HOME"/tester/jvm/Test_"$PROJECT".jar\
-    :"$CLASSPATH"
-
-
-
-
diff --git a/tool_shared/documentđź–‰/Eclipse.txt b/tool_shared/documentđź–‰/Eclipse.txt
new file mode 100644 (file)
index 0000000..167d14e
--- /dev/null
@@ -0,0 +1,22 @@
+
+The project is originally configured to be used with Emacs as an IDE. The tools
+can all be run from a shell inside of emacs. Even when using an IDE what the
+shell environment scripts and tools do should be understood.
+
+I have added a working IntelliJ IDEA configuration, so if you want a modern IDE
+it is probably best to go with this. See ItelliJ_IDEA.txt in this directory.
+
+I've not run Eclipse on the project, if you do, perhaps you can update the notes
+here.  These things will probably increase your odds of making it work:
+  1. open a shell
+  2. cd to Ariadne, and source the env_developer
+  3. run the tool 'distribute_source'
+  3. run eclipse from the command line
+  4. give eclipse the 'scratchpad' directory as its source
+
+Be sure to run `release` after development to update what the tester sees.
+
+Do the analogous steps if you contribute as a 'tester'.  I.e. from
+the shell source env_tester instead. Also, you will need to add
+distribute_source to tester/tool, as it is currently not there.
+
diff --git a/tool_shared/documentđź–‰/Emacs.txt b/tool_shared/documentđź–‰/Emacs.txt
new file mode 100644 (file)
index 0000000..19398de
--- /dev/null
@@ -0,0 +1,45 @@
+
+System requirements:
+
+dnf install libX11-devel libXpm-devel libjpeg-devel libpng-devel libtiff-devel 
+dnf install gtk3-devel giflib-devel gnutls-devel
+dnf install ncurses-devel texinfo
+dnf install libacl-devel libattr-devel libgccjit libgccjit-devel
+
+# install and build script:
+
+cd "$REPO_HOME"/tool_shared/third_party
+mkdir -p emacs/{src,build,bin}
+
+# We sought stability, and now this. What can I say? It has 'visual-wrap-prefix-mode'.
+pushd upstream
+curl -L -O https://alpha.gnu.org/gnu/emacs/pretest/emacs-30.0.92.tar.xz
+popd
+
+tar -xf upstream/emacs-30.0.92.tar.xz -C emacs/src --strip-components=1
+
+# need to clear the environment
+env -i bash
+
+pushd emacs/src
+./configure --prefix="$REPO_HOME"/tool_shared/third_party/emacs
+
+  I gather this warning is unavaoidable?
+  "configure: WARNING: Your version of Gtk+ will have problems with"
+
+
+# replace nproc with number of processors:
+make -j$(nproc)
+
+# make install installs locally due to the `--prefix` option `./configure` above
+make install 
+make clean
+
+popd
+rm -r emacs/{src,build}
+
+# Find emacs in the emacs/in directory.  Be sure to add it to the path
+# in the tool_shared/bespoke/env file:
+#     PATH="$REPO_HOME/tool_shared/third_party/emacs/bin:$PATH"
+
+
diff --git a/tool_shared/documentđź–‰/IntelliJ_IDEA.txt b/tool_shared/documentđź–‰/IntelliJ_IDEA.txt
new file mode 100644 (file)
index 0000000..82b21cc
--- /dev/null
@@ -0,0 +1,252 @@
+This file describes the local install and configuration of IntelliJ_IDEA for
+the Ariadne project.
+
+The project was/is originally configured to be used with Emacs as an IDE. The tools
+can all be run from a shell inside of emacs. Even when using an IDE what the
+shell environment scripts and tools do should be understood.
+
+--------------------------------------------------------------------------------
+Some notes
+
+'project directory' - the directory with the .git file in it. Called $REPO_HOME in
+  RT scripts. Called $PROJECT_DIR$ (doesn't seem to be reliable) in IntelliJ
+  file paths.
+
+'module directory' - for RT projects examples include `~/Ariadne/developer' 
+  `~/Ariadne/tester`.  These are independent build environments.
+
+  Careful, if Intellij scans directories it will not hesitate to pull things
+  from `tool_shared`/third_party or wherever else it finds things, and it will
+  make a big mess.
+
+IntelliJ paths on forms:
+
+  I tried using $PROJECT_DIR$ as a variable standing for the project directory,
+  as this was suggested by an AI.  However IntelliJ simply made a directory
+  with the literal variable name. 
+
+  Also tried using $REPO_HOME, as that was defined in the environment IntelliJ was run from.
+  It had the same effect as $PROJECT_DIR$.
+
+  It will work with `~` for the home directory. So I have been using
+  `~/Ariadne/...` when typing out paths.
+
+  There will be a browser icon at the right of a form entry boxes that take
+  paths.  The browser tool starts from either /home or at / rather than at the
+  project.  It inserts absolute path names.
+
+A GUI bug:
+
+  There is a Gnome Linux bug where the drop down menu can stay on top no matter
+  what other window, application, or what virtual desktop a person is on.  You
+  must go back to the IDEA application window and hit <escape> to make it go
+  away.
+
+The [OK] button at the bottom of dialogs:
+
+   This closes the dialog.
+
+   To apply changes hit [Apply].
+
+   [OK] will not save what is on the dialog if [Apply] would fail, but
+   it still closes it.
+
+--------------------------------------------------------------------------------
+To install ItelliJ
+
+  Download the tar file from 
+    `https://www.jetbrains.com/idea/download/?section=linux` 
+  into the
+    `$REPO_HOME/tool_shared/third_party/upstream`
+   directory.
+
+  Expand it into 
+    `$REPO_HOME/tool_shared/third_party` 
+  
+  cd into the expanded directory, into `bin`, then `chmod u+x` and run `idea_inst`.
+
+  set the env path to include 
+    `$REPO_HOME/tool_shared/third_party/idea-IC*/bin`
+
+  The executable is called `idea`.
+
+  Consider setting a desktop short cut. Consider instead installing it in your
+  own bin directory. Easily done, just move the directory created by the tar
+  file expansion there.
+
+  I prefer a user mode install, as there is no reason this tool should need
+  admin privileges.
+
+--------------------------------------------------------------------------------
+Startup
+
+  ./tool_shared/third_party/idea-IC-243.21565.193/bin/idea &
+
+  Shows: Welcome screen
+    select "Open" as Ariadne already exists
+
+  Shows: Open File or Project Browser
+    In top dialog box put full path to project directory.
+
+    Hit [OK] at the bottom. Unlikely, but might be scrolled off the bottom of the screen.
+
+  Shows: main window
+     Appears after hitting OK from the "Open File or Project" [ok].
+
+     Has a tool bar at the top. There is a double meat hamburger menu icon
+     at the left. Hitting this will replace the top bar with a vertical
+     menu for drop down menus.
+
+     Careful, after the hamburger icon is pressed, the first drop down
+     menu instantly appears. Slide over to get the other drop downs.
+     Don't click, slide!
+
+     Under tool bar:
+       Far left is an icon bar.  Then a file browser.  And then a big box
+       describing hot keys.
+
+--------------------------------------------------------------------------------
+Configuration
+
+If you cloned the Ariadne project, the modules will already be configured, and
+also probably some of the run configuration will already be configured.
+
+  -------------
+  Setup Project
+  Hamburger icon > File dop-down > Project Structure > Project
+
+    select project SDK from disk:
+      ~/Ariadne/tool_shared/third_party/jdk-11
+
+  -------------
+  Setup Modules
+
+    Hamburger icon > File dop-down > Project Structure > Modules
+
+      Shows: "Project Structure" dialog
+
+       Hit the '+' option that shows at the top of the second panel.
+
+       New Module.
+
+       Dialog pop-up
+
+          Name: developer
+
+          Location: (browse to the developer directory)
+
+            alternatively enter the full path, ~/Ariadne, e.g.
+
+            $PROJECT_DIR$ instead of, ~/Ariadne, worked when
+            entering the first module, but not the second. 
+
+          Dependencies:
+            Select the "Project SDK" from the drop down.
+
+          Careful, the module won't be made until hitting [Create] at the bottom.
+
+          As far as I can tell you can't get this panel again, rather delete and add
+          a new module if you need to change the entries.
+
+      Shows: "Project Structure" dialog, again, now the third panel with information about the
+      developer module.
+          Third panel shows three choices:  [Source] [Paths] [Dependencies]
+
+          [Sources] is already selected.
+
+              With Sources there are two panels.
+
+              In second panel, on right side, the module root should show at the top.
+              Under if it lists any sources, use the button at the far right of the
+              listing to x it out.
+
+              The first panel now shows a file browser for the module.
+
+                Select the `javac` directory with a single click. Then, and only
+                after, look immediately the directory lists and click on [Sources] 
+
+                "Source Folders" will now appear in the second panel. The
+                javac folder will be listed.
+
+              hit: [apply] at the bottom (or the form will reset to defaults next time)
+
+
+          Slide over to [Paths]      
+              Copmiler Output
+                select [Use Module Compile Output Path]
+                   Output Path: $PROJECT_DIR$/developer/scratchpad
+                   Test Path: $PROJECT_DIR$/developer/test
+
+                   leave the exclude output checkbox, that means to exclude from repo
+                   and from indexing for search
+
+              hit: [apply] at the bottom
+
+  -------------
+  To add an external tool, for example tester/tool/make:
+
+  This is how we integrate the local tools.
+
+  Note, even if a shell script runs then runs a java program, that jave program
+  was compiled with debug flags, and run in debug mode, it can't be debugged.  It
+  won't stop at break points, etc. For that an 'application' must be added see
+  the next section.
+
+  Hamburger> Run > edit configurations
+  Shows Run/Debug configurations dialog
+     Upper left hit '+'
+     Shows drop down
+       chose [Shell Script] second from bottom
+       Shows dialog, for example:
+         Name: tester make
+         Script Path: ~/Ariadne/tester/tool/make  (better to chose with the browser tool)
+         Script Options: tester make
+         Working Directory: ~/Ariadne  (location of the env source scripts that env_run uses)
+         Environment variabls:  (none, env_run will source env_tester)
+         Interpreter: /bin/bash  (left to default)
+
+  -------------
+  To add a program for debugging.
+
+    Humburger > Run > edit configurations
+    Shows Run/Debug configurations dialog
+       Upper left hit '+'
+       Shows drop down
+         chose [Application] first choice
+         Shows dialog, for example:
+         Name: Test_Graph_0
+
+         next line are two boxes, they are not labeled, the defaults show:
+         [ module not specified ] [ -cp no module ]
+           I selected::
+           [ java 11 SDk of 'tester' module]  [ -cp tester ]
+             This can be confusing, as the modules are 'tester' and 'developer', but
+             here it asks for an SDK! Then the next box says it wants a class path,
+             but it wants a module name!
+
+         next line one box, not labeled
+         [ main class [] ]
+           Note icon at right, it will give a list of class names, here in the tester module,
+           that have main calls, select one.
+
+         next line, again not labeled
+         [ Program Arguments ]
+           Test_Graph_0 has no arguments so I left it blank.
+
+         Working Directory: ~/Ariadne
+
+         Environment Variables:
+           Left blank because the executable itself does not make use of any. I do
+           know at this point if variables set in the environment IDEA ran in are
+           inherited.
+
+         'Modify Options' with a drop down menu. (At the top right of the configuration dialog)
+           Scan down for the `Java` section.
+           Check: 'Do not build before run'
+             (To build this example, go to the Run menu and run `tester make'. Or run make directly
+             from a console prompt. Be sure to source env_tester first.)
+
+    Next go to main window file browser, click on the file you want to debug, click on the line
+    to set a break point. Right click to get a menu, and 
+
diff --git a/tool_shared/documentđź–‰/install.txt b/tool_shared/documentđź–‰/install.txt
new file mode 100644 (file)
index 0000000..1e387cb
--- /dev/null
@@ -0,0 +1,67 @@
+----------------------------------------
+env_administrator
+
+For mucking around with the tools install and config, cd to the top of
+the project and source the env_administrator environment.
+
+  git clone <project>
+  cd project
+  source env_administrator
+
+----------------------------------------
+RT-project-share 
+
+This pulls in documents and commonly used scripts. The project has symbolic links
+into RT-icommon, so this is not optional.
+
+  cd "$REPO_HOME/tool_shared/third_party/"
+  git clone https://github.com/Thomas-Walker-Lynch/RT-project-share.git
+
+  note this link should already be present:
+    ln -s "$REPO_HOME/tool_shared/third_party/resource/document" see_also
+
+----------------------------------------
+jdk-23
+
+  cd "$REPO_HOME/tool_shared/third_party/upstream"
+
+  # source for the 11 version used before, now upgraded to 23
+  #curl -C - -o OpenJDK11U-jdk_x64_linux_hotspot_11.0.16_8.tar.gz https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.16+8/OpenJDK11U-jdk_x64_linux_hotspot_11.0.16_8.tar.gz
+  curl -L -C - -b "oraclelicense=accept-securebackup-cookie" -O https://download.oracle.com/java/23/latest/jdk-23_linux-x64_bin.tar.gz
+
+  cd ..
+  tar -xzf upstream/jdk-23_linux-x64_bin.tar.gz
+
+  edit $REPO_HOME/tool_shared/bespoke/env, and update JAVA_HOME:
+    export JAVA_HOME="$REPO_HOME/tool_shared/third_party/jdk-23.0.1"
+
+
+----------------------------------------
+Mosaic - for testing
+
+  > cd $REPO_HOME/tool_shared/third_party
+  > git clone https://github.com/Thomas-Walker-Lynch/Mosaic.git
+
+ This will have already been done:
+
+    $REPO_HOME/tool_shared/bespoke/env will have:
+       export MOSAIC_HOME="$REPO_HOME/tool_shared/third_party/Mosaic/release"
+
+    $REPO_HOME/tester/tool/env, will have Mosaic
+
+    export PATH=\
+    "$REPO_HOME"/tester/tool/\
+    :"$JAVA_HOME"/bin\
+    :"$MOSAIC_HOME"\
+    :"$PATH"
+
+    export CLASSPATH=\
+    "$JAVA_HOME"/lib\
+    :"$MOSAIC_HOME"/Mosaic.jar\
+    :"$REPO_HOME"/release/"$PROJECT".jar\
+    :"$REPO_HOME"/tester/jvm/Test_"$PROJECT".jar\
+    :"$CLASSPATH"
+
+
+
+
diff --git a/toolđź–‰/env b/toolđź–‰/env
new file mode 100644 (file)
index 0000000..4f0c70f
--- /dev/null
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+script_afp=$(realpath "${BASH_SOURCE[0]}")
+
+# input guards
+
+  env_must_be="tool_shared/bespoke/env"
+  error=false
+  if [ "$ENV" != "$env_must_be" ]; then
+    echo "$(script_fp):: error: must be run in the $env_must_be environment"
+    error=true
+  fi
+  if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
+    echo "$script_afp:: This script must be sourced, not executed."
+    error=true
+  fi
+  if $error; then exit 1; fi
+
+export PATH=\
+"$REPO_HOME"/tool_shared/bespoke/\
+:"$PATH"
+
+# expose sneaky hidden files
+alias ls="ls -a"
+
+# some feedback to show all went well
+
+  export PROMPT_DECOR="$PROJECT"_administrator
+  export ENV=$(script_fp)
+  echo ENV "$ENV"