Question regarding core.logic

191 views
Skip to first unread message

Laverne Schrock

unread,
Sep 4, 2017, 10:49:11 AM9/4/17
to Clojure
When I run (run* [q] (fresh [x] (== [x] ['z]) (== q x))), I get (z), which makes sense.

When I run (run* [q] (fresh [x] (== q x))), I get (_0), which makes sense since I've placed no restriction on x.

However, when I run (run* [q] (fresh [x] (== ['x] ['z]) (== q x))), I get (), which doesn't make sense to me. Obviously (== ['x] ['z]) is placing some sort of impossible constraint on x, but I can't tell what that constraint is actually doing.

Ultimately, what I want to be able to do is something along the lines of:

(def my-var '[x])
(run* [q] (fresh [x] (== my-var ['z]) (== q x)))

and get back (z) instead of ().

Note that the following produces (z) as desired:

(def my-other-var '[z])
(run* [q] (fresh [x] (== [x] my-other-var) (== q x)))

So it is only the passing in of the fresh variable that isn't working the way I would expect it to.

Any idea on what I can do to make this work?


Russell Mull

unread,
Sep 5, 2017, 2:50:59 PM9/5/17
to Clojure
On Monday, September 4, 2017 at 7:49:11 AM UTC-7, Laverne Schrock wrote:
When I run (run* [q] (fresh [x] (== [x] ['z]) (== q x))), I get (z), which makes sense.

When I run (run* [q] (fresh [x] (== q x))), I get (_0), which makes sense since I've placed no restriction on x.

However, when I run (run* [q] (fresh [x] (== ['x] ['z]) (== q x))), I get (), which doesn't make sense to me. Obviously (== ['x] ['z]) is placing some sort of impossible constraint on x, but I can't tell what that constraint is actually doing.

You're asking it to restrict the results to cases where the vector containing symbol x is unifies with the vector containing symbol z. Symbols unify with equality, and 'x does not equal 'z, so you get no results.  

 
Ultimately, what I want to be able to do is something along the lines of:

(def my-var '[x])
(run* [q] (fresh [x] (== my-var ['z]) (== q x)))

and get back (z) instead of ().

That doesn't make a ton of sense; the usage of my-var is evaluated in regular Clojure fashion to be '[x], and it devolves to the same case. 

It's not really clear what you're trying to do, so it's hard to offer further advice. But you might find the whole enterprise a bit less confusing if you use keywords or strings in the places you're using symbols. 

- Russell

Laverne Schrock

unread,
Sep 5, 2017, 5:03:36 PM9/5/17
to Clojure

On Tuesday, September 5, 2017 at 1:50:59 PM UTC-5, Russell Mull wrote:
On Monday, September 4, 2017 at 7:49:11 AM UTC-7, Laverne Schrock wrote:
When I run (run* [q] (fresh [x] (== [x] ['z]) (== q x))), I get (z), which makes sense.

When I run (run* [q] (fresh [x] (== q x))), I get (_0), which makes sense since I've placed no restriction on x.

However, when I run (run* [q] (fresh [x] (== ['x] ['z]) (== q x))), I get (), which doesn't make sense to me. Obviously (== ['x] ['z]) is placing some sort of impossible constraint on x, but I can't tell what that constraint is actually doing.

You're asking it to restrict the results to cases where the vector containing symbol x is unifies with the vector containing symbol z. Symbols unify with equality, and 'x does not equal 'z, so you get no results.  


Oh, right. I'm not sure what I was thinking there.
 
 
Ultimately, what I want to be able to do is something along the lines of:

(def my-var '[x])
(run* [q] (fresh [x] (== my-var ['z]) (== q x)))

and get back (z) instead of ().

That doesn't make a ton of sense; the usage of my-var is evaluated in regular Clojure fashion to be '[x], and it devolves to the same case. 


Okay, that makes sense.
 
It's not really clear what you're trying to do, so it's hard to offer further advice.

Essentially, what I'm trying to do is pass expressions dynamically to run*. If I hardcode [x] I'm fine, but if I want to be able to derive the vector from user input, I'm stuck, since I can't seem to figure out how to associate a symbol that I pass in with the fresh variable introduced with fresh.
 
But you might find the whole enterprise a bit less confusing if you use keywords or strings in the places you're using symbols. 

- Russell

Unfortunately, fresh doesn't allow anything other than symbols to be created as fresh variables. 

(run* [q] (fresh [x] (== x q))) obviously returns: (_0)
(run* [q] (fresh [:x] (== :x q))) throws: CompilerException java.lang.Exception: Unsupported binding form: :x


Russell Mull

unread,
Sep 6, 2017, 1:47:36 PM9/6/17
to Clojure

On Tuesday, September 5, 2017 at 2:03:36 PM UTC-7, Laverne Schrock wrote:

On Tuesday, September 5, 2017 at 1:50:59 PM UTC-5, Russell Mull wrote: 
It's not really clear what you're trying to do, so it's hard to offer further advice.

Essentially, what I'm trying to do is pass expressions dynamically to run*. If I hardcode [x] I'm fine, but if I want to be able to derive the vector from user input, I'm stuck, since I can't seem to figure out how to associate a symbol that I pass in with the fresh variable introduced with fresh.

You want user input to determine the list of logic variables you're passing to 'fresh'? That sounds strange. The analogue in regular Clojure would be to use user input to drive the binding part of a 'let' form. If you want to do code generation go for it, but I'm guessing that's not the right path here. 

Perhaps you just want to find out a list of things? You could do this by building a list in your logic program and unifying that with the unknown in your run form. 

- Russ
Reply all
Reply to author
Forward
0 new messages