Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 54s
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.
98 lines
2.0 KiB
Plaintext
98 lines
2.0 KiB
Plaintext
;; lib/minikanren/tests/send-more-money.sx — classic cryptarithmetic
|
|
;;
|
|
;; S E N D
|
|
;; + M O R E
|
|
;; ---------
|
|
;; M O N E Y
|
|
;;
|
|
;; Column-by-column encoding with carries c1, c2, c3, and the
|
|
;; leftmost column produces a carry which equals M (the result is 5 digits).
|
|
;; All 8 letters distinct; S ≠ 0, M ≠ 0.
|
|
;; Unique solution: S=9, E=5, N=6, D=7, M=1, O=0, R=8, Y=2.
|
|
;;
|
|
;; Note: the full search labelling 11 variables from {0..9} is too slow
|
|
;; for naive labelling order (10^11 combinations naively, even with
|
|
;; bounds-consistency the branching factor dominates). Real CLP(FD)
|
|
;; systems use first-fail heuristics. Here we only verify the encoding
|
|
;; against the known answer.
|
|
|
|
(define
|
|
digits-0-9
|
|
(list
|
|
0
|
|
1
|
|
2
|
|
3
|
|
4
|
|
5
|
|
6
|
|
7
|
|
8
|
|
9))
|
|
(define
|
|
digits-1-9
|
|
(list
|
|
1
|
|
2
|
|
3
|
|
4
|
|
5
|
|
6
|
|
7
|
|
8
|
|
9))
|
|
|
|
(define
|
|
smm-col-with-carry
|
|
(fn
|
|
(x y carry-in z carry-out)
|
|
(fresh
|
|
(xy xyc ten-cout z-plus-ten-cout)
|
|
(fd-plus x y xy)
|
|
(fd-plus xy carry-in xyc)
|
|
(fd-times 10 carry-out ten-cout)
|
|
(fd-plus z ten-cout z-plus-ten-cout)
|
|
(fd-eq xyc z-plus-ten-cout))))
|
|
|
|
(define
|
|
send-more-money
|
|
(fn
|
|
(S E N D M O R Y)
|
|
(fresh
|
|
(c1 c2 c3)
|
|
(mk-conj
|
|
(fd-in S digits-1-9)
|
|
(fd-in M digits-1-9)
|
|
(fd-in E digits-0-9)
|
|
(fd-in N digits-0-9)
|
|
(fd-in D digits-0-9)
|
|
(fd-in O digits-0-9)
|
|
(fd-in R digits-0-9)
|
|
(fd-in Y digits-0-9)
|
|
(fd-in c1 (list 0 1))
|
|
(fd-in c2 (list 0 1))
|
|
(fd-in c3 (list 0 1))
|
|
(fd-distinct (list S E N D M O R Y))
|
|
(smm-col-with-carry D E 0 Y c1)
|
|
(smm-col-with-carry N R c1 E c2)
|
|
(smm-col-with-carry E O c2 N c3)
|
|
(smm-col-with-carry S M c3 O M)
|
|
(fd-label (list S E N D M O R Y c1 c2 c3))))))
|
|
|
|
(mk-test
|
|
"send-more-money-verify-known-solution"
|
|
(run*
|
|
q
|
|
(send-more-money
|
|
9
|
|
5
|
|
6
|
|
7
|
|
1
|
|
0
|
|
8
|
|
2))
|
|
(list (make-symbol "_.0")))
|
|
|
|
(mk-tests-run!)
|