From 21205946948514433c83e24bc92187f0f69320ad Mon Sep 17 00:00:00 2001 From: Pepijn de Vos Date: Sat, 28 May 2011 21:30:44 +0200 Subject: [PATCH] rel, defrel, extend-rel --- src/main/clojure/clojure/core/logic/prelude.clj | 51 ++++++++++++----------- src/test/clojure/clojure/core/logic/tests.clj | 34 ++++++++-------- 2 files changed, 44 insertions(+), 41 deletions(-) diff --git a/src/main/clojure/clojure/core/logic/prelude.clj b/src/main/clojure/clojure/core/logic/prelude.clj index 8476faf..2ccf1f2 100644 --- a/src/main/clojure/clojure/core/logic/prelude.clj +++ b/src/main/clojure/clojure/core/logic/prelude.clj @@ -102,29 +102,6 @@ (apply merge-with (fn [a b] (set/union a b))))) -(defmacro defrel [name & args] - (let [setsym (symbol (str name "-set")) - idxsym (symbol (str name "-indexed"))] - `(do - (def ~setsym (atom #{})) - (def ~idxsym (atom {})) - (defmacro ~name [~@args] - (defrelg '~setsym '~idxsym ~@args))))) - -(defn defrelg [setsym idxsym & args] - `(fn [a#] - (answers a# (deref ~setsym) (deref ~idxsym) [~@args]))) - -;; NOTE: put in a dosync? - -(defmacro fact [rel & tuple] - (let [setsym (symbol (str rel "-set")) - idxsym (symbol (str rel "-indexed"))] - `(do - (swap! ~setsym conj [~@tuple]) - (reset! ~idxsym (index @~setsym)) - nil))) - (defn to-stream [aseq] (when (seq aseq) (choice (first aseq) @@ -140,4 +117,30 @@ (map (fn [cand] (when-let [a (unify a t cand)] a))) - (remove nil?))))) \ No newline at end of file + (remove nil?))))) + +(defn rel + ([values] (rel values (index values))) + ([values idx] (partial rel values idx)) + ([values idx names] + (fn goal [a] + (answers a values idx names)))) + +(defprotocol PRel + (fact [this tuple]) + (extend-rel [this tuples])) + +(deftype Rel [st idx] + PRel + (fact [_ tuple] + (swap! st conj tuple) + (reset! idx (index @st))) + (extend-rel [_ tuples] + (swap! st into tuples) + (reset! idx (index @st))) + clojure.lang.IFn + (invoke [_ tuples] + (rel @st @idx tuples))) + +(defmacro defrel [rname index] ; args will be used for indexing + `(def ~rname (Rel. (atom #{}) (atom {})))) diff --git a/src/test/clojure/clojure/core/logic/tests.clj b/src/test/clojure/clojure/core/logic/tests.clj index 5996b02..94fb2b4 100644 --- a/src/test/clojure/clojure/core/logic/tests.clj +++ b/src/test/clojure/clojure/core/logic/tests.clj @@ -995,30 +995,30 @@ ;; ----------------------------------------------------------------------------- ;; rel -(defrel man p) +(defrel man [p]) -(fact man 'Bob) -(fact man 'John) -(fact man 'Ricky) +(fact man ['Bob]) +(fact man ['John]) +(fact man ['Ricky]) -(defrel woman p) -(fact woman 'Mary) -(fact woman 'Martha) -(fact woman 'Lucy) +(defrel woman [p]) +(fact woman ['Mary]) +(fact woman ['Martha]) +(fact woman ['Lucy]) -(defrel likes p1 p2) -(fact likes 'Bob 'Mary) -(fact likes 'John 'Martha) -(fact likes 'Ricky 'Lucy) +(defrel likes [p1 p2]) +(fact likes ['Bob 'Mary]) +(fact likes ['John 'Martha]) +(fact likes ['Ricky 'Lucy]) -(defrel fun p) -(fact fun 'Lucy) +(defrel fun [p]) +(fact fun ['Lucy]) (deftest test-rel-1 (is (= (run* [q] (exist [x y] - (likes x y) - (fun y) + (likes [x y]) + (fun [y]) (== q [x y]))) '([Ricky Lucy])))) @@ -1093,4 +1093,4 @@ (def test-expr (prep '(?x 1 ?x))) (unifier test-expr test-expr) - ) \ No newline at end of file + ) -- 1.7.5.1