From cedbf7f81569e38c3d45a6f34011e76673fbadae Mon Sep 17 00:00:00 2001
From: Kia <kia@special-circumstanc.es>
Date: Mon, 17 Aug 2020 18:51:19 -0600
Subject: [PATCH] prepared instrumentation for tracing the mutual recursions to
 investigate this bug (which looks suspiciously like a highly elaborate
 off-by-one)

---
 cfg_utils.py | 46 ++++++++++++++++++++++++++++------------------
 1 file changed, 28 insertions(+), 18 deletions(-)

diff --git a/cfg_utils.py b/cfg_utils.py
index b09f493..b010e2f 100644
--- a/cfg_utils.py
+++ b/cfg_utils.py
@@ -519,10 +519,14 @@ class CFGBoltzmann:
     # select (weighted appropriately) which production rule for a nonterminal will
     # be used. It then calls out to GPrim, which actually generates the string.
 
-    def Gzero(self, nonterminal_index, requested_length):
+    def Gzero_shimmed(self, nonterminal, requested_length):
+        nonterminal_index = self.nonterminals_ordered.index(nonterminal)
+        return self.Gzero(nonterminal_index, requested_length, 0)
+    def Gzero(self, nonterminal_index, requested_length, depth):
+        print("    "* depth +"ENTERING Gzero")
         possibilities = self.Fzero(nonterminal_index, requested_length)
         chosen_production = self.normalized_choice(possibilities)
-        generated_string = self.Gprim(nonterminal_index, chosen_production, 0, requested_length)
+        generated_string = self.Gprim(nonterminal_index, chosen_production, 0, requested_length, depth)
 
         return generated_string
 
@@ -561,19 +565,19 @@ class CFGBoltzmann:
     #                        \----------------------------------------------------------/
 
 
-    def Gprim(self, nonterminal_index, chosen_production, how_far_into_the_RHS, exact_length_total):
-        print("GPRIM arguments are", nonterminal_index, chosen_production, how_far_into_the_RHS, exact_length_total)
+    def Gprim(self, nonterminal_index, chosen_production, how_far_into_the_RHS, exact_length_total, depth):
+        print("    "* depth + "GPRIM arguments are", nonterminal_index, chosen_production, how_far_into_the_RHS, exact_length_total)
 
         # first, handle the ultimate degenerate case:
         if (exact_length_total == 0):
-            print("LENGTH ZERO RETURNING []")
+            print("    "* depth +"XXXXXXXXXXXXXXXXXXX LENGTH ZERO RETURNING []")
             return []
 
         # The case analysis hinges on what is at X_ijk.
 
         RHS_in_question = self.processed_rulepack[nonterminal_index][1][chosen_production]
-        print("Our RHS is", RHS_in_question)
-        print("WE ARE PROCESSING index", how_far_into_the_RHS, "and our remaining lengthis", exact_length_total)
+        print("    "* depth +"Our RHS is", RHS_in_question)
+        print("    "* depth +"WE ARE PROCESSING index", how_far_into_the_RHS, "and our remaining lengthis", exact_length_total)
 
         xijk = RHS_in_question[how_far_into_the_RHS]
 
@@ -584,13 +588,14 @@ class CFGBoltzmann:
             # are we at the end of the rule
             if (how_far_into_the_RHS == (len(RHS_in_question) - 1)):
                 # CASE A
-                print("GPRIM CASE A ")
+                print("    "* depth +"GPRIM CASE A RETURNING", [xijk])
                 return [xijk]
             else:
                 # CASE B
-                print("CASE B")
-                reduct = self.Gprim(nonterminal_index, chosen_production, how_far_into_the_RHS + 1, exact_length_total - 1)
+                print("    "* depth +"GPRIM CASE B pointing @", [xijk])
+                reduct = self.Gprim(nonterminal_index, chosen_production, how_far_into_the_RHS + 1, exact_length_total - 1, depth+1)
                 retstring = [xijk] + reduct
+                print("    "* depth +"GPRIM CASE B RETURNING", retstring)
                 return retstring
 
 
@@ -605,29 +610,35 @@ class CFGBoltzmann:
 
             if (how_far_into_the_RHS == (len(RHS_in_question) - 1)):
                 # CASE C
-                print("CASE C")
-                retstring = self.Gzero(new_nonterminal_index, exact_length_total)
+                print("    "* depth +"CASE C STARTING")
+                retstring = self.Gzero(new_nonterminal_index, exact_length_total, depth+1)
+                print("    "* depth +"CASE C returning", retstring)
                 return retstring
 
             else:
                 # CASE D
 
-                print("CASE D")
+                print("    "* depth +"CASE D STARTING")
 
 
                 splitting_possibilities = self.Fprim(nonterminal_index, chosen_production, how_far_into_the_RHS, exact_length_total)
+                print ("    "* depth +"CASE D; SPLIT POSSIBILITIES ARE", splitting_possibilities)
+
                 split_choice = self.normalized_choice(splitting_possibilities)
+                print ("    "* depth +"CASE D; SPLITTING WITH LENGTH", split_choice)
 
                 # hit the nonterminal X_ijk with Gzero
 
-                nonterminal_generates = self.Gzero(new_nonterminal_index, split_choice)
+                nonterminal_generates = self.Gzero(new_nonterminal_index, split_choice, depth+1)
+                print ("    "* depth +"CASE D NONTERMINAL @ XIJK generates", nonterminal_generates)
 
                 # and then the remaining part of the rule
 
-                rest_of_rule_generates = self.Gprim(nonterminal_index, chosen_production, how_far_into_the_RHS + 1, exact_length_total - split_choice)
+                rest_of_rule_generates = self.Gprim(nonterminal_index, chosen_production, how_far_into_the_RHS + 1, exact_length_total - split_choice, depth+1)
+                print ("CASE D REST OF RULE generates", rest_of_rule_generates)
 
                 retstring = nonterminal_generates + rest_of_rule_generates
-                print ("Gprim returns", retstring)
+                print ("    "* depth +"CASE D RETURNING", retstring)
                 return retstring
 
 
@@ -640,8 +651,7 @@ z = CFGBoltzmann(rules, list_of_nonterminals, list_of_terminals)
 rulepack_cooked = z.preprocessor()
 
 
-print("XXXXXXXXXXXXXXXX", z.Gzero(0, 5))
-
+print("XXXXXXXXXXXXXXXX", z.Gzero_shimmed(nonterminals.EXPRESSION, 11))
 
 # Furthermore, we also note that the description of a context-free grammar is *itself* context-free
 # so if we take the CFG-description grammar (BNF or something isomorphic to it), and use Boltzmann
-- 
GitLab