Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add functional disjunction/conjunction operators.
conde and all don't need to be macros, so here they are as functions.
  • Loading branch information
amalloy authored and swannodette committed Mar 10, 2015
1 parent 0989152 commit f3f2b4c
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 10 deletions.
21 changes: 21 additions & 0 deletions src/main/clojure/clojure/core/logic.clj
Expand Up @@ -1182,6 +1182,21 @@
(-inc
(mplus* ~@(bind-conde-clauses a clauses))))))

(defn or*
"A function version of conde, which takes a list of goals and tries them as if via conde.
Note that or* only does disjunction, ie (or* [a b c]) is the same as (conde [a] [b] [c]).
If you need something like (conde [a b] [c]), you can use and*, or all:
(or* [(and* a b) c])."
[goals]
(letfn [(mplus'
([e] e)
([e & es]
(mplus e (fn [] (apply mplus' es)))))]
(fn [a]
(fn []
(apply mplus' (for [goal goals]
(bind a goal)))))))

(defn- lvar-bind [sym]
((juxt identity
(fn [s] `(lvar '~s))) sym))
Expand Down Expand Up @@ -1255,6 +1270,12 @@
([] `clojure.core.logic/s#)
([& goals] `(fn [a#] (bind* a# ~@goals))))

(defn and*
"A function version of all, which takes a list of goals and succeeds only fi they all succeed."
[goals]
(fn [a]
(reduce bind a goals)))

(defn solutions
([s g]
(solutions s (lvar) g))
Expand Down
30 changes: 20 additions & 10 deletions src/test/clojure/clojure/core/logic/tests.clj
Expand Up @@ -692,18 +692,22 @@
(def f1 (fresh [] f1))

(deftest test-divergence-1
(is (= (run 1 [q]
(conde
[f1]
[(== false false)]))
'(_0))))
(is (= '(_0)
(run 1 [q]
(conde
[f1]
[(== false false)]))
(run 1 [q]
(or* [f1 (== false false)])))))

(deftest test-divergence-2
(is (= (run 1 [q]
(conde
[f1 (== false false)]
[(== false false)]))
'(_0))))
(is (= '(_0)
(run 1 [q]
(conde
[f1 (== false false)]
[(== false false)]))
(run 1 [q]
(or* [(and* [f1 (== false false)]) (== false false)])))))

(def f2
(fresh []
Expand All @@ -713,8 +717,14 @@
[(== false false)])]
[(== false false)])))

(def f2-function
(fresh []
(or* [(and* [f2 (or* [f2 (== false false)])])
(== false false)])))

(deftest test-divergence-3
(is (= (run 5 [q] f2)
(run 5 [q] f2-function)
'(_0 _0 _0 _0 _0))))

;; -----------------------------------------------------------------------------
Expand Down

0 comments on commit f3f2b4c

Please sign in to comment.