对于软件基础的练习,我想证明以下定理:
Theorem rev_pal {X:Type} : forall (l:list X), l = rev l -> pal l.
朋友定义如下:
Inductive pal {X:Type} : list X -> Prop :=
| pal_nil : pal []
| pal_one : forall x, pal [x]
| pal_rec : forall x l, pal l -> pal (snoc(x:: l) x).
然而,为了证明这一点,我想使用exists
的引理来说明例如:
foral (l l':list X) (a b:X), a::l = l' ++[b] -> (a=b /\ l=[]) \/ exists k, l = k ++ [b].
事实上,我想提一些比l更少的东西。但使用destruct
策略似乎没有帮助。
为什么我不想使用exists
是因为在阅读本书软件基础时,我们还没有看到exists
。当然,有人可以告诉我,exists
可以被视为forall
,但在这种形式下难以使用。
那么如何在没有这样的引理的情况下证明这个定理呢?我被卡住了。
答案 0 :(得分:3)
您无法通过l
上的直接归纳来证明您的定理。
对于归纳步骤,归纳假设为pal l
(在清除前提后)并且您试图证明pal (x :: l)
。
但是归纳假设显然与结论相矛盾(除非repeat x n = l
),因此它无法使用。
看到书中的这一点,没有提及更高级的感应,这是一个五星级的练习,我认为可以安全地得出结论,你有更多自由锻炼。
答案 1 :(得分:2)
如前所述,使用列表的长度更容易证明这个定理:
Theorem rev_pal_aux {X:Type} : forall (l:list X) (n:nat) , length l<= n -> l = rev l -> pal l.
然后你可以在n上开始归纳。
避免使用存在的关键点是使用反转。对于这个证明,可以在x::l=rev x::l
之类的内容上使用反转,然后在rev l
上使用反转(对于某些l)。这样,您将获得x :: l = snoc (x0 :: l0) x
(l0是新的)。
(l0)是关键。你需要使用归纳假设在l0上。
最后,我使用了以下引理(不太容易证明):
Lemma length_snoc_aux {X:Type} : forall (l m:list X) (n:nat) (x:X), length l <= n -> l = snoc m x -> length m <= n.