代码之家  ›  专栏  ›  技术社区  ›  user4035

偶数不偶数-将一个假设应用于另一个假设

  •  1
  • user4035  · 技术社区  · 6 年前

    不幸的是,我又被卡住了:

    Inductive even : nat > Prop :=
    | ev_0 : even 0
    | ev_SS (n : nat) (H : even n) : even (S (S n)).
    
    Lemma even_Sn_not_even_n : forall n,
        even (S n) <-> not (even n).
    Proof.
      intros n. split.
      + intros H. unfold not. intros H1. induction H1 as [|n' E' IHn].
        - inversion H.
        - inversion_clear H. apply IHn in H0. apply H0.
      + intros H. induction n as [|n' IHn].
        - exfalso. apply H. apply ev_0.
        - apply evSS_inv'.
    

    结果如下:

    1 subgoal (ID 179)
    
    n' : nat
    H : ~ even (S n')
    IHn : ~ even n' -> even (S n')
    ============================
    even n'
    

    据我所能用语言证明:

    (n'+1)根据H不是偶数。因此根据IHn,n'不是偶数(双重否定)是不正确的:

    IHn : ~ ~ even n'
    

    展开双重否定,我们得出n'是偶数的结论。

    但是如何用coq来写呢?

    0 回复  |  直到 6 年前
        1
  •  2
  •   Bubbler    6 年前

    去除双重否定的通常方法是引入“排除中间”公理,该公理在名称下定义 classic 在里面 Coq.Logic.Classical_Prop ,并应用引理 NNPP .

    然而,在这种特殊情况下,您可以使用名为 反射 通过显示道具与布尔函数一致(您可能还记得 evenb 本书前面介绍的函数)。

    (假设你在IndProp的开头)你很快就会在该章后面看到以下定义:

    Inductive reflect (P : Prop) : bool -> Prop :=
    | ReflectT (H : P) : reflect P true
    | ReflectF (H : ~ P) : reflect P false.
    

    你可以证明这个说法

    Lemma even_reflect : forall n : nat, reflect (even n) (evenb n).
    

    然后用它在一个道具和一个布尔值之间移动(它们包含相同的信息,即(非)均匀度) n )同时。这也意味着你可以在不使用 经典 公理

    我建议完成IndProp中反思部分的练习,然后尝试以下练习。( 编辑: 我上传了完整答案 here .)

    (* Since `evenb` has a nontrivial recursion structure, you need the following lemma: *)
    Lemma nat_ind2 :
      forall P : nat -> Prop,
      P 0 -> P 1 -> (forall n : nat, P n -> P (S (S n))) -> forall n : nat, P n.
    Proof. fix IH 5. intros. destruct n as [| [| ]]; auto.
      apply H1. apply IH; auto. Qed.
    
    (* This is covered in an earlier chapter *)
    Lemma negb_involutive : forall x : bool, negb (negb x) = x.
    Proof. intros []; auto. Qed.
    
    (* This one too. *)
    Lemma evenb_S : forall n : nat, evenb (S n) = negb (evenb n).
    Proof. induction n.
      - auto.
      - rewrite IHn. simpl. destruct (evenb n); auto. Qed.
    
    (* Exercises. *)
    Lemma evenb_even : forall n : nat, evenb n = true -> even n.
    Proof. induction n using nat_ind2.
      (* Fill in here *) Admitted.
    
    Lemma evenb_odd : forall n : nat, evenb n = false -> ~ (even n).
    Proof. induction n using nat_ind2.
      (* Fill in here *) Admitted.
    
    Lemma even_reflect : forall n : nat, reflect (even n) (evenb n).
    Proof. (* Fill in here. Hint: You don't need induction. *) Admitted.
    
    Lemma even_iff_evenb : forall n, even n <-> evenb n = true.
    Proof. (* Fill in here. Hint: use `reflect_iff` from IndProp. *) Admitted.
    
    Theorem reflect_iff_false : forall P b, reflect P b -> (~ P <-> b = false).
    Proof. (* Fill in here. *) Admitted.
    
    Lemma n_even_iff_evenb : forall n, ~ (even n) <-> evenb n = false.
    Proof. (* Fill in here. *) Admitted.
    
    Lemma even_Sn_not_even_n : forall n,
        even (S n) <-> not (even n).
    Proof. (* Fill in here.
      Hint: Now you can convert all the (non-)evenness properties to booleans,
      and then work with boolean logic! *) Admitted.
    
    推荐文章