Skip to content

Commit

Permalink
LOGIC-108: recursive featurec. Add protocol IFeature. Implementers
Browse files Browse the repository at this point in the history
should return something which can optional unify in the manner of
partial-map. Extend IPersistentHashMap to IFeature. Add test cases
demonstrating recursive behavior.
  • Loading branch information
swannodette committed Mar 18, 2013
1 parent ae66b6f commit d5eda7d
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 2 deletions.
14 changes: 13 additions & 1 deletion src/main/clojure/clojure/core/logic.clj
Expand Up @@ -2629,6 +2629,10 @@
(defn partial-map? [x]
(instance? PMap x))

(extend-type clojure.lang.IPersistentMap
IFeature
(-feature [x] (partial-map x)))

(defn -featurec
[x fs]
(reify
Expand All @@ -2651,13 +2655,21 @@
IConstraintWatchedStores
(watched-stores [this] #{::subst})))

(defn ->feature [x]
(-feature
(walk-term x
(fn [y]
(if (tree-term? y)
(->feature y)
y)))))

(defn featurec
"Ensure that a map contains at least the key-value pairs
in the map fs. fs must be partially instantiated - that is,
it may contain values which are logic variables to support
feature extraction."
[x fs]
(cgoal (-featurec x (partial-map fs))))
(cgoal (-featurec x (->feature fs))))

;; =============================================================================
;; defnc
Expand Down
8 changes: 7 additions & 1 deletion src/main/clojure/clojure/core/logic/protocols.clj
Expand Up @@ -212,4 +212,10 @@
;; Deep constraints

(defprotocol IConstrainTree
(-constrain-tree [t fc s]))
(-constrain-tree [t fc s]))

;; -----------------------------------------------------------------------------
;; Features

(defprotocol IFeature
(-feature [x]))
14 changes: 14 additions & 0 deletions src/test/clojure/clojure/core/logic/tests.clj
Expand Up @@ -1736,6 +1736,20 @@
(is (= (u/unifier ['(?x ?y) '(?y ?x)])
'{?x ?y})))

(deftest test-108-recursive-features
(is (= (run* [x y]
(featurec x {:foo {:bar y}})
(== x {:foo {:bar 1}}))
'([{:foo {:bar 1}} 1])))
(is (= (run* [x y]
(featurec x {:foo {:bar y}})
(== x {:foo {:bar 1 :woz 2}}))
'([{:foo {:bar 1 :woz 2}} 1])))
(is (= (run* [x y]
(featurec x {:foo {:bar y}})
(== x {:foo {:baz 1}}))
'())))

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

Expand Down

0 comments on commit d5eda7d

Please sign in to comment.