Trying to wrap my head around core.logic. How can I mix functional and logic programming?
(defn squared [x]
(* x x))
(run* [x]
(membero x [1 2 3])
(fd/< (squared x) 9)
(fd/> (squared x) 1))
This does not work (`clojure.core.logic.LVar cannot be cast to java.lang.Number`). Do I have to rewrite my function squareinto a goal? How would I do that?You would need to turn it into a relation/goal. When turning a function into a relation, the most important step for reasoning about things (at least in my book) is to make the arity -> arity+1. Basically, you are turning the output of the function into one of the inputs of a relation. So for this problem
(defn squared [n]
(* n n))
Becomes
(defn squaredo [n s]
(fd/* n n s))
Now to use this in the run* statement, there needs to be a fresh variable.
(l/run* [x]
(l/membero x [1 2 3])
(l/fresh [sq]
(squaredo x sq)
(fd/< sq 9)
(fd/> sq 1)))
So in this case, it makes sq the square of x and sq is just used wherever (squared x) was used in the original example.There's also project but it makes it non relational
Thank you @patrick317, this helped.
Is it idiomatic to use featurec to "destructure" values from deeply nested data structures to "store" them in lvars so they can be used in other goals?