簡體   English   中英

為什么我有時可以通過引理證明一個目標,但不是直接?

[英]Why can I sometimes prove a goal via a lemma, but not directly?

考慮下面定義的函數。 它的作用並不重要。

Require Import Ring.
Require Import Vector.
Require Import ArithRing.

Fixpoint
  ScatHUnion_0 {A} (n:nat) (pad:nat) : t A n -> t (option A) ((S pad) * n).
 refine (
  match n return (t A n) -> (t (option A) ((S pad)*n)) with
  | 0 => fun _ =>  (fun H => _)(@nil (option A))
  | S p =>
    fun a =>
      let foo := (@ScatHUnion_0 A p pad (tl a)) in
      (fun H => _) (cons _ (Some (hd a)) _ (append (const None pad) foo))
  end
   ).
 rewrite  <-(mult_n_O (S pad)); auto.
 replace  (S pad * S p) with ( (S (pad + S pad * p)) ); auto; ring.
Defined.

我想證明

Lemma test0:  @ScatHUnion_0 nat 0 0 ( @nil nat) = ( @nil (option nat)).

做完之后

  simpl. unfold eq_rect_r. unfold eq_rect.

目標是

         match mult_n_O 1 in (_ = y) return (t (option nat) y) with
         | eq_refl => nil (option nat)
         end = nil (option nat)

當試圖完成它

  apply trans_eq with (Vector.const (@None nat) (1 * 0)); auto.
  destruct (mult_n_O 1); auto.

destruct不起作用(參見下面的錯誤消息)。 但是,如果我首先在引理中證明完全相同的目標,或者甚至在證明中使用assert ,我可以應用並解決它,如下所示:

Lemma test1:  @ScatHUnion_0 nat 0 0 ( @nil nat) = ( @nil (option nat)).
  simpl. unfold eq_rect_r. unfold eq_rect.

  assert (
      match mult_n_O 1 in (_ = y) return (t (option nat) y) with
        | eq_refl => nil (option nat)
      end = nil (option nat)
    ) as H.
  {
    apply trans_eq with (Vector.const (@None nat) (1 * 0)); auto.
    destruct (mult_n_O 1); auto.
  }
    apply H.
Qed.

有人可以解釋為什么會這樣,以及在遇到這種情況時應該如何考慮這種情況?


在Coq 8.4中我得到了錯誤

      Toplevel input, characters 0-21:
      Error: Abstracting over the terms "n" and "e" leads to a term
      "fun (n : nat) (e : 0 = n) =>
       match e in (_ = y) return (t (option nat) y) with
       | eq_refl => nil (option nat)
       end = const None n" which is ill-typed.

在Coq 8.5中我得到了錯誤

      Error: Abstracting over the terms "n" and "e" leads to a term
      fun (n0 : nat) (e0 : 0 = n0) =>
      match e0 in (_ = y) return (t (option nat) y) with
      | eq_refl => nil (option nat)
      end = const None n0
      which is ill-typed.
      Reason is: Illegal application: 
      The term "@eq" of type "forall A : Type, A -> A -> Prop"
      cannot be applied to the terms
       "t (option nat) 0" : "Set"
       "match e0 in (_ = y) return (t (option nat) y) with
        | eq_refl => nil (option nat)
        end" : "t (option nat) n0"
       "const None n0" : "t (option nat) n0"
      The 2nd term has type "t (option nat) n0" which should be coercible to
       "t (option nat) 0".

@Vinz回答原因解釋,並建議Set Printing All. 這表明了區別。 問題是簡單simpl. 簡化了match的返回類型。 使用unfold ScatHUnion_0. 而不是簡單simpl. 讓我直接在目標上使用destruct。

從根本上說,我的麻煩源於我想要說服類型系統0=00=1*0 (順便說一句,我仍然不知道這樣做的最佳方法。)我使用mult_n_O來表示,但它是不透明的,所以當檢查兩種類型相等時,類型系統無法展開它。

當我用我自己的Fixpoint變體(不是不透明的)替換它時,

Fixpoint mult_n_O n: 0 = n*0 :=
    match n as n0 return (0 = n0 * 0) with
  | 0 => eq_refl
  | S n' => mult_n_O n'
  end.

並且在ScatHUnion_0的定義中使用它,這個引理很容易證明:

Lemma test0:  @ScatHUnion_0 nat 0 0 ( @nil nat) = ( @nil (option nat)).
  reflexivity.
Qed.

附加評論:

這是一個適用於原始opaque mult_n_O定義的證明。 它基於Jason Gross證明 它通過使用generalizemult_n_O 1的類型操作為0=0 它使用set來修改術語的隱式部分,例如eq_refl的類型,該類型僅在Set Printing All.之后可見Set Printing All. 命令。 change也可以做到這一點,但replacerewrite似乎無法做到這一點。

Lemma test02:
  match mult_n_O 1 in (_ = y) return (t (option nat) y) with
    | eq_refl => nil (option nat)
  end = nil (option nat).
Proof.
  Set Printing All.
  generalize (mult_n_O 1 : 0=0).
  simpl.
  set (z:=0) at 2 3.
  change (nil (option nat)) with (const (@None nat) z) at 2.
  destruct e.
  reflexivity.
Qed.

更新:感謝coq-club的人們,這是一個更簡單的證據。

Lemma test03:
  match mult_n_O 1 in (_ = y) return (t (option nat) y) with
    | eq_refl => nil (option nat)
  end = nil (option nat).
Proof.
  replace (mult_n_O 1) with (@eq_refl nat 0);
  auto using Peano_dec.UIP_nat.
Qed.

我會說這是因為依賴類型,並且在兩種情況下你都沒有真正證明完全相同的東西(嘗試Set Printing All.查看隱式類型和隱藏信息)。

這種破壞失敗的事實通常是由於依賴會引入一個不良類型的術語,你必須更精確地指出你想破壞的東西(這里不是秘密,它是基於每個案例) 。 通過提取子引理,您可能已經刪除了麻煩的依賴關系,現在破壞可以運行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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