【发布时间】:2019-07-15 19:24:04
【问题描述】:
在函数的core.logic 中,我看到clojure.core.logic/everyg 的以下定义。
采用 coll 并确保目标 g 的伪关系 在集合的每个元素上都成功。
pseudo-relation 在这种情况下究竟意味着什么?
【问题讨论】:
标签: clojure clojure-core.logic
在函数的core.logic 中,我看到clojure.core.logic/everyg 的以下定义。
采用 coll 并确保目标 g 的伪关系 在集合的每个元素上都成功。
pseudo-relation 在这种情况下究竟意味着什么?
【问题讨论】:
标签: clojure clojure-core.logic
下面是对关系(和非关系)的一个很好的解释:What does non-relational mean in practice for core.logic? 另一个背景是 everyg 从 everyo 重命名为 this commit,因为 o 后缀只能用于关系。
关系目标的一个属性是,当他们的所有/部分/没有输入都是非基础时,他们可以提供答案。 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。虽然这些值都不是基础,但我们仍然可以在答案中看到它们之间的关系。
everyg 并非如此:
(run* [g coll] (everyg g coll)) ;; Don't know how to create ISeq from: clojure.core.logic.LVar
everyg 无法告诉我们g 和coll 之间的关系 是什么,也无法告诉我们g 是什么或 @987654345 @ 可能是如果我们提供任何一个接地值:
(run* [coll] (everyg succeed coll)) ;; throws
(let [coll (repeatedly 3 lvar)] ;; throws too
(run* [g]
(everyg g coll)))
虽然 everyg 本身不是关系,但您可以将目标 g 和 coll 传递给新鲜和/或地面变量:
(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 可以用于关系,这就是为什么我认为它被认为是伪关系而不是非关系。
【讨论】: