如何在core.logic中编写自己的简单约束函数?

时间:2018-01-08 19:53:15

标签: clojure clojure-core.logic

我刚刚阅读了primer的core.logic。到目前为止它是有道理的,但我不知道去哪里学习更多。

假设我想编写自己的约束,有点像引子中显示的membero。这个被称为vectoro,并将事物约束为矢量。

(defn vectoro [s] ???)

(run* [q]
  (conde
    [(== q [1 2])]
    [(== q :a)])
  (vectoro q))

现在我想要返回[1 2]。你怎么写vectoro?这是在任何地方记录的吗?

2 个答案:

答案 0 :(得分:3)

有一个core.logic pred宏可以让这很容易:

(run* [q]
  (== q [1 2])
  (pred q vector?))
=> ([1 2])

(run* [q]
  (== q '(1 2))
  (pred q vector?))
=> ()

以下是您定义vectoro函数/约束的方法(但实现这是essentially the exact same thing pred is doing):

(defn vectoro [a]
  (project [a]
    (== true (vector? a))))

project用于对逻辑变量(LVar)的实际/具体进行操作。然后我们可以使用普通的旧谓词vector?并要求结果为真。这也适用于您的示例程序:

(run* [q]
  (conde
    [(== q [1 2])]
    [(== q :a)])
  (vectoro q))
=> ([1 2])

(run* [q]
  (conde
    [(== q '(1 2))]
    [(== q :a)])
  (vectoro q))
=> ()

答案 1 :(得分:1)

要继续学习,我建议您查找projects that use core.logic,看看他们的源代码是否教给您任何东西。

至于您关于vectoro的具体问题,“project”功能(如“投影”中)可能会实现您想要的功能,这与

相似。
(defn vectoro [s v]
  (core.logic/project [v]
    (core.logic/== s (vector? v)))