[英]How do I prove the following lemma in Coq?
Lemma rev_firstn : forall (x : list bool) (n : nat),
rev (firstn n x) = firstn n (rev x).
我花了很多時間在這上面。 我以一個明智的目標開始,但總是以無法證明的目標告終。
這是我目前的方法:
Proof.
intros. generalize dependent x. induction n.
+ easy.
+ induction x.
- easy.
-
就我而言,我現在有:
IHn : forall x : list bool, rev (firstn n x) = firstn n (rev x)
IHx : rev (firstn (S n) x) = firstn (S n) (rev x)
我的目標是:
rev (firstn (S n) (a :: x)) = firstn (S n) (rev (a :: x))
有沒有一種方法可以在IHx中泛化x,以便我可以將其專門化為(a :: x)? 由於我不知道執行此操作的正確策略,因此請嘗試以下操作,最后得出前面提到的不可能的目標。
Proof.
intros. generalize dependent x. induction n.
+ easy.
+ induction x.
- easy.
- assert (rev_cons : forall (b : bool) (l : list bool),
rev (b :: l) = rev l ++ [b]).
{ easy. } rewrite firstn_cons.
rewrite rev_cons. rewrite rev_cons. specialize (@IHn x).
rewrite IHn.
Goal: firstn n (rev x) ++ [a] = firstn (S n) (rev x ++ [a])
這個目標是不可能的,因為對於n = 0且rev x = h :: t,目標降低為[a] = List.hd (rev (h :: t)) ++ [a]
。
這個引理實際上是不合理的,還是我只是缺少一些戰術?
假設firstn
和rev
是我認為的樣子,我認為引理不是正確的。
rev (firstn 2 [true, false, false])
= rev [true, false]
= [false, true]
但
firstn 2 (rev [true, false, false])
= firstn 2 [false, false, true]
= [false, false]
從本質上講, rev (firstn nx)
是第一n
的元素x
(以相反的順序),但firstn n (rev x)
是最后n
的元素x
(也以相反的順序)。 為了使該引理在任何形式的普遍性上都成立,您需要x最多具有n
元素。 正如亞瑟·阿茲維多·德·阿莫林(Arthur Azevedo De Amorim)在評論中指出的那樣,如果您插入一個被skipn n
僅看x
的最后n
(最多)元素,那么您也可以獲得該引理的正確版本。
rev (firstn n (skipn (length x - n)) x) = firstn n (rev x)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.