在理解自定义core.logic约束时需要澄清

时间:2019-07-07 15:19:39

标签: clojure clojure-core.logic functional-logic-progr

我试图理解如下定义的自定义private fun toggleView1Visibility() { TransitionManager.endTransitions(sceneRoot) val isView1Appearing = view1.visibility != View.VISIBLE TransitionManager.beginDelayedTransition( sceneRoot, createTransition(isView1Appearing) ) view1.visibility = if (isView1Appearing) View.VISIBLE else View.GONE } private fun createTransition( isView1Appearing: Boolean ): Transition { val view1Fade = Fade().apply { addTarget(view1) duration = 750 } val view2ChangeBounds = ChangeBounds().apply { addTarget(view2) duration = 750 } return TransitionSet().apply { ordering = TransitionSet.ORDERING_SEQUENTIAL if (isView1Appearing) { addTransition(view2ChangeBounds) addTransition(view1Fade) } else { addTransition(view1Fade) addTransition(view2ChangeBounds) } } } 约束,

core.logic

如何在(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))) 的上下文中解释_.

1 个答案:

答案 0 :(得分:2)

defne是使用特殊模式匹配语法的宏,但其行为与conde类似。 (仅供参考,其中每个e代表“一切”,即每个子句都可以做出贡献。)

  • _下划线表示必须存在的值,但是您不在乎它是什么。
  • .表示项目在.左侧,列表的尾部在.右侧。这用于将列表的各个项目和列表的其余部分绑定到不同的值。 (另请参见core.logic中的llist。)

Clojure中类似的序列破坏操作将使用&而不是.

(let [[_ _ [_ & tail]] coll] ...)

因此以下模式的意思是“我们不在乎第一个或第二个输入参数,但第三个应该是列表,其中我们的头是x(即等于函数的x输入参数),然后将尾部绑定到tail“:

[_ _ [x . tail]]

还请注意,tail在此处可以为空列表,并且您可以在.之前绑定多个值。

由于您的示例是递归目标,因此它最终会通过在x之前找到y而终止,或者由于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)))

有两个子句,每个子句都由顶级列表()表示:

  1. [_ [x . tail]]-第一个_代表输入x arg,我们不在乎 match [x . tail]描述了第二个参数l的模式,其中如果xl的头,则此模式匹配并且membero成功。
  2. [_ [head . tail]-_在这里的含义相同。但是请注意,我们已经为l的头添加了一个新名称,只需要将其命名为非空列表即可满足此模式。如果匹配,则我们以(membero x tail)递归继续搜索。

只有第一个子句可以通过在x的(子)列表中找到l来使目标成功。第二个子句仅用于解构head的{​​{1}}和tail并递归。

此处l的翻译为membero,但没有模式匹配:

conde