我希望以下表达式返回一些结果,每个结果由两个cons单元组成,其中两个cons单元格不相等。但是,它返回0结果。为什么我没有结果?
(run* [c1 c2]
(fresh [lx ly x1 y1 x2 y2]
(== lx [1 2])
(== ly [4 5])
(membero x1 lx)
(membero x2 lx)
(membero y1 ly)
(membero y2 ly)
(conso x1 y1 c1)
(conso x2 y2 c2)
(!= c1 c2)))
预期结果的例子:
[(1 . 4) (2 . 5)]
[(1 . 4) (1 . 5)]
[(2 . 4) (2 . 5)]
我不希望它返回像[(1 . 4) (1 . 4)]
这样的结果,其中每个缺点中的两个点都相等。
如果删除(!= c1 c2)
部分,我会得到16个结果,包括两个缺点相同的结果。
如果我将(!= c1 c2)
替换为:
(conde
((!= x1 x2))
((!= y1 y2)))
应该做同样的事情,但明确检查两个单元格。
答案 0 :(得分:5)
这不是一个有效的core.logic程序。你不能在尾巴不合适的地方使用conso
。 Scheme中的miniKanren将允许您执行此操作,但core.logic的行为未定义。我修改了conso
的文档字符串以反映这一点。一个工作计划:
(run* [c1 c2]
(fresh [lx ly x1 y1 x2 y2]
(== lx [1 2])
(== ly [4 5])
(membero x1 lx)
(membero x2 lx)
(membero y1 ly)
(membero y2 ly)
(== [x1 y1] c1)
(== [x2 y2] c2)
(!= c1 c2)))
答案 1 :(得分:0)
说你不能像这样使用conso的海报是正确的。这是docstring:
l是集合的关系,其中a是l的第一个 而d是l的其余部分。如果地面d必须绑定到合适的尾部。
您应使用(== [x1 y1] c1)
和(== [x2 y2] c2)
或(conso x1 [y1] c1)
和(conso x2 [y2] c2)
制作正确的列表。