Hi Daniel,
I may not understand what you mean by non-deterministic. I think that
relation itself is deterministic, but things are being shuffled around
across the river (i.e. being put on the lists) in different orders, so the
next time pick-one takes the first element, it may not always be the :fox
per se. Let me explain what I mean.
Here I run pick-one by itself:
(l/run* [q]
(l/fresh [a b]
(l/== q [a b])
(pick-one a b [1 2 3])))
That will always produce a list of 3 answers, in the same order: ([1 (2 3)]
[2 (1 3)] [3 (1 2)])
And we can run in other "directions," like so:
(l/run* [q]
(pick-one 1 [2 3] q))
Which will always product a list of 3 answers, again in the same order each
time: ((1 2 3) (2 1 3) (2 3 1))
(The answers will always be in the same order as long as the miniKanren
implementation you are using runs conde clauses from top to bottom. I don't
believe anything about "being a miniKanren" mandates this, but generally
implementations follow this. This holds for both Racket miniKanren and
Clojure's core.logic, so we can safely rely on the above ordering of
answers.)
So what is "non-deterministic"? I think what you might be seeing is that my
problem encoding is using lists to represent the set of things on each side
of the river. So if we start with this scenario:
[:left [:fox :goose :beans] []]
We can pick any of the items and take it to the right. Let's say we are in
the part of the search that tries to take the :goose across. We have this
now:
[:right [:fox :beans] [:goose]]
And now the farmer comes back without an item:
[:left [:fox :beans] [:goose]]
Now, let's say the farmer takes the :beans across:
[:right [:fox] [:beans :goose]]
Whoa! Because my version is using conso to add the item to the list (I'm
writing Clojure vectors, but I mean lists), the :beans are not *in front
of* the :goose. Things are not in the original order we wrote. As you can
probably imagine, things get shuffled around like this throughout the
problem, and when we finally get everything across the river, there's no
guarantee the ordering will be [:fox :goose :beans] like we started with.
My solution ends with this:
[:right [] [:goose :fox :beans]]
Is that what you meant by things not being deterministic? I don't think
it's non-determinism but rather a deterministic shuffling of the order of
the lists, but maybe I'm completely misunderstanding your question. :-P
Apologies if I've given a long answer to something you didn't ask!
By the way, I realized afterward that I could have used this representation
for each state:
[:left [:fox :goose :beans] ['_ '_ '_]]
Here the intention is that the :fox is always the first element on either
side, the :goose is the second element, and the :beans come last. So in the
earlier example of moving the :goose, we would have:
[:right [:fox '_ :beans] ['_ :goose '_]]
This would allow us to write the full specification/program directly,
without the messy extra logic variables, like so:
(l/run 1 [steps]
(firsto steps [:left [:fox :goose :beans] ['_ '_ '_]])
(lasto steps [:right ['_ '_ '_] [:fox :goose :beans]])
(transportations steps))
This would require reworking pick-one, and it would mean transport should
use pick-one "in reverse" instead of conso to add items to a side (I
probably should have done this anyway! Kind of an abstraction leak). I
started reworking the code to try this idea, but I have to get back to work
:-P.
As for logging, you can put print statements into the goals to get some
rudimentary idea of what's happening in the search, but it may not exactly
make sense. miniKanren and core.logic interleave their search streams, so
you would see partial results from different parts of the search tree, and
I'm not sure how you would be able to distinguish one stream from another
mid-flight. If that doesn't make sense, I can explain that in more
detail. In fact, this debugging of miniKanren programs is something of
interest right now, and I think people are looking for a really good way to
do it well.
Cheers!
Jon
On Wed, Jul 5, 2017 at 7:56 AM, Daniel S <[email protected]> wrote:
> Hey Jon,
>
> i worked through the code and run it.
>
> Just for curiosity:
>
> Is there a way in core.logic to print things to console...to analyze/trace
> control/data flow?
> I guess the pick-one relation is non-determistic.
> And the transport relation should fail serveral times during execution.
>
> And would it be possible to include some kind of "logica time stamp".
> Should be just a counter.
> So you could see in what temporal order the actions are in case the result
> list is out of order.
>
>
>
>
> Am Montag, 3. Juli 2017 22:16:06 UTC+2 schrieb Smock Jonathan:
>>
>> Hey Daniel,
>>
>> I realized I could put it behind a gist link:
>> https://gist.github.com/jonsmock/3e4abf488bfcc064f33373a3d090e027
>>
>> Don't look if you want to think it through, but feel free if you're
>> stuck. The invitation to offer hints is still open as well.
>>
>> I think my code could be cleaned up, but I did get my recursive version
>> working (once I noticed I had hardcoded the order of the final solution
>> list).
>>
>> Let me know if you need help!
>>
>> Thanks,
>> Jon
>>
>> On Mon, Jul 3, 2017 at 3:36 PM, Smock Jonathan <[email protected]> wrote:
>>
>>> Hi Daniel,
>>>
>>> I did this one just now: https://en.wikipedia.org/wiki
>>> /Fox,_goose_and_bag_of_beans_puzzle
>>>
>>> It looks like I can solve it, but I'm having trouble making my solution
>>> fully recursive. Instead I had to create 8 fresh variables for the initial
>>> state, the 6 intermediate states, and the final solution state. With that,
>>> my solution comes back very quickly.
>>>
>>> Do you want to see code, or do you want hints? I don't want to spoil it,
>>> if you want to keep working through it.
>>>
>>> I will say the final gotcha for me was in encoding the final solution. I
>>> keep a list of which animals/items are on each side of the river, and while
>>> I can give a list of animals/items of the initial state, I can't hardcode
>>> the list on the ending state. Instead I use a list with 3 fresh variables.
>>> This ensures the farmer ends with all 3 items on the other side, but it
>>> doesn't constraint the the order of the list to any particular order. Does
>>> that make sense?
>>>
>>> Let me know how I can help! Good luck!
>>>
>>> Jon
>>>
>>> On Mon, Jul 3, 2017 at 11:06 AM, Daniel S <[email protected]> wrote:
>>>
>>>> Hello,
>>>>
>>>> anyone solved the River Crossing Puzzle (https://en.wikipedia.org/wiki
>>>> /River_crossing_puzzle)
>>>> with minikanren yet?
>>>>
>>>> bye
>>>>
>>>> Daniel
>>>>
>>>>
>>>> --
>>>> You received this message because you are subscribed to the Google
>>>> Groups "minikanren" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>> an email to [email protected].
>>>> To post to this group, send email to [email protected].
>>>> Visit this group at https://groups.google.com/group/minikanren.
>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>>
>>>
>> --
> You received this message because you are subscribed to the Google Groups
> "minikanren" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at https://groups.google.com/group/minikanren.
> For more options, visit https://groups.google.com/d/optout.
>
--
You received this message because you are subscribed to the Google Groups
"minikanren" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/minikanren.
For more options, visit https://groups.google.com/d/optout.