core.logic 中的伪关系
pseudo-relation in core.logic
在函数的 core.logic
中,我看到 clojure.core.logic/everyg
的以下定义。
A pseudo-relation that takes a coll and ensures that the goal g
succeeds on every element of the collection.
在这种情况下,pseudo-relation
到底是什么意思?
下面是关系(和non-relational)的一个很好的解释: Another bit of background is everyg
was renamed from everyo
in this commit因为o
后缀应该只用于关系。
一个 属性 关系目标是当 all/some/none 的输入是 non-ground 时,他们可以提供答案。 conso
是相关的,所以我们可以问什么是满足关系的值,其中 l
是 a
前置到 d
,其中所有变量都是新鲜的:
(run* [a d l] (conso a d l))
=> ([_0 _1 (_0 . _1)])
这告诉我们a
(_0
)是新鲜的,d
(_1
)是新鲜的,而l
((_0 . _1)
) 是 a
前置到 d
。虽然这些值中的 none 是基础值,但我们仍然可以在答案中看到它们之间的 关系 。
everyg
情况不一样:
(run* [g coll] (everyg g coll)) ;; Don't know how to create ISeq from: clojure.core.logic.LVar
everyg
不能告诉我们g
和coll
之间的关系是什么,也不能告诉我们g
或 coll
可能是如果我们提供任一接地值:
(run* [coll] (everyg succeed coll)) ;; throws
(let [coll (repeatedly 3 lvar)] ;; throws too
(run* [g]
(everyg g coll)))
虽然 everyg
本身不是关系,但您可以将目标 g
和 coll
的新鲜 and/or 基础变量传递给它:
(let [coll (cons 1 (repeatedly 2 lvar))] ;; 1 prepended to two fresh logic vars
(run* [q]
(== q coll)
(everyg #(fd/in % (fd/domain 0 1)) coll)))
=> ((1 0 0) (1 1 0) (1 0 1) (1 1 1))
无论 everyg
目标的位置如何,此示例都会给出相同的答案,这是另一个 属性 关系目标。
并且我们可以将 conso
关系传递给 everyg
以及所有新的逻辑变量,并且仍然可以在答案中看到关系,与上面的 conso
示例完全一样:
(run* [a d q]
(everyg #(conso a d %) [q]))
=> ([_0 _1 (_0 . _1)])
所以有一些注意事项,everyg
可以关联使用,这就是为什么我认为它被认为是 pseudo-relational 而不是 non-relational。
在函数的 core.logic
中,我看到 clojure.core.logic/everyg
的以下定义。
A pseudo-relation that takes a coll and ensures that the goal g succeeds on every element of the collection.
在这种情况下,pseudo-relation
到底是什么意思?
下面是关系(和non-relational)的一个很好的解释:everyg
was renamed from everyo
in this commit因为o
后缀应该只用于关系。
一个 属性 关系目标是当 all/some/none 的输入是 non-ground 时,他们可以提供答案。 conso
是相关的,所以我们可以问什么是满足关系的值,其中 l
是 a
前置到 d
,其中所有变量都是新鲜的:
(run* [a d l] (conso a d l))
=> ([_0 _1 (_0 . _1)])
这告诉我们a
(_0
)是新鲜的,d
(_1
)是新鲜的,而l
((_0 . _1)
) 是 a
前置到 d
。虽然这些值中的 none 是基础值,但我们仍然可以在答案中看到它们之间的 关系 。
everyg
情况不一样:
(run* [g coll] (everyg g coll)) ;; Don't know how to create ISeq from: clojure.core.logic.LVar
everyg
不能告诉我们g
和coll
之间的关系是什么,也不能告诉我们g
或 coll
可能是如果我们提供任一接地值:
(run* [coll] (everyg succeed coll)) ;; throws
(let [coll (repeatedly 3 lvar)] ;; throws too
(run* [g]
(everyg g coll)))
虽然 everyg
本身不是关系,但您可以将目标 g
和 coll
的新鲜 and/or 基础变量传递给它:
(let [coll (cons 1 (repeatedly 2 lvar))] ;; 1 prepended to two fresh logic vars
(run* [q]
(== q coll)
(everyg #(fd/in % (fd/domain 0 1)) coll)))
=> ((1 0 0) (1 1 0) (1 0 1) (1 1 1))
无论 everyg
目标的位置如何,此示例都会给出相同的答案,这是另一个 属性 关系目标。
并且我们可以将 conso
关系传递给 everyg
以及所有新的逻辑变量,并且仍然可以在答案中看到关系,与上面的 conso
示例完全一样:
(run* [a d q]
(everyg #(conso a d %) [q]))
=> ([_0 _1 (_0 . _1)])
所以有一些注意事项,everyg
可以关联使用,这就是为什么我认为它被认为是 pseudo-relational 而不是 non-relational。