了解core.logic!=

时间:2013-05-09 18:39:12

标签: clojure clojure-core.logic

我希望以下表达式返回一些结果,每个结果由两个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)))

应该做同样的事情,但明确检查两个单元格。

2 个答案:

答案 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)制作正确的列表。