证明融合法的展开

时间:2017-08-13 22:25:01

标签: haskell recursion proof induction recursion-schemes

我正在读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上对函数应用程序使用某种归纳法?相关问题:什么是解释和激励各种归纳技术的好资源,如结构诱导?

2 个答案:

答案 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')