簡體   English   中英

如何證明Coq中的以下引理?

[英]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]

這個引理實際上是不合理的,還是我只是缺少一些戰術?

假設firstnrev是我認為的樣子,我認為引理不是正確的。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM