refactor(truth-table): translate Estonian names and add regression harness
authorSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Sat, 26 Sep 2026 12:38:26 +0000 (15:38 +0300)
committerSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Sat, 26 Sep 2026 12:38:26 +0000 (15:38 +0300)
- truth.bas: second readability pass — translate remaining Estonian
  identifiers (sist/lahend/tee/teeslg/lend/mov, tehl/nm/muu/prnp) into
  descriptive English, add per-SUB description headers, document the
  operator encoding (CHR$(1..5), t/v as tosi/vaar constants) and mark
  the dead 2002-era code (removeRedundancies, drainKeyboardBuffer,
  xlahn). Algorithm, labels and GOTOs unchanged.
- Tests/: GameDriver-based regression harness — drives the program in
  crtbasic for 19 formulas, verifies truth columns against an
  independent Python oracle and byte-diffs full 8x8-cell text dumps
  against the baselines in expected/. Validated pixel-identical
  against real QB45 in DOSBox.

22 files changed:
Math/Truth table/Tests/expected/and.txt [new file with mode: 0644]
Math/Truth table/Tests/expected/chain-4var.txt [new file with mode: 0644]
Math/Truth table/Tests/expected/constants.txt [new file with mode: 0644]
Math/Truth table/Tests/expected/double-not.txt [new file with mode: 0644]
Math/Truth table/Tests/expected/equiv-chain.txt [new file with mode: 0644]
Math/Truth table/Tests/expected/equiv.txt [new file with mode: 0644]
Math/Truth table/Tests/expected/example.txt [new file with mode: 0644]
Math/Truth table/Tests/expected/five-var.txt [new file with mode: 0644]
Math/Truth table/Tests/expected/implies-chain.txt [new file with mode: 0644]
Math/Truth table/Tests/expected/implies.txt [new file with mode: 0644]
Math/Truth table/Tests/expected/mixed-andor.txt [new file with mode: 0644]
Math/Truth table/Tests/expected/nested-parens.txt [new file with mode: 0644]
Math/Truth table/Tests/expected/not-and.txt [new file with mode: 0644]
Math/Truth table/Tests/expected/not-implies.txt [new file with mode: 0644]
Math/Truth table/Tests/expected/not-in-parens.txt [new file with mode: 0644]
Math/Truth table/Tests/expected/not-paren-and.txt [new file with mode: 0644]
Math/Truth table/Tests/expected/not.txt [new file with mode: 0644]
Math/Truth table/Tests/expected/or.txt [new file with mode: 0644]
Math/Truth table/Tests/expected/repeated-var.txt [new file with mode: 0644]
Math/Truth table/Tests/formulas.txt [new file with mode: 0644]
Math/Truth table/Tests/run_tests.py [new file with mode: 0644]
Math/Truth table/truth.bas

