pythological / kanren

An extensible, lightweight relational/logic programming DSL written in pure Python
Other
181 stars 18 forks source link

Running with python3.10 produces typeError #79

Closed DrLynch closed 1 year ago

DrLynch commented 1 year ago

Greetings, when I run a basic example of the zebra problem with miniKanren 1.0.3 under python3.10 I receive a type error. The minimal example is:

  def left(X, Y, list):
     return kanren.membero((X, Y), zip(list, list[1:]))

  def next(X, Y, list):
     return kanren.conde([left(Y, X, list)], [left(X, Y, list)])

   Houses = kanren.var()

   Zebra_Rules = kanren.lall(
      (kanren.eq, (kanren.var(), kanren.var(), kanren.var(), kanren.var(), kanren.var()), Houses),

    (kanren.membero, ('Englishman', kanren.var(), kanren.var(), kanren.var(), 'red'), Houses),
    (kanren.membero, ('Swede', kanren.var(), kanren.var(), 'dog', kanren.var()), Houses),
    (kanren.membero, ('Dane', kanren.var(), 'tea', kanren.var(), kanren.var()), Houses),
    (left,(kanren.var(), kanren.var(), kanren.var(), kanren.var(), 'green'),
    (kanren.var(), kanren.var(), kanren.var(), kanren.var(), 'white'), Houses),
    (kanren.membero, (kanren.var(), kanren.var(), 'coffee', kanren.var(), 'green'), Houses),
    (kanren.membero, (kanren.var(), 'Pall Mall', kanren.var(), 'birds', kanren.var()), Houses),
    (kanren.membero, (kanren.var(), 'Dunhill', kanren.var(), kanren.var(), 'yellow'), Houses),
    (kanren.eq,(kanren.var(), kanren.var(), (kanren.var(), kanren.var(), 'milk', kanren.var(), kanren.var()), kanren.var(), kanren.var()), Houses),
    (kanren.eq,(('Norwegian', kanren.var(), kanren.var(), kanren.var(), kanren.var()), kanren.var(), kanren.var(), kanren.var(), kanren.var()), Houses),
    (next,(kanren.var(), 'Blend', kanren.var(), kanren.var(), kanren.var()),
    (kanren.var(), kanren.var(), kanren.var(), 'cats', kanren.var()), Houses),
    (next,(kanren.var(), 'Dunhill', kanren.var(), kanren.var(), kanren.var()),
    (kanren.var(), kanren.var(), kanren.var(), 'horse', kanren.var()), Houses),
    (kanren.membero, (kanren.var(), 'Blue Master', 'beer', kanren.var(), kanren.var()), Houses),
    (kanren.membero, ('German', 'Prince', kanren.var(), kanren.var(), kanren.var()), Houses),
    (next,('Norwegian', kanren.var(), kanren.var(), kanren.var(), kanren.var()),
    (kanren.var(), kanren.var(), kanren.var(), kanren.var(), 'blue'), Houses),
    (next,(kanren.var(), 'Blend', kanren.var(), kanren.var(), kanren.var()),
    (kanren.var(), kanren.var(), 'water', kanren.var(), kanren.var()), Houses),
    (kanren.membero, (kanren.var(), kanren.var(), kanren.var(), 'zebra', kanren.var()), Houses)
)

Solution = kanren.run(0, Houses, Zebra_Rules)

Executing this code in the interpreter or a file yields the following error:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/share/anaconda3/install/lib/python3.10/site-packages/kanren/core.py", line 202, in run
    return tuple(results)
  File "/usr/local/share/anaconda3/install/lib/python3.10/site-packages/kanren/core.py", line 83, in lconj_seq_goal
    yield from reduce(bind, _goals, g0(S))
  File "/usr/local/share/anaconda3/install/lib/python3.10/site-packages/kanren/core.py", line 83, in lconj_seq_goal
    yield from reduce(bind, _goals, g0(S))
TypeError: 'tuple' object is not callable
DrLynch commented 1 year ago

This problem persists with the latest GitHub sources as well:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/username/Teaching/AIAcademy/Intro-to-AI-Cohort-3-2022/WorkshopMaterials/AIAWorkshopRepo/Week-04/Code/kanren/kanren/core.py", line 238, in run
    return tuple(results)
  File "/home/username/Teaching/AIAcademy/Intro-to-AI-Cohort-3-2022/WorkshopMaterials/AIAWorkshopRepo/Week-04/Code/kanren/kanren/core.py", line 104, in lconj_seq_goal
    yield from reduce(bind, _goals, g0(S))
  File "/home/username/Teaching/AIAcademy/Intro-to-AI-Cohort-3-2022/WorkshopMaterials/AIAWorkshopRepo/Week-04/Code/kanren/kanren/core.py", line 104, in lconj_seq_goal
    yield from reduce(bind, _goals, g0(S))
TypeError: 'tuple' object is not callable
brandonwillard commented 1 year ago

It looks like you're using the tuple-based approach to defining goals from LogPy (e.g. (eq, a, b)). When using this fork, those tuples can be replaced by actual calls on the goals (e.g. eq(a, b)).

brandonwillard commented 1 year ago

The rewritten zebra example is here and it appears to work in Python 3.10, so I'll close this for now.