Вот мое индуктивное определение палиндромов:
Inductive pal { X : Type } : list X -> Prop :=
| pal0 : pal []
| pal1 : forall ( x : X ), pal [x]
| pal2 : forall ( x : X ) ( l : list X ), pal l -> pal ( x :: l ++ [x] ).
И теорема, которую я хочу доказать, из Software Foundations:
Theorem rev_eq_pal : forall ( X : Type ) ( l : list X ),
l = rev l -> pal l.
Мои неофициальные наброски доказательства следующие:
Предположим, что
l0
- произвольный список, такой чтоl0 = rev l0
. Тогда должен иметь место один из следующих трех случаев.l0
имеет:(а) нулевые элементы, в этом случае это палиндром по определению.
(б) один элемент, в этом случае он также является палиндромом по определению.
(c) два или более элемента, и в этом случае
l0 = x :: l1 ++ [x]
для некоторого элементаx
и некоторого спискаl1
, такого чтоl1 = rev l1
.Теперь, начиная с
l1 = rev l1
, должен выполняться один из следующих трех случаев ...Рекурсивный анализ случаев будет прекращен для любого конечного списка
l0
, потому что длина анализируемого списка уменьшается на 2 на каждой итерации. Если он завершается для любого спискаln
, все его внешние списки доl0
также являются палиндромами, поскольку список, построенный путем добавления двух идентичных элементов на обоих концах палиндрома, также является палиндромом.
Я думаю, что это разумная аргументация, но я не знаю, как ее формализовать. Можно ли превратить это в доказательство в Coq? Некоторые объяснения того, как работает использованная тактика, были бы особенно полезны.