Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
159 lines
3.9 KiB
Plaintext
159 lines
3.9 KiB
Plaintext
;; lib/prolog/tests/dynamic.sx — assert/asserta/assertz/retract.
|
|
|
|
(define pl-dy-test-count 0)
|
|
(define pl-dy-test-pass 0)
|
|
(define pl-dy-test-fail 0)
|
|
(define pl-dy-test-failures (list))
|
|
|
|
(define
|
|
pl-dy-test!
|
|
(fn
|
|
(name got expected)
|
|
(begin
|
|
(set! pl-dy-test-count (+ pl-dy-test-count 1))
|
|
(if
|
|
(= got expected)
|
|
(set! pl-dy-test-pass (+ pl-dy-test-pass 1))
|
|
(begin
|
|
(set! pl-dy-test-fail (+ pl-dy-test-fail 1))
|
|
(append!
|
|
pl-dy-test-failures
|
|
(str name "\n expected: " expected "\n got: " got)))))))
|
|
|
|
(define
|
|
pl-dy-goal
|
|
(fn
|
|
(src env)
|
|
(pl-instantiate (nth (first (pl-parse (str "g :- " src "."))) 2) env)))
|
|
|
|
;; assertz then query
|
|
(define pl-dy-db1 (pl-mk-db))
|
|
(pl-solve-once!
|
|
pl-dy-db1
|
|
(pl-dy-goal "assertz(foo(1))" {})
|
|
(pl-mk-trail))
|
|
(pl-dy-test!
|
|
"assertz(foo(1)) + foo(1)"
|
|
(pl-solve-once! pl-dy-db1 (pl-dy-goal "foo(1)" {}) (pl-mk-trail))
|
|
true)
|
|
|
|
(pl-dy-test!
|
|
"after one assertz, foo/1 has 1 clause"
|
|
(pl-solve-count! pl-dy-db1 (pl-dy-goal "foo(X)" {}) (pl-mk-trail))
|
|
1)
|
|
|
|
;; assertz appends — order preserved
|
|
(define pl-dy-db2 (pl-mk-db))
|
|
(pl-solve-once!
|
|
pl-dy-db2
|
|
(pl-dy-goal "assertz(p(1))" {})
|
|
(pl-mk-trail))
|
|
(pl-solve-once!
|
|
pl-dy-db2
|
|
(pl-dy-goal "assertz(p(2))" {})
|
|
(pl-mk-trail))
|
|
(pl-dy-test!
|
|
"assertz twice — count 2"
|
|
(pl-solve-count! pl-dy-db2 (pl-dy-goal "p(X)" {}) (pl-mk-trail))
|
|
2)
|
|
|
|
(define pl-dy-env-a {})
|
|
(pl-solve-once! pl-dy-db2 (pl-dy-goal "p(X)" pl-dy-env-a) (pl-mk-trail))
|
|
(pl-dy-test!
|
|
"assertz: first solution is the first asserted (1)"
|
|
(pl-num-val (pl-walk-deep (dict-get pl-dy-env-a "X")))
|
|
1)
|
|
|
|
;; asserta prepends
|
|
(define pl-dy-db3 (pl-mk-db))
|
|
(pl-solve-once!
|
|
pl-dy-db3
|
|
(pl-dy-goal "assertz(p(1))" {})
|
|
(pl-mk-trail))
|
|
(pl-solve-once!
|
|
pl-dy-db3
|
|
(pl-dy-goal "asserta(p(99))" {})
|
|
(pl-mk-trail))
|
|
(define pl-dy-env-b {})
|
|
(pl-solve-once! pl-dy-db3 (pl-dy-goal "p(X)" pl-dy-env-b) (pl-mk-trail))
|
|
(pl-dy-test!
|
|
"asserta: prepended clause is first solution"
|
|
(pl-num-val (pl-walk-deep (dict-get pl-dy-env-b "X")))
|
|
99)
|
|
|
|
;; assert/1 = assertz/1
|
|
(define pl-dy-db4 (pl-mk-db))
|
|
(pl-solve-once!
|
|
pl-dy-db4
|
|
(pl-dy-goal "assert(g(7))" {})
|
|
(pl-mk-trail))
|
|
(pl-dy-test!
|
|
"assert/1 alias"
|
|
(pl-solve-once! pl-dy-db4 (pl-dy-goal "g(7)" {}) (pl-mk-trail))
|
|
true)
|
|
|
|
;; retract removes a fact
|
|
(define pl-dy-db5 (pl-mk-db))
|
|
(pl-solve-once!
|
|
pl-dy-db5
|
|
(pl-dy-goal "assertz(q(1))" {})
|
|
(pl-mk-trail))
|
|
(pl-solve-once!
|
|
pl-dy-db5
|
|
(pl-dy-goal "assertz(q(2))" {})
|
|
(pl-mk-trail))
|
|
(pl-solve-once!
|
|
pl-dy-db5
|
|
(pl-dy-goal "assertz(q(3))" {})
|
|
(pl-mk-trail))
|
|
(pl-dy-test!
|
|
"before retract: 3 clauses"
|
|
(pl-solve-count! pl-dy-db5 (pl-dy-goal "q(X)" {}) (pl-mk-trail))
|
|
3)
|
|
(pl-solve-once!
|
|
pl-dy-db5
|
|
(pl-dy-goal "retract(q(2))" {})
|
|
(pl-mk-trail))
|
|
(pl-dy-test!
|
|
"after retract(q(2)): 2 clauses left"
|
|
(pl-solve-count! pl-dy-db5 (pl-dy-goal "q(X)" {}) (pl-mk-trail))
|
|
2)
|
|
|
|
(define pl-dy-env-c {})
|
|
(pl-solve-once! pl-dy-db5 (pl-dy-goal "q(X)" pl-dy-env-c) (pl-mk-trail))
|
|
(pl-dy-test!
|
|
"after retract(q(2)): first remaining is 1"
|
|
(pl-num-val (pl-walk-deep (dict-get pl-dy-env-c "X")))
|
|
1)
|
|
|
|
;; retract of non-existent
|
|
(pl-dy-test!
|
|
"retract(missing(0)) on empty db fails"
|
|
(pl-solve-once!
|
|
(pl-mk-db)
|
|
(pl-dy-goal "retract(missing(0))" {})
|
|
(pl-mk-trail))
|
|
false)
|
|
|
|
;; retract with unbound var matches first
|
|
(define pl-dy-db6 (pl-mk-db))
|
|
(pl-solve-once!
|
|
pl-dy-db6
|
|
(pl-dy-goal "assertz(r(11))" {})
|
|
(pl-mk-trail))
|
|
(pl-solve-once!
|
|
pl-dy-db6
|
|
(pl-dy-goal "assertz(r(22))" {})
|
|
(pl-mk-trail))
|
|
(define pl-dy-env-d {})
|
|
(pl-solve-once!
|
|
pl-dy-db6
|
|
(pl-dy-goal "retract(r(X))" pl-dy-env-d)
|
|
(pl-mk-trail))
|
|
(pl-dy-test!
|
|
"retract(r(X)) binds X to first match"
|
|
(pl-num-val (pl-walk-deep (dict-get pl-dy-env-d "X")))
|
|
11)
|
|
|
|
(define pl-dynamic-tests-run! (fn () {:failed pl-dy-test-fail :passed pl-dy-test-pass :total pl-dy-test-count :failures pl-dy-test-failures}))
|