Add constant dump info
author |
Steve Losh <steve@stevelosh.com> |
date |
Sun, 05 Jun 2016 12:27:01 +0000 |
parents |
e244881864f7 |
children |
72bbdd515725 |
(in-package #:bones-test.wam)
(def-suite :bones.wam)
(in-suite :bones.wam)
;;;; Setup
(defun make-test-database ()
(let ((db (make-database)))
(with-database db
(facts (always))
(facts (drinks tom :anything)
(drinks kim water)
(drinks alice bourbon)
(drinks bob genny-cream)
(drinks candace birch-beer))
(facts (listens alice blues)
(listens alice jazz)
(listens bob blues)
(listens bob rock)
(listens candace blues))
(facts (fuzzy cats))
(facts (cute cats)
(cute snakes))
(rules ((pets alice :what)
(cute :what))
((pets bob :what)
(cute :what)
(fuzzy :what))
((pets candace :bird)
(flies :bird)))
(rules ((likes sally :who)
(likes :who cats)
(drinks :who beer))
((likes tom cats))
((likes alice cats))
((likes kim cats))
((likes kim :who)
(likes :who cats)))
(rules ((narcissist :person)
(likes :person :person)))
(rules ((member :x '(:x . :rest)))
((member :x '(:y . :rest))
(member :x :rest))))
db))
(defparameter *test-database* (make-test-database))
;;;; Utils
(defun result= (x y)
(set-equal (plist-alist x)
(plist-alist y)
:test #'equal))
(defun results= (r1 r2)
(set-equal r1 r2 :test #'result=))
(defmacro q (&body query)
`(return-all ,@query))
(defmacro should-fail (&body queries)
`(progn
,@(loop :for query :in queries :collect
`(is (results= nil (q ,query))))))
(defmacro should-return (&body queries)
`(progn
,@(loop :for (query results) :in queries :collect
`(is (results= ',results (q ,query))))))
;;;; Tests
(test facts-literal
(with-database *test-database*
(is (results= '(nil) (q (always))))
(is (results= '(nil) (q (fuzzy cats))))
(is (results= nil (q (fuzzy snakes))))))
(test facts-variables
(with-database *test-database*
(is (results= '((:what cats))
(q (fuzzy :what))))
(is (results= '((:what blues)
(:what rock))
(q (listens bob :what))))
(is (results= '((:who alice)
(:who bob)
(:who candace))
(q (listens :who blues))))
(is (results= '()
(q (listens :who metal))))))
(test facts-conjunctions
(with-database *test-database*
(is (results= '((:who alice))
(q (listens :who blues)
(listens :who jazz))))
(is (results= '((:who alice))
(q (listens :who blues)
(drinks :who bourbon))))
(is (results= '((:what bourbon :who alice)
(:what genny-cream :who bob)
(:what birch-beer :who candace))
(q (listens :who blues)
(drinks :who :what))))))
(test backtracking
(with-fresh-database
(facts (a))
(facts (b))
(facts (c))
(facts (d))
(rules ((f :x) (a))
((f :x) (b) (c))
((f :x) (d)))
(should-return
((f foo)
(nil))))
(with-fresh-database
; (facts (a))
(facts (b))
(facts (c))
(facts (d))
(rules ((f :x) (a))
((f :x) (b) (c))
((f :x) (d)))
(should-return
((f foo)
(nil))))
(with-fresh-database
; (facts (a))
(facts (b))
(facts (c))
; (facts (d))
(rules ((f :x) (a))
((f :x) (b) (c))
((f :x) (d)))
(should-return
((f foo)
(nil))))
(with-fresh-database
; (facts (a))
; (facts (b))
(facts (c))
; (facts (d))
(rules ((f :x) (a))
((f :x) (b) (c))
((f :x) (d)))
(should-return
((f foo)
nil)))
(with-fresh-database
; (facts (a))
(facts (b))
; (facts (c))
; (facts (d))
(rules ((f :x) (a))
((f :x) (b) (c))
((f :x) (d)))
(should-return
((f foo)
nil))))
(test basic-rules
(with-database *test-database*
(should-fail
(pets candace :what))
(should-return
((pets alice :what)
((:what snakes) (:what cats)))
((pets bob :what)
((:what cats)))
((pets :who snakes)
((:who alice)))
((likes kim :who)
((:who tom)
(:who alice)
(:who kim)
(:who cats)))
((likes sally :who)
((:who tom)))
((narcissist :person)
((:person kim))))))
(test lists
(with-database *test-database*
(should-fail
(member :anything nil)
(member a nil)
(member b '(a))
(member '(a) '(a))
(member a '('(a))))
(should-return
((member :m '(a))
((:m a)))
((member :m '(a b))
((:m a) (:m b)))
((member :m '(a b a))
((:m a) (:m b)))
((member a '(a))
(nil))
((member '(foo) '(a '(foo) b))
(nil)))))
(test cut
(with-fresh-database
(facts (a))
(facts (b))
(facts (c))
(facts (d))
(rules ((f a) (a))
((f bc) (b) ! (c))
((f d) (d)))
(rules ((g :what) (never))
((g :what) (f :what)))
(should-return
((f :what) ((:what a)
(:what bc)))
((g :what) ((:what a)
(:what bc)))))
(with-fresh-database
; (facts (a))
(facts (b))
(facts (c))
(facts (d))
(rules ((f a) (a))
((f bc) (b) ! (c))
((f d) (d)))
(rules ((g :what) (never))
((g :what) (f :what)))
(should-return
((f :what) ((:what bc)))
((g :what) ((:what bc)))))
(with-fresh-database
; (facts (a))
; (facts (b))
(facts (c))
(facts (d))
(rules ((f a) (a))
((f bc) (b) ! (c))
((f d) (d)))
(rules ((g :what) (never))
((g :what) (f :what)))
(should-return
((f :what) ((:what d)))
((g :what) ((:what d)))))
(with-fresh-database
; (facts (a))
(facts (b))
; (facts (c))
(facts (d))
(rules ((f a) (a))
((f bc) (b) ! (c))
((f d) (d)))
(rules ((g :what) (never))
((g :what) (f :what)))
(should-fail
(f :what)
(g :what)))
(with-fresh-database
; (facts (a))
; (facts (b))
(facts (c))
; (facts (d))
(rules ((f a) (a))
((f bc) (b) ! (c))
((f d) (d)))
(rules ((g :what) (never))
((g :what) (f :what)))
(should-fail
(f :what)
(g :what))))