;; lib/minikanren/tests/tabling-more.sx — table-1 + table-3.

;; --- table-1 (predicate caching) ---

(define
  tab-in-list
  (table-1
    "in-list"
    (fn
      (x)
      (membero
        x
        (list 1 2 3 4 5)))))

(mk-tab-clear!)
(mk-test
  "table-1-hit"
  (run* q (tab-in-list 3))
  (list (make-symbol "_.0")))
(mk-test "table-1-miss-no" (run* q (tab-in-list 99)) (list))
(mk-test
  "table-1-replay"
  (run* q (tab-in-list 3))
  (list (make-symbol "_.0")))

;; --- table-3 (Ackermann) ---

(define
  ack-o
  (table-3
    "ack"
    (fn
      (m n result)
      (conde
        ((== m 0) (pluso-i n 1 result))
        ((fresh (m-1) (lto-i 0 m) (== n 0) (minuso-i m 1 m-1) (ack-o m-1 1 result)))
        ((fresh (m-1 n-1 inner) (lto-i 0 m) (lto-i 0 n) (minuso-i m 1 m-1) (minuso-i n 1 n-1) (ack-o m n-1 inner) (ack-o m-1 inner result)))))))

(mk-tab-clear!)
(mk-test
  "ack-0-0"
  (run* q (ack-o 0 0 q))
  (list 1))
(mk-tab-clear!)
(mk-test
  "ack-2-3"
  (run* q (ack-o 2 3 q))
  (list 9))
(mk-tab-clear!)
(mk-test
  "ack-3-3"
  (run* q (ack-o 3 3 q))
  (list 61))

(mk-tests-run!)
