我正在尝试证明Z_3类型的组公理:
Require Import Coq.Arith.PeanoNat.
Record Z_3 : Type := Z3
{
n :> nat;
proof : (Nat.ltb n 3) = true
}.
Proposition lt_0_3 : (0 <? 3) = true.
Proof.
simpl. reflexivity.
Qed.
Definition z3_0 : Z_3 := (Z3 0 lt_0_3).
Proposition lt_1_3 : (1 <? 3) = true.
Proof.
reflexivity.
Qed.
Definition z3_1 : Z_3 := (Z3 1 lt_1_3).
Proposition lt_2_3 : (2 <? 3) = true.
Proof.
reflexivity.
Qed.
Definition z3_2 : Z_3 := (Z3 2 lt_2_3).
Proposition three_ne_0 : 3 <> 0.
Proof.
discriminate.
Qed.
Lemma mod_upper_bound_bool : forall (a b : nat), (not (eq b O)) -> (Nat.ltb (a mod b) b) = true.
Proof.
intros a b H. apply (Nat.mod_upper_bound a b) in H. case Nat.ltb_spec0.
- reflexivity.
- intros Hcontr. contradiction.
Qed.
Definition Z3_op (x y: Z_3) : Z_3 :=
let a := (x + y) mod 3 in
Z3 a (mod_upper_bound_bool _ 3 three_ne_0).
Lemma Z3_eq n m p q : n = m -> Z3 n p = Z3 m q.
Proof.
intros H. revert p q. rewrite H. clear H. intros. apply f_equal.
我们快完成了:
1 subgoal (ID 41)
n, m : nat
p, q : (m <? 3) = true
============================
p = q
我应该使用什么定理证明p = q?
更新1
Theorem bool_dec :
(forall x y: bool, {x = y} + {x <> y}).
Proof.
intros x y. destruct x.
- destruct y.
+ left. reflexivity.
+ right. intro. discriminate H.
- destruct y.
+ right. intro. discriminate H.
+ left. reflexivity.
Qed.
Lemma Z3_eq n m p q : n = m -> Z3 n p = Z3 m q.
Proof.
intros H. revert p q. rewrite H. clear H. intros. apply f_equal. apply UIP_dec. apply bool_dec.
Qed.
答案 0 :(得分:1)
您可能有兴趣知道可判定相等性的每两个证明都是相等的。在这里对此进行了解释和证明:https://coq.inria.fr/library/Coq.Logic.Eqdep_dec.html
您特别对引理UIP_dec
:https://coq.inria.fr/library/Coq.Logic.Eqdep_dec.html#UIP_dec
Theorem UIP_dec :
forall (A:Type),
(forall x y:A, {x = y} + {x <> y}) ->
forall (x y:A) (p1 p2:x = y), p1 = p2.
然后,您必须证明布尔值的相等性是可判定的(即,您可以编写一个函数来说明两个给定的布尔值是否相等),您也应该能够在标准库中找到它,但应该也很容易用手证明。
这是一个不同的问题,但是自从您问到:bool_dec
存在,甚至有这个名字!
找到它的简单方法是使用命令
Search sumbool bool.
它将出现几个引理,包括相当早的时间:
Bool.bool_dec: forall b1 b2 : bool, {b1 = b2} + {b1 <> b2}
为什么我搜索sumbool
? sumbool
是上面写的类型:
{ A } + { B } := sumbool A B
您可以使用非常不错的Locate
命令找到它:
Locate "{".
会出现
"{ A } + { B }" := sumbool A B : type_scope (default interpretation)
(以及其他涉及“ {”的符号)。