Two related questions in one:
Can Clojure's core.logic module perform arithmetic, logical comparison, etc, like ordinary Prolog? I am envisioning something like the following:
(defrel points person n)
(fact :bob 2)
(fact :charlie 3)
(run* [q] (fresh [x y]
(points :bob x)
(points :charlie y)
(< x y)
(== q (+ x y))))
=> (5)
In this example, neither the logical comparison (< x y)
nor the attempted binding of q to (+ x y)
works. I suppose that this is because I'm working with LVar
s, not integers at this point, and I can't make these comparisons because the symbols aren't yet bound. But it works in prolog:
points(bob, 2).
points(charlie, 3).
?- points(bob, X), points(charlie, Y), Result is X + Y.
=> Result = 5.
In a similar vein, can I somehow use Clojure functions (which return booleans or other "truthy" values) as logic predicates? In other words, to use functions to tell Minikanren which terms unify or not. Something along the lines of:
(defmagic startswithhi-o [v]
(.startsWith v "hi"))
(defrel person n)
(fact person "bob")
(fact person "hillary")
(run* [q]
(fresh [n]
(person n)
(startswithhi-o n)
(== q n)))
=> ("hillary")
If I try things like this I get errors also complaining that the LVars aren't bound. Is there a way to do this?
Lastly if anyone has read this far, I might as well ask: are there plans to incorporate probabilistic logic into core.logic, along the lines of:
http://dtai.cs.kuleuven.be/problog/ ?
I'm not holding my breath but it would be awesome!
Non-relational arithmetic is possible via project
.
(run 1 [q]
(fresh [x y]
(== x 1)
(== y 2)
(project [x y]
(== q (+ x y)))))
(3)
I believe the Prolog example given is also non-relational.
The second half of your question can also be solved via project
, but you must be careful that you always input a ground value.
(defn startwith [x]
(project [x]
(== true (.startsWith x "hi"))))
PS: Hold your breath for Constraint Logic Programming to come to core.logic!
I believe you have to "project" (nonrel/project) a logic variable to its binding before you can apply a function to it:
(defrel points person n)
(fact points :bob 2)
(fact points :charlie 3)
(run* [q]
(exist [x y]
(points :bob x)
(points :charlie y)
(project [x y]
(== true (< x y))
(== q (+ x y)))))
Note that exist substitutes for fresh in the original snippet and the additional argument for the fact declarations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With