rlm@10
|
1 ;; Copyright (c) Jeffrey Straszheim. All rights reserved. The use and
|
rlm@10
|
2 ;; distribution terms for this software are covered by the Eclipse Public
|
rlm@10
|
3 ;; License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) which can
|
rlm@10
|
4 ;; be found in the file epl-v10.html at the root of this distribution. By
|
rlm@10
|
5 ;; using this software in any fashion, you are agreeing to be bound by the
|
rlm@10
|
6 ;; terms of this license. You must not remove this notice, or any other,
|
rlm@10
|
7 ;; from this software.
|
rlm@10
|
8 ;;
|
rlm@10
|
9 ;; test-rules.clj
|
rlm@10
|
10 ;;
|
rlm@10
|
11 ;; A Clojure implementation of Datalog -- Rule Tests
|
rlm@10
|
12 ;;
|
rlm@10
|
13 ;; straszheimjeffrey (gmail)
|
rlm@10
|
14 ;; Created 12 Feburary 2009
|
rlm@10
|
15
|
rlm@10
|
16
|
rlm@10
|
17 (ns clojure.contrib.datalog.tests.test-rules
|
rlm@10
|
18 (:use clojure.test
|
rlm@10
|
19 clojure.contrib.datalog.rules
|
rlm@10
|
20 clojure.contrib.datalog.literals
|
rlm@10
|
21 clojure.contrib.datalog.database))
|
rlm@10
|
22
|
rlm@10
|
23
|
rlm@10
|
24 (def tr-1 (<- (:fred :x ?x :y ?y) (:mary :x ?x :z ?z) (:sally :z ?z :y ?y)))
|
rlm@10
|
25 (def tr-2 (<- (:fred) (not! :mary :x 3)))
|
rlm@10
|
26 (def tr-3 (<- (:fred :x ?x :y ?y) (if > ?x ?y) (:mary :x ?x) (:sally :y ?y)))
|
rlm@10
|
27
|
rlm@10
|
28
|
rlm@10
|
29
|
rlm@10
|
30 (deftest test-rule-safety
|
rlm@10
|
31 (is (thrown-with-msg? Exception #".*Head vars.*not bound.*"
|
rlm@10
|
32 (<- (:fred :x ?x) (:sally :y ?y))))
|
rlm@10
|
33 (is (thrown-with-msg? Exception #".*Body vars.*not bound.*negative position.*"
|
rlm@10
|
34 (<- (:fred :x ?x) (:becky :x ?x) (not! :sally :y ?y))))
|
rlm@10
|
35 (is (thrown-with-msg? Exception #".*Body vars.*not bound.*negative position.*"
|
rlm@10
|
36 (<- (:fred :x ?x) (:becky :x ?x) (if > ?x ?y)))))
|
rlm@10
|
37
|
rlm@10
|
38
|
rlm@10
|
39 (deftest test-sip
|
rlm@10
|
40 (is (= (compute-sip #{:x} #{:mary :sally} tr-1)
|
rlm@10
|
41 (<- ({:pred :fred :bound #{:x}} :x ?x :y ?y)
|
rlm@10
|
42 ({:pred :mary :bound #{:x}} :z ?z :x ?x)
|
rlm@10
|
43 ({:pred :sally :bound #{:z}} :y ?y :z ?z))))
|
rlm@10
|
44
|
rlm@10
|
45 (is (= (compute-sip #{} #{:mary :sally} tr-1)
|
rlm@10
|
46 (<- (:fred :y ?y :x ?x) (:mary :z ?z :x ?x) ({:pred :sally :bound #{:z}} :y ?y :z ?z))))
|
rlm@10
|
47
|
rlm@10
|
48 (is (= (compute-sip #{} #{:mary} tr-2)
|
rlm@10
|
49 (<- (:fred) (not! {:pred :mary :bound #{:x}} :x 3))))
|
rlm@10
|
50
|
rlm@10
|
51 (is (= (compute-sip #{} #{} tr-2)
|
rlm@10
|
52 tr-2))
|
rlm@10
|
53
|
rlm@10
|
54 (is (= (display-rule (compute-sip #{:x} #{:mary :sally} tr-3))
|
rlm@10
|
55 (display-rule (<- ({:pred :fred :bound #{:x}} :x ?x :y ?y)
|
rlm@10
|
56 ({:pred :mary :bound #{:x}} :x ?x)
|
rlm@10
|
57 (:sally :y ?y)
|
rlm@10
|
58 (if > ?x ?y))))))
|
rlm@10
|
59 ; Display rule is used because = does not work on
|
rlm@10
|
60 ; (if > ?x ?y) because it contains a closure
|
rlm@10
|
61
|
rlm@10
|
62
|
rlm@10
|
63 (def rs
|
rlm@10
|
64 (rules-set
|
rlm@10
|
65 (<- (:path :a ?x :b ?y) (:edge :a ?x :b ?y))
|
rlm@10
|
66 (<- (:path :a ?x :b ?y) (:edge :a ?x :b ?z) (:path :a ?z :b ?y))
|
rlm@10
|
67 (<- (:edge :a ?x :b ?y) (:route :a ?x :b ?y) (if not= ?x ?y))))
|
rlm@10
|
68
|
rlm@10
|
69 (deftest test-rules-set
|
rlm@10
|
70 (is (= (count rs) 3))
|
rlm@10
|
71 (is (contains? rs (<- (:path :a ?x :b ?y) (:edge :a ?x :b ?z) (:path :a ?z :b ?y)))))
|
rlm@10
|
72
|
rlm@10
|
73 (deftest test-predicate-map
|
rlm@10
|
74 (let [pm (predicate-map rs)]
|
rlm@10
|
75 (is (= (pm :path)
|
rlm@10
|
76 #{(<- (:path :a ?x :b ?y) (:edge :a ?x :b ?y))
|
rlm@10
|
77 (<- (:path :a ?x :b ?y) (:edge :a ?x :b ?z) (:path :a ?z :b ?y))}))
|
rlm@10
|
78 (is (= (-> :edge pm count) 1))))
|
rlm@10
|
79
|
rlm@10
|
80
|
rlm@10
|
81 (def db1 (make-database
|
rlm@10
|
82 (relation :fred [:x :y])
|
rlm@10
|
83 (index :fred :x)
|
rlm@10
|
84 (relation :sally [:x])
|
rlm@10
|
85 (relation :ben [:y])))
|
rlm@10
|
86
|
rlm@10
|
87 (def db2 (add-tuples db1
|
rlm@10
|
88 [:fred :x 1 :y :mary]
|
rlm@10
|
89 [:fred :x 1 :y :becky]
|
rlm@10
|
90 [:fred :x 3 :y :sally]
|
rlm@10
|
91 [:fred :x 4 :y :joe]
|
rlm@10
|
92 [:fred :x 4 :y :bob]
|
rlm@10
|
93 [:sally :x 1]
|
rlm@10
|
94 [:sally :x 2]
|
rlm@10
|
95 [:sally :x 3]
|
rlm@10
|
96 [:sally :x 4]
|
rlm@10
|
97 [:ben :y :bob]))
|
rlm@10
|
98
|
rlm@10
|
99
|
rlm@10
|
100 (deftest test-apply-rule
|
rlm@10
|
101 (is (= (apply-rule db2 empty-database (<- (:becky :y ?y) (:sally :x ?x)
|
rlm@10
|
102 (:fred :x ?x :y ?y)
|
rlm@10
|
103 (not! :ben :y ?y)
|
rlm@10
|
104 (if not= ?x 3)))
|
rlm@10
|
105 (datalog-database
|
rlm@10
|
106 {
|
rlm@10
|
107 :becky
|
rlm@10
|
108 (datalog-relation
|
rlm@10
|
109 ;; Schema
|
rlm@10
|
110 #{:y}
|
rlm@10
|
111 ;; Data
|
rlm@10
|
112 #{
|
rlm@10
|
113 {:y :joe}
|
rlm@10
|
114 {:y :mary}
|
rlm@10
|
115 {:y :becky}
|
rlm@10
|
116 }
|
rlm@10
|
117 ;; Indexes
|
rlm@10
|
118 {
|
rlm@10
|
119 })
|
rlm@10
|
120 }))))
|
rlm@10
|
121
|
rlm@10
|
122
|
rlm@10
|
123
|
rlm@10
|
124
|
rlm@10
|
125 (comment
|
rlm@10
|
126 (run-tests)
|
rlm@10
|
127 )
|
rlm@10
|
128
|
rlm@10
|
129 ;; End of file
|
rlm@10
|
130
|