Fork me on GitHub
#core-logic
<
2023-08-14
>
branch1408:08:40

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?

Patrick05:08:44

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.

❤️ 1
Patrick05:08:36

There's also project but it makes it non relational

branch1414:08:04

Thank you @U049Q8NTLG3, 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?