;; lib/minikanren/tests/clpfd-distinct.sx — fd-distinct (alldifferent).

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

(mk-test
  "fd-distinct-singleton"
  (run* q (fd-distinct (list 5)))
  (list (make-symbol "_.0")))

(mk-test
  "fd-distinct-pair-distinct"
  (run* q (fd-distinct (list 1 2)))
  (list (make-symbol "_.0")))

(mk-test
  "fd-distinct-pair-equal-fails"
  (run* q (fd-distinct (list 5 5)))
  (list))

(mk-test
  "fd-distinct-3-perms-of-3"
  (let
    ((res (run* q (fresh (a b c) (fd-in a (list 1 2 3)) (fd-in b (list 1 2 3)) (fd-in c (list 1 2 3)) (fd-distinct (list a b c)) (fd-label (list a b c)) (== q (list a b c))))))
    (= (len res) 6))
  true)

(mk-test
  "fd-distinct-4-perms-of-4-count"
  (let
    ((res (run* q (fresh (a b c d) (fd-in a (list 1 2 3 4)) (fd-in b (list 1 2 3 4)) (fd-in c (list 1 2 3 4)) (fd-in d (list 1 2 3 4)) (fd-distinct (list a b c d)) (fd-label (list a b c d)) (== q (list a b c d))))))
    (= (len res) 24))
  true)

(mk-test
  "fd-distinct-pigeonhole-fails"
  (run*
    q
    (fresh
      (a b c d)
      (fd-in a (list 1 2 3))
      (fd-in b (list 1 2 3))
      (fd-in c (list 1 2 3))
      (fd-in d (list 1 2 3))
      (fd-distinct (list a b c d))
      (fd-label (list a b c d))
      (== q (list a b c d))))
  (list))

(mk-tests-run!)
