Here is my inductive definition of palindromes:
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] ).
And the theorem I want to prove, from Software Foundations:
Theorem rev_eq_pal : forall ( X : Type ) ( l : list X ),
l = rev l -> pal l.
My informal outlines of the proof are as follows:
Suppose
l0
is an arbitrary list such thatl0 = rev l0
. Then one of the following three cases must hold.l0
has:(a) zero elements, in which case it is a palindrome by definition.
(b) one element, in which case it is also a palindrome by definition.
(c) two elements or more, in which case
l0 = x :: l1 ++ [x]
for some elementx
and some listl1
such thatl1 = rev l1
.Now, since
l1 = rev l1
, one of the following three cases must hold...The recursive case analysis will terminate for any finite list
l0
because the length of the list analyzed decreases by 2 through each iteration. If it terminates for any listln
, all of its outer lists up tol0
are also palindromes, since a list constructed by appending two identical elements at either end of a palindrome is also a palindrome.
I think the reasoning is sound, but I'm not sure how to formalize it. Can it be turned into a proof in Coq? Some explanations of how the tactics used work would be especially helpful.