diff --git a/Math/Truth table/Tests/expected/and.txt b/Math/Truth table/Tests/expected/and.txt
new file mode 100644 (file)
index 0000000..e40a247
--- /dev/null
@@ -0,0 +1,60 @@
+ab                                                                             
+tttt                                                                            
+tvvv                                                                            
+vvtv                                                                            
+vvvv                                                                            
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
diff --git a/Math/Truth table/Tests/expected/chain-4var.txt b/Math/Truth table/Tests/expected/chain-4var.txt
new file mode 100644 (file)
index 0000000..4866ef4
--- /dev/null
@@ -0,0 +1,60 @@
+abcd                                                                         
+tttttttt                                                                        
+tttttvvv                                                                        
+ttttvttt                                                                        
+ttttvvvv                                                                        
+ttvttttt                                                                        
+ttvttvvv                                                                        
+tvvvvvtv                                                                        
+tvvvvtvt                                                                        
+vttttttt                                                                        
+vttttvvv                                                                        
+vtttvttt                                                                        
+vtttvvvv                                                                        
+vtvttttt                                                                        
+vtvttvvv                                                                        
+vtvvvttt                                                                        
+vtvvvvvv                                                                        
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
diff --git a/Math/Truth table/Tests/expected/constants.txt b/Math/Truth table/Tests/expected/constants.txt
new file mode 100644 (file)
index 0000000..7fbbe51
--- /dev/null
@@ -0,0 +1,60 @@
+tav                                                                           
+ttttvt                                                                          
+tvvvvv                                                                          
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
diff --git a/Math/Truth table/Tests/expected/double-not.txt b/Math/Truth table/Tests/expected/double-not.txt
new file mode 100644 (file)
index 0000000..fcccac3
--- /dev/null
@@ -0,0 +1,60 @@
+(a)                                                                           
+t vt t                                                                          
+v tv v                                                                          
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
diff --git a/Math/Truth table/Tests/expected/equiv-chain.txt b/Math/Truth table/Tests/expected/equiv-chain.txt
new file mode 100644 (file)
index 0000000..de5d79b
--- /dev/null
@@ -0,0 +1,60 @@
+abc                                                                           
+tttttt                                                                          
+tttvvv                                                                          
+tvvvtv                                                                          
+tvvtvt                                                                          
+vvtvtv                                                                          
+vvttvt                                                                          
+vtvttt                                                                          
+vtvvvv                                                                          
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
diff --git a/Math/Truth table/Tests/expected/equiv.txt b/Math/Truth table/Tests/expected/equiv.txt
new file mode 100644 (file)
index 0000000..bc89cb2
--- /dev/null
@@ -0,0 +1,60 @@
+ab                                                                             
+tttt                                                                            
+tvvv                                                                            
+vvtv                                                                            
+vtvt                                                                            
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
diff --git a/Math/Truth table/Tests/expected/example.txt b/Math/Truth table/Tests/expected/example.txt
new file mode 100644 (file)
index 0000000..330755a
--- /dev/null
@@ -0,0 +1,60 @@
+ab(gb)                                                                       
+tttt ttt t                                                                      
+tttt vtt t                                                                      
+ttvt ttv t                                                                      
+ttvt vvv t                                                                      
+vvtt ttt v                                                                      
+vvtt vtt v                                                                      
+vvvt ttv v                                                                      
+vvvt vvv v                                                                      
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
diff --git a/Math/Truth table/Tests/expected/five-var.txt b/Math/Truth table/Tests/expected/five-var.txt
new file mode 100644 (file)
index 0000000..fbe6ecf
--- /dev/null
@@ -0,0 +1,60 @@
+abcde                                                                       
+tttttttttt                                                                      
+tttttttvvv                                                                      
+tttttvvvtv                                                                      
+tttttvvtvt                                                                      
+tttvvttttt                                                                      
+tttvvttvvv                                                                      
+tttvvtvttt                                                                      
+tttvvtvvvv                                                                      
+ttvttttttt                                                                      
+ttvttttvvv                                                                      
+ttvttvvvtv                                                                      
+ttvttvvtvt                                                                      
+ttvvvttttt                                                                      
+ttvvvttvvv                                                                      
+ttvvvtvttt                                                                      
+ttvvvtvvvv                                                                      
+vttttttttt                                                                      
+vttttttvvv                                                                      
+vttttvvvtv                                                                      
+vttttvvtvt                                                                      
+vttvvttttt                                                                      
+vttvvttvvv                                                                      
+vttvvtvttt                                                                      
+vttvvtvvvv                                                                      
+vvvvtttttt                                                                      
+vvvvtttvvv                                                                      
+vvvvttvttt                                                                      
+vvvvttvvvv                                                                      
+vvvvvttttt                                                                      
+vvvvvttvvv                                                                      
+vvvvvtvttt                                                                      
+vvvvvtvvvv                                                                      
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
diff --git a/Math/Truth table/Tests/expected/implies-chain.txt b/Math/Truth table/Tests/expected/implies-chain.txt
new file mode 100644 (file)
index 0000000..685f838
--- /dev/null
@@ -0,0 +1,60 @@
+abc                                                                           
+tttttt                                                                          
+tttvvv                                                                          
+tvvttt                                                                          
+tvvtvt                                                                          
+vttttt                                                                          
+vttvvv                                                                          
+vtvttt                                                                          
+vtvvvv                                                                          
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
diff --git a/Math/Truth table/Tests/expected/implies.txt b/Math/Truth table/Tests/expected/implies.txt
new file mode 100644 (file)
index 0000000..bc6521e
--- /dev/null
@@ -0,0 +1,60 @@
+ab                                                                             
+tttt                                                                            
+tvvv                                                                            
+vttt                                                                            
+vtvt                                                                            
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
diff --git a/Math/Truth table/Tests/expected/mixed-andor.txt b/Math/Truth table/Tests/expected/mixed-andor.txt
new file mode 100644 (file)
index 0000000..43fb724
--- /dev/null
@@ -0,0 +1,60 @@
+abc                                                                           
+tttttt                                                                          
+ttttvt                                                                          
+tvvttt                                                                          
+tvvvvv                                                                          
+vvtttt                                                                          
+vvtvvv                                                                          
+vvvttt                                                                          
+vvvvvv                                                                          
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
diff --git a/Math/Truth table/Tests/expected/nested-parens.txt b/Math/Truth table/Tests/expected/nested-parens.txt
new file mode 100644 (file)
index 0000000..451a27e
--- /dev/null
@@ -0,0 +1,60 @@
+((ab)(ca))                                                                   
+  ttt t ttt  t                                                                  
+  ttt t vtt  t                                                                  
+  tvv t ttt  t                                                                  
+  tvv t vtt  t                                                                  
+  vvt t ttv  t                                                                  
+  vvt t vvv  t                                                                  
+  vvv t ttv  t                                                                  
+  vvv t vvv  t                                                                  
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
diff --git a/Math/Truth table/Tests/expected/not-and.txt b/Math/Truth table/Tests/expected/not-and.txt
new file mode 100644 (file)
index 0000000..257ef5a
--- /dev/null
@@ -0,0 +1,60 @@
+ab                                                                            
+vtvtv                                                                           
+vtvvv                                                                           
+tvttt                                                                           
+tvvvv                                                                           
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
diff --git a/Math/Truth table/Tests/expected/not-implies.txt b/Math/Truth table/Tests/expected/not-implies.txt
new file mode 100644 (file)
index 0000000..2b9467c
--- /dev/null
@@ -0,0 +1,60 @@
+ab                                                                            
+vtttt                                                                           
+vttvt                                                                           
+tvttt                                                                           
+tvvvv                                                                           
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
diff --git a/Math/Truth table/Tests/expected/not-in-parens.txt b/Math/Truth table/Tests/expected/not-in-parens.txt
new file mode 100644 (file)
index 0000000..608c338
--- /dev/null
@@ -0,0 +1,60 @@
+(ab)c                                                                        
+ tvvt ttt                                                                       
+ tvvt vvv                                                                       
+ tttv ttt                                                                       
+ tttv tvt                                                                       
+ vvvt ttt                                                                       
+ vvvt vvv                                                                       
+ vvtv ttt                                                                       
+ vvtv vvv                                                                       
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
diff --git a/Math/Truth table/Tests/expected/not-paren-and.txt b/Math/Truth table/Tests/expected/not-paren-and.txt
new file mode 100644 (file)
index 0000000..27fa18f
--- /dev/null
@@ -0,0 +1,60 @@
+(ab)c                                                                        
+v ttt vtv                                                                       
+v ttt vvv                                                                       
+v ttv vtv                                                                       
+v ttv vvv                                                                       
+v vtt vtv                                                                       
+v vtt vvv                                                                       
+t vvv ttt                                                                       
+t vvv vvv                                                                       
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
diff --git a/Math/Truth table/Tests/expected/not.txt b/Math/Truth table/Tests/expected/not.txt
new file mode 100644 (file)
index 0000000..332bc61
--- /dev/null
@@ -0,0 +1,60 @@
+a                                                                              
+vtv                                                                             
+tvt                                                                             
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
diff --git a/Math/Truth table/Tests/expected/or.txt b/Math/Truth table/Tests/expected/or.txt
new file mode 100644 (file)
index 0000000..f570f8a
--- /dev/null
@@ -0,0 +1,60 @@
+ab                                                                             
+tttt                                                                            
+ttvt                                                                            
+vttt                                                                            
+vvvv                                                                            
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
diff --git a/Math/Truth table/Tests/expected/repeated-var.txt b/Math/Truth table/Tests/expected/repeated-var.txt
new file mode 100644 (file)
index 0000000..3ab3c7d
--- /dev/null
@@ -0,0 +1,60 @@
+aaa                                                                           
+tttttt                                                                          
+vvvvvv                                                                          
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
+                                                                                
diff --git a/Math/Truth table/Tests/formulas.txt b/Math/Truth table/Tests/formulas.txt
new file mode 100644 (file)
index 0000000..9d8d20c
--- /dev/null
@@ -0,0 +1,21 @@
+# name<TAB>formula as typed on the keyboard (digits 1-5 = operator keys:
+# 1 equivalent, 2 implies, 3 or, 4 and, 5 not)
+and    a4b
+or     a3b
+implies        a2b
+equiv  a1b
+not    5a
+not-and        5a4b
+not-implies    5a2b
+example        a1b2(g3b)
+not-paren-and  5(a3b)4c
+chain-4var     a2b3c1d
+nested-parens  ((a4b)2(c3a))
+constants      t4a3v
+repeated-var   a4a3a
+five-var       a3b4c2d1e
+double-not     5(5a)
+not-in-parens  (a45b)3c
+mixed-andor    a4b3c
+implies-chain  a2b2c
+equiv-chain    a1b1c
diff --git a/Math/Truth table/Tests/run_tests.py b/Math/Truth table/Tests/run_tests.py
new file mode 100644 (file)
index 0000000..a18bdfb
--- /dev/null
@@ -0,0 +1,263 @@
+#!/usr/bin/env python3
+"""Regression + oracle test harness for truth.bas (Truth table calculator).
+
+How it works:
+  1. For every formula in formulas.txt the harness drives the .bas program
+     in crtbasic's headless GameDriver: it types the formula, presses Enter,
+     waits for the computation, takes a *text dump* of the graphics screen
+     (GameDriver --textdump recognizes the 8x8 font cells), satisfies the
+     closing INPUT$(1) with 'x' and quits with ESC.
+  2. Oracle check: an independent Python implementation of the program's
+     logic (same operator semantics: NOT tightest, AND/OR equal precedence
+     left-associative, then IMPLIES, then EQUIV; 't'/'v' are true/false
+     constants, not variables) recomputes every variable column and the
+     final result column and compares them against the dump.
+  3. Regression check: the full 80x60 text dump is diffed byte-for-byte
+     against the baseline recorded in expected/ from the original program.
+     Readability improvements must not change a single pixel.
+
+Usage:
+  run_tests.py --record          # record baselines from the CURRENT truth.bas
+  run_tests.py                   # check truth.bas against baselines + oracle
+  run_tests.py --bas PATH        # test a different .bas file
+"""
+
+import subprocess
+import sys
+import tempfile
+from pathlib import Path
+
+HERE = Path(__file__).resolve().parent
+DEFAULT_BAS = HERE.parent / "truth.bas"
+FORMULAS = HERE / "formulas.txt"
+EXPECTED = HERE / "expected"
+CRTBASIC = Path("/home/n0/workspace/svjatoslav/crtbasic")
+DRIVER_CP = "target/classes:target/test-classes"
+DRIVER_CLASS = "eu.svjatoslav.crtbasic.drivers.GameDriver"
+
+# Key script template: type formula, Enter, settle, $ = dump screen,
+# 'x' satisfies INPUT$(1), ESC quits the menu (SYSTEM).
+KEYS_TEMPLATE = "{formula}\n~~$~x~\x1b"
+
+OP_NAMES = {"1": "EQUIV", "2": "IMPLIES", "3": "OR", "4": "AND", "5": "NOT"}
+
+
+# ---------------------------------------------------------------- oracle --
+
+class Parser:
+    """Recursive-descent parser mirroring the program's operator semantics."""
+
+    def __init__(self, text: str):
+        self.tokens = list(text)
+        self.pos = 0
+
+    def peek(self) -> str:
+        return self.tokens[self.pos] if self.pos < len(self.tokens) else ""
+
+    def take(self) -> str:
+        tok = self.tokens[self.pos]
+        self.pos += 1
+        return tok
+
+    def parse_equiv(self):
+        node = self.parse_implies()
+        while self.peek() == "1":
+            self.take()
+            node = ("equiv", node, self.parse_implies())
+        return node
+
+    def parse_implies(self):
+        node = self.parse_andor()
+        while self.peek() == "2":
+            self.take()
+            node = ("implies", node, self.parse_andor())
+        return node
+
+    def parse_andor(self):
+        node = self.parse_operand()
+        while self.peek() in ("3", "4"):
+            op = "or" if self.take() == "3" else "and"
+            node = (op, node, self.parse_operand())
+        return node
+
+    def parse_operand(self):
+        tok = self.peek()
+        if tok == "5":
+            self.take()
+            return ("not", self.parse_operand())
+        if tok == "(":
+            self.take()
+            node = self.parse_equiv()
+            assert self.take() == ")", "missing closing paren"
+            return node
+        self.take()
+        return ("var", tok)
+
+
+def evaluate(node, values: dict) -> bool:
+    kind = node[0]
+    if kind == "var":
+        name = node[1]
+        if name == "t":
+            return True
+        if name == "v":
+            return False
+        return values[name]
+    if kind == "not":
+        return not evaluate(node[1], values)
+    left, right = evaluate(node[1], values), evaluate(node[2], values)
+    if kind == "and":
+        return left and right
+    if kind == "or":
+        return left or right
+    if kind == "implies":
+        return (not left) or right
+    if kind == "equiv":
+        return left == right
+    raise ValueError(kind)
+
+
+def variables_of(formula: str) -> list:
+    """Distinct variables in first-appearance order; t/v are constants."""
+    names = []
+    for ch in formula:
+        if ch.isalpha() and ch not in ("t", "v") and ch not in names:
+            names.append(ch)
+    return names
+
+
+def combo_values(names: list, row: int) -> dict:
+    """Variable values for combo row (1-based), mirroring lahend():
+    variable i (1-based) flips every 2**(nm-i) rows, starting at true."""
+    nm = len(names)
+    values = {}
+    for i, name in enumerate(names):
+        block = 2 ** (nm - i - 1)
+        values[name] = ((row - 1) // block) % 2 == 0
+    return values
+
+
+def oracle_check(name: str, formula: str, dump: str) -> list:
+    """Compare variable columns and the result column against the oracle."""
+    errors = []
+    stripped = formula.replace(" ", "")
+    names = variables_of(formula)
+    var_columns = [(i, ch) for i, ch in enumerate(stripped) if ch in names]
+    rows = dump.split("\n")
+    ast = Parser(stripped).parse_equiv()
+    combos = 2 ** len(names)
+    for row in range(1, combos + 1):
+        if row >= len(rows):
+            errors.append(f"{name}: dump has no row {row}")
+            break
+        line = rows[row]
+        values = combo_values(names, row)
+        for col, ch in var_columns:
+            want = "t" if values[ch] else "v"
+            got = line[col] if col < len(line) else "?"
+            if got != want:
+                errors.append(
+                    f"{name} row {row} col {col} (variable {ch}): want {want}, got {got!r}")
+        # The result column is the rightmost t/v cell in the row. Its
+        # position shifts right by the number of parentheses teeslg
+        # inserted: truth.bas DECLAREs teeslg's second parameter as x2
+        # while the SUB itself names it x4, and crtbasic registers one
+        # cell under both names, so teeslg's x2 writes land in lahend's
+        # x2. The column is located, not computed.
+        result_col = max(line.rfind("t"), line.rfind("v"))
+        if result_col < 0:
+            errors.append(f"{name} row {row}: no result cell found")
+            continue
+        want = "t" if evaluate(ast, values) else "v"
+        got = line[result_col]
+        if got != want:
+            errors.append(
+                f"{name} row {row} col {result_col} (result): want {want}, got {got!r}")
+    # Below the table the screen must be blank.
+    for row in range(combos + 1, len(rows)):
+        if rows[row].strip():
+            errors.append(f"{name}: unexpected content below table at row {row}: "
+                          f"{rows[row].strip()!r}")
+            break
+    return errors
+
+
+# ---------------------------------------------------------------- driver --
+
+def run_formula(bas: Path, name: str, formula: str, workdir: Path) -> str:
+    keys = KEYS_TEMPLATE.format(formula=formula)
+    cmd = [
+        "java", "-cp", DRIVER_CP, DRIVER_CLASS, str(bas),
+        "--steps=200000000", "--interval=60", "--block",
+        f"--screenshot={workdir / name}.png",
+        f"--textdump={workdir / name}.txt",
+        f"--keys={keys}",
+    ]
+    proc = subprocess.run(cmd, cwd=CRTBASIC, capture_output=True, text=True, timeout=300)
+    if proc.returncode != 0:
+        raise RuntimeError(f"{name}: driver failed:\n{proc.stdout}\n{proc.stderr}")
+    dump_path = workdir / f"{name}-1.txt"
+    if not dump_path.exists():
+        raise RuntimeError(f"{name}: no text dump produced:\n{proc.stdout}\n{proc.stderr}")
+    return dump_path.read_text()
+
+
+def load_formulas() -> list:
+    entries = []
+    for line in FORMULAS.read_text().splitlines():
+        line = line.strip()
+        if not line or line.startswith("#"):
+            continue
+        name, formula = line.split("\t")
+        entries.append((name, formula))
+    return entries
+
+
+def main() -> int:
+    record = "--record" in sys.argv
+    bas = DEFAULT_BAS
+    if "--bas" in sys.argv:
+        bas = Path(sys.argv[sys.argv.index("--bas") + 1])
+    formulas = load_formulas()
+    print(f"Program: {bas}")
+    print(f"Formulas: {len(formulas)}")
+    failures = 0
+    with tempfile.TemporaryDirectory(prefix="truthtest-") as tmp:
+        workdir = Path(tmp)
+        for name, formula in formulas:
+            dump = run_formula(bas, name, formula, workdir)
+            errors = oracle_check(name, formula, dump)
+            for err in errors:
+                print(f"ORACLE FAIL: {err}")
+                failures += 1
+            expected_path = EXPECTED / f"{name}.txt"
+            if record:
+                EXPECTED.mkdir(exist_ok=True)
+                expected_path.write_text(dump)
+            elif expected_path.exists():
+                baseline = expected_path.read_text()
+                if dump != baseline:
+                    failures += 1
+                    print(f"REGRESSION: {name}: dump differs from baseline")
+                    old, new = baseline.split("\n"), dump.split("\n")
+                    shown = 0
+                    for row in range(max(len(old), len(new))):
+                        before = old[row] if row < len(old) else "<missing>"
+                        after = new[row] if row < len(new) else "<missing>"
+                        if before != after and shown < 5:
+                            print(f"  row {row}: baseline {before.strip()!r} -> got {after.strip()!r}")
+                            shown += 1
+            else:
+                failures += 1
+                print(f"MISSING BASELINE: {name} (run with --record)")
+            status = "recorded" if record else ("ok" if not errors else "FAILED")
+            print(f"  {name}: {status}")
+    if failures:
+        print(f"\n{failures} failure(s)")
+        return 1
+    print("\nAll checks passed")
+    return 0
+
+
+if __name__ == "__main__":
+    sys.exit(main())
index ee39e82..8e2a82c 100755 (executable)
@@ -8,6 +8,10 @@
 ' Changelog:\r
 ' 2002, Initial version\r
 ' 2024 - 2025, Improved program readability\r
+' 2026, Second readability pass: translated the remaining Estonian names\r
+'       (sist, lahend, tee, teeslg, lend, mov), documented the operator\r
+'       encoding and the addPrecedenceParens/solveEquation parameter\r
+'       aliasing. Algorithm unchanged.\r
 '\r
 '\r
 ' A truth table is a mathematical table used to determine the output of a\r
 ' understanding digital circuits, Boolean algebra, and logical\r
 ' expressions.\r
 '\r
-' Implemented operations:\r
+' Implemented operations (typed with digit keys, stored as CHR$(1)..CHR$(5)):\r
 '   Equivalent ( Keyboard shortcut: 1 )\r
 '   Implies ( Keyboard shortcut: 2 )\r
 '   OR ( Keyboard shortcut: 3 )\r
 '   AND ( Keyboard shortcut: 4 )\r
 '   NOT ( Keyboard shortcut: 5 )\r
+'\r
+' The letters t and v are NOT variables: they are the truth constants\r
+' (Estonian tosi = true, vaar = false). Every other letter becomes a\r
+' variable of the table.\r
 \r
 DECLARE SUB removeRedundancies (startIndex!, endIndex!, removalCount!)\r
-DECLARE SUB getOperatorPriority (a!, b!)\r
-DECLARE SUB movM (x1!, n!)\r
-DECLARE SUB clearScreenBuffer ()\r
-DECLARE SUB lendm (x1!, m!)\r
-DECLARE SUB mov (x1!, n!)\r
-DECLARE SUB lendp (x1!, m!)\r
-DECLARE SUB teeslg (x1!, x2!, l!)\r
-DECLARE SUB prepare ()\r
-DECLARE SUB tee (x1!, x2!)\r
-DECLARE SUB lahend (x1, x2)\r
-DECLARE SUB printText (x!, y!, c!, c1!, a$)\r
-DECLARE SUB sist ()\r
-DECLARE SUB start ()\r
+DECLARE SUB getOperatorPriority (operatorCode!, priority!)\r
+DECLARE SUB shiftExpressionLeft (position!, count!)\r
+DECLARE SUB drainKeyboardBuffer ()\r
+DECLARE SUB operandLengthBefore (position!, outLength!)\r
+DECLARE SUB shiftExpressionRight (position!, count!)\r
+DECLARE SUB operandLengthAfter (position!, outLength!)\r
+DECLARE SUB addPrecedenceParens (exprStart!, exprEnd!, addedChars!)\r
+DECLARE SUB processEquation ()\r
+DECLARE SUB evaluateExpression (exprStart!, exprEnd!)\r
+DECLARE SUB solveEquation (exprStart, exprEnd)\r
+DECLARE SUB printText (column!, row!, foreground!, background!, text$)\r
+DECLARE SUB inputEquation ()\r
+DECLARE SUB initializeDisplay ()\r
 DIM SHARED font(0 TO 7, 0 TO 7, 0 TO 122)\r
 \r
 ' Logical expression storage and processing arrays\r
@@ -46,28 +54,30 @@ DIM SHARED variableValues(1 TO 8, 1 TO 100) ' Stores variable values for each co
 DIM SHARED variableNames(1 TO 8) ' Stores ASCII values of variable names\r
 DIM SHARED resultValues(1 TO 100) ' Stores computed result values\r
 DIM SHARED expressionPosition(0 TO 79) ' Stores screen positions of expression characters\r
-DIM SHARED xlahn\r
-DIM SHARED tehl\r
-DIM SHARED nm\r
-DIM SHARED prnp\r
+DIM SHARED xlahn ' Unused legacy variable (kept from the 2002 original)\r
+DIM SHARED combinationCount ' Number of truth-table rows: 2 ^ variableCount\r
+DIM SHARED variableCount ' Number of variables, plus 2 for the t/v constants\r
+DIM SHARED printRowOffset ' Vertical offset for printText (always 0)\r
 \r
-start\r
+initializeDisplay\r
 \r
 13\r
-sist\r
-prepare\r
+inputEquation\r
+processEquation\r
 GOTO 13\r
 \r
-SUB clearScreenBuffer\r
-' Waits for user input to clear the screen buffer\r
-FOR a = 1 TO 50\r
-    a$ = INKEY$\r
-NEXT a\r
+SUB drainKeyboardBuffer\r
+' Throws away up to 50 pending keystrokes.\r
+' NOTE: currently never called - kept from the 2002 original.\r
+FOR flushIndex = 1 TO 50\r
+    key$ = INKEY$\r
+NEXT flushIndex\r
 END SUB\r
 \r
-SUB getOperatorPriority (operator, priority)\r
-' Determines the priority of logical operators\r
-SELECT CASE operator\r
+SUB getOperatorPriority (operatorCode, priority)\r
+' Determines the priority of logical operators.\r
+' NOTE: only used by removeRedundancies, which itself is never called.\r
+SELECT CASE operatorCode\r
     CASE 5   ' NOT\r
         priority = 1\r
     CASE 3, 4  ' OR, AND\r
@@ -82,263 +92,281 @@ END SELECT
 END SUB\r
 \r
 \r
-SUB lahend (x1, x2)\r
-' Analyzes and prepares the logical equation for solving\r
-DIM muu(65 TO 122)\r
-FOR a = 65 TO 122\r
-    muu(a) = 0\r
-NEXT a\r
-\r
-muu(116) = 1 ' t\r
-muu(118) = 1 ' v\r
-\r
-nm = 0\r
-FOR a = x1 TO x2\r
-    b = logicalExpression(a)\r
-    IF ((b >= 65) AND (b <= 90)) OR ((b >= 97) AND (b <= 122)) THEN\r
-        IF muu(b) = 0 THEN\r
-            nm = nm + 1\r
-            variableNames(nm) = b\r
-            muu(b) = 1\r
+SUB solveEquation (exprStart, exprEnd)\r
+' Analyzes the logical equation and computes the whole truth table:\r
+' collects the distinct variables, builds every input combination,\r
+' lets addPrecedenceParens parenthesize the expression by operator\r
+' priority, evaluates it for every row and prints the result column.\r
+DIM seenChar(65 TO 122)\r
+FOR charIndex = 65 TO 122\r
+    seenChar(charIndex) = 0\r
+NEXT charIndex\r
+\r
+seenChar(116) = 1 ' t (true constant, never a variable)\r
+seenChar(118) = 1 ' v (false constant, never a variable)\r
+\r
+variableCount = 0\r
+FOR charIndex = exprStart TO exprEnd\r
+    charCode = logicalExpression(charIndex)\r
+    IF ((charCode >= 65) AND (charCode <= 90)) OR ((charCode >= 97) AND (charCode <= 122)) THEN\r
+        IF seenChar(charCode) = 0 THEN\r
+            variableCount = variableCount + 1\r
+            variableNames(variableCount) = charCode\r
+            seenChar(charCode) = 1\r
         END IF\r
     END IF\r
-NEXT a\r
-\r
-variableNames(nm + 1) = 116 ' t\r
-variableNames(nm + 2) = 118 ' v\r
-\r
-f = 2 ^ nm\r
-tehl = f\r
-FOR a = 1 TO nm\r
-    d = 1\r
-    e = 1\r
-    f = f / 2\r
-    FOR b = 1 TO 2 ^ nm\r
-        IF e > f THEN d = -d: e = 1\r
-        IF d = 1 THEN c = ASC("t") ELSE c = ASC("v")\r
-        variableValues(a, b) = c\r
-        e = e + 1\r
-    NEXT b\r
-NEXT a\r
-\r
-FOR a = 1 TO tehl\r
-    variableValues(nm + 1, a) = 116 ' t\r
-    variableValues(nm + 2, a) = 118 ' v\r
-NEXT a\r
-\r
-nm = nm + 2\r
-\r
-DIM bck(0 TO 79)\r
-FOR a = 0 TO 79\r
-    bck(a) = logicalExpression(a)\r
-    expressionPosition(a) = a\r
-NEXT a\r
+NEXT charIndex\r
+\r
+variableNames(variableCount + 1) = 116 ' t\r
+variableNames(variableCount + 2) = 118 ' v\r
+\r
+blockSize = 2 ^ variableCount\r
+combinationCount = blockSize\r
+FOR variableIndex = 1 TO variableCount\r
+    truthToggle = 1\r
+    runCount = 1\r
+    blockSize = blockSize / 2\r
+    FOR comboRow = 1 TO 2 ^ variableCount\r
+        ' Alternate runs of t and v; each next variable's runs are\r
+        ' half as long, so the first variable changes slowest.\r
+        IF runCount > blockSize THEN truthToggle = -truthToggle: runCount = 1\r
+        IF truthToggle = 1 THEN cellValue = ASC("t") ELSE cellValue = ASC("v")\r
+        variableValues(variableIndex, comboRow) = cellValue\r
+        runCount = runCount + 1\r
+    NEXT comboRow\r
+NEXT variableIndex\r
+\r
+FOR comboRow = 1 TO combinationCount\r
+    variableValues(variableCount + 1, comboRow) = 116 ' t\r
+    variableValues(variableCount + 2, comboRow) = 118 ' v\r
+NEXT comboRow\r
+\r
+variableCount = variableCount + 2\r
+\r
+DIM expressionBackup(0 TO 79)\r
+FOR charIndex = 0 TO 79\r
+    expressionBackup(charIndex) = logicalExpression(charIndex)\r
+    expressionPosition(charIndex) = charIndex\r
+NEXT charIndex\r
 \r
 LOCATE 5, 1\r
-teeslg x1, x2, a\r
+' charIndex returns how many parenthesis characters addPrecedenceParens\r
+' inserted, so evaluateExpression receives the extended expression range.\r
+addPrecedenceParens exprStart, exprEnd, charIndex\r
 \r
-tee x1, x2 + a\r
+evaluateExpression exprStart, exprEnd + charIndex\r
 \r
-FOR a = 0 TO 79\r
-    logicalExpression(a) = bck(a)\r
-NEXT a\r
+FOR charIndex = 0 TO 79\r
+    logicalExpression(charIndex) = expressionBackup(charIndex)\r
+NEXT charIndex\r
 \r
-FOR a = 1 TO tehl\r
-    printText x2 + 1, a, 14, 0, CHR$(resultValues(a))\r
-NEXT a\r
+FOR comboRow = 1 TO combinationCount\r
+    printText exprEnd + 1, comboRow, 14, 0, CHR$(resultValues(comboRow))\r
+NEXT comboRow\r
 \r
 END SUB\r
 \r
-SUB lendm (x1, m)\r
-' Measures the length of a logical expression enclosed in parentheses\r
-IF logicalExpression(x1) <> 41 THEN m = 1: GOTO 19\r
-c = x1\r
-d = 1\r
+SUB operandLengthBefore (position, outLength)\r
+' Measures the length of the operand ending just before position:\r
+' either a single character, or a parenthesized group scanned backwards.\r
+IF logicalExpression(position) <> 41 THEN outLength = 1: GOTO 19\r
+scanPos = position\r
+parenDepth = 1\r
 20\r
-c = c - 1\r
-IF logicalExpression(c) = 40 THEN d = d - 1\r
-IF logicalExpression(c) = 41 THEN d = d + 1\r
-IF d > 0 THEN GOTO 20\r
-m = x1 - c\r
+scanPos = scanPos - 1\r
+IF logicalExpression(scanPos) = 40 THEN parenDepth = parenDepth - 1\r
+IF logicalExpression(scanPos) = 41 THEN parenDepth = parenDepth + 1\r
+IF parenDepth > 0 THEN GOTO 20\r
+outLength = position - scanPos\r
 19\r
 END SUB\r
 \r
-SUB lendp (x1, m)\r
-' Measures the length of a logical expression enclosed in parentheses\r
-IF logicalExpression(x1) <> 40 THEN m = 1: GOTO 17\r
-c = x1\r
-d = 1\r
+SUB operandLengthAfter (position, outLength)\r
+' Measures the length of the operand starting at position:\r
+' either a single character, or a parenthesized group scanned forwards.\r
+IF logicalExpression(position) <> 40 THEN outLength = 1: GOTO 17\r
+scanPos = position\r
+parenDepth = 1\r
 18\r
-c = c + 1\r
-IF logicalExpression(c) = 40 THEN d = d + 1\r
-IF logicalExpression(c) = 41 THEN d = d - 1\r
-IF d > 0 THEN GOTO 18\r
-m = c - x1 + 1\r
+scanPos = scanPos + 1\r
+IF logicalExpression(scanPos) = 40 THEN parenDepth = parenDepth + 1\r
+IF logicalExpression(scanPos) = 41 THEN parenDepth = parenDepth - 1\r
+IF parenDepth > 0 THEN GOTO 18\r
+outLength = scanPos - position + 1\r
 17\r
 END SUB\r
 \r
-SUB mov (x1, n)\r
-' Moves a portion of the logical expression to the right\r
-FOR a = 79 - n TO x1 STEP -1\r
-    logicalExpression(a + n) = logicalExpression(a)\r
-    expressionPosition(a + n) = expressionPosition(a)\r
-NEXT a\r
+SUB shiftExpressionRight (position, count)\r
+' Moves a portion of the logical expression to the right,\r
+' opening a gap of count characters at position.\r
+FOR charIndex = 79 - count TO position STEP -1\r
+    logicalExpression(charIndex + count) = logicalExpression(charIndex)\r
+    expressionPosition(charIndex + count) = expressionPosition(charIndex)\r
+NEXT charIndex\r
 END SUB\r
 \r
-SUB movM (x1, n)\r
-' Moves a portion of the logical expression to the left\r
-FOR a = x1 TO 79 - n\r
-    logicalExpression(a) = logicalExpression(a + n)\r
-    expressionPosition(a) = expressionPosition(a + n)\r
-NEXT a\r
+SUB shiftExpressionLeft (position, count)\r
+' Moves a portion of the logical expression to the left,\r
+' deleting count characters at position.\r
+FOR charIndex = position TO 79 - count\r
+    logicalExpression(charIndex) = logicalExpression(charIndex + count)\r
+    expressionPosition(charIndex) = expressionPosition(charIndex + count)\r
+NEXT charIndex\r
 END SUB\r
 \r
-SUB prepare\r
-' Prepares the logical equation for processing\r
+SUB processEquation\r
+' Prepares the typed equation for processing: strips spaces and empty\r
+' cells, prints it, solves it, then waits for a keypress.\r
 CLS\r
 \r
-ln = 79\r
-FOR a = 0 TO 79\r
+lastCharIndex = 79\r
+FOR charIndex = 0 TO 79\r
 5\r
-    IF logicalExpression(a) = 32 OR logicalExpression(a) = 0 THEN\r
-        FOR b = a TO 78\r
-            logicalExpression(b) = logicalExpression(b + 1)\r
-        NEXT b\r
-        ln = ln - 1\r
-        IF ln <= a - 1 THEN GOTO 6\r
+    IF logicalExpression(charIndex) = 32 OR logicalExpression(charIndex) = 0 THEN\r
+        FOR shiftIndex = charIndex TO 78\r
+            logicalExpression(shiftIndex) = logicalExpression(shiftIndex + 1)\r
+        NEXT shiftIndex\r
+        lastCharIndex = lastCharIndex - 1\r
+        IF lastCharIndex <= charIndex - 1 THEN GOTO 6\r
         GOTO 5\r
     END IF\r
-NEXT a\r
+NEXT charIndex\r
 6\r
 \r
 CLS\r
 \r
-FOR a = 0 TO ln\r
-    printText a, 0, 13, 1, CHR$(logicalExpression(a))\r
-NEXT a\r
+FOR charIndex = 0 TO lastCharIndex\r
+    printText charIndex, 0, 13, 1, CHR$(logicalExpression(charIndex))\r
+NEXT charIndex\r
 \r
 printText 0, 1, 7, 0, SPACE$(79)\r
 \r
-lahend 0, ln\r
+solveEquation 0, lastCharIndex\r
 \r
-a$ = INPUT$(1)\r
+key$ = INPUT$(1)\r
 \r
 END SUB\r
 \r
-SUB printText (x, y, c, c1, a$)\r
-    ' Prints characters to the screen at location (x,y) with color c, background c1\r
-    x1 = x * 8\r
-    y1 = (y + prnp) * 8\r
-\r
-    FOR b = 1 TO LEN(a$)\r
-        LINE (x1, y1)-(x1 + 7, y1 + 7), c1, BF\r
-        d = ASC(RIGHT$(LEFT$(a$, b), 1))\r
-        IF d > 122 THEN GOTO 22\r
-        FOR y2 = 0 TO 7\r
-            FOR x2 = 0 TO 7\r
-                c2 = font(x2, y2, d)\r
-                IF c2 > 0 THEN PSET (x1 + x2, y1 + y2), c\r
-            NEXT x2\r
-        NEXT y2\r
-22      x1 = x1 + 8\r
-    NEXT b\r
+SUB printText (column, row, foreground, background, text$)\r
+    ' Prints characters to the screen at location (column,row) with color\r
+    ' foreground, background background, using the 8x8 font bitmaps that\r
+    ' initializeDisplay captured at startup.\r
+    pixelX = column * 8\r
+    pixelY = (row + printRowOffset) * 8\r
+\r
+    FOR charIndex = 1 TO LEN(text$)\r
+        LINE (pixelX, pixelY)-(pixelX + 7, pixelY + 7), background, BF\r
+        glyphCode = ASC(RIGHT$(LEFT$(text$, charIndex), 1))\r
+        IF glyphCode > 122 THEN GOTO 22\r
+        FOR glyphRow = 0 TO 7\r
+            FOR glyphCol = 0 TO 7\r
+                pixelValue = font(glyphCol, glyphRow, glyphCode)\r
+                IF pixelValue > 0 THEN PSET (pixelX + glyphCol, pixelY + glyphRow), foreground\r
+            NEXT glyphCol\r
+        NEXT glyphRow\r
+22      pixelX = pixelX + 8\r
+    NEXT charIndex\r
 \r
 END SUB\r
 \r
 SUB removeRedundancies (startIndex, endIndex, removalCount)\r
     ' This procedure scans for parentheses that can be safely removed\r
     ' without changing the logic of the expression, then removes them.\r
+    ' NOTE: currently never called - an abandoned feature of the 2002\r
+    ' original, kept as reference.\r
 \r
     DIM currentEnd, parenthesesCount\r
     currentEnd = endIndex\r
     parenthesesCount = 0\r
 \r
-    a = startIndex\r
-26  IF logicalExpression(a) = 40 THEN\r
+    charIndex = startIndex\r
+26  IF logicalExpression(charIndex) = 40 THEN\r
         ' We found an opening parenthesis. Now let's see if it can be removed.\r
-        IF a = startIndex THEN p1 = 100 ELSE getOperatorPriority logicalExpression(a - 1), p1\r
+        IF charIndex = startIndex THEN priorityBefore = 100 ELSE getOperatorPriority logicalExpression(charIndex - 1), priorityBefore\r
 \r
-        c = a\r
-        d = 1\r
-        p2 = 0\r
+        closePos = charIndex\r
+        parenDepth = 1\r
+        priorityInside = 0\r
 \r
-25      c = c + 1\r
-        IF logicalExpression(c) = 40 THEN d = d + 1\r
-        IF logicalExpression(c) = 41 THEN d = d - 1\r
+25      closePos = closePos + 1\r
+        IF logicalExpression(closePos) = 40 THEN parenDepth = parenDepth + 1\r
+        IF logicalExpression(closePos) = 41 THEN parenDepth = parenDepth - 1\r
 \r
-        ' Once d returns to 1, we are back to one level of parentheses,\r
+        ' Once parenDepth returns to 1, we are back to one level of parentheses,\r
         ' meaning we can check operator priority inside.\r
-        IF d = 1 THEN\r
-            IF (logicalExpression(c) > 0) AND (logicalExpression(c) <= 5) THEN\r
-                getOperatorPriority logicalExpression(c), b\r
-                IF b > p2 THEN p2 = b\r
+        IF parenDepth = 1 THEN\r
+            IF (logicalExpression(closePos) > 0) AND (logicalExpression(closePos) <= 5) THEN\r
+                getOperatorPriority logicalExpression(closePos), opPriority\r
+                IF opPriority > priorityInside THEN priorityInside = opPriority\r
             END IF\r
         END IF\r
 \r
-        IF d > 0 THEN GOTO 25\r
+        IF parenDepth > 0 THEN GOTO 25\r
 \r
-        IF c + 1 > currentEnd THEN p3 = 100 ELSE getOperatorPriority logicalExpression(c + 1), p3\r
+        IF closePos + 1 > currentEnd THEN priorityAfter = 100 ELSE getOperatorPriority logicalExpression(closePos + 1), priorityAfter\r
 \r
         ' If the operator outside is higher priority than what's inside,\r
         ' we can safely remove the parentheses.\r
-        IF (p1 > p2) AND (p3 >= p2) THEN\r
-            movM c, 1\r
-            movM a, 1\r
+        IF (priorityBefore > priorityInside) AND (priorityAfter >= priorityInside) THEN\r
+            shiftExpressionLeft closePos, 1\r
+            shiftExpressionLeft charIndex, 1\r
             parenthesesCount = parenthesesCount + 2\r
             currentEnd = currentEnd - 2\r
-            a = a - 1\r
+            charIndex = charIndex - 1\r
         END IF\r
     END IF\r
 \r
-    a = a + 1\r
-    IF a <= currentEnd THEN GOTO 26\r
+    charIndex = charIndex + 1\r
+    IF charIndex <= currentEnd THEN GOTO 26\r
 \r
     removalCount = parenthesesCount\r
 END SUB\r
 \r
-SUB sist\r
-' Interacts with the user to input a logical equation\r
+SUB inputEquation\r
+' Interacts with the user to input a logical equation.\r
+' Digit keys 1..5 insert the operator characters CHR$(1)..CHR$(5),\r
+' letters insert variables, arrows move the cursor, Enter finishes.\r
 CLS\r
 printText 0, 0, 3, 0, "Enter equation (ESC to quit) keys: 1 - " + CHR$(1) + "   2 - " + CHR$(2) + "   3 - " + CHR$(3) + "   4 - " + CHR$(4) + "   5 - " + CHR$(5)\r
 printText 0, 1, 3, 0, "Example: a" + CHR$(1) + "b" + CHR$(2) + "(g" + CHR$(3) + "b)"\r
 \r
-FOR a = 0 TO 79\r
-    logicalExpression(a) = 0\r
-NEXT a\r
+FOR charIndex = 0 TO 79\r
+    logicalExpression(charIndex) = 0\r
+NEXT charIndex\r
 \r
-x = 0\r
+cursorPos = 0\r
 1\r
-FOR a = 0 TO 79\r
-    IF a = x THEN printText a, 2, 14, 1, CHR$(logicalExpression(a)) ELSE printText a, 2, 3, 0, CHR$(logicalExpression(a))\r
-NEXT a\r
+FOR charIndex = 0 TO 79\r
+    IF charIndex = cursorPos THEN printText charIndex, 2, 14, 1, CHR$(logicalExpression(charIndex)) ELSE printText charIndex, 2, 3, 0, CHR$(logicalExpression(charIndex))\r
+NEXT charIndex\r
 2\r
-a$ = INKEY$\r
-IF a$ = "" THEN GOTO 2\r
+key$ = INKEY$\r
+IF key$ = "" THEN GOTO 2\r
 \r
-IF a$ = CHR$(27) THEN SYSTEM\r
-IF a$ = CHR$(0) + "M" THEN x = x + 1\r
-IF a$ = CHR$(0) + "K" THEN x = x - 1\r
-IF x < 0 THEN x = 0\r
-IF x > 79 THEN x = 79\r
+IF key$ = CHR$(27) THEN SYSTEM\r
+IF key$ = CHR$(0) + "M" THEN cursorPos = cursorPos + 1\r
+IF key$ = CHR$(0) + "K" THEN cursorPos = cursorPos - 1\r
+IF cursorPos < 0 THEN cursorPos = 0\r
+IF cursorPos > 79 THEN cursorPos = 79\r
 \r
-IF LEN(a$) = 1 THEN\r
-    SELECT CASE ASC(a$)\r
+IF LEN(key$) = 1 THEN\r
+    SELECT CASE ASC(key$)\r
         CASE 32, 40, 41, 65 TO 90, 97 TO 122\r
 3\r
-            FOR a = 78 TO x STEP -1\r
-                logicalExpression(a + 1) = logicalExpression(a)\r
-            NEXT a\r
-            logicalExpression(x) = ASC(a$)\r
-            x = x + 1\r
+            FOR charIndex = 78 TO cursorPos STEP -1\r
+                logicalExpression(charIndex + 1) = logicalExpression(charIndex)\r
+            NEXT charIndex\r
+            logicalExpression(cursorPos) = ASC(key$)\r
+            cursorPos = cursorPos + 1\r
         CASE 8\r
-            IF x > 0 THEN\r
-                FOR a = x - 1 TO 78\r
-                    logicalExpression(a) = logicalExpression(a + 1)\r
-                NEXT a\r
-                x = x - 1\r
+            IF cursorPos > 0 THEN\r
+                FOR charIndex = cursorPos - 1 TO 78\r
+                    logicalExpression(charIndex) = logicalExpression(charIndex + 1)\r
+                NEXT charIndex\r
+                cursorPos = cursorPos - 1\r
             END IF\r
         CASE 49 TO 53\r
-            a$ = CHR$(ASC(a$) - 48)\r
+            key$ = CHR$(ASC(key$) - 48)\r
             GOTO 3\r
         CASE 13\r
             GOTO 4\r
@@ -350,15 +378,19 @@ GOTO 1
 \r
 END SUB\r
 \r
-SUB start\r
-' Initializes the screen and font\r
-prnp = 0\r
+SUB initializeDisplay\r
+' Initializes the screen and captures the font: every displayable\r
+' character is PRINTed once in SCREEN 7 and read back pixel by pixel\r
+' into the font() array, so printText can draw text in graphics modes.\r
+' The operator characters CHR$(1)..CHR$(5) have no glyphs, so their\r
+' bitmaps are drawn by hand with LINE.\r
+printRowOffset = 0\r
 \r
 SCREEN 7\r
 \r
-FOR a = 0 TO 122\r
+FOR charCode = 0 TO 122\r
     LOCATE 1, 1\r
-    SELECT CASE a\r
+    SELECT CASE charCode\r
         CASE 7\r
         CASE 1\r
             LINE (0, 0)-(7, 7), 0, BF\r
@@ -392,206 +424,222 @@ FOR a = 0 TO 122
             LINE (4, 1)-(4, 7), 15\r
 \r
         CASE ELSE\r
-            PRINT CHR$(a)\r
+            PRINT CHR$(charCode)\r
     END SELECT\r
 \r
-    FOR y = 0 TO 7\r
-        FOR x = 0 TO 7\r
-            font(x, y, a) = POINT(x, y)\r
-        NEXT x\r
-    NEXT y\r
-NEXT a\r
+    FOR pixelRow = 0 TO 7\r
+        FOR pixelCol = 0 TO 7\r
+            font(pixelCol, pixelRow, charCode) = POINT(pixelCol, pixelRow)\r
+        NEXT pixelCol\r
+    NEXT pixelRow\r
+NEXT charCode\r
 \r
 SCREEN 12\r
 \r
 END SUB\r
 \r
-SUB tee (x1, x2)\r
-' Processes the logical equation and applies logical operations\r
-DIM opr(1 TO 2, 1 TO tehl)\r
-ng = 0\r
-ngx = 0\r
-oprm = 1\r
-oe = 0\r
-oex = 0\r
-\r
-FOR a = x1 TO x2\r
-    b = logicalExpression(a)\r
-    SELECT CASE b\r
+SUB evaluateExpression (exprStart, exprEnd)\r
+' Evaluates the logical equation for every truth-table row.\r
+' Parenthesized groups are evaluated recursively; the two operand\r
+' columns accumulate in operandValues(1..2, row) and every binary\r
+' operator combines them left to right back into slot 1. The final\r
+' column lands in resultValues().\r
+DIM operandValues(1 TO 2, 1 TO combinationCount)\r
+notPending = 0\r
+notPosition = 0\r
+operandSlot = 1\r
+pendingOperator = 0\r
+operatorPosition = 0\r
+\r
+FOR charIndex = exprStart TO exprEnd\r
+    charCode = logicalExpression(charIndex)\r
+    SELECT CASE charCode\r
         CASE 40\r
-            c = a\r
-            d = 1\r
+            scanPos = charIndex\r
+            parenDepth = 1\r
 10\r
-            c = c + 1\r
-            IF logicalExpression(c) = ASC("(") THEN d = d + 1\r
-            IF logicalExpression(c) = ASC(")") THEN d = d - 1\r
-            IF d = 0 THEN GOTO 11\r
+            scanPos = scanPos + 1\r
+            IF logicalExpression(scanPos) = ASC("(") THEN parenDepth = parenDepth + 1\r
+            IF logicalExpression(scanPos) = ASC(")") THEN parenDepth = parenDepth - 1\r
+            IF parenDepth = 0 THEN GOTO 11\r
             GOTO 10\r
 11\r
-            tee a + 1, c - 1\r
-            a = c\r
-            FOR c = 1 TO tehl\r
-                opr(oprm, c) = resultValues(c)\r
-            NEXT c\r
+            evaluateExpression charIndex + 1, scanPos - 1\r
+            charIndex = scanPos\r
+            FOR comboRow = 1 TO combinationCount\r
+                operandValues(operandSlot, comboRow) = resultValues(comboRow)\r
+            NEXT comboRow\r
             GOTO 12\r
         CASE 5\r
-            ng = 1\r
-            ngx = a\r
+            notPending = 1\r
+            notPosition = charIndex\r
         CASE 1 TO 4\r
-            oe = b\r
-            oex = a\r
+            pendingOperator = charCode\r
+            operatorPosition = charIndex\r
         CASE 65 TO 90, 97 TO 122\r
-            FOR c = 1 TO nm\r
-                IF variableNames(c) = b THEN d = c: GOTO 8\r
-            NEXT c\r
+            FOR lookupIndex = 1 TO variableCount\r
+                IF variableNames(lookupIndex) = charCode THEN variableIndex = lookupIndex: GOTO 8\r
+            NEXT lookupIndex\r
 8\r
-            FOR c = 1 TO tehl\r
-                opr(oprm, c) = variableValues(d, c)\r
-                printText expressionPosition(a), c, 3, 0, CHR$(variableValues(d, c))\r
-            NEXT c\r
+            FOR comboRow = 1 TO combinationCount\r
+                operandValues(operandSlot, comboRow) = variableValues(variableIndex, comboRow)\r
+                printText expressionPosition(charIndex), comboRow, 3, 0, CHR$(variableValues(variableIndex, comboRow))\r
+            NEXT comboRow\r
 12\r
-            IF ng = 1 THEN GOSUB mkneg\r
-            IF oprm = 2 THEN\r
-                SELECT CASE oe\r
+            IF notPending = 1 THEN GOSUB mkneg\r
+            IF operandSlot = 2 THEN\r
+                SELECT CASE pendingOperator\r
                     CASE 1\r
-                        FOR c = 1 TO tehl\r
-                            d = opr(1, c)\r
-                            e = opr(2, c)\r
-                            IF d = e THEN f = ASC("t") ELSE f = ASC("v")\r
-                            opr(1, c) = f\r
-                            printText expressionPosition(oex), c, 12, 0, CHR$(f)\r
-                        NEXT c\r
+                        FOR comboRow = 1 TO combinationCount\r
+                            leftValue = operandValues(1, comboRow)\r
+                            rightValue = operandValues(2, comboRow)\r
+                            IF leftValue = rightValue THEN resultValue = ASC("t") ELSE resultValue = ASC("v")\r
+                            operandValues(1, comboRow) = resultValue\r
+                            printText expressionPosition(operatorPosition), comboRow, 12, 0, CHR$(resultValue)\r
+                        NEXT comboRow\r
                     CASE 2\r
-                        FOR c = 1 TO tehl\r
-                            d = opr(1, c)\r
-                            e = opr(2, c)\r
-                            f = ASC("t")\r
-                            IF (d = ASC("t")) AND (e = ASC("v")) THEN f = ASC("v")\r
-                            opr(1, c) = f\r
-                            printText expressionPosition(oex), c, 12, 0, CHR$(f)\r
-                        NEXT c\r
+                        FOR comboRow = 1 TO combinationCount\r
+                            leftValue = operandValues(1, comboRow)\r
+                            rightValue = operandValues(2, comboRow)\r
+                            resultValue = ASC("t")\r
+                            IF (leftValue = ASC("t")) AND (rightValue = ASC("v")) THEN resultValue = ASC("v")\r
+                            operandValues(1, comboRow) = resultValue\r
+                            printText expressionPosition(operatorPosition), comboRow, 12, 0, CHR$(resultValue)\r
+                        NEXT comboRow\r
                     CASE 3\r
-                        FOR c = 1 TO tehl\r
-                            d = opr(1, c)\r
-                            e = opr(2, c)\r
-                            f = ASC("t")\r
-                            IF (d = ASC("v")) AND (e = ASC("v")) THEN f = ASC("v")\r
-                            opr(1, c) = f\r
-                            printText expressionPosition(oex), c, 12, 0, CHR$(f)\r
-                        NEXT c\r
+                        FOR comboRow = 1 TO combinationCount\r
+                            leftValue = operandValues(1, comboRow)\r
+                            rightValue = operandValues(2, comboRow)\r
+                            resultValue = ASC("t")\r
+                            IF (leftValue = ASC("v")) AND (rightValue = ASC("v")) THEN resultValue = ASC("v")\r
+                            operandValues(1, comboRow) = resultValue\r
+                            printText expressionPosition(operatorPosition), comboRow, 12, 0, CHR$(resultValue)\r
+                        NEXT comboRow\r
                     CASE 4\r
-                        FOR c = 1 TO tehl\r
-                            d = opr(1, c)\r
-                            e = opr(2, c)\r
-                            f = ASC("v")\r
-                            IF (d = ASC("t")) AND (e = ASC("t")) THEN f = ASC("t")\r
-                            opr(1, c) = f\r
-                            printText expressionPosition(oex), c, 12, 0, CHR$(f)\r
-                        NEXT c\r
+                        FOR comboRow = 1 TO combinationCount\r
+                            leftValue = operandValues(1, comboRow)\r
+                            rightValue = operandValues(2, comboRow)\r
+                            resultValue = ASC("v")\r
+                            IF (leftValue = ASC("t")) AND (rightValue = ASC("t")) THEN resultValue = ASC("t")\r
+                            operandValues(1, comboRow) = resultValue\r
+                            printText expressionPosition(operatorPosition), comboRow, 12, 0, CHR$(resultValue)\r
+                        NEXT comboRow\r
                 END SELECT\r
             ELSE\r
-                oprm = oprm + 1\r
+                operandSlot = operandSlot + 1\r
             END IF\r
     END SELECT\r
-NEXT a\r
+NEXT charIndex\r
 \r
 GOTO 9\r
 \r
 mkneg:\r
     ' NOT operation (negation) is applied to the current operand\r
-    FOR c = 1 TO tehl\r
-        d = opr(oprm, c)\r
-        IF d = ASC("t") THEN d = ASC("v") ELSE d = ASC("t")\r
-        printText expressionPosition(ngx), c, 4, 0, CHR$(d)\r
-        opr(oprm, c) = d\r
-    NEXT c\r
-    ng = 0\r
+    FOR comboRow = 1 TO combinationCount\r
+        negatedValue = operandValues(operandSlot, comboRow)\r
+        IF negatedValue = ASC("t") THEN negatedValue = ASC("v") ELSE negatedValue = ASC("t")\r
+        printText expressionPosition(notPosition), comboRow, 4, 0, CHR$(negatedValue)\r
+        operandValues(operandSlot, comboRow) = negatedValue\r
+    NEXT comboRow\r
+    notPending = 0\r
 RETURN\r
 9\r
 \r
-FOR c = 1 TO tehl\r
-    resultValues(c) = opr(1, c)\r
-NEXT c\r
+FOR comboRow = 1 TO combinationCount\r
+    resultValues(comboRow) = operandValues(1, comboRow)\r
+NEXT comboRow\r
 END SUB\r
 \r
-SUB teeslg (x1, x4, l)\r
-' Prepares the logical equation for solving by simplifying expressions within parentheses\r
-x2 = x4\r
-h = 0\r
-FOR e = 1 TO 4\r
-    g = 1\r
-    a = x1\r
+SUB addPrecedenceParens (exprStart, rangeEnd, addedChars)\r
+' Parenthesizes the logical equation so that operator priority is\r
+' explicit: four passes wrap NOT first, then OR/AND, then Implies\r
+' (Equivalent needs no parentheses, it is the loosest). Each pass only\r
+' wraps an operator when the operator before it was looser (lastOpClass\r
+' tracks the previous operator's class) - otherwise plain left-to-right\r
+' evaluation already gives the right grouping.\r
+'\r
+' NOTE: the DECLARE statement names the second parameter exprEnd while\r
+' this definition names it rangeEnd. In QBasic DECLARE parameter names\r
+' are just placeholders, so exprEnd here is a plain local and only\r
+' addedChars carries the insertion count back to solveEquation.\r
+' (crtbasic versions before 2026-09-26 registered the argument cell\r
+' under both names, aliasing exprEnd to the caller's variable; fixed\r
+' to match QB45.)\r
+exprEnd = rangeEnd\r
+insertedTotal = 0\r
+FOR passIndex = 1 TO 4\r
+    lastOpClass = 1\r
+    charIndex = exprStart\r
 21\r
