I tried to define the reciprocal of a nonzero rational number, imitating the answers in my another question. I tried to delay the proof, but it seems that I misunderstood.
The following is my code:
1) Integers: define z (= a - b)
as a pair (a, b)
which is in a setoid with the equiv rel (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) Positive integers: {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) Nonzero integers: {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) Rational numbers: ( 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.
I think this definitions are somewhat complex, but it was my best try...
Now, how can I prove the consistency of the morphism Q_recip
?