From 627400055e079483e95a6dc044f2f9641b4d887a Mon Sep 17 00:00:00 2001
From: Christian Gram Kalhauge <chrg@dtu.dk>
Date: Thu, 25 Apr 2024 10:44:15 +0200
Subject: [PATCH] Final code

---
 pyrtree/expr.py                         | 14 ++++++------
 pyrtree/rtree.py                        |  3 ++-
 rtree/rtree.cabal                       |  1 +
 rtree/src/Control/Monad/RTree/Simple.hs | 29 +++++++++++++++++++++++++
 4 files changed, 39 insertions(+), 8 deletions(-)
 create mode 100644 rtree/src/Control/Monad/RTree/Simple.hs

diff --git a/pyrtree/expr.py b/pyrtree/expr.py
index 2f5844c..e5f70b6 100644
--- a/pyrtree/expr.py
+++ b/pyrtree/expr.py
@@ -111,16 +111,16 @@ def reduce_expr(expr: Expr, check) -> Expr:
             return Const(0)
         return expr
     elif isinstance(expr, Add):
-        if check("2) reduce to lhs"):
-            return reduce_expr(expr.lhs, check)
-        if check("3) reduce to rhs"):
-            return reduce_expr(expr.rhs, check)
         lhs_ = reduce_expr(expr.lhs, check)
         rhs_ = reduce_expr(expr.rhs, check)
+        if check("2) reduce to lhs"):
+            return lhs_
+        if check("3) reduce to rhs"):
+            return rhs_
         return Add(lhs_, rhs_)
     elif isinstance(expr, Let):
         assignee_ = reduce_expr(expr.assignee, check)
-        if check("4) reduce to lhs"):
+        if check("4) reduce to assingee"):
             return assignee_
         if check(f"5) inline {expr.var!r}"):
             return reduce_expr(expr.body.replace({expr.var: assignee_}), check)
@@ -145,7 +145,7 @@ if __name__ == "__main__":
     rt = partial(reduce_expr, expr)
     p(rtree.Probe(rt, []))
     rp = rtree.reduce(p, rt)
-    print(f"&& {input_format(rp.input)} & true \\\\")
+    print(f"& \\verb|{rtree.pretty(rp)}| & {input_format(rp.input)} & true \\\\")
 
     print()
 
@@ -158,4 +158,4 @@ if __name__ == "__main__":
     rt = partial(reduce_expr, expr)
     p(rtree.Probe(rt, []))
     rp = rtree.reduce(p, rt)
-    print(f"& {rtree.pretty{rp}} & {input_format(rp.input)} & true \\\\")
+    print(f"& {rtree.pretty(rp)} & {input_format(rp.input)} & true \\\\")
diff --git a/pyrtree/rtree.py b/pyrtree/rtree.py
index 48efc46..ec34513 100644
--- a/pyrtree/rtree.py
+++ b/pyrtree/rtree.py
@@ -96,7 +96,8 @@ def pretty(rp):
         return "1" if a else "0"
 
     return "".join(
-        a for a, _ in zip_longest(map(binary, rp.path), rp.reasons, fillvalue="*")
+        a if b != "*" else "!"
+        for a, b in zip_longest(map(binary, rp.path), rp.reasons, fillvalue="*")
     )
 
 
diff --git a/rtree/rtree.cabal b/rtree/rtree.cabal
index 5b9dfbd..62066a4 100644
--- a/rtree/rtree.cabal
+++ b/rtree/rtree.cabal
@@ -13,6 +13,7 @@ library
       Control.Monad.IRTree
       Control.Monad.Reduce
       Control.Monad.RTree
+      Control.Monad.RTree.Simple
       Data.RPath
       Data.Valuation
   other-modules:
diff --git a/rtree/src/Control/Monad/RTree/Simple.hs b/rtree/src/Control/Monad/RTree/Simple.hs
new file mode 100644
index 0000000..73ab863
--- /dev/null
+++ b/rtree/src/Control/Monad/RTree/Simple.hs
@@ -0,0 +1,29 @@
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE DerivingVia #-}
+
+module Control.Monad.RTree.Simple where
+
+import Control.Monad.Identity
+import Control.Monad.State
+
+type RTree a = State ([Bool], Int) a
+
+check :: RTree Bool
+check = state \(c : cs, n) -> (c, (cs, n + 1))
+
+probe :: RTree a -> [Bool] -> (a, Int)
+probe root path = (extract, depth - length path)
+ where
+  (extract, (_, depth)) = runState root (path ++ repeat False, 0)
+
+reduce :: (a -> IO Bool) -> RTree a -> [Bool] -> IO a
+reduce predicate root path
+  | undecided > 0 = do
+      result <- predicate (fst (probe root (path ++ [True])))
+      reduce predicate root (path ++ [result])
+  | otherwise = pure extract
+ where
+  (extract, undecided) = probe root path
+
+reduceAbc :: RTree [Char]
+reduceAbc = filterM (\_ -> check) "abc"
-- 
GitLab