From 33a3e4d4e821e2a4f0dc71a0908771cd748c10f9 Mon Sep 17 00:00:00 2001 From: Joel Holdbrooks Date: Tue, 7 Oct 2014 14:00:07 -0700 Subject: [PATCH 01/11] Exclude reduced in util tests --- test/datalog/test_util.clj | 1 + 1 file changed, 1 insertion(+) diff --git a/test/datalog/test_util.clj b/test/datalog/test_util.clj index 44bf8b6..a817b33 100644 --- a/test/datalog/test_util.clj +++ b/test/datalog/test_util.clj @@ -16,6 +16,7 @@ ;; Converted to Clojure1.4 by Martin Trojer 2012. (ns datalog.test-util + (:refer-clojure :exclude [reduced]) (:use [datalog.util]) (:use [clojure.test])) From 2c93cef070982c4eda1a6341ab1f5c9fc6cb5405 Mon Sep 17 00:00:00 2001 From: Joel Holdbrooks Date: Tue, 7 Oct 2014 14:00:29 -0700 Subject: [PATCH 02/11] Use :require instead of :use in datalog.clj --- src/datalog/datalog.clj | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/datalog/datalog.clj b/src/datalog/datalog.clj index e707814..0542604 100644 --- a/src/datalog/datalog.clj +++ b/src/datalog/datalog.clj @@ -21,10 +21,9 @@ (ns ^{:author "Jeffrey Straszheim", :doc "A Clojure implementation of Datalog"} datalog.datalog - (:use [datalog.rules] - [datalog.softstrat] - [datalog.database]) - (:use [clojure.set :only (intersection)])) + (:require + [clojure.set :as set] + [datalog.softstrat :as softstrat])) (defrecord WorkPlan [work-plan ; The underlying structure @@ -35,7 +34,7 @@ (defn- validate-work-plan "Ensure any top level semantics are not violated" [work-plan database] - (let [common-relations (-> work-plan :rules (intersection (-> database keys set)))] + (let [common-relations (-> work-plan :rules (set/intersection (-> database keys set)))] (when (-> common-relations empty? not) @@ -45,11 +44,11 @@ "Given a list of rules and a query, build a work plan that can be used to execute the query." [rules query] - (->WorkPlan (build-soft-strat-work-plan rules query) rules query ::soft-stratified)) + (->WorkPlan (softstrat/build-soft-strat-work-plan rules query) rules query ::soft-stratified)) (defn run-work-plan "Given a work plan, a database, and some query bindings, run the work plan and return the results." [work-plan database query-bindings] (validate-work-plan work-plan database) - (evaluate-soft-work-set (:work-plan work-plan) database query-bindings)) + (softstrat/evaluate-soft-work-set (:work-plan work-plan) database query-bindings)) From 6b4cb1274189d40aa429005b62189a9570aa1851 Mon Sep 17 00:00:00 2001 From: Joel Holdbrooks Date: Tue, 7 Oct 2014 14:00:48 -0700 Subject: [PATCH 03/11] Use :require instead of :use in graph.clj --- src/datalog/graph.clj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/datalog/graph.clj b/src/datalog/graph.clj index 74de7e8..4c5d2d4 100644 --- a/src/datalog/graph.clj +++ b/src/datalog/graph.clj @@ -20,7 +20,7 @@ ^{:author "Jeffrey Straszheim", :doc "Basic graph theory algorithms"} datalog.graph - (:use [clojure.set :only (union)])) + (:require [clojure.set :as set])) (defrecord DirectedGraph [nodes ; The nodes of the graph, a collection @@ -143,7 +143,7 @@ find-neighbors (fn [ns] (let [nbs1 (map (partial get-neighbors g) ns) nbs2 (map set nbs1) - nbs3 (apply union nbs2)] + nbs3 (apply set/union nbs2)] (set (map find-node-set nbs3)))) nm (into {} (map (fn [ns] [ns (find-neighbors ns)]) sccs))] (->DirectedGraph (set sccs) nm)))) From 506ad9e9c0d6b0d2b3293a9ffaf3c027e03fa2e6 Mon Sep 17 00:00:00 2001 From: Joel Holdbrooks Date: Tue, 7 Oct 2014 14:02:44 -0700 Subject: [PATCH 04/11] Use :require instead of :use in database.clj --- src/datalog/database.clj | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/datalog/database.clj b/src/datalog/database.clj index 74daefd..d3b4d1a 100644 --- a/src/datalog/database.clj +++ b/src/datalog/database.clj @@ -16,8 +16,9 @@ ;; Converted to Clojure1.4 by Martin Trojer 2012. (ns datalog.database - (:use [datalog.util]) - (:use [clojure.set :only (union intersection difference)])) + (:require + [clojure.set :as set] + [datalog.util :as util])) (defrecord Relation [schema ; A set of key names @@ -137,7 +138,7 @@ (defn database-counts "Returns a map with the count of elements in each relation." [db] - (map-values #(-> % :data count) db)) + (util/map-values #(-> % :data count) db)) (defn- modify-indexes "Perform f on the indexed tuple-set. f should take a set and tuple, @@ -231,8 +232,8 @@ idxs (find-indexes (:indexes rel) pt) space (if (empty? idxs) (:data rel) ; table scan :( - (reduce intersection idxs))] - (trace-datalog (when (empty? idxs) + (reduce set/intersection idxs))] + (util/trace-datalog (when (empty? idxs) (println (format "Table scan of %s: %s rows!!!!!" rn (count space))))) @@ -255,7 +256,7 @@ (defn merge-indexes [idx1 idx2] - (merge-with (fn [h1 h2] (merge-with union h1 h2)) idx1 idx2)) + (merge-with (fn [h1 h2] (merge-with set/union h1 h2)) idx1 idx2)) (defn merge-relations "Merges two relations" @@ -263,7 +264,7 @@ (assert (= (:schema r1) (:schema r2))) (let [merged-indexes (merge-indexes (:indexes r1) (:indexes r2)) - merged-data (union (:data r1) + merged-data (set/union (:data r1) (:data r2))] (assoc r1 :data merged-data :indexes merged-indexes))) @@ -275,4 +276,4 @@ (defn database-merge-parallel "Merges databases together in parallel" [dbs] - (preduce merge-relations dbs)) + (util/preduce merge-relations dbs)) From 58829e5198877045067deb9fa4f7036959f4e480 Mon Sep 17 00:00:00 2001 From: Joel Holdbrooks Date: Tue, 7 Oct 2014 14:05:41 -0700 Subject: [PATCH 05/11] Use :require instead of :use in literals.clj --- src/datalog/literals.clj | 47 ++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/src/datalog/literals.clj b/src/datalog/literals.clj index 3240d9d..148b58a 100644 --- a/src/datalog/literals.clj +++ b/src/datalog/literals.clj @@ -16,9 +16,10 @@ ;; Converted to Clojure1.4 by Martin Trojer 2012. (ns datalog.literals - (:use [datalog.util] - [datalog.database]) - (:use [clojure.set :only (intersection subset?)])) + (:require + [clojure.set :as set] + [datalog.util :as util] + [datalog.database :as database])) ;; ============================= ;; Type Definitions @@ -77,11 +78,11 @@ (defmethod literal-vars ::literal [l] - (set (filter is-var? (-> l :term-bindings vals)))) + (set (filter util/is-var? (-> l :term-bindings vals)))) (defmethod literal-vars ::conditional [l] - (set (filter is-var? (:terms l)))) + (set (filter util/is-var? (:terms l)))) (defmethod positive-vars ::literal [l] @@ -133,7 +134,7 @@ atom." [f type] (let [p (first f) - ts (map #(if (is-var? %) `(quote ~%) %) (next f)) + ts (map #(if (util/is-var? %) `(quote ~%) %) (next f)) b (if (seq ts) (apply assoc {} ts) nil)] `(->AtomicLiteral ~p ~b ~type))) @@ -188,7 +189,7 @@ (defmethod get-vs-from-cs ::literal [l bound] - (set (filter is-var? + (set (filter util/is-var? (vals (select-keys (:term-bindings l) bound))))) @@ -221,7 +222,7 @@ (reduce conj #{} (remove nil? - (map (fn [[k v]] (if (not (is-var? v)) k nil)) + (map (fn [[k v]] (if (not (util/is-var? v)) k nil)) (:term-bindings l))))) (defmethod get-self-bound-cs ::conditional @@ -235,15 +236,15 @@ (defmethod literal-appropriate? ::literal [bound l] - (not (empty? (intersection (literal-vars l) bound)))) + (not (empty? (set/intersection (literal-vars l) bound)))) (defmethod literal-appropriate? ::negated [bound l] - (subset? (literal-vars l) bound)) + (set/subset? (literal-vars l) bound)) (defmethod literal-appropriate? ::conditional [bound l] - (subset? (literal-vars l) bound)) + (set/subset? (literal-vars l) bound)) (defmulti adorned-literal "When passed a set of bound columns, returns the adorned literal" @@ -252,7 +253,7 @@ (defmethod adorned-literal ::literal [l bound] (let [pred (literal-predicate l) - bnds (intersection (literal-columns l) bound)] + bnds (set/intersection (literal-columns l) bound)] (if (empty? bound) l (assoc l :predicate {:pred pred :bound bnds})))) @@ -298,7 +299,7 @@ its bound constants to new variables." [s] (assert (-> s :literal-type (isa? ::literal))) - (let [ntbs (map-values (fn [_] (gensym '?_gen_)) (:term-bindings s))] + (let [ntbs (util/map-values (fn [_] (gensym '?_gen_)) (:term-bindings s))] (assoc s :term-bindings ntbs))) ;; ============================= @@ -324,7 +325,7 @@ [lit binds] (let [tbs (:term-bindings lit) each (fn [[key val :as pair]] - (if (is-var? val) + (if (util/is-var? val) (if-let [n (binds val)] [key n] nil) @@ -336,7 +337,7 @@ bindings." [lit tuple] (let [step (fn [binds [key val]] - (if (and (is-var? val) + (if (and (util/is-var? val) (contains? tuple key)) (assoc binds val (tuple key)) binds))] @@ -360,12 +361,12 @@ (join-literal* db lit bs (fn [binds pt] (map #(merge binds %) (map (partial project-onto-literal lit) - (select db (literal-predicate lit) pt)))))) + (database/select db (literal-predicate lit) pt)))))) (defmethod join-literal ::negated [db lit bs] (join-literal* db lit bs (fn [binds pt] - (if (any-match? db (literal-predicate lit) pt) + (if (database/any-match? db (literal-predicate lit) pt) nil [binds])))) @@ -373,7 +374,7 @@ [db lit bs] (let [each (fn [binds] (let [resolve (fn [term] - (if (is-var? term) + (if (util/is-var? term) (binds term) term)) args (map resolve (:terms lit))] @@ -385,19 +386,19 @@ (defn project-literal "Project a stream of bindings onto a literal/relation. Returns a new db." - ([db lit bs] (project-literal db lit bs is-var?)) + ([db lit bs] (project-literal db lit bs util/is-var?)) ([db lit bs var?] (assert (= (:literal-type lit) ::literal)) (let [rel-name (literal-predicate lit) columns (-> lit :term-bindings keys) idxs (vec (get-adorned-bindings (literal-predicate lit))) - db1 (ensure-relation db rel-name columns idxs) - rel (get-relation db1 rel-name) + db1 (database/ensure-relation db rel-name columns idxs) + rel (database/get-relation db1 rel-name) step (fn [rel bindings] (let [step (fn [t [k v]] (if (var? v) (assoc t k (bindings v)) (assoc t k v))) tuple (reduce step {} (:term-bindings lit))] - (add-tuple rel tuple)))] - (replace-relation db rel-name (reduce step rel bs))))) + (database/add-tuple rel tuple)))] + (database/replace-relation db rel-name (reduce step rel bs))))) From 247b1ba68df058a622a7583f2a223f0daef564f1 Mon Sep 17 00:00:00 2001 From: Joel Holdbrooks Date: Tue, 7 Oct 2014 14:10:06 -0700 Subject: [PATCH 06/11] Use :require instead of :use in rules.clj --- src/datalog/rules.clj | 84 +++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/src/datalog/rules.clj b/src/datalog/rules.clj index c1d0e7a..8c2094e 100644 --- a/src/datalog/rules.clj +++ b/src/datalog/rules.clj @@ -16,10 +16,10 @@ ;; Converted to Clojure1.4 by Martin Trojer 2012. (ns datalog.rules - (:use [datalog.util] - [datalog.literals] - [datalog.database]) - (:use [clojure.set :only (union intersection difference subset?)])) + (:require + [clojure.set :as set] + [datalog.util :as util] + [datalog.literals :as literals])) (defrecord DatalogRule [head body]) @@ -27,13 +27,13 @@ "Return the rule in a readable format." [rule] (list* '<- - (-> rule :head display-literal) - (map display-literal (:body rule)))) + (-> rule :head literals/display-literal) + (map literals/display-literal (:body rule)))) (defn display-query "Return a query in a readable format." [query] - (list* '?- (display-literal query))) + (list* '?- (literals/display-literal query))) ;; ============================= ;; Check rule safety @@ -41,11 +41,11 @@ (defn is-safe? "Is the rule safe according to the datalog protocol?" [rule] - (let [hv (literal-vars (:head rule)) - bpv (apply union (map positive-vars (:body rule))) - bnv (apply union (map negative-vars (:body rule))) - ehv (difference hv bpv) - env (difference bnv bpv)] + (let [hv (literals/literal-vars (:head rule)) + bpv (apply set/union (map literals/positive-vars (:body rule))) + bnv (apply set/union (map literals/negative-vars (:body rule))) + ehv (set/difference hv bpv) + env (set/difference bnv bpv)] (when-not (empty? ehv) (throw (Exception. (str "Head vars" ehv "not bound in body of rule" rule)))) (when-not (empty? env) @@ -62,10 +62,10 @@ (defmacro <- "Build a datalog rule. Like this: - (<- (:head :x ?x :y ?y) (:body-1 :x ?x :y ?y) (:body-2 :z ?z) (not! :body-3 :x ?x) (if > ?y ?z))" + (<- (:head :x ?x :y ?y) (:body-1 :x ?x :y ?y) (:body-2 :z ?z) (not! :body-3 :x ?x) (if > ?y ?z))" [hd & body] - (let [head (build-atom hd :datalog.literals/literal) - body (map build-literal body)] + (let [head (literals/build-atom hd :datalog.literals/literal) + body (map literals/build-literal body)] `(is-safe? (build-rule ~head [~@body])))) (defmethod print-method ::datalog-rule @@ -80,7 +80,7 @@ (defmacro ?- "Define a datalog query" [& q] - (let [qq (build-atom q :datalog.literals/literal)] + (let [qq (literals/build-atom q :datalog.literals/literal)] `(with-meta ~qq {:type ::datalog-query}))) (defmethod print-method ::datalog-query @@ -92,26 +92,26 @@ (defn compute-sip "Given a set of bound column names, return an adorned sip for this - rule. A set of intensional predicates should be provided to - determine what should be adorned." + rule. A set of intensional predicates should be provided to + determine what should be adorned." [bindings i-preds rule] (let [next-lit (fn [bv body] (or (first (drop-while - #(not (literal-appropriate? bv %)) + #(not (literals/literal-appropriate? bv %)) body)) - (first (drop-while (complement positive?) body)))) + (first (drop-while (complement literals/positive?) body)))) adorn (fn [lit bvs] - (if (i-preds (literal-predicate lit)) - (let [bnds (union (get-cs-from-vs lit bvs) - (get-self-bound-cs lit))] - (adorned-literal lit bnds)) + (if (i-preds (literals/literal-predicate lit)) + (let [bnds (set/union (literals/get-cs-from-vs lit bvs) + (literals/get-self-bound-cs lit))] + (literals/adorned-literal lit bnds)) lit)) - new-h (adorned-literal (:head rule) bindings)] - (loop [bound-vars (get-vs-from-cs (:head rule) bindings) + new-h (literals/adorned-literal (:head rule) bindings)] + (loop [bound-vars (literals/get-vs-from-cs (:head rule) bindings) body (:body rule) sip []] (if-let [next (next-lit bound-vars body)] - (recur (union bound-vars (literal-vars next)) + (recur (set/union bound-vars (literals/literal-vars next)) (remove #(= % next) body) (conj sip (adorn next bound-vars))) (build-rule new-h (concat sip body)))))) @@ -121,7 +121,7 @@ (defn make-rules-set "Given an existing set of rules, make it a 'rules-set' for - printing." + printing." [rs] (with-meta rs {:type ::datalog-rules-set})) @@ -145,10 +145,10 @@ (defn predicate-map "Given a rules-set, return a map of rules keyed by their predicates. - Each value will be a set of rules." + Each value will be a set of rules." [rs] (let [add-rule (fn [m r] - (let [pred (-> r :head literal-predicate) + (let [pred (-> r :head literals/literal-predicate) os (get m pred #{})] (assoc m pred (conj os r))))] (reduce add-rule {} rs))) @@ -156,7 +156,7 @@ (defn all-predicates "Given a rules-set, return all defined predicates" [rs] - (set (map literal-predicate (map :head rs)))) + (set (map literals/literal-predicate (map :head rs)))) (defn non-base-rules "Return a collection of rules that depend, somehow, on other rules" @@ -164,7 +164,7 @@ (let [pred (all-predicates rs) non-base (fn [r] (if (some #(pred %) - (map literal-predicate (:body r))) + (map literals/literal-predicate (:body r))) r nil))] (remove nil? (map non-base rs)))) @@ -176,22 +176,22 @@ (defn apply-rule "Apply the rule against db-1, adding the results to the appropriate - relation in db-2. The relation will be created if needed." + relation in db-2. The relation will be created if needed." ([db rule] (apply-rule db db rule)) ([db-1 db-2 rule] - (trace-datalog (println) - (println) - (println "--------------- Begin Rule ---------------") - (println rule)) + (util/trace-datalog (println) + (println) + (println "--------------- Begin Rule ---------------") + (println rule)) (let [head (:head rule) body (:body rule) step (fn [bs lit] - (trace-datalog (println bs) - (println lit)) - (join-literal db-1 lit bs)) + (util/trace-datalog (println bs) + (println lit)) + (literals/join-literal db-1 lit bs)) bs (reduce step empty-bindings body)] - (do (trace-datalog (println bs)) - (project-literal db-2 head bs))))) + (do (util/trace-datalog (println bs)) + (literals/project-literal db-2 head bs))))) (defn apply-rules-set [db rs] From 213875cc4e6222553d9c3f8573a6b5fc0b786847 Mon Sep 17 00:00:00 2001 From: Joel Holdbrooks Date: Tue, 7 Oct 2014 14:13:01 -0700 Subject: [PATCH 07/11] Use :require instead of :use in magic.clj --- src/datalog/magic.clj | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/datalog/magic.clj b/src/datalog/magic.clj index 2db6119..d16b458 100644 --- a/src/datalog/magic.clj +++ b/src/datalog/magic.clj @@ -16,9 +16,10 @@ ;; Converted to Clojure1.4 by Martin Trojer 2012. (ns datalog.magic - (:use [datalog.util] - [datalog.literals] - [datalog.rules]) + (:require + [datalog.util :as util] + [datalog.literals :as literals]) + (:use [datalog.rules]) (:use [clojure.set :only (union intersection difference)])) ;; ============================= @@ -27,7 +28,7 @@ (defn adorn-query "Adorn a query" [q] - (adorned-literal q (get-self-bound-cs q))) + (literals/adorned-literal q (literals/get-self-bound-cs q))) (defn adorn-rules-set "Adorns the given rules-set for the given query. (rs) is a @@ -36,13 +37,13 @@ (let [i-preds (all-predicates rs) p-map (predicate-map rs)] (loop [nrs empty-rules-set ; The rules set being built - needed #{(literal-predicate q)}] + needed #{(literals/literal-predicate q)}] (if (empty? needed) nrs (let [pred (first needed) remaining (disj needed pred) - base-pred (get-base-predicate pred) - bindings (get-adorned-bindings pred) + base-pred (literals/get-base-predicate pred) + bindings (literals/get-adorned-bindings pred) new-rules (p-map base-pred) new-adorned-rules (map (partial compute-sip bindings i-preds) new-rules) @@ -50,11 +51,11 @@ current-preds (all-predicates new-nrs) not-needed? (fn [pred] (or (current-preds pred) - (-> pred get-base-predicate i-preds not))) + (-> pred literals/get-base-predicate i-preds not))) add-pred (fn [np pred] (if (not-needed? pred) np (conj np pred))) add-preds (fn [np rule] - (reduce add-pred np (map literal-predicate (:body rule)))) + (reduce add-pred np (map literals/literal-predicate (:body rule)))) new-needed (reduce add-preds remaining new-adorned-rules)] (recur new-nrs new-needed)))))) @@ -66,14 +67,14 @@ "Given a magic form of a query, give back the literal form of its seed relation" [q] - (let [pred (-> q literal-predicate get-base-predicate) - bnds (-> q literal-predicate get-adorned-bindings)] + (let [pred (-> q literals/literal-predicate literals/get-base-predicate) + bnds (-> q literals/literal-predicate literals/get-adorned-bindings)] (with-meta (assoc q :predicate [pred :magic-seed bnds]) {}))) (defn seed-rule "Given an adorned query, give back its seed rule" [q] - (let [mq (build-seed-bindings (magic-literal q)) + (let [mq (literals/build-seed-bindings (literals/magic-literal q)) sr (seed-relation mq)] (build-rule mq [sr]))) @@ -82,9 +83,9 @@ to extract the relation from the database." [q bindings] (into {} (remove nil? (map (fn [[k v :as pair]] - (if (is-var? v) + (if (util/is-var? v) nil - (if (is-query-var? v) + (if (util/is-query-var? v) [k (bindings v)] pair))) (:term-bindings q))))) @@ -106,18 +107,18 @@ ([rs i-preds] (let [not-duplicate? (fn [l mh bd] (or (not (empty? bd)) - (not (= (magic-literal l) + (not (= (literals/magic-literal l) mh)))) xr (fn [rs rule] (let [head (:head rule) body (:body rule) - mh (magic-literal head) + mh (literals/magic-literal head) answer-rule (build-rule head (concat [mh] body)) step (fn [[rs bd] l] - (if (and (i-preds (literal-predicate l)) + (if (and (i-preds (literals/literal-predicate l)) (not-duplicate? l mh bd)) - (let [nr (build-rule (magic-literal l) + (let [nr (build-rule (literals/magic-literal l) (concat [mh] bd))] [(conj rs nr) (conj bd l)]) [rs (conj bd l)])) From e5f62e4bb6742233b96a92dad442f3ea3b526e9a Mon Sep 17 00:00:00 2001 From: Joel Holdbrooks Date: Tue, 7 Oct 2014 14:18:59 -0700 Subject: [PATCH 08/11] Use :require instead of :use in softstrat.clj --- src/datalog/softstrat.clj | 83 ++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/src/datalog/softstrat.clj b/src/datalog/softstrat.clj index 0079e6b..455a729 100644 --- a/src/datalog/softstrat.clj +++ b/src/datalog/softstrat.clj @@ -16,30 +16,31 @@ ;; Converted to Clojure1.4 by Martin Trojer 2012. (ns datalog.softstrat - (:use [datalog.util] - [datalog.database] - [datalog.literals] - [datalog.rules] - [datalog.magic]) - (:use [clojure.set :only (union intersection difference)]) - (:require [datalog.graph :as graph])) + (:require + [clojure.set :as set] + [datalog.database :as database] + [datalog.graph :as graph] + [datalog.literals :as literals] + [datalog.magic :as magic] + [datalog.rules :as rules] + [datalog.util :as util])) ;; ============================= ;; Dependency graph (defn- build-rules-graph "Given a rules-set (rs), build a graph where each predicate symbol in rs, - there is a node n, and for each rule (<- h b-1 b-2 ...), there are edges - from the (literal-predicate h) -> (literal-predicate b-*), one for each - b-*." + there is a node n, and for each rule (<- h b-1 b-2 ...), there are edges + from the (literal-predicate h) -> (literal-predicate b-*), one for each + b-*." [rs] - (let [preds (all-predicates rs) - pred-map (predicate-map rs) + (let [preds (rules/all-predicates rs) + pred-map (rules/predicate-map rs) step (fn [nbs pred] (let [rules (pred-map pred) preds (reduce (fn [pds lits] (reduce (fn [pds lit] - (if-let [pred (literal-predicate lit)] + (if-let [pred (literals/literal-predicate lit)] (conj pds pred) pds)) pds @@ -53,13 +54,13 @@ (defn- build-def "Given a rules-set, build its def function" [rs] - (let [pred-map (predicate-map rs) + (let [pred-map (rules/predicate-map rs) graph (-> rs build-rules-graph graph/transitive-closure graph/add-loops)] (fn [pred] - (apply union (map set (map pred-map (graph/get-neighbors graph pred))))))) + (apply set/union (map set (map pred-map (graph/get-neighbors graph pred))))))) ;; ============================= ;; Soft Stratificattion REQ Graph @@ -72,18 +73,18 @@ body (:body rule) lit (nth body lit-index) pre (subvec (vec body) 0 lit-index)] - (conj (-> lit literal-predicate soft-def (magic-transform (all-predicates rs))) - (build-rule (magic-literal lit) pre)))) + (conj (-> lit literals/literal-predicate soft-def (magic/magic-transform (rules/all-predicates rs))) + (rules/build-rule (literals/magic-literal lit) pre)))) (defn- rule-dep "Given a rule, return the set of rules it depends on." [rs mrs soft-def rule] (let [step (fn [nrs [idx lit]] - (if (negated? lit) - (union nrs (req rs soft-def rule idx)) + (if (literals/negated? lit) + (set/union nrs (req rs soft-def rule idx)) nrs))] - (intersection mrs - (reduce step empty-rules-set + (set/intersection mrs + (reduce step rules/empty-rules-set (->> rule :body (map-indexed vector)))))) (defn- soft-strat-graph @@ -97,15 +98,15 @@ (defn- build-soft-strat "Given a rules-set (unadorned) and an adorned query, return the soft - stratified list. The rules will be magic transformed, and the - magic seed will be appended." + stratified list. The rules will be magic transformed, and the + magic seed will be appended." [rs q] - (let [ars (adorn-rules-set rs q) - mrs (conj (magic-transform ars) - (seed-rule q)) + (let [ars (magic/adorn-rules-set rs q) + mrs (conj (magic/magic-transform ars) + (magic/seed-rule q)) gr (soft-strat-graph ars mrs)] - (map make-rules-set (graph/dependency-list gr)))) - + (map rules/make-rules-set (graph/dependency-list gr)))) + ;; ============================= ;; Work plan @@ -114,28 +115,28 @@ (defn build-soft-strat-work-plan "Return a work plan for the given rules-set and query" [rs q] - (let [aq (adorn-query q)] + (let [aq (magic/adorn-query q)] (->SoftStratWorkPlan aq (build-soft-strat rs aq)))) (defn get-all-relations "Return a set of all relation names defined in this workplan" [ws] - (apply union (map all-predicates (:stratification ws)))) + (apply set/union (map rules/all-predicates (:stratification ws)))) ;; ============================= ;; Evaluate (defn- weak-consq-operator [db strat] - (trace-datalog (println) - (println) - (println "=============== Begin iteration ===============")) - (let [counts (database-counts db)] + (util/trace-datalog (println) + (println) + (println "=============== Begin iteration ===============")) + (let [counts (database/database-counts db)] (loop [strat strat] (let [rs (first strat)] (if rs - (let [new-db (apply-rules-set db rs)] - (if (= counts (database-counts new-db)) + (let [new-db (rules/apply-rules-set db rs)] + (if (= counts (database/database-counts new-db)) (recur (next strat)) new-db)) db))))) @@ -145,12 +146,12 @@ ([ws db bindings] (let [query (:query ws) strat (:stratification ws) - seed (seed-predicate-for-insertion query) - seeded-db (project-literal db seed [bindings] is-query-var?) + seed (magic/seed-predicate-for-insertion query) + seeded-db (literals/project-literal db seed [bindings] util/is-query-var?) fun (fn [data] (weak-consq-operator data strat)) equal (fn [db1 db2] - (= (database-counts db1) (database-counts db2))) + (= (database/database-counts db1) (database/database-counts db2))) new-db (graph/fixed-point seeded-db fun nil equal) - pt (build-partial-tuple query bindings)] - (select new-db (literal-predicate query) pt)))) + pt (magic/build-partial-tuple query bindings)] + (database/select new-db (literals/literal-predicate query) pt)))) From e38fb3b1e664e9b9f12637d2253672863f20bbeb Mon Sep 17 00:00:00 2001 From: Joel Holdbrooks Date: Tue, 7 Oct 2014 23:01:17 -0700 Subject: [PATCH 09/11] Use :require instead of :use in example.clj --- src/datalog/example.clj | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/datalog/example.clj b/src/datalog/example.clj index ab41ce4..a36cc03 100644 --- a/src/datalog/example.clj +++ b/src/datalog/example.clj @@ -16,10 +16,11 @@ ;; Converted to Clojure1.4 by Martin Trojer 2012. (ns datalog.example - (:use [datalog.datalog :only (build-work-plan run-work-plan)] - [datalog.rules :only (<- ?- rules-set)] - [datalog.database :only (make-database add-tuples)] - [datalog.util :only (*trace-datalog*)])) + (:require + [datalog.datalog :refer (build-work-plan run-work-plan)] + [datalog.rules :refer (<- ?- rules-set)] + [datalog.database :refer (make-database add-tuples)] + [datalog.util :refer (*trace-datalog*)])) (def db-base (make-database @@ -77,22 +78,35 @@ (def rules (rules-set - (<- (:works-for :employee ?x :boss ?y) (:boss :employee-id ?e-id :boss-id ?b-id) + (<- (:works-for :employee ?x :boss ?y) + (:boss :employee-id ?e-id :boss-id ?b-id) (:employee :id ?e-id :name ?x) (:employee :id ?b-id :name ?y)) - (<- (:works-for :employee ?x :boss ?y) (:works-for :employee ?x :boss ?z) + + (<- (:works-for :employee ?x :boss ?y) + (:works-for :employee ?x :boss ?z) (:works-for :employee ?z :boss ?y)) - (<- (:employee-job* :employee ?x :job ?y) (:employee :name ?x :position ?pos) + + (<- (:employee-job* :employee ?x :job ?y) + (:employee :name ?x :position ?pos) (:can-do-job :position ?pos :job ?y)) - (<- (:employee-job* :employee ?x :job ?y) (:job-replacement :job ?y :can-be-done-by ?z) + + (<- (:employee-job* :employee ?x :job ?y) + (:job-replacement :job ?y :can-be-done-by ?z) (:employee-job* :employee ?x :job ?z)) - (<- (:employee-job* :employee ?x :job ?y) (:can-do-job :job ?y) + + (<- (:employee-job* :employee ?x :job ?y) + (:can-do-job :job ?y) (:employee :name ?x :position ?z) (if = ?z :boss)) - (<- (:employee-job :employee ?x :job ?y) (:employee-job* :employee ?x :job ?y) + + (<- (:employee-job :employee ?x :job ?y) + (:employee-job* :employee ?x :job ?y) (:employee :id ?id :name ?x) (not! :job-exceptions :id ?id :job ?y)) - (<- (:bj :name ?x :boss ?y) (:works-for :employee ?x :boss ?y) + + (<- (:bj :name ?x :boss ?y) + (:works-for :employee ?x :boss ?y) (not! :employee-job :employee ?y :job :pc-support)))) (def wp-1 (build-work-plan rules (?- :works-for :employee '??name :boss ?x))) From 4b1d2e2ec0821a9b6dc29bd471f7c1ba34659158 Mon Sep 17 00:00:00 2001 From: Joel Holdbrooks Date: Tue, 7 Oct 2014 23:08:13 -0700 Subject: [PATCH 10/11] Finish converting :use to :require in magic.clj --- src/datalog/magic.clj | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/src/datalog/magic.clj b/src/datalog/magic.clj index d16b458..a3231c0 100644 --- a/src/datalog/magic.clj +++ b/src/datalog/magic.clj @@ -18,9 +18,8 @@ (ns datalog.magic (:require [datalog.util :as util] - [datalog.literals :as literals]) - (:use [datalog.rules]) - (:use [clojure.set :only (union intersection difference)])) + [datalog.literals :as literals] + [datalog.rules :as rules])) ;; ============================= ;; Adornment @@ -32,11 +31,11 @@ (defn adorn-rules-set "Adorns the given rules-set for the given query. (rs) is a - rules-set, (q) is an adorned query." + rules-set, (q) is an adorned query." [rs q] - (let [i-preds (all-predicates rs) - p-map (predicate-map rs)] - (loop [nrs empty-rules-set ; The rules set being built + (let [i-preds (rules/all-predicates rs) + p-map (rules/predicate-map rs)] + (loop [nrs rules/empty-rules-set ; The rules set being built needed #{(literals/literal-predicate q)}] (if (empty? needed) nrs @@ -45,10 +44,10 @@ base-pred (literals/get-base-predicate pred) bindings (literals/get-adorned-bindings pred) new-rules (p-map base-pred) - new-adorned-rules (map (partial compute-sip bindings i-preds) + new-adorned-rules (map (partial rules/compute-sip bindings i-preds) new-rules) new-nrs (reduce conj nrs new-adorned-rules) - current-preds (all-predicates new-nrs) + current-preds (rules/all-predicates new-nrs) not-needed? (fn [pred] (or (current-preds pred) (-> pred literals/get-base-predicate i-preds not))) @@ -65,7 +64,7 @@ (defn seed-relation "Given a magic form of a query, give back the literal form of its seed - relation" + relation" [q] (let [pred (-> q literals/literal-predicate literals/get-base-predicate) bnds (-> q literals/literal-predicate literals/get-adorned-bindings)] @@ -76,11 +75,11 @@ [q] (let [mq (literals/build-seed-bindings (literals/magic-literal q)) sr (seed-relation mq)] - (build-rule mq [sr]))) + (rules/build-rule mq [sr]))) (defn build-partial-tuple "Given a query and a set of bindings, build a partial tuple needed - to extract the relation from the database." + to extract the relation from the database." [q bindings] (into {} (remove nil? (map (fn [[k v :as pair]] (if (util/is-var? v) @@ -100,10 +99,10 @@ (defn magic-transform "Return a magic transformation of an adorned rules-set (rs). The - (i-preds) are the predicates of the intension database. These - default to the predicates within the rules-set." + (i-preds) are the predicates of the intension database. These + default to the predicates within the rules-set." ([rs] - (magic-transform rs (all-predicates rs))) + (magic-transform rs (rules/all-predicates rs))) ([rs i-preds] (let [not-duplicate? (fn [l mh bd] (or (not (empty? bd)) @@ -113,15 +112,15 @@ (let [head (:head rule) body (:body rule) mh (literals/magic-literal head) - answer-rule (build-rule head - (concat [mh] body)) + answer-rule (rules/build-rule head + (concat [mh] body)) step (fn [[rs bd] l] (if (and (i-preds (literals/literal-predicate l)) (not-duplicate? l mh bd)) - (let [nr (build-rule (literals/magic-literal l) - (concat [mh] bd))] + (let [nr (rules/build-rule (literals/magic-literal l) + (concat [mh] bd))] [(conj rs nr) (conj bd l)]) [rs (conj bd l)])) [nrs _] (reduce step [rs []] body)] (conj nrs answer-rule)))] - (reduce xr empty-rules-set rs)))) + (reduce xr rules/empty-rules-set rs)))) From 85c40018ad175c789c75e92dd9381e0c9feca8d8 Mon Sep 17 00:00:00 2001 From: Joel Holdbrooks Date: Wed, 8 Oct 2014 00:10:20 -0700 Subject: [PATCH 11/11] Formatting corrections --- src/datalog/database.clj | 62 ++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/src/datalog/database.clj b/src/datalog/database.clj index d3b4d1a..fbd12cd 100644 --- a/src/datalog/database.clj +++ b/src/datalog/database.clj @@ -29,15 +29,15 @@ (defmethod print-method ::datalog-database [db ^java.io.Writer writer] - (binding [*out* writer] - (do - (println "(datalog-database") - (println "{") - (doseq [key (keys db)] - (println) - (println key) - (print-method (db key) writer)) - (println "})")))) + (binding [*out* writer] + (do + (println "(datalog-database") + (println "{") + (doseq [key (keys db)] + (println) + (println key) + (print-method (db key) writer)) + (println "})")))) (defn datalog-database [rels] @@ -104,12 +104,12 @@ (defmacro make-database "Makes a database, like this - (make-database - (relation :fred [:mary :sue]) - (index :fred :mary) - (relation :sally [:jen :becky]) - (index :sally :jen) - (index :sally :becky))" + (make-database + (relation :fred [:mary :sue]) + (index :fred :mary) + (relation :sally [:jen :becky]) + (index :sally :jen) + (index :sally :becky))" [& commands] (let [wrapper (fn [cur new] (let [cmd (first new) @@ -142,7 +142,7 @@ (defn- modify-indexes "Perform f on the indexed tuple-set. f should take a set and tuple, - and return the new set." + and return the new set." [idxs tuple f] (into {} (for [ik (keys idxs)] (let [im (idxs ik) @@ -166,10 +166,10 @@ (defn add-tuple "Two forms: - [db relation-name tuple] adds tuple to the named relation. Returns - the new database. + [db relation-name tuple] adds tuple to the named relation. Returns + the new database. - [rel tuple] adds to the relation object. Returns the new relation." + [rel tuple] adds to the relation object. Returns the new relation." ([db rel-name tuple] (assert (= (-> tuple keys set) (-> rel-name db :schema))) (assoc db rel-name (add-tuple (db rel-name) tuple))) @@ -184,11 +184,11 @@ (defn remove-tuple "Two forms: - [db relation-name tuple] removes the tuple from the named relation, - returns a new database. + [db relation-name tuple] removes the tuple from the named relation, + returns a new database. - [rel tuple] removes the tuple from the relation. Returns the new - relation." + [rel tuple] removes the tuple from the relation. Returns the new + relation." ([db rel-name tuple] (assoc db rel-name (remove-tuple (db rel-name) tuple))) ([rel tuple] (let [data (:data rel) @@ -200,9 +200,9 @@ (defn add-tuples "Adds a collection of tuples to the db, as - (add-tuples db - [:rel-name :key-1 1 :key-2 2] - [:rel-name :key-1 2 :key-2 3])" + (add-tuples db + [:rel-name :key-1 1 :key-2 2] + [:rel-name :key-1 2 :key-2 3])" [db & tupls] (reduce #(add-tuple %1 (first %2) (apply hash-map (next %2))) db tupls)) @@ -226,7 +226,7 @@ (defn- scan-space "Computes a stream of tuples from relation rn matching partial tuple (pt) - and applies fun to each" + and applies fun to each" [fun db rn pt] (let [rel (db rn) idxs (find-indexes (:indexes rel) pt) @@ -234,9 +234,9 @@ (:data rel) ; table scan :( (reduce set/intersection idxs))] (util/trace-datalog (when (empty? idxs) - (println (format "Table scan of %s: %s rows!!!!!" - rn - (count space))))) + (println (format "Table scan of %s: %s rows!!!!!" + rn + (count space))))) (fun #(match? % pt) space))) (defn select @@ -265,7 +265,7 @@ (let [merged-indexes (merge-indexes (:indexes r1) (:indexes r2)) merged-data (set/union (:data r1) - (:data r2))] + (:data r2))] (assoc r1 :data merged-data :indexes merged-indexes))) (defn database-merge