;; lib/minikanren/tests/conda.sx — Phase 5 piece A tests for `conda`.

;; --- conda commits to first non-failing head, keeps ALL its answers ---

(mk-test
  "conda-first-clause-keeps-all"
  (run*
    q
    (conda
      ((mk-disj (== q 1) (== q 2)))
      ((== q 100))))
  (list 1 2))

(mk-test
  "conda-skips-failing-head"
  (run*
    q
    (conda
      ((== 1 2))
      ((mk-disj (== q 10) (== q 20)))))
  (list 10 20))

(mk-test
  "conda-all-fail"
  (run*
    q
    (conda ((== 1 2)) ((== 3 4))))
  (list))

(mk-test "conda-no-clauses" (run* q (conda)) (list))

;; --- conda DIFFERS from condu: conda keeps all head answers ---

(mk-test
  "conda-vs-condu-divergence"
  (list
    (run*
      q
      (conda
        ((mk-disj (== q 1) (== q 2)))
        ((== q 100))))
    (run*
      q
      (condu
        ((mk-disj (== q 1) (== q 2)))
        ((== q 100)))))
  (list (list 1 2) (list 1)))

;; --- conda head's rest-goals run on every head answer ---

(mk-test
  "conda-rest-goals-run-on-all-answers"
  (run*
    q
    (fresh
      (x r)
      (conda
        ((mk-disj (== x 1) (== x 2))
          (== r (list :tag x))))
      (== q r)))
  (list (list :tag 1) (list :tag 2)))

;; --- if rest-goals fail on a head answer, that head answer is filtered;
;;     the clause does not fall through to next clauses (per soft-cut). ---

(mk-test
  "conda-rest-fails-no-fallthrough"
  (run*
    q
    (conda
      ((mk-disj (== q 1) (== q 2)) (== q 99))
      ((== q 200))))
  (list))

(mk-tests-run!)
