Coq:定义非零有理数及其倒数的嵌套(?)子类型

Coq:定义非零有理数及其倒数的嵌套(?)子类型,coq,Coq,我试着定义一个非零有理数的倒数,模仿我书中的答案。我试图推迟举证,但似乎我误解了 以下是我的代码: 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.

我试着定义一个非零有理数的倒数,模仿我书中的答案。我试图推迟举证,但似乎我误解了

以下是我的代码:

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我想你忘了在开发中添加
Q|u nonzero
的定义,因此我无法运行你的代码。但是,我认为问题是你在一些定义中使用了
Qed
而不是
定义的
。详细讨论了这个问题。(在任何情况下,例如,通常最好避免在证明模式下使用定义,因为它们往往更难推理,正如您可能已经注意到的那样。)

关于风格的一点说明:您的开发模仿了集合论第一原理中对数字系统的常见定义,在集合论中,我们经常使用等价类来定义整数、有理数等。虽然这种方法很优雅,但在Coq中使用起来往往不方便。主要问题是,由于缺乏适当的商类型,您的u在任何地方都必须使用setoids,这使得您无法使用Coq更方便的相等运算符
=
。将这些定义编写为普通数据类型更简单。例如,您可以将整数定义为

Inductive int :=
| Posz : nat -> int
| Negz : nat -> int.

其中,
Posz
表示从自然数到整数的标准注入,而
Negz
将自然数
n
映射到整数
-n-1
。这是中遵循的方法。当然,标准库也有自己的整数定义(),因此您不需要复制它。定义有理数更复杂,但仍然可以做到:,它们被定义为互质整数对
(num,den)
,因此
den>0
num

感谢您的回答。首先,Q_nonzero被定义为
定义Q_nonzero:Set:={q:rational | q|u分子q Z0}。
现在我遇到了如下问题:“无法将q|u recip强制为可计算的引用。”,当我展开q|u recip时。这个错误意味着什么?最后,对于样式…(因为我研究Coq的目的是:从底部构造实数,我不想导入mathcomp。)使用整数的setoid定义也让我感到如此困难,但我只是想用“优雅”的方式(这是一个错误的选择:()谢谢你的建议。@KanuKim这个错误可能意味着你用
Qed
而不是
Defined
结束了
Q\u recip
的证明。如果我用
accepted
而不是
Defined
,会发生这个错误吗?是的,我想是这样。@KanuKim这个公理是不合理的,因为它与pai上的平等概念相冲突rs(也就是说,如果你假设这个公理,你会得到一个矛盾)。例如,这个公理意味着对
(0,0)
(1,1)
是相等的,但它们不是。再一次,我认为有两个构造函数的定义是定义Coq中整数的最干净的定义。
(** 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.
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.
Inductive int :=
| Posz : nat -> int
| Negz : nat -> int.