去除双重否定的通常方法是引入“排除中间”公理,该公理在名称下定义
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.