;; lib/minikanren/tests/clpfd-neq.sx — fd-neq with constraint propagation. ;; --- ground / domain interaction --- (mk-test "fd-neq-ground-distinct" (run* q (fresh (x) (fd-neq x 5) (fd-in x (list 4 5 6)) (fd-label (list x)) (== q x))) (list 4 6)) (mk-test "fd-neq-ground-equal-fails" (run* q (fresh (x) (== x 5) (fd-neq x 5) (== q x))) (list)) (mk-test "fd-neq-symmetric" (run* q (fresh (x) (fd-neq 7 x) (fd-in x (list 5 6 7 8 9)) (fd-label (list x)) (== q x))) (list 5 6 8 9)) ;; --- two vars with overlapping domains --- (mk-test "fd-neq-pair-from-3" (let ((res (run* q (fresh (x y) (fd-in x (list 1 2 3)) (fd-in y (list 1 2 3)) (fd-neq x y) (fd-label (list x y)) (== q (list x y)))))) (= (len res) 6)) true) (mk-test "fd-all-distinct-3-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-neq a b) (fd-neq a c) (fd-neq b c) (fd-label (list a b c)) (== q (list a b c)))))) (= (len res) 6)) true) (mk-test "fd-pigeonhole-fails" (run* q (fresh (a b c) (fd-in a (list 1 2)) (fd-in b (list 1 2)) (fd-in c (list 1 2)) (fd-neq a b) (fd-neq a c) (fd-neq b c) (fd-label (list a b c)) (== q (list a b c)))) (list)) ;; --- propagation when one side becomes ground --- (mk-test "fd-neq-propagates-after-ground" (run* q (fresh (x y) (fd-in x (list 1 2 3)) (fd-in y (list 1 2 3)) (fd-neq x y) (== x 2) (fd-label (list y)) (== q y))) (list 1 3)) (mk-tests-run!)