我有以下内容:
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
有人能帮助我吗?
答案 0 :(得分:5)
这是一个暗示。
++
运算符是通过对第一个参数的归纳来定义的:
[] ++ ys = ys
(x:xs) ++ ys = x : (xs ++ ys)
你想要证明
elem z (xs ++ ys) == elem z xs || elem z ys
这是z
,xs
和ys
的属性。我们称之为p(z,xs,ys)
。
此外,++
的第一个参数是xs
,因此建议在xs
上进行归纳。
我们需要证明:
p(z,[],ys)
。p(z,x:xs,ys)
假设归纳假设p(z,xs,ys)
您还需要在某些时候利用elem
的定义。
答案 1 :(得分:3)
平等推理很有趣!如果你自己做一些证明,你会很快得到它的诀窍。我热烈推荐ch。 Graham Hutton的
无论如何,你可以证明,对于所有等于和有限的(见Tom Ellis's answer)xs
,ys
和z
,
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
让ys
为Eq a => [a]
类型的值,z
为Eq a => a
类型的值;那我们有
elem z ([] ++ ys)
= {applying ++}
elem z ys
= {unapplying ||}
False || elem z ys
= {unapplying elem}
elem z [] || elem z ys
允许xs
,ys
为Eq 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)
然后请注意f
和f'
的表达式相同。
我之前的回答不正确:
<德尔> 事实并非如此。考虑 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`。但这有点乞求这个问题。什么是*有限*列表? 德尔>