Skip to content

Commit

Permalink
Add PMap (partial-map) record that unifies with maps whose keys are a…
Browse files Browse the repository at this point in the history
… superset of its keys.
  • Loading branch information
lynaghk authored and David Nolen committed Oct 12, 2012
1 parent e458733 commit 9b340ea
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/main/clojure/clojure/core/logic.clj
Expand Up @@ -3738,3 +3738,11 @@
([_ [y . ys] [y . zs]]
(!= y x)
(rembero x ys zs)))







(load "logic/partial_map")
59 changes: 59 additions & 0 deletions src/main/clojure/clojure/core/logic/partial_map.clj
@@ -0,0 +1,59 @@
;;This file defines a PMap (partial map) record that unifies with maps without having all of that map's keys.
(in-ns 'clojure.core.logic)

(defprotocol IUnifyWithPMap
(unify-with-pmap [pmap u s]))

(defrecord PMap []
IUnifyWithMap
(unify-with-map [v u s]
(loop [ks (keys v) s s]
(if (seq ks)
(let [kf (first ks)
uf (get u kf ::not-found)]
(if (= uf ::not-found)
nil
(if-let [s (unify s (get v kf) uf)]
(recur (next ks) s)
nil)))
s)))

IUnifyWithPMap
(unify-with-pmap [v u s]
(unify-with-map v u s))

IUnifyTerms
(unify-terms [u v s]
(unify-with-pmap v u s))

IUnifyWithLVar
(unify-with-lvar [v u s]
(ext-no-check s u v)))

(extend-protocol IUnifyWithPMap
nil
(unify-with-pmap [v u s] nil)

Object
(unify-with-pmap [v u s] nil)

clojure.core.logic.LVar
(unify-with-pmap [v u s]
(ext s v u))

clojure.lang.IPersistentMap
(unify-with-pmap [v u s]
(unify-with-map u v s)))

(defn partial-map
"Given map m, returns partial map that unifies with maps even if it doesn't share all of the keys of that map.
Only the keys of the partial map will be unified:
(run* [q]
(fresh [pm x]
(== pm (partial-map {:a x}))
(== pm {:a 1 :b 2})
(== pm q)))
;;=> ({:a 1})"
[m]
(map->PMap m))
8 changes: 8 additions & 0 deletions src/test/clojure/clojure/core/logic/tests.clj
Expand Up @@ -1196,6 +1196,14 @@
(== z [x y])
(== [x] [3])))))

(deftest test-49-partial-map-unification
(is (= '[{:a 1}]
(run* [q]
(fresh [pm x]
(== pm (partial-map {:a x}))
(== pm {:a 1 :b 2})
(== pm q))))))

;; =============================================================================
;; cKanren

Expand Down

0 comments on commit 9b340ea

Please sign in to comment.