3

Attempting to use Logic to solve the following in python:

from kanren             import run, eq, membero, var, conde
from kanren.constraints import neq, isinstanceo

rules = (eq, (var(), var(), var(), var()), people),
  (membero, (4, x, ('Steve'  , var()   , 'blue' , var()      ), people)),
  (membero, (4, x, ( var()   , 'cat'   , var()  , 'Canada'   ), people)),
  (membero, (4, x, ('Matthew', var()   , var()  , 'USA'      ), people)),
  (membero, (4, x, ( var()   , var()   , 'black', 'Australia'), people)),
  (membero, (4, x, ('Jack'   , 'cat'   , var()  , var()      ), people)),
  (membero, (4, x, ('Alfred' , var()   , var()  , 'Australia'), people)),
  (membero, (4, x, ( var()   , 'dog'   , var()  , 'France'   ), people)),
  (membero, (4, x, ( var()   , 'rabbit', var()  , var()      ), people))

results in:

(<function kanren.goals.membero(x, ls)>,
(4, ~_2, (~_2422, 'rabbit', ~_2423, ~_2424), ~_809))

which keeps me from running

solutions = run(0, people, rules)

Can you help me with a solution?

Thank you.

Will Ness
  • 70,110
  • 9
  • 98
  • 181
  • just shooting in the dark here (looking at the opening page at https://pypi.org/project/miniKanren/), maybe you need to add `x = var()` somewhere. – Will Ness Jun 19 '21 at 04:57
  • or maybe try removing the first two arguments to `membero`. in the [examples that I could find](https://python.hotexamples.com/examples/logpy.core/-/membero/python-membero-function-examples.html) `membero` is called with only two arguments. – Will Ness Jun 19 '21 at 08:00
  • 1
    I wrote a zebra puzzle solver that you can find here: https://puzzle-solvers.readthedocs.io/en/latest/. Not Kanren, but it works – Mad Physicist Jan 10 '22 at 10:46

1 Answers1

0

Not sure what version of kanren you were using but it sure doesn't work that way under the latest one. This seemed to produce the result:

    people = var()
    things = lall(eq((var(), var(), var(), var()), people),
    membero(('Steve', var(), 'blue', var()), people),
    membero((var(), 'cat', var(), 'Canada'), people),
    membero(('Matthew', var(), var(), 'USA'), people),
    membero((var(), var(), 'black', 'Australia'), people),
    membero(('Jack', 'cat', var(), var()), people),
    membero(('Alfred', var(), var(), 'Australia'), people),
    membero((var(), 'dog', var(), 'France'), people),
    membero((var(), 'rabbit', var(), var()), people)

    solutions = run(0, people, things)

It results in many solutions, but I think they're just permutations of each other. Maybe it can be made tighter like this:

    people = var()
    things = lall(eq((('Steve', var(), var(), var()),
                      ('Matthew', var(), var(), var()),
                      ('Jack', var(), var(), var()),
                      ('Alfred', var(), var(), var())),
                     people),
    membero(('Steve', var(), 'blue', var()), people),
    membero((var(), 'cat', var(), 'Canada'), people),
    membero(('Matthew', var(), var(), 'USA'), people),
    membero((var(), var(), 'black', 'Australia'), people),
    membero(('Jack', 'cat', var(), var()), people),
    membero(('Alfred', var(), var(), 'Australia'), people),
    membero((var(), 'dog', var(), 'France'), people),
    membero((var(), 'rabbit', var(), var()), people)
         )

    solutions = run(0, people, things)

This still resulted in two solutions, both of which look identical to me.

(('Alfred', ~_16, 'black', 'Australia'),
 ('Jack', 'cat', ~_14, 'Canada'),
 ('Matthew', 'rabbit', ~_21, 'USA'),
 ('Steve', 'dog', 'blue', 'France'))

Of course, only mentioning three animals and two colors, that's all you're gonna get.

I can see where you might have gotten the syntax in the original question: was it perhaps here? I wish I could get that puzzle going, but nothing I do works for it...

Update

Had a very helpful exchange with the developers at kanren. Check it out

rschwieb
  • 746
  • 2
  • 16
  • 41