首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用实例证明函数的定理

用实例证明函数的定理
EN

Stack Overflow用户
提问于 2018-05-01 17:40:57
回答 2查看 104关注 0票数 1

假设我们有一个函数merge,它只合并两个列表:

代码语言:javascript
复制
Order : Type -> Type
Order a = a -> a -> Bool

merge : (f : Order a) -> (xs : List a) -> (ys : List a) -> List a
merge f xs [] = xs
merge f [] ys = ys
merge f (x :: xs) (y :: ys) = case x `f` y of
                                   True  => x :: merge f xs (y :: ys)
                                   False => y :: merge f (x :: xs) ys

我们想要证明它的一些聪明之处,例如,合并两个非空列表会产生一个非空列表:

代码语言:javascript
复制
mergePreservesNonEmpty : (f : Order a) ->
                         (xs : List a) -> (ys : List a) ->
                         {auto xsok : NonEmpty xs} -> {auto ysok : NonEmpty ys} ->
                         NonEmpty (merge f xs ys)
mergePreservesNonEmpty f (x :: xs) (y :: ys) = ?wut

检查wut孔的类型给我们

代码语言:javascript
复制
wut : NonEmpty (case f x y of   True => x :: merge f xs (y :: ys) False => y :: merge f (x :: xs) ys)

到目前为止是有意义的!因此,让我们按照这种类型进行案例分割:

代码语言:javascript
复制
mergePreservesNonEmpty f (x :: xs) (y :: ys) = case x `f` y of
                                                    True => ?wut_1
                                                    False => ?wut_2

似乎有理由希望wut_1wut_2的类型能够匹配merge的案例表达式的相应分支(因此wut_1类似于NonEmpty (x :: merge f xs (y :: ys)),可以立即满足),但我们的希望失败了:这些类型与最初的wut相同。

实际上,唯一的方法似乎是使用with-clause:

代码语言:javascript
复制
mergePreservesNonEmpty f (x :: xs) (y :: ys) with (x `f` y)
  mergePreservesNonEmpty f (x :: xs) (y :: ys) | True = ?wut_1
  mergePreservesNonEmpty f (x :: xs) (y :: ys) | False = ?wut_2

在本例中,类型将如预期的那样,但这会导致对每个with分支重复函数参数(一旦with嵌套,情况就会变得更糟),而且with似乎对隐式参数不太好(但这本身可能值得提出一个问题)。

那么,为什么case在这里没有帮助,除了纯粹的实现之外,还有什么其他的原因吗?在其行为与with的行为不匹配的背后,还有其他方法来编写这个证明吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-05-01 21:35:00

只有当新信息以某种方式向后传播到参数时,|左侧的内容才是必要的。

代码语言:javascript
复制
mergePreservesNonEmpty : (f : Order a) ->
                         (xs : List a) -> (ys : List a) ->
                         {auto xsok : NonEmpty xs} -> {auto ysok : NonEmpty ys} ->
                         NonEmpty (merge f xs ys)
mergePreservesNonEmpty f (x :: xs) (y :: ys) with (x `f` y)
  | True = IsNonEmpty
  | False = IsNonEmpty

-- for contrast
sym' : (() -> x = y) -> y = x
sym' {x} {y} prf with (prf ())
-- matching against Refl needs x and y to be the same
-- now we need to write out the full form
  sym' {x} {y=x} prf | Refl = Refl

至于为什么会出现这种情况,我确实认为这只是实现,但更了解情况的人可能会对此提出异议。

票数 2
EN

Stack Overflow用户

发布于 2018-05-02 10:09:24

casehttps://github.com/idris-lang/Idris-dev/issues/4001来证明事情有一个问题

因此,在伊德里斯-比中,我们最终必须删除这些函数中的所有case,并定义与案例条件匹配的单独的顶级帮助程序,例如这里

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50121149

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档