;; lib/minikanren/tests/clpfd-bounds.sx — Phase 6 piece B: bounds-consistency ;; for fd-plus and fd-times in the partial- and all-domain cases. ;; ;; We probe domains directly (peek at the FD store) before any labelling ;; happens. This isolates the propagator's narrowing behaviour from the ;; search engine. (define probe-dom (fn (goal var-key) (let ((s (first (stream-take 1 (goal empty-s))))) (cond ((= s nil) :no-subst) (:else (fd-domain-of s var-key)))))) ;; --- fd-plus partial-domain narrowing --- (mk-test "fd-plus-vvn-narrows-x" (let ((x (mk-var "x")) (y (mk-var "y"))) (probe-dom (mk-conj (fd-in x (list 1 2 3 4 5 6 7 8 9 10)) (fd-in y (list 1 2 3)) (fd-plus x y 10)) "x")) (list 7 8 9)) (mk-test "fd-plus-vvn-narrows-y" (let ((x (mk-var "x")) (y (mk-var "y"))) (probe-dom (mk-conj (fd-in x (list 1 2 3 4 5 6 7 8 9 10)) (fd-in y (list 1 2 3)) (fd-plus x y 10)) "y")) (list 1 2 3)) (mk-test "fd-plus-nvv-narrows" (let ((y (mk-var "y")) (z (mk-var "z"))) (probe-dom (mk-conj (fd-in y (list 1 2 3)) (fd-in z (list 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20)) (fd-plus 5 y z)) "z")) (list 6 7 8)) (mk-test "fd-plus-vvv-narrows-z" (let ((x (mk-var "x")) (y (mk-var "y")) (z (mk-var "z"))) (probe-dom (mk-conj (fd-in x (list 1 2 3)) (fd-in y (list 1 2 3)) (fd-in z (list 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20)) (fd-plus x y z)) "z")) (list 2 3 4 5 6)) (mk-test "fd-plus-vvv-narrows-x" (let ((x (mk-var "x")) (y (mk-var "y")) (z (mk-var "z"))) (probe-dom (mk-conj (fd-in x (list 1 2 3 4 5 6 7 8 9 10)) (fd-in y (list 1 2 3)) (fd-in z (list 5 6 7)) (fd-plus x y z)) "x")) (list 2 3 4 5 6)) ;; --- fd-times partial-domain narrowing (positive domains) --- (mk-test "fd-times-vvn-narrows" (let ((x (mk-var "x")) (y (mk-var "y"))) (probe-dom (mk-conj (fd-in x (list 1 2 3 4 5 6)) (fd-in y (list 1 2 3 4 5 6)) (fd-times x y 12)) "x")) (list 2 3 4 5 6)) (mk-test "fd-times-nvv-narrows" (let ((y (mk-var "y")) (z (mk-var "z"))) (probe-dom (mk-conj (fd-in y (list 1 2 3 4)) (fd-in z (list 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20)) (fd-times 3 y z)) "z")) (list 3 4 5 6 7 8 9 10 11 12)) (mk-test "fd-times-vvv-narrows" (let ((x (mk-var "x")) (y (mk-var "y")) (z (mk-var "z"))) (probe-dom (mk-conj (fd-in x (list 1 2 3)) (fd-in y (list 1 2 3)) (fd-in z (list 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20)) (fd-times x y z)) "z")) (list 1 2 3 4 5 6 7 8 9)) ;; --- bounds force impossible branches to fail early --- (mk-test "fd-plus-impossible-via-bounds" (let ((x (mk-var "x")) (y (mk-var "y"))) (probe-dom (mk-conj (fd-in x (list 1 2 3 4 5 6 7 8 9 10)) (fd-in y (list 1 2 3 4 5 6 7 8 9 10)) (fd-plus x y 100)) "x")) :no-subst) (mk-tests-run!)