Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
Adds 5 new built-in predicates to the Prolog runtime with 15 tests. 390 → 405 tests across 20 suites (all passing). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
196 lines
6.2 KiB
Plaintext
196 lines
6.2 KiB
Plaintext
;; lib/prolog/tests/set_predicates.sx — foldl/4, list_to_set/2, intersection/3, subtract/3, union/3
|
|
|
|
(define pl-sp-test-count 0)
|
|
(define pl-sp-test-pass 0)
|
|
(define pl-sp-test-fail 0)
|
|
(define pl-sp-test-failures (list))
|
|
|
|
(define
|
|
pl-sp-test!
|
|
(fn
|
|
(name got expected)
|
|
(begin
|
|
(set! pl-sp-test-count (+ pl-sp-test-count 1))
|
|
(if
|
|
(= got expected)
|
|
(set! pl-sp-test-pass (+ pl-sp-test-pass 1))
|
|
(begin
|
|
(set! pl-sp-test-fail (+ pl-sp-test-fail 1))
|
|
(append!
|
|
pl-sp-test-failures
|
|
(str name "\n expected: " expected "\n got: " got)))))))
|
|
|
|
(define
|
|
pl-sp-goal
|
|
(fn
|
|
(src env)
|
|
(pl-instantiate (nth (first (pl-parse (str "g :- " src "."))) 2) env)))
|
|
|
|
;; DB with add/3 for foldl tests
|
|
(define pl-sp-db (pl-mk-db))
|
|
(pl-db-load! pl-sp-db (pl-parse "add(X, Acc, NAcc) :- NAcc is Acc + X."))
|
|
|
|
;; ── foldl/4 ────────────────────────────────────────────────────────
|
|
|
|
(define pl-sp-env-fl1 {:S (pl-mk-rt-var "S")})
|
|
(pl-solve-once!
|
|
pl-sp-db
|
|
(pl-sp-goal "foldl(add, [1,2,3,4], 0, S)" pl-sp-env-fl1)
|
|
(pl-mk-trail))
|
|
(pl-sp-test!
|
|
"foldl(add,[1,2,3,4],0,S) -> S=10"
|
|
(pl-num-val (pl-walk-deep (dict-get pl-sp-env-fl1 "S")))
|
|
10)
|
|
|
|
(define pl-sp-env-fl2 {:S (pl-mk-rt-var "S")})
|
|
(pl-solve-once!
|
|
pl-sp-db
|
|
(pl-sp-goal "foldl(add, [], 5, S)" pl-sp-env-fl2)
|
|
(pl-mk-trail))
|
|
(pl-sp-test!
|
|
"foldl(add,[],5,S) -> S=5"
|
|
(pl-num-val (pl-walk-deep (dict-get pl-sp-env-fl2 "S")))
|
|
5)
|
|
|
|
(define pl-sp-env-fl3 {:S (pl-mk-rt-var "S")})
|
|
(pl-solve-once!
|
|
pl-sp-db
|
|
(pl-sp-goal "foldl(add, [1,2,3], 0, S)" pl-sp-env-fl3)
|
|
(pl-mk-trail))
|
|
(pl-sp-test!
|
|
"foldl(add,[1,2,3],0,S) -> S=6"
|
|
(pl-num-val (pl-walk-deep (dict-get pl-sp-env-fl3 "S")))
|
|
6)
|
|
|
|
;; ── list_to_set/2 ──────────────────────────────────────────────────
|
|
|
|
(define pl-sp-env-lts1 {:R (pl-mk-rt-var "R")})
|
|
(pl-solve-once!
|
|
pl-sp-db
|
|
(pl-sp-goal "list_to_set([1,2,3,2,1], R)" pl-sp-env-lts1)
|
|
(pl-mk-trail))
|
|
(pl-sp-test!
|
|
"list_to_set([1,2,3,2,1],R) -> [1,2,3]"
|
|
(pl-format-term (pl-walk-deep (dict-get pl-sp-env-lts1 "R")))
|
|
".(1, .(2, .(3, [])))")
|
|
|
|
(define pl-sp-env-lts2 {:R (pl-mk-rt-var "R")})
|
|
(pl-solve-once!
|
|
pl-sp-db
|
|
(pl-sp-goal "list_to_set([], R)" pl-sp-env-lts2)
|
|
(pl-mk-trail))
|
|
(pl-sp-test!
|
|
"list_to_set([],R) -> []"
|
|
(pl-format-term (pl-walk-deep (dict-get pl-sp-env-lts2 "R")))
|
|
"[]")
|
|
|
|
(define pl-sp-env-lts3 {:R (pl-mk-rt-var "R")})
|
|
(pl-solve-once!
|
|
pl-sp-db
|
|
(pl-sp-goal "list_to_set([a,b,a,c], R)" pl-sp-env-lts3)
|
|
(pl-mk-trail))
|
|
(pl-sp-test!
|
|
"list_to_set([a,b,a,c],R) -> [a,b,c]"
|
|
(pl-format-term (pl-walk-deep (dict-get pl-sp-env-lts3 "R")))
|
|
".(a, .(b, .(c, [])))")
|
|
|
|
;; ── intersection/3 ─────────────────────────────────────────────────
|
|
|
|
(define pl-sp-env-int1 {:R (pl-mk-rt-var "R")})
|
|
(pl-solve-once!
|
|
pl-sp-db
|
|
(pl-sp-goal "intersection([1,2,3,4], [2,4,6], R)" pl-sp-env-int1)
|
|
(pl-mk-trail))
|
|
(pl-sp-test!
|
|
"intersection([1,2,3,4],[2,4,6],R) -> [2,4]"
|
|
(pl-format-term (pl-walk-deep (dict-get pl-sp-env-int1 "R")))
|
|
".(2, .(4, []))")
|
|
|
|
(define pl-sp-env-int2 {:R (pl-mk-rt-var "R")})
|
|
(pl-solve-once!
|
|
pl-sp-db
|
|
(pl-sp-goal "intersection([1,2,3], [4,5,6], R)" pl-sp-env-int2)
|
|
(pl-mk-trail))
|
|
(pl-sp-test!
|
|
"intersection([1,2,3],[4,5,6],R) -> []"
|
|
(pl-format-term (pl-walk-deep (dict-get pl-sp-env-int2 "R")))
|
|
"[]")
|
|
|
|
(define pl-sp-env-int3 {:R (pl-mk-rt-var "R")})
|
|
(pl-solve-once!
|
|
pl-sp-db
|
|
(pl-sp-goal "intersection([], [1,2,3], R)" pl-sp-env-int3)
|
|
(pl-mk-trail))
|
|
(pl-sp-test!
|
|
"intersection([],[1,2,3],R) -> []"
|
|
(pl-format-term (pl-walk-deep (dict-get pl-sp-env-int3 "R")))
|
|
"[]")
|
|
|
|
;; ── subtract/3 ─────────────────────────────────────────────────────
|
|
|
|
(define pl-sp-env-sub1 {:R (pl-mk-rt-var "R")})
|
|
(pl-solve-once!
|
|
pl-sp-db
|
|
(pl-sp-goal "subtract([1,2,3,4], [2,4], R)" pl-sp-env-sub1)
|
|
(pl-mk-trail))
|
|
(pl-sp-test!
|
|
"subtract([1,2,3,4],[2,4],R) -> [1,3]"
|
|
(pl-format-term (pl-walk-deep (dict-get pl-sp-env-sub1 "R")))
|
|
".(1, .(3, []))")
|
|
|
|
(define pl-sp-env-sub2 {:R (pl-mk-rt-var "R")})
|
|
(pl-solve-once!
|
|
pl-sp-db
|
|
(pl-sp-goal "subtract([1,2,3], [], R)" pl-sp-env-sub2)
|
|
(pl-mk-trail))
|
|
(pl-sp-test!
|
|
"subtract([1,2,3],[],R) -> [1,2,3]"
|
|
(pl-format-term (pl-walk-deep (dict-get pl-sp-env-sub2 "R")))
|
|
".(1, .(2, .(3, [])))")
|
|
|
|
(define pl-sp-env-sub3 {:R (pl-mk-rt-var "R")})
|
|
(pl-solve-once!
|
|
pl-sp-db
|
|
(pl-sp-goal "subtract([], [1,2], R)" pl-sp-env-sub3)
|
|
(pl-mk-trail))
|
|
(pl-sp-test!
|
|
"subtract([],[1,2],R) -> []"
|
|
(pl-format-term (pl-walk-deep (dict-get pl-sp-env-sub3 "R")))
|
|
"[]")
|
|
|
|
;; ── union/3 ────────────────────────────────────────────────────────
|
|
|
|
(define pl-sp-env-uni1 {:R (pl-mk-rt-var "R")})
|
|
(pl-solve-once!
|
|
pl-sp-db
|
|
(pl-sp-goal "union([1,2,3], [2,3,4], R)" pl-sp-env-uni1)
|
|
(pl-mk-trail))
|
|
(pl-sp-test!
|
|
"union([1,2,3],[2,3,4],R) -> [1,2,3,4]"
|
|
(pl-format-term (pl-walk-deep (dict-get pl-sp-env-uni1 "R")))
|
|
".(1, .(2, .(3, .(4, []))))")
|
|
|
|
(define pl-sp-env-uni2 {:R (pl-mk-rt-var "R")})
|
|
(pl-solve-once!
|
|
pl-sp-db
|
|
(pl-sp-goal "union([], [1,2], R)" pl-sp-env-uni2)
|
|
(pl-mk-trail))
|
|
(pl-sp-test!
|
|
"union([],[1,2],R) -> [1,2]"
|
|
(pl-format-term (pl-walk-deep (dict-get pl-sp-env-uni2 "R")))
|
|
".(1, .(2, []))")
|
|
|
|
(define pl-sp-env-uni3 {:R (pl-mk-rt-var "R")})
|
|
(pl-solve-once!
|
|
pl-sp-db
|
|
(pl-sp-goal "union([1,2], [], R)" pl-sp-env-uni3)
|
|
(pl-mk-trail))
|
|
(pl-sp-test!
|
|
"union([1,2],[],R) -> [1,2]"
|
|
(pl-format-term (pl-walk-deep (dict-get pl-sp-env-uni3 "R")))
|
|
".(1, .(2, []))")
|
|
|
|
;; ── Runner ─────────────────────────────────────────────────────────
|
|
|
|
(define pl-set-predicates-tests-run! (fn () {:failed pl-sp-test-fail :passed pl-sp-test-pass :total pl-sp-test-count :failures pl-sp-test-failures}))
|