Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
168 lines
3.9 KiB
Plaintext
168 lines
3.9 KiB
Plaintext
;; lib/prolog/tests/findall.sx — findall/3, bagof/3, setof/3.
|
|
|
|
(define pl-fb-test-count 0)
|
|
(define pl-fb-test-pass 0)
|
|
(define pl-fb-test-fail 0)
|
|
(define pl-fb-test-failures (list))
|
|
|
|
(define
|
|
pl-fb-test!
|
|
(fn
|
|
(name got expected)
|
|
(begin
|
|
(set! pl-fb-test-count (+ pl-fb-test-count 1))
|
|
(if
|
|
(= got expected)
|
|
(set! pl-fb-test-pass (+ pl-fb-test-pass 1))
|
|
(begin
|
|
(set! pl-fb-test-fail (+ pl-fb-test-fail 1))
|
|
(append!
|
|
pl-fb-test-failures
|
|
(str name "\n expected: " expected "\n got: " got)))))))
|
|
|
|
(define
|
|
pl-fb-term-to-sx
|
|
(fn
|
|
(t)
|
|
(cond
|
|
((pl-num? t) (pl-num-val t))
|
|
((pl-atom? t) (pl-atom-name t))
|
|
(true (list :complex)))))
|
|
|
|
(define
|
|
pl-fb-list-walked
|
|
(fn
|
|
(w)
|
|
(cond
|
|
((and (pl-atom? w) (= (pl-atom-name w) "[]")) (list))
|
|
((and (pl-compound? w) (= (pl-fun w) ".") (= (len (pl-args w)) 2))
|
|
(cons
|
|
(pl-fb-term-to-sx (first (pl-args w)))
|
|
(pl-fb-list-walked (nth (pl-args w) 1))))
|
|
(true (list :not-list)))))
|
|
|
|
(define pl-fb-list-to-sx (fn (t) (pl-fb-list-walked (pl-walk-deep t))))
|
|
|
|
(define
|
|
pl-fb-goal
|
|
(fn
|
|
(src env)
|
|
(pl-instantiate (nth (first (pl-parse (str "g :- " src "."))) 2) env)))
|
|
|
|
(define pl-fb-prog-src "member(X, [X|_]). member(X, [_|T]) :- member(X, T).")
|
|
|
|
(define pl-fb-db (pl-mk-db))
|
|
(pl-db-load! pl-fb-db (pl-parse pl-fb-prog-src))
|
|
|
|
;; ── findall ──
|
|
|
|
(define pl-fb-env-1 {})
|
|
(pl-solve-once!
|
|
pl-fb-db
|
|
(pl-fb-goal "findall(X, member(X, [a, b, c]), L)" pl-fb-env-1)
|
|
(pl-mk-trail))
|
|
(pl-fb-test!
|
|
"findall member [a, b, c]"
|
|
(pl-fb-list-to-sx (dict-get pl-fb-env-1 "L"))
|
|
(list "a" "b" "c"))
|
|
|
|
(define pl-fb-env-2 {})
|
|
(pl-solve-once!
|
|
pl-fb-db
|
|
(pl-fb-goal "findall(X, (member(X, [1, 2, 3]), X >= 2), L)" pl-fb-env-2)
|
|
(pl-mk-trail))
|
|
(pl-fb-test!
|
|
"findall with comparison filter"
|
|
(pl-fb-list-to-sx (dict-get pl-fb-env-2 "L"))
|
|
(list 2 3))
|
|
|
|
(define pl-fb-env-3 {})
|
|
(pl-solve-once!
|
|
pl-fb-db
|
|
(pl-fb-goal "findall(X, fail, L)" pl-fb-env-3)
|
|
(pl-mk-trail))
|
|
(pl-fb-test!
|
|
"findall on fail succeeds with empty list"
|
|
(pl-fb-list-to-sx (dict-get pl-fb-env-3 "L"))
|
|
(list))
|
|
|
|
(pl-fb-test!
|
|
"findall(X, fail, L) the goal succeeds"
|
|
(pl-solve-once!
|
|
pl-fb-db
|
|
(pl-fb-goal "findall(X, fail, L)" {})
|
|
(pl-mk-trail))
|
|
true)
|
|
|
|
(define pl-fb-env-4 {})
|
|
(pl-solve-once!
|
|
pl-fb-db
|
|
(pl-fb-goal
|
|
"findall(p(X, Y), (member(X, [1, 2]), member(Y, [a, b])), L)"
|
|
pl-fb-env-4)
|
|
(pl-mk-trail))
|
|
(pl-fb-test!
|
|
"findall over compound template — count = 4"
|
|
(len (pl-fb-list-to-sx (dict-get pl-fb-env-4 "L")))
|
|
4)
|
|
|
|
;; ── bagof ──
|
|
|
|
(pl-fb-test!
|
|
"bagof succeeds when results exist"
|
|
(pl-solve-once!
|
|
pl-fb-db
|
|
(pl-fb-goal "bagof(X, member(X, [1, 2, 3]), L)" {})
|
|
(pl-mk-trail))
|
|
true)
|
|
|
|
(pl-fb-test!
|
|
"bagof fails on empty"
|
|
(pl-solve-once!
|
|
pl-fb-db
|
|
(pl-fb-goal "bagof(X, fail, L)" {})
|
|
(pl-mk-trail))
|
|
false)
|
|
|
|
(define pl-fb-env-5 {})
|
|
(pl-solve-once!
|
|
pl-fb-db
|
|
(pl-fb-goal "bagof(X, member(X, [c, a, b]), L)" pl-fb-env-5)
|
|
(pl-mk-trail))
|
|
(pl-fb-test!
|
|
"bagof preserves order"
|
|
(pl-fb-list-to-sx (dict-get pl-fb-env-5 "L"))
|
|
(list "c" "a" "b"))
|
|
|
|
;; ── setof ──
|
|
|
|
(define pl-fb-env-6 {})
|
|
(pl-solve-once!
|
|
pl-fb-db
|
|
(pl-fb-goal "setof(X, member(X, [c, a, b, a, c]), L)" pl-fb-env-6)
|
|
(pl-mk-trail))
|
|
(pl-fb-test!
|
|
"setof sorts + dedupes atoms"
|
|
(pl-fb-list-to-sx (dict-get pl-fb-env-6 "L"))
|
|
(list "a" "b" "c"))
|
|
|
|
(pl-fb-test!
|
|
"setof fails on empty"
|
|
(pl-solve-once!
|
|
pl-fb-db
|
|
(pl-fb-goal "setof(X, fail, L)" {})
|
|
(pl-mk-trail))
|
|
false)
|
|
|
|
(define pl-fb-env-7 {})
|
|
(pl-solve-once!
|
|
pl-fb-db
|
|
(pl-fb-goal "setof(X, member(X, [3, 1, 2, 1, 3]), L)" pl-fb-env-7)
|
|
(pl-mk-trail))
|
|
(pl-fb-test!
|
|
"setof sorts + dedupes nums"
|
|
(pl-fb-list-to-sx (dict-get pl-fb-env-7 "L"))
|
|
(list 1 2 3))
|
|
|
|
(define pl-findall-tests-run! (fn () {:failed pl-fb-test-fail :passed pl-fb-test-pass :total pl-fb-test-count :failures pl-fb-test-failures}))
|