Доказательство закона слияния для разворачивания

Я читал статью Джереми Гиббонса о программировании оригами. и я застрял на упражнении 3.7, в котором читателю предлагается доказать закон слияния для развертывания списка:

unfoldL p f g . h = unfoldL p' f' g'

if

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? Связанный с этим вопрос: какие есть хорошие ресурсы, которые объясняют и мотивируют различные методы индукции, такие как структурная индукция?


person Dan Oneață    schedule 13.08.2017    source источник


Ответы (2)


Я не читал статью Гиббонса, и могут быть другие методы, на которые он опирается, но вот что я знаю.

Это хорошая интуиция, что вы ищете какую-то индукцию, потому что то, что вам нужно, очень похоже на то, что вы пытаетесь доказать. Но здесь действительно нужна коиндукция. Это потому, что unfoldL может создавать бесконечные списки. В системах формальных типов очень редко можно доказать, что две бесконечные структуры «равны» — формальное равенство слишком сильно, чтобы доказать большинство результатов. Вместо этого мы доказываем биподобие, которое в неформальных обстоятельствах могло бы также быть равенством.

Бисимилярность теоретически сложна, и я не буду вдаваться в нее (отчасти потому, что не до конца понимаю ее основы), но работать с ней на практике не так уж сложно. По сути, чтобы доказать, что два списка биподобны, вы доказываете, что они либо оба Nil, либо что они оба Cons с одной и той же головой, а их хвосты биподобны, и вы можете использовать гипотезу коиндукции при доказательстве биподобности списков. хвосты (но не где-либо еще).

Итак, мы доказываем методом коиндукции, что для всех b (поскольку нам нужно использовать гипотезу коиндукции для разных b):

(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 верно, то

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 равно False, то

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. Если бы нам разрешили использовать его где-нибудь еще, мы могли бы доказать, что любые два списка биподобны.

person luqui    schedule 13.08.2017
comment
Зачем здесь нужна бисимуляция? Что не так с определением, что два списка равны, если они содержат одни и те же элементы в одном и том же порядке? Мне кажется, это определение работает для бесконечных списков. Два шага, включающие ~~, по-видимому, справедливы и для =Nil = Nil и x = y => Cons a x = Cons a y. Кроме того, зачем рассуждать по падежам? Вы можете применить гипотезу индукции непосредственно под \a -> if p' b then Nil else Cons (f' b) a, так как это охраняемый конструктором термин (т.е. путем применения конгруэнтности к гипотезе индукции для большей функции, чем Cons ..). - person user2407038; 14.08.2017
comment
@user2407038 user2407038, иметь те же элементы в том же порядке это что означает бисимуляция. И нет ничего противоречащего в аксиоме биподобия, предполагающей равенство, но это, в конце концов, аксиома — она не следует из законов лямбда-исчисления — и мы должны знать, что делаем. - person luqui; 14.08.2017
comment
@ user2407038, вы правы насчет шагов, связанных с равенством, но нам все равно нужно сказать, если Nil = Nil или x = y => Cons a x = Cons a y выполняется в каждой позиции, то списки равны, то есть коиндукция. И именно в попытке сказать это строго мы приходим к биподобию. - person luqui; 14.08.2017
comment
@ user2407038, анализ случая снова связан с этим разделением между биподобием и равенством, потому что у нас нет априорно правила, которое говорит, что если xs ~~ ys, то f xs ~~ f ys, и есть непротиворечивые миры, в которых это это не тот случай, когда f может проверить что-то в своем аргументе, что находится за пределами его элементов (хотя я не могу думать ни о каких вычислимых, и моя догадка говорит, что их нет). Разумно требовать, чтобы все функции были ссылочно прозрачными для подобных бесконечных структур, но это не данность и должно быть сформулировано аксиоматически. - person luqui; 14.08.2017
comment
@ user2407038, я подхожу ко всему этому с точки зрения своего опыта в теории типов. Я не особо задумывался об этом, но предполагаю, что если бы мы рассуждали на уровне денотативной семантики Haskell как домена Скотта, то вы были бы правы, и равенство выполнило бы эту работу (нам все еще нужно было бы выяснить точные условия (ко)индукции). У меня просто нет опыта подобных рассуждений. - person luqui; 14.08.2017
comment
иметь одни и те же элементы в одном и том же порядке - вот что означает бисимуляция - разве это не определение равенства? Или «бисимуляция» означает «поточечное поднятие пропозиционального равенства до коиндуктивных списков» (что не то же самое, что пропозициональное равенство для коиндуктивных списков. Тогда как для конечных списков поточечное поднятие пропозиционального равенства и пропозиционального равенства изоморфны. Является ли «формальное равенство ' означает пропозициональное равенство?). Если это понимание правильное, то оно отвечает на мои вопросы (но вики-страница для бисимуляции, похоже, не отражает это понимание...) - person user2407038; 14.08.2017
comment
@user2407038 user2407038, да, похоже, мы согласны, начиная с Или :-), Да, на вики-странице на самом деле не говорится ни об одной из этих проблем ... Я не знаю хорошей ссылки. - person luqui; 14.08.2017
comment
Спасибо за ответ и за обсуждение, которое немного выше моего понимания :-) Несколько моментов, которые я хотел бы уточнить: (i) Когда вы определили биподобие, я думаю, вы забыли упомянуть, что главы списков должны быть равным для случая Cons, верно? (ii) Просто чтобы убедиться, является ли это коиндуктивной гипотезой: unfoldL p f g (g (h b)) ~~ unfoldL p' f' g' (g' b)? - person Dan Oneață; 14.08.2017
comment
@DanOneață, спасибо, исправлено. Что касается (ii), то он немного более общий: для всех b, unfoldL p f g b ~~ unfoldL p' f' g' b. это точно то же самое, что мы пытаемся доказать изначально для всего списка, за исключением того, что это должно быть применено к хвосту Cons. Обратите внимание на симметрию с индукцией, когда мы предполагаем, что хвост верен, чтобы использовать его во всем списке. - person luqui; 14.08.2017

Погуглив, я нашел статью того же Джереми Гиббонса (и Грэма Хаттона), в которой представлен методы подтверждения для корекурсивных программ; статья включает раздел о бисимуляции и коиндукции, методе доказательства, использованном @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')
person Dan Oneață    schedule 14.08.2017