Clojure 在理解自定义core.logic约束时需要澄清
我试图理解下面定义的自定义Clojure 在理解自定义core.logic约束时需要澄清,clojure,clojure-core.logic,functional-logic-progr,Clojure,Clojure Core.logic,Functional Logic Progr,我试图理解下面定义的自定义核心逻辑约束 (defne lefto "x appears to the left of y in collection l." [x y l] ([_ _ [x . tail]] (membero y tail)) ([_ _ [_ . tail]] (lefto x y tail))) 如何在核心逻辑的上下文中解释和?定义是一个使用特殊模式匹配语法的宏,但其行为类似于压缩。(仅供参考,每一条中的e代表“一切”,即每一条都可以贡献。) 下划线表示
核心逻辑约束
(defne lefto
"x appears to the left of y in collection l."
[x y l]
([_ _ [x . tail]] (membero y tail))
([_ _ [_ . tail]] (lefto x y tail)))
如何在核心逻辑
的上下文中解释和
?定义
是一个使用特殊模式匹配语法的宏,但其行为类似于压缩
。(仅供参考,每一条中的e
代表“一切”,即每一条都可以贡献。)
下划线表示必须存在的值,但您不关心它是什么
表示将
左侧的项目和
右侧的列表尾部串联起来。这用于将列表的各个项目和列表的其余部分绑定到不同的值。(另请参见core.logic中的llist
)
Clojure中类似的序列分解将使用&
而不是
:
(let [[_ _ [_ & tail]] coll] ...)
因此,下面的模式表示“我们不关心第一个或第二个输入参数,但第三个应该是一个列表,其中头部是x
(即等于函数的x
输入参数),并将尾部绑定到tail
”:
还要注意,tail
可以是此处的空列表,并且可以在
之前绑定多个值
由于您的示例是一个递归目标,它最终将通过在y
之前查找x
而终止,或者它将无法匹配任一模式,因为l
将(最终)成为空列表()
,这两种情况都不匹配
简单的例子
membero
定义本身就是相同想法的一个简单示例:
(defne membero
"A relation where l is a collection, such that l contains x."
[x l]
([_ [x . tail]])
([_ [head . tail]]
(membero x tail)))
有两个子句,每个子句由顶级列表表示()
:
[[uu[x.tail]]
-第一个
表示我们不想匹配的输入x
arg。[x.tail]
描述了第二个参数l
的模式,其中如果x
是l
的头,则此模式匹配并且membero
成功
[[uuhead.tail]
-这里的
意思相同。但是请注意,我们为l
的头部指定了一个新名称,它只需要是一个非空列表就可以满足此模式。如果它匹配,那么我们将使用(membero x tail)
递归以继续搜索
只有第一个子句可以通过在l
的(子)列表中查找x
使目标成功;第二个子句仅用于分解l
的头和尾并递归
以下是用conde
翻译的membero
,没有模式匹配:
(defn memberoo [x l]
(conde
[(fresh [a d]
(conso a d l)
(== a x))]
[(fresh [a d]
(conso a d l)
(memberoo x d))]))
我想clojure使用了&
,因为它没有虚线列表。这里的
是什么?一个符号?@sylvester作为答案,其核心逻辑中的“.”是串联。
(defn memberoo [x l]
(conde
[(fresh [a d]
(conso a d l)
(== a x))]
[(fresh [a d]
(conso a d l)
(memberoo x d))]))