core-logic

branch14 2023-08-14T08:03:40.008939Z

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?

Patrick 2023-08-15T05:37:44.779069Z

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
Patrick 2023-08-15T05:40:36.599429Z

There's also project but it makes it non relational

branch14 2023-08-15T14:21:04.616399Z

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?