I'm looking for core.logic guides with real life examples (eg, math questions), does anyone know something that could help?
I'd probably start here https://www.youtube.com/watch?v=iCuVTGWNU3s
Thank you, I will ask questions in that channel if that's ok
Is there a difference between (let [x (lvar)] goals... and (fresh [x] goals...) , when no x has been introduced in the run* expression before?
Yes, there is a difference. Fresh is a goal constructor (I.e. returns a function that takes a substitution/state and returns a stream of answers). A let form is not a goal constructor by itself. You would have to wrap the goals in a conjunction goal. In other words, it's close but not identical. I'm not close to the source at the moment, but you can macro expand fresh and see what's underneath. In microkanren, which is not core.logic, fresh basically maps to a call to a lambda where the parameter is a newly created lvar and the function is a goal constructor that returns a goal that is a conjunction of the goals in the fresh. I highly encourage you to read through the microkanren paper (see the papers section of http://minikanren.org. It's less than a page of source for the whole implementation and it will really help you understand what's happening under the hood.
I see, thank you, it helped a lot.
Why doesn't this output [:c :f]?
(do
(db-rel signal input output)
(db
[signal [:a :b :c :e :f] 0]
[signal [:c :f] 1]
[signal [:a :c :d :e :g] 2]
[signal [:a :c :d :f :g] 3]
[signal [:b :c :d :f] 4]
[signal [:a :b :d :f :g] 5]
[signal [:a :b :d :e :f :g] 6]
[signal [:a :c :f] 7]
[signal [:a :b :c :d :e :f :g] 8]
[signal [:a :b :c :d :f :g] 9])
(run* [q]
(fresh [a b]
(signal [a b] 1)
(== q [a b]))))Got it, I forgot with-db
Will two lvars defined like this: (lvar :a true) will be the same?
The REPL is your friend:
clojure.core.logic> (identical? (lvar :a true) (lvar :a true))
false
clojure.core.logic> (= (lvar :a true) (lvar :a true))
false
So, no. They are not the same and wonβt compare as the same. You can see this in the printed representation:
clojure.core.logic> (lvar :a true)
<lvar::a__4588>
clojure.core.logic> (lvar :a true)
<lvar::a__4591>
If you look at the source, around line 714 you can see most of the creation paths use a unique counter to instantiate the lvar. You can force them to compare as equal using the false flag:
clojure.core.logic> (= (lvar :a false) (lvar :a false))
true
clojure.core.logic> (lvar :a false)
<lvar::a>
clojure.core.logic> (lvar :a false)
<lvar::a>I see, very helpful thank you.
Is it safe to assume that run* returning '() means a contradiction in the goals?
I think so. It means there is no substitution which meets the goals
Okay, thank you
I'm getting a stack overflow error with run*:
(StackOverflowError) at clojure.core.logic.Substitutions/walk (logic.clj:359)
Does that mean my constraint set is too broad?Oh nevermind, sets aren't supported.