;; lib/minikanren/tests/simplifyo.sx — algebraic expression simplifier
;; demo using conda for first-match-wins dispatch.

(define
  simplify-step-o
  (fn
    (expr result)
    (conda
      ((fresh (x) (== expr (list :+ 0 x)) (== result x)))
      ((fresh (x) (== expr (list :+ x 0)) (== result x)))
      ((fresh (y) (== expr (list :* 0 y)) (== result 0)))
      ((fresh (x) (== expr (list :* x 0)) (== result 0)))
      ((fresh (x) (== expr (list :* 1 x)) (== result x)))
      ((fresh (x) (== expr (list :* x 1)) (== result x)))
      ((== result expr)))))                                  ;; default: unchanged

(mk-test
  "simplify-zero-plus"
  (run* q (simplify-step-o (list :+ 0 :y) q))
  (list :y))

(mk-test
  "simplify-plus-zero"
  (run* q (simplify-step-o (list :+ :x 0) q))
  (list :x))

(mk-test
  "simplify-zero-times"
  (run* q (simplify-step-o (list :* 0 :y) q))
  (list 0))

(mk-test
  "simplify-one-times"
  (run* q (simplify-step-o (list :* 1 :y) q))
  (list :y))

(mk-test
  "simplify-no-rule-applies"
  (run* q (simplify-step-o (list :+ :x :y) q))
  (list (list :+ :x :y)))

(mk-test
  "simplify-non-identity-form"
  (run* q (simplify-step-o (list :+ 5 7) q))
  (list (list :+ 5 7)))

(mk-tests-run!)