-    b = logicalExpression(a)\r
-    IF b = 40 THEN\r
-        c = a\r
-        d = 1\r
+    charCode = logicalExpression(charIndex)\r
+    IF charCode = 40 THEN\r
+        scanPos = charIndex\r
+        parenDepth = 1\r
 14\r
-        c = c + 1\r
-        IF logicalExpression(c) = ASC("(") THEN d = d + 1\r
-        IF logicalExpression(c) = ASC(")") THEN d = d - 1\r
-        IF d = 0 THEN GOTO 15\r
+        scanPos = scanPos + 1\r
+        IF logicalExpression(scanPos) = ASC("(") THEN parenDepth = parenDepth + 1\r
+        IF logicalExpression(scanPos) = ASC(")") THEN parenDepth = parenDepth - 1\r
+        IF parenDepth = 0 THEN GOTO 15\r
         GOTO 14\r
 15\r
-        IF e = 1 THEN teeslg a + 1, c - 1, l ELSE l = 0\r
-        a = c + l\r
-        x2 = x2 + l\r
-        h = h + l\r
+        IF passIndex = 1 THEN addPrecedenceParens charIndex + 1, scanPos - 1, addedChars ELSE addedChars = 0\r
+        charIndex = scanPos + addedChars\r
+        exprEnd = exprEnd + addedChars\r
+        insertedTotal = insertedTotal + addedChars\r
         GOTO 16\r
     END IF\r
 \r
