;; lib/minikanren/tests/list-relations.sx — rembero, assoco, nth-o, samelengtho.

;; --- rembero (remove first occurrence) ---

(mk-test
  "rembero-element-present"
  (run*
    q
    (rembero 2 (list 1 2 3 2) q))
  (list (list 1 3 2)))

(mk-test
  "rembero-element-not-present"
  (run* q (rembero 99 (list 1 2 3) q))
  (list (list 1 2 3)))

(mk-test
  "rembero-empty"
  (run* q (rembero 1 (list) q))
  (list (list)))

(mk-test
  "rembero-only-element"
  (run* q (rembero 5 (list 5) q))
  (list (list)))

(mk-test
  "rembero-first-of-many"
  (run*
    q
    (rembero 1 (list 1 2 3 4) q))
  (list (list 2 3 4)))

;; --- assoco (alist lookup) ---

(define
  test-pairs
  (list
    (list "alice" 30)
    (list "bob" 25)
    (list "carol" 35)))

(mk-test
  "assoco-found"
  (run* q (assoco "bob" test-pairs q))
  (list 25))

(mk-test
  "assoco-first"
  (run* q (assoco "alice" test-pairs q))
  (list 30))

(mk-test "assoco-missing" (run* q (assoco "dave" test-pairs q)) (list))

(mk-test
  "assoco-find-keys-with-value"
  (run* q (assoco q test-pairs 25))
  (list "bob"))

;; --- nth-o (Peano-indexed access) ---

(mk-test
  "nth-o-zero"
  (run* q (nth-o :z (list 10 20 30) q))
  (list 10))

(mk-test
  "nth-o-one"
  (run* q (nth-o (list :s :z) (list 10 20 30) q))
  (list 20))

(mk-test
  "nth-o-two"
  (run*
    q
    (nth-o (list :s (list :s :z)) (list 10 20 30) q))
  (list 30))

(mk-test
  "nth-o-out-of-range"
  (run*
    q
    (nth-o
      (list :s (list :s (list :s :z)))
      (list 10 20 30)
      q))
  (list))

;; --- samelengtho ---

(mk-test
  "samelengtho-equal"
  (run*
    q
    (samelengtho (list 1 2 3) (list :a :b :c)))
  (list (make-symbol "_.0")))

(mk-test
  "samelengtho-different-fails"
  (run* q (samelengtho (list 1 2) (list :a :b :c)))
  (list))

(mk-test
  "samelengtho-empty-equal"
  (run* q (samelengtho (list) (list)))
  (list (make-symbol "_.0")))

(mk-test
  "samelengtho-builds-vars"
  (run 1 q (samelengtho (list 1 2 3) q))
  (list (list (make-symbol "_.0") (make-symbol "_.1") (make-symbol "_.2"))))

(mk-test
  "samelengtho-enumerates-pairs"
  (run
    3
    q
    (fresh (l1 l2) (samelengtho l1 l2) (== q (list l1 l2))))
  (list
    (list (list) (list))
    (list (list (make-symbol "_.0")) (list (make-symbol "_.1")))
    (list
      (list (make-symbol "_.0") (make-symbol "_.1"))
      (list (make-symbol "_.2") (make-symbol "_.3")))))

(mk-tests-run!)
