Skip to content

Instantly share code, notes, and snippets.

@piotr-yuxuan
Created January 27, 2016 05:08
Show Gist options
  • Save piotr-yuxuan/fa0cfdc63a26b667c3f3 to your computer and use it in GitHub Desktop.
Save piotr-yuxuan/fa0cfdc63a26b667c3f3 to your computer and use it in GitHub Desktop.
How to use clojure functions in core.logic?
;; I have defined a function, let's call it modifier, which has a
;; specific logic inside. I want core.logic to deal with it in order to
;; find the correct parameters for this function to output the
;; result I want.
;; Let's define two states. The goal is to find out how to go from the
;; depart state to the arrival one. These states are not that very
;; difficult structures, they're basically maps.
(def depart-state {:a {:a 1 :c 4} :b {:a 2 :b 3 :c 6} :c 3})
(def arrival-state {:a {:a 1 :b 2 :c 4} :b {:a 2 :b 3 :c 6} :c 3})
;; Now here is the basic clojure function I want to use. Ok, mine is a
;; bit different but this is a minimal (non-)working example the real
;; function I want to use change a map with assoc and assoc-in so this
;; mock function stays relevant :-)
(defn modifier [basic x y value] (assoc-in basic [x y] value))
;; Let's first make sure this function works as intended:
(clojure.test/is (= (modifier depart-state :a :b 2) arrival-state))
;; Great, now let's use it!
(run* [_1 _2 _3]
(membero _1 [:a :b])
(membero _2 [:a :b])
(membero _3 (range 4))
(clojure.core.logic/== arrival-state (modifier depart-state _1 _2 _3)))
;; => ()
;; Nothing. So I'm very puzzled: sure any basic Clojure function can't
;; deal with lvars but how could I get core.logic seamlessly use these
;; functions?
@piotr-yuxuan
Copy link
Author

Well, I just figured out it's enough to project the lvars:

(let [depart-state  {:a {:a 1      :c 4} :b {:a 2 :b 3 :c 6} :c 3}
      arrival-state {:a {:a 1 :b 2 :c 4} :b {:a 2 :b 3 :c 6} :c 3}
      modifier (fn [basic x y value] (assoc-in basic [x y] value))]
  (run* [_1 _2 _3]
    (membero _1 [:a :b])
    (membero _2 [:a :b])
    (membero _3 (range 4))
    (project [_1 _2 _3]
             (clojure.core.logic/== arrival-state (modifier depart-state _1 _2 _3)))))

By the way, when using this, it's better not to use set as duplicates may appears.

So this issue can be seen as solved but do not hesitate to suggest any better ways :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment