(* $Id: CFields.v,v 1.60 2000/11/10 11:27:26 freek Exp $ *)

Require Export Rational.
Require Export RRefl_corr.

Tactic Definition Step_Rat_lft [$y] :=
  [<:tactic:<Apply eq_transitive_unfolded with $y;
    [Rational | Idtac]>>].
Tactic Definition Step_Rat_rht [$y] :=
  [<:tactic:<Apply eq_transitive_unfolded with y:= $y;
    [Idtac | Rational]>>].

Tactic Definition Step_Rat_ap_rht [$y] :=
  [<:tactic:<Apply ap_well_def_rht_unfolded with $y;
    [Idtac | Rational] >>].
Tactic Definition Step_Rat_ap_lft [$y] :=
  [<:tactic:<Apply ap_well_def_lft_unfolded with $y;
    [Idtac | Rational] >>].

Transparent sym_eq.
Transparent f_equal.


Transparent cs_crr.
Transparent csg_crr.
Transparent cm_crr.
Transparent cg_crr.
Transparent cr_crr.

Transparent csf_fun.
Transparent csbf_fun.
Transparent csr_rel.

Transparent cs_eq.
Transparent cs_neq.
Transparent cs_ap.
Transparent csg_unit.
Transparent csg_op.
Transparent cg_inv.
Transparent cg_minus.
Transparent cr_one.
Transparent cr_mult.

Transparent nzpro.
Transparent nexp_op.

(* Begin_SpecReals *)

(* FIELDS *)

(* Tex_Prose
\section{Fields}\label{section:fields}
\subsection{Definition of the notion Field}
*)

(* Begin_Tex_Verb *)
Definition is_CField
  [R: CRing; cf_rcpcl: (CSetoid_un_op (NonZeros R))] : Prop :=
  (x: (NonZeros R))(Is_inverse (cr_mult R) One
                               (NZinj x) (NZinj (cf_rcpcl x))).

Record CField : Type :=
  { cf_crr   :> CRing;
    cf_rcpcl :  (CSetoid_un_op (NonZeros cf_crr));
    cf_proof :  (is_CField cf_crr cf_rcpcl)
  }.
(* End_Tex_Verb *)
(* End_SpecReals *)

(* Begin_Tex_Verb *)
Definition f_rcpcl [F:CField; x:(NonZeros F)] : F := (NZinj ((cf_rcpcl ?) x)).
(* End_Tex_Verb *)

Syntactic Definition F_rcpcl := (f_rcpcl ?).


(* Tex_Prose
\verb!cf_div! is the division in a field.
*)
(* Begin_Tex_Verb *)
Definition cf_div [F:CField; x: F; y: (NonZeros F)]: F := (x [*] (F_rcpcl y)).
(* End_Tex_Verb *)
Syntactic Definition F_div := (cf_div ?).