-    IF (b = 5) AND (e = 1) AND (g > 1) THEN\r
-        mov a, 1\r
-        logicalExpression(a) = 40\r
-        lendp a + 2, f\r
-        mov a + 2 + f, 1\r
-        logicalExpression(a + 2 + f) = 41\r
-        h = h + 2\r
-        x2 = x2 + 2\r
-        a = a + 2 + f\r
+    IF (charCode = 5) AND (passIndex = 1) AND (lastOpClass > 1) THEN\r
+        shiftExpressionRight charIndex, 1\r
+        logicalExpression(charIndex) = 40\r
+        operandLengthAfter charIndex + 2, operandLength\r
+        shiftExpressionRight charIndex + 2 + operandLength, 1\r
+        logicalExpression(charIndex + 2 + operandLength) = 41\r
+        insertedTotal = insertedTotal + 2\r
+        exprEnd = exprEnd + 2\r
+        charIndex = charIndex + 2 + operandLength\r
         GOTO 16\r
     END IF\r
 \r
-    IF (b = 3 OR b = 4) AND (e = 2) AND (g > 2) THEN\r
-        lendm a - 1, f\r
-        mov a - f, 1\r
-        logicalExpression(a - f) = 40\r
-        lendp a + 2, f\r
-        mov a + 2 + f, 1\r
-        logicalExpression(a + 2 + f) = 41\r
-        h = h + 2\r
-        x2 = x2 + 2\r
-        a = a + 2 + f\r
+    IF (charCode = 3 OR charCode = 4) AND (passIndex = 2) AND (lastOpClass > 2) THEN\r
+        operandLengthBefore charIndex - 1, operandLength\r
+        shiftExpressionRight charIndex - operandLength, 1\r
+        logicalExpression(charIndex - operandLength) = 40\r
+        operandLengthAfter charIndex + 2, operandLength\r
+        shiftExpressionRight charIndex + 2 + operandLength, 1\r
+        logicalExpression(charIndex + 2 + operandLength) = 41\r
+        insertedTotal = insertedTotal + 2\r
+        exprEnd = exprEnd + 2\r
+        charIndex = charIndex + 2 + operandLength\r
         GOTO 16\r
     END IF\r
 \r
