我试图定义一个非零有理数的倒数,模仿了我的another question中的答案。我试图推迟证明,但似乎我误会了。
以下是我的代码:
1)整数:将z (= a - b)
定义为一对(a, b)
,它与等价线(a, b) ~ (c, d) <-> a + d = b + c
处于类固醇中
Definition Z_eq (z w: integer): Prop :=
match z with
| (z1, z2) =>
match w with
| (w1, w2) => z1 + w2 = z2 + w1
end
end.
Add Parametric Relation:
integer Z_eq
reflexivity proved by Z_refl
symmetry proved by Z_symm
transitivity proved by Z_tran
as Z. (** proved; omitting the proof *)
(** addition, subtraction, negation, multiplication are well-defined as a morphism *)
Add Morphism Z_plus with signature Z_eq ==> Z_eq ==> Z_eq as Z_plus_morph.
(** etc. *)
2)正整数:{n : nat | 0 <? n }
(** as in answers of the previous question *)
Local Coercion is_true : bool >-> Sortclass.
Definition Z_pos: Set := {n : nat | 0 <? n }.
Definition Z_pos__N (p: Z_pos): nat := proj1_sig p.
Coercion Z_pos__N : Z_pos >-> nat.
Definition Z_pos__Z (p: Z_pos): integer := (proj1_sig p, 0).
Coercion Z_pos__Z : Z_pos >-> integer.
Definition Z_pos_plus : Z_pos -> Z_pos -> Z_pos.
intros [x xpos%Nat.ltb_lt] [y ypos%Nat.ltb_lt].
refine (exist _ (x + y) _).
now apply Nat.ltb_lt, Nat.add_pos_pos.
Defined.
Definition Z_pos_mult : Z_pos -> Z_pos -> Z_pos.
intros [x xpos%Nat.ltb_lt] [y ypos%Nat.ltb_lt].
refine (exist _ (x * y) _).
now apply Nat.ltb_lt, Nat.mul_pos_pos.
Defined.
Lemma Z_pos_mult_compat: forall p q: Z_pos, Z_pos__N (Z_pos_mult p q) = Z_pos__N p * Z_pos__N q.
Proof. now intros [x xpos] [y ypos]. Qed.
Definition ZP1: Z_pos.
refine (exist _ 1 _). easy.
Defined.
3)非零整数:{z : integer | z <Z> Z0}
(** nonzero integer *)
Definition Z_nonzero: Set := {z : integer | z <Z> Z0}.
(* abs value of a nonzero integer as an obj of type Z_pos *)
Definition Z_nonzero_abs__Z_pos (z: Z_nonzero): Z_pos.
destruct z as [[z1 z2] z3].
exists ((z1 - z2) + (z2 - z1))%nat.
Admitted. (** proof ommited *)
(* multiplication b/w two nonzero integers *)
Definition Z_nonzero_mult (z w: Z_nonzero): Z_nonzero.
exists (proj1_sig z *Z proj1_sig w).
Admitted.
(* sign of n - m *)
Definition N_sgn_diff__Z (n m: nat): integer :=
if n >? m then Z1 else if n =? m then Z0 else -Z Z1.
(* sign of n - m *)
Definition Z_nonzero_sgn__Z (z: Z_nonzero): Z_nonzero.
destruct z as [[z1 z2] z3].
exists (N_sgn_diff__Z z1 z2).
Admitted.
4)有理数:( a // b ) (a: integer, b: Z_pos)
Inductive rational: Type :=
| prerat : integer -> Z_pos -> rational.
Notation "( x '//' y )" := (prerat x y).
(* equality *)
Definition Q_eq (p q: rational): Prop :=
match p with
| (p1 // p2) =>
match q with
| (q1 // q2) => (Z_mult p1 (Z_pos__Z q2)) =Z= (Z_mult (Z_pos__Z p2) q1)
end
end.
(* numerator of a rational *)
Definition Q_numerator (q: rational) :=
match q with
| (iq // rq) => iq
end.
(* nonzero rationals *)
Definition Q_nonzero: Set := {q : rational | Q_numerator q <Z> Z0}.
(* numerator and denominator *)
Definition Q_nonzero_numerator (q: Q_nonzero): Z_nonzero.
destruct q as [[q1 q2] q3].
exists q1.
simpl in q3. apply q3.
Qed.
Definition Q_nonzero_denominator (q: Q_nonzero): Z_pos.
destruct q as [[q1 q2] q3].
exact q2.
Qed.
Definition Q_recip (q: Q_nonzero): Q_nonzero.
exists ( proj1_sig (Z_nonzero_mult (Z_nonzero_sgn__Z (Q_nonzero_numerator q)) (Z_pos__Z_nonzero (Q_nonzero_denominator q))) // Z_nonzero_abs__Z_pos (Q_nonzero_numerator q) ).
Admitted. (* proved. *)
(* inherited equality *)
Definition Q_nonzero_eq (p q: Q_nonzero): Prop := (proj1_sig p) =Q= (proj1_sig q).
Add Morphism Q_recip with signature Q_nonzero_eq ==> Q_nonzero_eq as Q_recip_morph.
Proof. (* well-definedness of Q_recip *)
destruct x, y.
unfold Q_nonzero_eq. simpl. intros.
unfold Q_recip. (* <----- unfolded result was very long and complex; not simplified after simpl. *)
Abort.
我认为这个定义有些复杂,但这是我的最佳尝试...
现在,如何证明态射Q_recip
的一致性?
答案 0 :(得分:1)
我认为您忘记在开发中添加Q_nonzero
的定义,因此我无法运行您的代码。但是,我认为问题在于您在某些定义中使用了Qed
而不是Defined
。 This question详细讨论了该问题。 (无论如何,像Emilio points out一样,通常最好避免以证明模式进行定义,因为您可能已经注意到,因为它们往往更难以推理。)
关于样式的注释:您的开发模仿集合论中的第一条原则对数字系统的通用定义,在集合论中,我们经常使用等价类来定义整数,有理数等。尽管优雅,但这种方法使用起来常常不方便在Coq。主要问题是,由于缺少适当的商类型,您被迫在各处使用setoid,这使您无法使用Coq更方便的等于运算符=
。将这些定义写为纯数据类型更简单。例如,您可以将整数定义为
Inductive int :=
| Posz : nat -> int
| Negz : nat -> int.
其中Posz
表示从自然数到整数的规范注入,而Negz
将自然数n
映射到整数- n - 1
。这是mathematical components library中遵循的方法。当然,标准库也有自己的整数定义(here),因此您无需复制它。定义有理数较为复杂,但仍可以完成:in mathematical components,它们被定义为成对的互质整数(num, den)
,使得den > 0
和num
。