(* Tex_Prose
\begin{notation}
The division \verb!cf_div x y! is denoted infix by \verb!x [/] y!.
\end{notation}
Recall that \verb!x [//] p! is of type \verb!NonZeros F! if \verb!x : F!
and \verb!p : x [#] Zero! (see Notation~\ref{notation:nzpro}).
*)
Infix NONA 6 "[/]" F_div.
Syntax constr level 6:
  cf_div_infix [<<(cf_div $e0 $e1 $e2)>>] ->
    [[<hov 1> $e1:E [0 1] "[/]" $e2:L]].

(* Tex_Prose
\begin{numconvention}\label{convention:div-form}
\begin{enumerate}
\item
 We do not use \verb!NonZeros!,
 but write the condition \verb![#]Zero! separately.
\item
 In each lemma, we use only variables for proof objects, and these variables
 are universally quantified.

 E.g. the informal lemma
\begin{verbatim}
(1/x).(1/y) = 1/(x.y) for all x and y
\end{verbatim}
   is formalized as
\begin{verbatim}
(x,y:F)(H1:x#0)(H2:y#0)(H3:(x.y)#0) (1/x//H1).(1/y//H2) = 1/(x.y)//H3
\end{verbatim}
and {\em not} as
\begin{verbatim}
(x,y:F)(H1:x#0)(H2:y#0)(1/x//H1).(1/y//H2) = 1/(x.y)//(prod_nz x y H1 H2)
\end{verbatim}

   We have made this choice to make it easier to apply lemmas; this can be
   quite awkward if we would use the last formulation.

\item
   So every division occurring in the formulation of a lemma is of the form
   \verb!e[/]e'[//]H! where \verb!H! is a variable.
   Only exceptions: we may write \verb!e[/](Snring n)! and
   \verb!e[/]TwoNZ!,  \verb!e[/]ThreeNZ! and so on.
   (Constants like \verb!TwoNZ! will be defined later on.)
\end{enumerate}
\end{numconvention}
*)

(* Tex_Prose
\subsection{Field axioms}
\begin{convention}
Let \verb!F! be a field.
\end{convention}
*)
Section Field_axioms.
Variable F : CField.

(* Begin_Tex_Verb *)
Lemma CField_is_CField : (is_CField F (cf_rcpcl F)).
(* End_Tex_Verb *)
Elim F; Intros.
Exact cf_proof0.
Qed.

(* Begin_Tex_Verb *)
Lemma rcpcl_is_inverse :
 (x: (NonZeros F))(Is_inverse (cr_mult F) One
                               (NZinj x) (NZinj ((cf_rcpcl F) x))).
(* End_Tex_Verb *)
Generalize CField_is_CField; Intro.
Unfold is_CField in H.
Assumption.
Qed.

End Field_axioms.

Section Field_basics.
(* Tex_Prose
\subsection{Field basics}
\begin{convention}
Let \verb!F! be a field.
\end{convention}
*)
Variable F : CField.


(* Begin_Tex_Verb *)
Lemma rcpcl_is_inverse_unfolded :
              (x: (NonZeros F))(NZinj x) [*] (NZinj ((cf_rcpcl F) x)) [=] One.
(* End_Tex_Verb *)
Exact (rcpcl_is_inverse F).
Qed.

(* Begin_Tex_Verb *)
Lemma field_mult_inv: (x:F)(H:x[#]Zero)(x [*] (F_rcpcl (x[//]H))) [=] One.
(* End_Tex_Verb *)
Intros.
Unfold f_rcpcl.
Generalize (cf_proof F); Intro.
Unfold is_CField in H0.
Generalize (H0 (x[//]H)); Intro.
Exact H1.
Qed.
Hints Resolve field_mult_inv : algebra.

(* Begin_Tex_Verb *)
Lemma field_mult_inv_op : (x:F)(H:x[#]Zero)((F_rcpcl (x[//]H)) [*] x) [=] One.
(* End_Tex_Verb *)
Intros.
Step x [*] (F_rcpcl (x[//]H)).
Apply field_mult_inv.
Qed.

End Field_basics.

Hints Resolve field_mult_inv field_mult_inv_op : algebra.

Section Field_multiplication.
(* Tex_Prose
\subsection{Properties of multiplication}
\begin{convention}
Let \verb!F! be a field.
\end{convention}
*)
Variable F : CField.

(* Begin_Tex_Verb *)
Lemma mult_resp_ap_zero:
  (x,y:F)(x [#] Zero) -> (y [#] Zero) -> (x[*]y [#] Zero).
(* End_Tex_Verb *)
Intros.
Cut ((x[*]y) [*] (F_rcpcl y [//] H0)) [#] (Zero [*] (F_rcpcl y [//] H0)).
Intros.
Case (bin_op_strext ?????? H1).
Auto.
Intro contra; Elim (ap_irreflexive ?? contra).
Step_ap_rht (Zero::F).
Step_ap_lft x.
Stepr x[*](y[*](F_rcpcl y [//] H0)).
Step_final x[*]One.
Qed.

(* Begin_Tex_Verb *)
Lemma mult_lft_resp_ap :
   (x,y,z:F)(x [#] y) -> (z [#] Zero) -> (z [*] x) [#] (z [*] y).
(* End_Tex_Verb *)
Intros.
Apply zero_minus_apart.
Unfold cg_minus.
Step_ap_lft z[*]x[+](z[*][--]y).
Step_ap_lft z[*](x[+][--]y).
Step_ap_lft z[*](x[-]y).
Apply mult_resp_ap_zero; Algebra.
Qed.

(* Begin_Tex_Verb *)
Lemma mult_rht_resp_ap :
   (x,y,z:F)(x [#] y) -> (z [#] Zero) -> (x [*] z) [#] (y [*] z).
(* End_Tex_Verb *)
Intros.
Step_ap_lft z [*] x.
Step_ap_rht z [*] y.
Apply mult_lft_resp_ap; Assumption.
Qed.


(* Begin_Tex_Verb *)
Lemma mult_resp_neq_zero :
   (x,y:F)(x [~=] Zero)->(y [~=] Zero)->((x [*] y) [~=] Zero).
(* End_Tex_Verb *)
Intros x y.
Intro.
Cut ~~(x [#] Zero).
Intro.
Intro.
Cut ~~(y [#] Zero).
Intro.
Apply notnot_ap_imp_neq.
Cut (x [#] Zero)->(y [#] Zero)->((Cr_mult x y) [#] Zero).
Intro.
Tauto.

Intros.
Apply mult_resp_ap_zero.
Assumption.

Assumption.

Apply neq_imp_notnot_ap.
Assumption.

Apply neq_imp_notnot_ap.
Assumption.
Qed.

(* Begin_Tex_Verb *)
Lemma mult_resp_neq :
   (x,y,z:F)(x [~=] y)->(z [~=] Zero)->((x [*] z) [~=] (y [*] z)).
(* End_Tex_Verb *)
Intros.
Generalize (neq_imp_notnot_ap ? ? ? H).
Generalize (neq_imp_notnot_ap ? ? ? H0).
Generalize (mult_rht_resp_ap x y z).
Intros.
Intros.
Apply notnot_ap_imp_neq.
Tauto.
Qed.

(* Begin_Tex_Verb *)
Lemma mult_eq_zero :
   (x,y:F)(x [~=] Zero)->((x [*] y) [=] Zero)->(y [=] Zero).
(* End_Tex_Verb *)
Intros.
Cut ~(y [#] Zero).
Intro.
Apply not_ap_imp_eq.
Assumption.

(Unfold not; Intro).
Generalize (eq_imp_not_neq ? ? ? H0).
Intro.
Elim H2.
Apply mult_resp_neq_zero.
Assumption.

Apply ap_imp_neq.
Assumption.
Qed.

(* Begin_Tex_Verb *)
Lemma mult_cancel_lft : (x,y,z:F)(z [#] Zero)->(z[*]x [=] z[*]y)->(x [=] y).
(* End_Tex_Verb *)
Intros.
(Generalize (eq_imp_not_ap ? ? ? H0); Intro).
Apply not_ap_imp_eq.
(Unfold not; Intro).
Elim H1.
Apply mult_lft_resp_ap.
Assumption.

Assumption.
Qed.

(* Begin_Tex_Verb *)
Lemma mult_cancel_rht : (x,y,z:F)(z [#] Zero)->(x[*]z [=] y[*]z)->(x [=] y).
(* End_Tex_Verb *)
Intros.
Apply eq_symmetric_unfolded.
Apply (mult_cancel_lft y x z).
Assumption.

Step (Cr_mult y z).
Step (Cr_mult x z).
Apply mult_commutes.
Qed.

(* Tex_Prose
The multiplicative group of nonzeros of a field.
*)
(* Tex_Prose
The multiplicative monoid of NonZeros.
*)
(* Begin_Tex_Verb *)
Definition NonZeroMonoid : CMonoid :=
  (Build_SubCMonoid (Build_multCMonoid F)
                    (nonZeroP F) (one_ap_zero F) mult_resp_ap_zero).
(* End_Tex_Verb *)

(* Begin_Tex_Verb *)
Lemma fmg_cs_inv: (CSetoid_un_op NonZeroMonoid).
(* End_Tex_Verb *)
Exact (cf_rcpcl F).
Qed.

(* Begin_Tex_Verb *)
Lemma plus_nonzeros_eq_mult_dom : (x,y:NonZeroMonoid)
            (NZinj (x [+] y)) [=] ((NZinj x) [*] (NZinj y)).
(* End_Tex_Verb *)
Intros.
Elim x.
Intros.
Elim y.
Intros.
Apply eq_reflexive_unfolded.
Qed.


(* Begin_Tex_Verb *)
Lemma cfield_to_mult_cgroup : CGroup.
(* End_Tex_Verb *)
Apply (Build_CGroup NonZeroMonoid (cf_rcpcl F)).
Unfold is_CGroup.
Intros.
Unfold is_inverse.
Apply (nonz_eq F).
Apply eq_transitive_unfolded with (NZinj x) [*] (NZinj (csf_fun ?? (cf_rcpcl F) x)).
Apply (plus_nonzeros_eq_mult_dom).
Exact (cf_proof F x).
Qed.

(* Begin_Tex_Verb *)
Lemma square_eq_aux :
      (x,a:F)(x[^](2) [=] a[^](2))-> (x[+]a)[*](x[-]a) [=] Zero.
(* End_Tex_Verb *)
Intros.
Step_Rat_lft (x[^](2) [-] a[^](2)).
Step a[^](2) [-] a[^](2).
Algebra.
Qed.

(* Begin_Tex_Verb *)
Lemma square_eq_weak :
      (x,a:F)(x[^](2) [=] a[^](2))-> ~((x [#] a) /\ (x [#] [--]a)).
(* End_Tex_Verb *)
Intros.
Intro.
Elim H0; Intros.
Generalize (square_eq_aux ?? H); Intro.
Apply (eq_imp_not_ap ??? H3).
Apply mult_resp_ap_zero.
Step_ap_rht [--]a [+] a.
Step_ap_rht a [-] a.

Apply minus_resp_ap_rht.
Assumption.
Qed.

(* Begin_Tex_Verb *)
Lemma conditional_square_eq :
   (x,a:F)(Two::F [#] Zero)->(a [#] Zero)->
   (x[^](2) [=] a[^](2))->((x [=] a) \/ (x [=] [--]a)).
(* End_Tex_Verb *)
Intros.
Cut a [#] [--]a.
Intro.
Generalize (ap_cotransitive_unfolded ??? H2 x); Intro.
Elim H3; Intro.
Right.
Apply not_ap_imp_eq.
Intro.
Apply (square_eq_weak ?? H1).
Split.
Apply ap_symmetric_unfolded.
Assumption.
Assumption.
Left.
Apply not_ap_imp_eq.
Intro.
Apply (square_eq_weak ?? H1).
Split.
Assumption.
Assumption.
Apply plus_cancel_ap_lft with a.
Step_ap_rht (Zero::F).
Step_ap_lft Two[*]a.
Apply mult_resp_ap_zero.
Assumption.
Assumption.
Qed.

End Field_multiplication.

Hints Resolve mult_resp_ap_zero : algebra.


Section Rcpcl_properties.
(* Tex_Prose
\subsection{Properties of reciprocal}
\begin{convention}
Let \verb!F! be a field.
\end{convention}
*)
Variable F : CField.

(* Begin_Tex_Verb *)
Lemma inv_one : (F_rcpcl (One[//](ring_non_triv F))) [=] One.
(* End_Tex_Verb *)
Intros.
Step One [*] (F_rcpcl (One[//](ring_non_triv F))).
Apply field_mult_inv.
Qed.

(* Begin_Tex_Verb *)
Lemma cf_rcpcl_wd : (F:CField)(x,y:(NonZeros F)) (x [=] y) ->
                                        ((cf_rcpcl F) x) [=] ((cf_rcpcl F) y).
(* End_Tex_Verb *)
Intros.
Apply (csf_wd ?? (cf_rcpcl F0)).
Assumption.
Qed.

(* Begin_Tex_Verb *)
Lemma F_rcpcl_wd : (F:CField)(x,y:(NonZeros F)) (x [=] y) ->
                                                (F_rcpcl x) [=] (F_rcpcl y).
(* End_Tex_Verb *)
Intros.
Unfold f_rcpcl.
Apply nzinj_wd.
Apply cf_rcpcl_wd.
Assumption.
Qed.

(* Begin_Tex_Verb *)
Lemma F_rcpcl_mult : (y,z:F)(nzy:y [#] Zero)(nzz:z[#]Zero)(nzyz:y[*]z[#]Zero)
 (F_rcpcl ((y[*]z) [//]nzyz)) [=] (F_rcpcl y [//] nzy) [*](F_rcpcl z [//] nzz).
(* End_Tex_Verb *)
Intros.
Apply mult_cancel_lft with y[*]z.
Assumption.
Step (One::F).
Stepr (y[*]z)[*]((f_rcpcl F z[//]nzz)[*](f_rcpcl F y[//]nzy)).
Stepr y[*](z[*]((f_rcpcl F z[//]nzz)[*](f_rcpcl F y[//]nzy))).
Stepr y[*]((z[*](f_rcpcl F z[//]nzz))[*](f_rcpcl F y[//]nzy)).
Stepr y[*](One[*](f_rcpcl F y[//]nzy)).
Stepr y[*](f_rcpcl F y[//]nzy).
Step_final (One::F).
Qed.

(* Begin_Tex_Verb *)
Lemma F_rcpcl_resp_ap_zero : (y:F)(nzy:(y [#] Zero))
                                  ((F_rcpcl (y [//]nzy)) [#] Zero).
(* End_Tex_Verb *)
Intros.
Apply cring_mult_ap_zero_op with y.
Step_ap_lft One::F.
Qed.

(* Begin_Tex_Verb *)
Lemma F_rcpcl_F_rcpcl : (x:F)(nzx:x [#] Zero)(nzr:(F_rcpcl x [//] nzx)[#]Zero)
                        (F_rcpcl (F_rcpcl x [//] nzx) [//] nzr) [=] x.
(* End_Tex_Verb *)
Intros.
Apply mult_cancel_rht with (F_rcpcl x [//] nzx).
Assumption.
Stepr One::F.
Step (f_rcpcl F x[//]nzx)[*](f_rcpcl F (f_rcpcl F x[//]nzx)[//]nzr).
Algebra.
Qed.

End Rcpcl_properties.

Section Div_properties.
(* Tex_Prose
\subsection{Properties of division}
\begin{convention}
Let \verb!F! be a field.
\end{convention}

\begin{nameconvention}
In the names of lemmas, we denote \verb![/]! by \verb!div!, and
\verb!One[/]! by \verb!recip!.
\end{nameconvention}
*)
Variable F : CField.

(* Begin_Tex_Verb *)
Lemma div_prop : (F:CField)(x:F)(H:x[#]Zero)(Zero[/]x[//]H [=] Zero).
(* End_Tex_Verb *)
Unfold cf_div.
Intros.
Algebra.
Qed.

(* Begin_Tex_Verb *)
Lemma div_1 : (x,y:F)(y_:y [#] Zero)((x[/](y[//]y_))[*]y [=] x).
(* End_Tex_Verb *)
Intros.
Step (x[*](F_rcpcl y [//] y_))[*]y.
Step x[*]((F_rcpcl y [//] y_)[*]y).
Step_final x[*]One.
Qed.

(* Begin_Tex_Verb *)
Lemma div_1' : (x,y:F)(y_:y [#] Zero)(y[*](x[/](y[//]y_)) [=] x).
(* End_Tex_Verb *)
Intros.
Step_lft (x[/]y[//]y_)[*]y.
Apply div_1.
Qed.

(* Begin_Tex_Verb *)
Lemma div_1'' : (x,y:F)(y_:y [#] Zero)((x[*]y)[/](y[//]y_) [=] x).
(* End_Tex_Verb *)
Intros.
Unfold cf_div.
Step_lft y[*]x[*](f_rcpcl F y[//]y_).
Step_lft y[*](x[*](f_rcpcl F y[//]y_)).
Change y[*](x[/](y[//]y_)) [=] x.
Apply div_1'.
Qed.

Hints Resolve div_1 : algebra.

(* Begin_Tex_Verb *)
Lemma x_div_x : (x:F)(x_: x [#] Zero)((x[/](x[//]x_)) [=] One).
(* End_Tex_Verb *)
Intros.
Unfold cf_div.
Apply field_mult_inv.
Qed.

Hints Resolve x_div_x : algebra.

(* Begin_Tex_Verb *)
Lemma x_div_one : (x:F)((x[/](One[//](ring_non_triv (F)))) [=] x).
(* End_Tex_Verb *)
Intros.
Unfold cf_div.
Generalize inv_one; Intro.
Step x[*]One.
Apply mult_one.
Qed.

(* Tex_Prose
The next lemma says \verb!x.(y/z) = (x.y)/z!.
*)
(* Begin_Tex_Verb *)
Lemma x_mult_y_div_z : (x,y,z:F)(z_: z [#] Zero)
                       ((x[*](y[/](z[//]z_))) [=] ((x[*]y)[/](z[//]z_))).
(* End_Tex_Verb *)
Intros.
Unfold cf_div.
Algebra.
Qed.

Hints Resolve x_mult_y_div_z : algebra.


(* Begin_Tex_Verb *)
Lemma div_wd : (x0,x1,y0,y1:F)(nzy0:y0 [#] Zero)(nzy1:y1[#]Zero)
  (x0 [=] x1)->(y0 [=] y1)->(x0[/]y0[//]nzy0 [=] x1[/]y1[//]nzy1).
(* End_Tex_Verb *)
Intros.
Unfold cf_div.
Cut (F_rcpcl y0[//]nzy0) [=] (F_rcpcl y1[//]nzy1).
Intro.
Algebra.
Apply F_rcpcl_wd.
Simpl.
Assumption.
Qed.

Hints Resolve div_wd : algebra_c.

(* Tex_Prose
The next lemma says \verb!(x/y)/z = x/(y.z)!
*)
(* Begin_Tex_Verb *)
Lemma div_div : (x,y,z:F)(nzy:y [#] Zero)(nzz:z[#]Zero)
  (nzyz:y[*]z[#]Zero)
    (((x[/]y[//]nzy)[/]z[//]nzz) [=] (x[/](y[*]z)[//]nzyz)).
(* End_Tex_Verb *)
Intros.
Unfold cf_div.
Step x[*]((f_rcpcl F y[//]nzy)[*](f_rcpcl F z[//]nzz)).
Apply mult_wd_rht.
Apply eq_symmetric_unfolded.
Apply F_rcpcl_mult.
Qed.


(* Begin_Tex_Verb *)
Lemma div_resp_ap_zero_rev : (x,y:F)(nzy:(y [#] Zero))(x[#]Zero) ->
                                  (x [/] y [//]nzy [#] Zero).
(* End_Tex_Verb *)
Intros.
Unfold cf_div.
Apply mult_resp_ap_zero.
Assumption.
Apply F_rcpcl_resp_ap_zero.
Qed.


(* Begin_Tex_Verb *)
Lemma div_resp_ap_zero:
(x,y:F)(nzy:(y [#] Zero))(x [/] y [//]nzy [#] Zero) -> (x[#]Zero).
(* End_Tex_Verb *)
Intros x y nzy Hxy.
Step_ap_lft (x[/]y[//]nzy)[*]y.
Qed.

(* Tex_Prose
The next lemma says \verb!x/(y/z) = (x.z)/y!
*)
(* Begin_Tex_Verb *)
Lemma div_div2 : (x,y,z:F)
  (nzy:y [#] Zero)(nzz:z[#]Zero)(nzyz:(y[/]z[//]nzz)[#]Zero)
  ((x[/](y[/](z[//]nzz)) [//]nzyz) [=] ((x[*]z)[/](y[//]nzy))).
(* End_Tex_Verb *)
Intros.
Unfold cf_div.
Stepr x[*](z[*](f_rcpcl F y[//]nzy)).
Apply mult_wd_rht.
Cut (F_rcpcl z[//]nzz) [#] Zero.
Intro nzrz.
Apply eq_transitive_unfolded with (F_rcpcl y [//] nzy) [*] (F_rcpcl (F_rcpcl z[//]nzz) [//] nzrz).
Apply F_rcpcl_mult.
Stepr (f_rcpcl F y[//]nzy)[*]z.
Apply mult_wd_rht.
Apply F_rcpcl_F_rcpcl.
Apply F_rcpcl_resp_ap_zero.
Qed.

(* Tex_Prose
The next lemma says \verb!(x.p)/(y.q) = (x/y).(p/q)!
*)
(* Begin_Tex_Verb *)
Lemma mult_of_divs : (x,y,p,q:F)
  (nzy:(y[#]Zero))(nzq:(q[#]Zero))(nzyq:y[*]q[#]Zero)
    ((x[*]p)[/](y[*]q)[//]nzyq [=] (x[/]y[//]nzy)[*](p[/]q[//]nzq)).
(* End_Tex_Verb *)
Intros.
Unfold cf_div.
Step x[*](p[*](f_rcpcl F (y[*]q)[//]nzyq)).
Stepr x[*]((f_rcpcl F y[//]nzy)[*](p[*](f_rcpcl F q[//]nzq))).
Apply mult_wd_rht.
Stepr ((f_rcpcl F y[//]nzy)[*]p)[*](f_rcpcl F q[//]nzq).
Stepr (p[*](f_rcpcl F y[//]nzy))[*](f_rcpcl F q[//]nzq).
Stepr p[*]((f_rcpcl F y[//]nzy)[*](f_rcpcl F q[//]nzq)).
Apply mult_wd_rht.
Apply F_rcpcl_mult.
Qed.

(* Begin_Tex_Verb *)
Lemma div_dist : (x,y,z:F)(nzz:z[#]Zero)
  (x[+]y)[/]z[//]nzz [=] x[/]z[//]nzz[+]y[/]z[//]nzz.
(* End_Tex_Verb *)
Intros.
Unfold cf_div.
Apply ring_distl_unfolded.
Qed.

(* Begin_Tex_Verb *)
Lemma div_semi_sym : (x,y,z:F)(Hy:y[#]Zero)(Hz:z[#]Zero)
                     (x[/]y[//]Hy)[/]z[//]Hz [=] (x[/]z[//]Hz)[/]y[//]Hy.
(* End_Tex_Verb *)
Intros.
Unfold cf_div.
Rational.
Qed.

Hints Resolve div_semi_sym : algebra.

(* Begin_Tex_Verb *)
Lemma eq_div : (x,y,u,v:F)(Hy:y[#]Zero)(Hv:v[#]Zero)
               (x[*]v [=] u[*]y) -> (x[/]y[//]Hy [=] u[/]v[//]Hv).
(* End_Tex_Verb *)
Intros.
Step_lft (x[*]One)[/]y[//]Hy.
Step_lft (x[*](v[/]v[//]Hv))[/]y[//]Hy.
Step_lft ((x[*]v)[/]v[//]Hv)[/]y[//]Hy.
Step_lft ((u[*]y) [/] v[//]Hv) [/]y[//]Hy.
Step_lft ((u[*]y) [/] y[//]Hy) [/]v[//]Hv.
Step_lft (u[*] (y [/] y[//]Hy)) [/]v[//]Hv.
Step_lft (u[*] One) [/]v[//]Hv.
Algebra.
Qed.

(* Begin_Tex_Verb *)
Lemma div_strong_ext : (x0,x1,y0,y1:F)(Hy0:y0[#]Zero)(Hy1:y1[#]Zero)
                       (x0[/]y0[//]Hy0 [#] x1[/]y1[//]Hy1) ->
                       (x0[#]x1) \/ (y0[#]y1).
(* End_Tex_Verb *)
Intros.
Unfold cf_div in H.
Generalize (bin_op_strext F (cr_mult F)).
Unfold bin_fun_strong_ext.
Intro.
Elim (H0 ???? H); Intro.
Left.
Assumption.
Right.
Unfold f_rcpcl in H1.
Generalize (nzinj_strong_ext ??? H1); Intro.
Generalize (un_op_strext ???? H2); Intro.
Generalize (nzpro_strong_ext ????? H3); Auto.
Qed.

End Div_properties.

Hints Resolve div_1 div_1' div_1'' div_wd x_div_x x_div_one div_div div_div2
  mult_of_divs x_mult_y_div_z mult_of_divs div_dist div_semi_sym
  div_prop : algebra.


Section Mult_Cancel_Ap_Zero.

Variable R : CField.

(* Begin_Tex_Verb *)
Lemma mult_cancel_ap_zero_lft :
 (x,y:R)(x [*] y [#] Zero) -> x [#] Zero.
(* End_Tex_Verb *)
Intros.
Cut x [*] y [#] Zero[*]Zero.
Intro.
Elim (bin_op_strext_unfolded ?????? H0); Intro.
3: Step_ap_rht Zero::R.
Assumption.
Step_ap_lft (x[*]y)[/]y[//]H1.
Apply div_resp_ap_zero_rev.
Assumption.
Qed.

(* Begin_Tex_Verb *)
Lemma mult_cancel_ap_zero_rht :
 (x,y:R)(x [*] y [#] Zero) -> y [#] Zero.
(* End_Tex_Verb *)
Intros.
Cut y[*]x [#] Zero.
Intro.
Apply mult_cancel_ap_zero_lft with x.
Assumption.
Step_ap_lft x[*]y.
Qed.

End Mult_Cancel_Ap_Zero.


