我怎样才能证明elem z(xs ++ ys)== elem z xs ||你好吗?

时间:2015-03-05 19:21:28

标签: haskell proof induction

我有以下内容:

elem :: Eq a => a -> [a] -> Bool
elem _ [] = False
elem x (y:ys) = x == y || elem x ys

我怎样才能证明所有x和y的所有......

elem z (xs ++ ys) == elem z xs || elem z ys

我试图让左侧等同于右侧,但是我的尝试都没有取得丰硕的成果。

L.S elem z (x:xs ++ y:ys) = z==x || z==y || elem xs || elem ys

R.S elem z (x:xs) || elem z (y:ys) = z==x || z==y || elem xs || elem ys

有人能帮助我吗?

4 个答案:

答案 0 :(得分:5)

这是一个暗示。

++运算符是通过对第一个参数的归纳来定义的:

[]     ++ ys = ys
(x:xs) ++ ys = x : (xs ++ ys)

你想要证明

elem z (xs ++ ys) == elem z xs || elem z ys

这是zxsys的属性。我们称之为p(z,xs,ys)。 此外,++的第一个参数是xs,因此建议在xs上进行归纳。

我们需要证明:

  1. 基本情况:p(z,[],ys)
  2. 归纳案例:p(z,x:xs,ys)假设归纳假设p(z,xs,ys)
  3. 您还需要在某些时候利用elem的定义。

答案 1 :(得分:3)

平等推理很有趣!如果你自己做一些证明,你会很快得到它的诀窍。我热烈推荐ch。 Graham Hutton的 中的编程<13>中的简要介绍。

无论如何,你可以证明,对于所有等于和有限的(见Tom Ellis's answerxsysz

elem z (xs ++ ys) == elem z xs || elem z ys

通过列表xs上的归纳。为此,您需要使用++||elem的定义,并使用||关联的事实:

[]     ++ ys = ys
(x:xs) ++ ys = x : (xs ++ ys)

False || b = b
True  || _ = True

elem _ [] = False
elem x (y:ys) = x == y || elem x ys

基本案例

ysEq a => [a]类型的值,zEq a => a类型的值;那我们有

elem z ([] ++ ys)
=     {applying ++}
elem z ys
=     {unapplying ||}
False || elem z ys
=     {unapplying elem}
elem z [] || elem z ys

归纳案例

允许xsysEq a => [a]类型的值,以及类型x的{​​{1}},z值。假设(归纳假设)

Eq a => a

然后我们

elem z (xs ++ ys) == elem z xs || elem z ys

(QED)

答案 2 :(得分:2)

要扩展已接受的答案,当xs无限时,此等式也是如此。如果是elem z xs = True,那么elem z (xs ++ ys) = True = elem z xs || elem z ys。否则,elem z (xs ++ ys) = ⊥ = elem z xs || elem z ys,可以在ghci中轻松验证。

答案 3 :(得分:1)

Haskell中的列表不满足归纳原理,因为Haskell是一种惰性语言,列表可能是无限的。相反,我相信你应该用相同的形式写两个表达式来表明它们是等价的。所需的形式是

f [] = z
f (x:xs) = g x (f xs)

使用这种方法来证明所需的结果

f xs = elem z (xs ++ ys)
f' xs = elem z xs || elem z ys

请注意,通过xs上的模式匹配并使用(++)elem的定义,这些相当于

f [] = elem z ys
f (x:xs) = x == z || elem z (xs ++ ys)

f' [] = elem z ys
f' (x:xs) = x == z || elem z xs || elem z ys

我们可以将递归调用重写为

f [] = elem z ys
f (x:xs) = x == z || f xs

f' [] = elem z ys
f' (x:xs) = x == z || f' xs

如果我们定义g x rest = x == z || rest那么

f [] = elem z ys
f (x:xs) = g x (f xs)

f' [] = elem z ys
f' (x:xs) = g x (f' xs)

然后请注意ff'的表达式相同。

我之前的回答不正确:

<德尔> 事实并非如此。考虑     xs =重复0     ys = [1]     z = 1 然后     elem z ys = elem 1 [1] =真 所以     elem z xs || elem z ys = True 但     elem z(xs ++ ys)= elem 1(重复0 ++ [1])= False 因为在`repeat 0`中搜索`1`永远不会终止。 这是一个典型的例子,说明为什么懒惰语言的等式理论不如严格语言那么丰富。 正如其他答案所示,你可以通过结构归纳证明你的定理是* finite *`xs`。但这有点乞求这个问题。什么是*有限*列表?