Files
rose-ash/lib/minikanren/tests/sudoku-4x4.sx
giles 2921aa30b4
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 54s
mk: phase 6 piece D — send-more-money + Sudoku 4x4
Two CLP(FD) demo puzzles plus an underlying improvement.

clpfd.sx: each fd-* posting goal now wraps its post-time propagation
in fd-fire-store, so cross-constraint narrowing happens BEFORE
labelling. Without this, a chain like fd-eq xyc z-plus-tenc1 followed
by fd-plus 2 ten-c1 z-plus-tenc1 wouldn't deduce ten-c1 = 10 until
labelling kicked in. Now the deduction happens at goal-construction
time. Guard against (c s2) returning nil before fd-fire-store runs.

tests/send-more-money.sx: full column-by-column carry encoding
(D+E = Y+10*c1; N+R+c1 = E+10*c2; E+O+c2 = N+10*c3; S+M+c3 = O+10*M).
Verifies the encoding against the known answer (9 5 6 7 1 0 8 2);
the full search labelling 11 vars from {0..9} is too slow for naive
labelling order — documented as a known limitation. Real CLP(FD)
needs first-fail / failure-driven heuristics for SMM to be fast.

tests/sudoku-4x4.sx: 16 cells / 12 distinctness constraints. The
empty grid enumerates exactly 288 distinct fillings (the known count
for 4x4 Latin squares with 2x2 box constraints). An impossible-clue
test (two 1s in row 0) fails immediately.

50/50 sudoku + smm tests, full clpfd suite green at 132/132.
2026-05-09 14:06:47 +00:00

90 lines
2.4 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
;; lib/minikanren/tests/sudoku-4x4.sx — Sudoku 4×4 via CLP(FD).
;;
;; Grid in row-major order:
;;
;; c0 c1 | c2 c3
;; c4 c5 | c6 c7
;; ------+------
;; c8 c9 | cA cB
;; cC cD | cE cF
;;
;; Each cell ∈ {1, 2, 3, 4}. 4 rows + 4 cols + 4 2x2 boxes are each a
;; distinct permutation.
(define digits-1-4 (list 1 2 3 4))
(define
sudoku-4x4
(fn
(cells)
(let
((c0 (nth cells 0))
(c1 (nth cells 1))
(c2 (nth cells 2))
(c3 (nth cells 3))
(c4 (nth cells 4))
(c5 (nth cells 5))
(c6 (nth cells 6))
(c7 (nth cells 7))
(c8 (nth cells 8))
(c9 (nth cells 9))
(cA (nth cells 10))
(cB (nth cells 11))
(cC (nth cells 12))
(cD (nth cells 13))
(cE (nth cells 14))
(cF (nth cells 15)))
(mk-conj
(fd-in c0 digits-1-4)
(fd-in c1 digits-1-4)
(fd-in c2 digits-1-4)
(fd-in c3 digits-1-4)
(fd-in c4 digits-1-4)
(fd-in c5 digits-1-4)
(fd-in c6 digits-1-4)
(fd-in c7 digits-1-4)
(fd-in c8 digits-1-4)
(fd-in c9 digits-1-4)
(fd-in cA digits-1-4)
(fd-in cB digits-1-4)
(fd-in cC digits-1-4)
(fd-in cD digits-1-4)
(fd-in cE digits-1-4)
(fd-in cF digits-1-4)
(fd-distinct (list c0 c1 c2 c3))
(fd-distinct (list c4 c5 c6 c7))
(fd-distinct (list c8 c9 cA cB))
(fd-distinct (list cC cD cE cF))
(fd-distinct (list c0 c4 c8 cC))
(fd-distinct (list c1 c5 c9 cD))
(fd-distinct (list c2 c6 cA cE))
(fd-distinct (list c3 c7 cB cF))
(fd-distinct (list c0 c1 c4 c5))
(fd-distinct (list c2 c3 c6 c7))
(fd-distinct (list c8 c9 cC cD))
(fd-distinct (list cA cB cE cF))
(fd-label cells)))))
;; --- Tests ---
(mk-test
"sudoku-4x4-empty-grid-count"
(let
((sols (run* q (fresh (c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 cA cB cC cD cE cF) (== q (list c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 cA cB cC cD cE cF)) (sudoku-4x4 (list c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 cA cB cC cD cE cF))))))
(len sols))
288)
(mk-test
"sudoku-4x4-impossible-clue-empty"
(run*
q
(fresh
(c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 cA cB cC cD cE cF)
(== c0 1)
(== c1 1)
(== q (list c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 cA cB cC cD cE cF))
(sudoku-4x4 (list c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 cA cB cC cD cE cF))))
(list))
(mk-tests-run!)