-    IF (b = 2) AND (e = 3) AND (g > 3) THEN\r
-        lendm a - 1, f\r
-        mov a - f, 1\r
-        logicalExpression(a - f) = 40\r
-        lendp a + 2, f\r
-        mov a + 2 + f, 1\r
-        logicalExpression(a + 2 + f) = 41\r
-        h = h + 2\r
-        x2 = x2 + 2\r
-        a = a + 2 + f\r
+    IF (charCode = 2) AND (passIndex = 3) AND (lastOpClass > 3) THEN\r
+        operandLengthBefore charIndex - 1, operandLength\r
+        shiftExpressionRight charIndex - operandLength, 1\r
+        logicalExpression(charIndex - operandLength) = 40\r
+        operandLengthAfter charIndex + 2, operandLength\r
+        shiftExpressionRight charIndex + 2 + operandLength, 1\r
+        logicalExpression(charIndex + 2 + operandLength) = 41\r
+        insertedTotal = insertedTotal + 2\r
+        exprEnd = exprEnd + 2\r
+        charIndex = charIndex + 2 + operandLength\r
         GOTO 16\r
     END IF\r
 \r
-    SELECT CASE b\r
+    SELECT CASE charCode\r
         CASE 5\r
-            g = 1\r
+            lastOpClass = 1\r
         CASE 3, 4\r
-            g = 2\r
+            lastOpClass = 2\r
         CASE 2\r
-            g = 3\r
+            lastOpClass = 3\r
         CASE 1\r
-            g = 4\r
+            lastOpClass = 4\r
     END SELECT\r
 16\r
-    a = a + 1\r
-    IF a <= x2 THEN GOTO 21\r
-NEXT e\r
-l = h\r
+    charIndex = charIndex + 1\r
+    IF charIndex <= exprEnd THEN GOTO 21\r
+NEXT passIndex\r
+addedChars = insertedTotal\r
 END SUB\r
-\r