我正在读Jeremy Gibbons'关于origami programming的文章,我坚持练习3.7,要求读者证明融合法列表展开:
unfoldL p f g . h = unfoldL p' f' g'
如果
p . h = p' f . h = f' g . h = h . g'
展开列表的函数unfoldL
定义如下:
unfoldL :: (b -> Bool) -> (b -> a) -> (b -> b) -> b -> List a
unfoldL p f g b = if p b then Nil else Cons (f b) (unfoldL p f g (g b))
以下是我目前对证据的尝试:
(unfoldL p f g . h) b
= { composition }
unfoldL p f g (h b)
= { unfoldL }
if p (h b) then Nil else Cons (f (h b)) (unfoldL p f g (g (h b)))
= { composition }
if (p . h) b then Nil else Cons ((f . h) b) (unfoldL p f g ((g . h) b))
= { assumptions }
if p' b then Nil else Cons (f' b) (unfoldL p f g ((h . g') b))
= { composition }
if p' b then Nil else Cons (f' b) ((unfoldL p f g . h) (g' b))
= { ??? }
if p' b then Nil else Cons (f' b) (unfoldL p' f' g' (g' b))
= { unFoldL }
unFoldL p' f' g'
我不确定如何证明标有???
的步骤。我应该在b
上对函数应用程序使用某种归纳法?相关问题:什么是解释和激励各种归纳技术的好资源,如结构诱导?
答案 0 :(得分:3)
我没看过Gibbons的文章,可能还有其他技术可供他参考,但这就是我所知道的。
你正在寻找某种感应,这是一种很好的直觉,因为你需要的东西与你想要证明的东西非常相似。但你实际上需要在这里进行共同诱导。这是因为unfoldL
可以生成无限列表。在正式类型系统中,很难证明两个无限结构是“平等的” - 形式上的平等太强大而不能证明大多数结果。相反,我们证明bisimilarity,在非正式的情况下也可能是平等的。
相似性在理论上是棘手的,我不会进入它(部分是因为我不完全理解基础),但在实践中使用它并不太难。基本上,为了证明两个列表是相似的,你证明它们都是Nil
,或者它们都是Cons
具有相同的头部并且它们的尾部是相似的,你可以使用证明尾巴的相似性时的共同假设(但不是其他地方)。
所以对你来说,我们通过共同证明了所有b
的(因为我们需要对不同的b
s使用共同假设):
(unfoldL p f g . h) b ~~ unfoldL p' f' g' b
到目前为止我们已经
了(unfoldL p f g . h) b
= { your reasoning }
if p' b then Nil else Cons (f' b) ((unfoldL p f g . h) (g' b))
根据p' b
上的案例进行分析,如果p' b
为True,则
if p' b then Nil else Cons (f' b) ((unfoldL p f g . h) (g' b))
= { p' b is True }
Nil
~~ { reflexivity }
Nil
= { p' b is True }
if p' b then Nil else Cons (f' b) (unfoldL p' f' g' (g' b))
= { unfoldL }
unfoldL p' f' g'
如果p' b
为假,那么
if p' b then Nil else Cons (f' b) ((unfoldL p f g . h) (g' b))
= { p' b is False }
Cons (f' b) ((unfoldL p f g . h) (g' b))
*** ~~ { bisimilarity Cons rule, coinductive hypothesis } ***
Cons (f' b) (unfoldL p' f' g' (g' b))
= { p' b is False }
if p' b then Nil else Cons (f' b) (unfoldL p' f' g' (g' b))
= { unfoldL }
标有***
的行是关键行。首先,请注意它是~~
而不是=
。此外,我们被允许仅在Cons
构造函数下使用coinductive假设。如果我们被允许在其他任何地方使用它,那么我们可以证明任何两个列表是相似的。
答案 1 :(得分:2)
经过一些谷歌搜索后,我发现了同一个杰里米·吉本斯(和格雷厄姆·赫顿)发表的论文proof methods for corecursive programs; 该文章包括一个关于互模拟和共同引用的部分,@ luqui在接受的答案中使用的证明技术。 第6节使用展开的普遍性来证明融合法。 为了完整起见,我复制了下面的证明。
unfoldL
的通用属性:
h = unfoldL p f g
<=>
∀ b . h b = if p b then Nil else Cons (f b) (h (g b))
融合法的证明:
unfoldL p f g . h = unfoldL p' f' g'
<=> { universal property }
∀ b . (unfoldL p f g . h) b = if p' b then Nil else Cons (f' b) ((unfoldL p f g . h) (g' b))
<=> { composition }
∀ b . unfoldL p f g (h b) = if p' b then Nil else Cons (f' b) (unfoldL p f g (h (g' b)))
<=> { unfoldL }
∀ b . if p (h b) then Nil else Cons (p (h b)) (unfoldL p f g (g (h b))) = if p' b then Nil else Cons (f' b) (unfoldL p f g (h (g' b)))
<=> { composition }
∀ b . if (p . h) b then Nil else Cons (p . h) b (unfoldL p f g ((g . h) b)) = if p' b then Nil else Cons (f' b) (unfoldL p f g ((h . g') b))
<= { assumptions }
(p . h = p') ^ (f . h = f') ^ (g . h = h . g')