From 9ef5a27145b0a3bb078249ad17d4566e3e9ee7ff Mon Sep 17 00:00:00 2001
From: Gary Fredericks <fredericksgary@gmail.com>
Date: Wed, 13 Jun 2012 19:34:52 -0500
Subject: [PATCH] Generalize run (and friends) to accept multiple logic vars

---
 src/main/clojure/clojure/core/logic.clj       |   20 +++++++++++---------
 src/test/clojure/clojure/core/logic/tests.clj |    6 ++++++
 2 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/src/main/clojure/clojure/core/logic.clj b/src/main/clojure/clojure/core/logic.clj
index 23c07c3..c93c142 100644
--- a/src/main/clojure/clojure/core/logic.clj
+++ b/src/main/clojure/clojure/core/logic.clj
@@ -882,15 +882,17 @@
       (let [~@(lvar-binds lvars)]
         (bind* a# ~@goals)))))
 
-(defmacro solve [& [n [x] & goals]]
-  `(let [xs# (take* (fn []
-                      ((fresh [~x] ~@goals
-                         (fn [a#]
-                           (cons (-reify a# ~x) '()))) ;; TODO: do we need this?
-                       empty-s)))]
-     (if ~n
-       (take ~n xs#)
-       xs#)))
+(defmacro solve [& [n [x :as bindings] & goals]]
+  (if (> (count bindings) 1)
+    `(solve ~n [q#] (fresh ~bindings ~@goals (== q# ~bindings)))
+    `(let [xs# (take* (fn []
+                        ((fresh [~x] ~@goals
+                                (fn [a#]
+                                  (cons (-reify a# ~x) '()))) ;; TODO: do we need this?
+                         empty-s)))]
+       (if ~n
+         (take ~n xs#)
+         xs#))))
 
 (defmacro run
   "Executes goals until a maximum of n results are found."
diff --git a/src/test/clojure/clojure/core/logic/tests.clj b/src/test/clojure/clojure/core/logic/tests.clj
index 1c88ed5..d9dd742 100644
--- a/src/test/clojure/clojure/core/logic/tests.clj
+++ b/src/test/clojure/clojure/core/logic/tests.clj
@@ -1288,6 +1288,12 @@
             (== q (quote ^:haz-meta-daytuhs (form form form))))
       '((^:haz-meta-daytuhs (form form form)))))
 
+(deftest test-42-multiple-run-parameters
+  (is (= '[[3 _.0 [3 _.0]]]
+         (run* [x y z]
+               (== z [x y])
+               (== [x] [3])))))
+
 ;; =============================================================================
 ;; nil & false to-stream
 
-- 
1.7.5.4

