From d53e24567ed4d4bcf0c6b3c84101dfe541122502 Mon Sep 17 00:00:00 2001
From: Kia <kia@special-circumstanc.es>
Date: Sun, 16 Aug 2020 18:42:37 -0600
Subject: [PATCH] there was an off-by-one that somehow managed to morph into an
 off-by-two

---
 cfg_utils.py | 56 ++++++++++++++++++++++++++++++++--------------------
 1 file changed, 35 insertions(+), 21 deletions(-)

diff --git a/cfg_utils.py b/cfg_utils.py
index 5e79b7b..064f7b1 100644
--- a/cfg_utils.py
+++ b/cfg_utils.py
@@ -383,7 +383,7 @@ class CFGBoltzmann:
             rulepack_list.append((x, factorized_rulepack[x]))
             list_of_terminals_in_sync_with_rulepack.append(x)
         self.nonterminals_ordered = list_of_terminals_in_sync_with_rulepack
-        print("ORDERED nonterminal list is", self.nonterminals_ordered)
+ #       print("ORDERED nonterminal list is", self.nonterminals_ordered)
 
         self.processed_rulepack = rulepack_list
 
@@ -396,15 +396,15 @@ class CFGBoltzmann:
         # First find the nonterminal in the rulepack
 
         possible_RHSes = self.processed_rulepack[nonterminal_index][1]
-        print(possible_RHSes)
+      #  print(possible_RHSes)
         assert(possible_RHSes != [])
 
         retlist = []
 
         for rhs_index in range(len(possible_RHSes)):
-            print(rhs_index)
+            print("IN Fzero, trying rhs_index", rhs_index)
             retlist.append(sum(self.Fprim(nonterminal_index, rhs_index, 0, exact_length_total))) # we index arrays starting at zero. like everyone else.
-
+        print ("Fzero returns", retlist)
         return retlist
 
 
@@ -412,50 +412,62 @@ class CFGBoltzmann:
     # Fprim is where the complicated case analysis lives.
 
     def Fprim(self, nonterminal_index, which_RHS, how_far_into_the_RHS, exact_length_total):
-        print("arguments are", nonterminal_index, which_RHS, how_far_into_the_RHS, exact_length_total)
+        #print("arguments are", nonterminal_index, which_RHS, how_far_into_the_RHS, exact_length_total)
 
         # first, handle the ultimate degenerate case:
         if (exact_length_total == 0):
+            print("LENGTH ZERO RETURNING []")
             return []
 
         # The case analysis hinges on what is at X_ijk.
 
         RHS_in_question = self.processed_rulepack[nonterminal_index][1][which_RHS]
-        print(RHS_in_question)
+        print("Our RHS is", RHS_in_question)
+        print("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]
 
         if (xijk in self.terminals):
-            print("xijk", xijk, "is a terminal, hokay")
-            print("lenghts of RHS In question is", len(RHS_in_question))
+         #   print("xijk", xijk, "is a terminal, hokay")
+        #    print("lenghts of RHS In question is", len(RHS_in_question))
 
             # are we at the end of the rule
             if (how_far_into_the_RHS == (len(RHS_in_question) - 1)):
                 # CASE A
                 if (exact_length_total == 1):
+                    print("CASE A LEN 1")
+                    print ("Fprim returns SPECIAL CASE", [1])
                     return [1]
                 else:
+                    print("CASE A LEN NON-ONE")
+                    print ("Fprim returns BAD SPECIAL CASE", [0])
                     return [0]
             else:
                 # CASE B
+                print("CASE B")
                 reduct = self.Fprim(nonterminal_index, which_RHS, how_far_into_the_RHS + 1, exact_length_total - 1)
-                return [sum(reduct)]
+                retlist = [sum(reduct)]
+                print ("Fprim returns", retlist)
+
+                return retlist
 
 
         else:
             assert (xijk in self.nonterminals)
-            print("xijk", xijk, "is a NONterminal!")
-            print("lenghts of RHS In question is", len(RHS_in_question))
-
-            # we now calculate the index of nonterminal at index K, we need it for both cases
+       #     print("xijk", xijk, "is a NONterminal!")
+       #     print("lenghts of RHS In question is", len(RHS_in_question))
+            #print("how far?", how_far_into_the_RHS)
+            ## we now calculate the index of nonterminal at index K, we need it for both cases
             new_nonterminal_index = self.nonterminals_ordered.index(xijk)
-            print("NEW NONTERMINAL INDDEX IS", new_nonterminal_index)
+           # print("NEW NONTERMINAL INDDEX IS", new_nonterminal_index)
 
             if (how_far_into_the_RHS == (len(RHS_in_question) - 1)):
                 # CASE C
+                print("CASE C")
                 reduct = self.Fzero(new_nonterminal_index, exact_length_total)
-
-                return [sum(reduct)]
+                retlist = [sum(reduct)]
+                print ("Fprim returns", retlist)
+                return retlist
 
             else:
                 # CASE D
@@ -473,15 +485,17 @@ class CFGBoltzmann:
                 # But T_ij is the INDEX of the last element of the rule, aka len(rule)-1
                 # so the expression is
                 # Total Characters Requested - (len(rule)-k-1)
-                # exact_length_total - len(rule) - how_far_into_the_RHS - 1
+                # exact_length_total - len(rule) + how_far_into_the_RHS + 1
 
-                # in the range() call we lop off the "-1" because we want to be inclusive and range gives us [)
-                # bounds. Phantasmagoria of off-by-ones here we go! 
+                print("CASE D")
                 retlist = []
-                for l in range(1, exact_length_total - len(RHS_in_question) - how_far_into_the_RHS):
+                print(exact_length_total - len(RHS_in_question) + how_far_into_the_RHS + 2)
+                for l in range(1, exact_length_total - len(RHS_in_question) + how_far_into_the_RHS + 2):
+                    print("L IS", l)
                     nonterminal_possibilities = sum(self.Fzero(new_nonterminal_index, l))
                     remainder_possibilities   = sum(self.Fprim(nonterminal_index, which_RHS, how_far_into_the_RHS + 1, exact_length_total - l))
                     retlist.append(nonterminal_possibilities * remainder_possibilities)
+                print ("Fprim returns", retlist)
                 return retlist
 
 z = CFGBoltzmann(rules, list_of_nonterminals, list_of_terminals)
@@ -489,7 +503,7 @@ z = CFGBoltzmann(rules, list_of_nonterminals, list_of_terminals)
 rulepack_cooked = z.preprocessor()
 
 
-z.Fzero(1, 42)
+print("XXXXXXXXXXXXXXXX", z.Fzero(0, 13))
 
 
 # Furthermore, we also note that the description of a context-free grammar is *itself* context-free
-- 
GitLab