(* $Id: CGroups.v,v 1.69 2000/10/13 12:32:09 freek Exp $ *)

Require Export CMonoids.

(* Begin_SpecReals *)

(* Tex_Prose
\section{Groups}
*)

(* Tex_Prose
\subsection{Definition of the notion of Group}
*)
(* Begin_Tex_Verb *)
Definition is_inverse
 [S:CSetoid; op:(CSetoid_bin_op S); one:S; x:S; x_inv:S] : Prop :=
  ((op x x_inv) [=] one).
(* End_Tex_Verb *)
Syntactic Definition Is_inverse := (is_inverse ?).

(* Begin_Tex_Verb *)
Definition is_CGroup [G: CMonoid; inv: (CSetoid_un_op G)] :=
     (x: G)(Is_inverse Csg_op Zero x (inv x)).
(* End_Tex_Verb *)

(* Begin_Tex_Verb *)
Record CGroup : Type :=
  { cg_crr   :> CMonoid;
    cg_inv   :  (CSetoid_un_op cg_crr);
    cg_proof :  (is_CGroup cg_crr cg_inv)
  }.
(* End_Tex_Verb *)

(* End_SpecReals *)

(* Begin_SpecReals *)

(* Tex_Prose
\begin{notation}
\verb!cg_inv ? a! is denoted by \verb![--]a!.
\end{notation}
*)
Syntactic Definition Cg_inv := (cg_inv ?).
Grammar command command1 :=
  Cg_inv_prefix [ "[--]" command1($c) ] -> [<<(Cg_inv $c)>>].
Syntax constr level 1:
  cg_inv_prefix [<<(csf_fun $_ $_ (cg_inv $_) $e1)>>] ->
    [[<hov 1> "[--]" $e1:L]].

(* Begin_Tex_Verb *)
Definition cg_minus := [G: CGroup][x, y: G](x [+] [--]y).
(* End_Tex_Verb *)

(* Tex_Prose
\begin{notation}
\verb!cg_minus ? a b! is denoted by \verb!a[-]b!.
\end{notation}

\begin{nameconvention}
In the {\em names} of lemmas, we will denote \verb![--]! with \verb!min!,
and \verb![-]! with \verb!minus!.
\end{nameconvention}
*)
Syntactic Definition Cg_minus := (cg_minus ?).
Infix NONA 7 "[-]" Cg_minus.
Syntax constr level 7:
  cg_minus_infix [<<(cg_minus $_ $e1 $e2)>>] ->
    [[<hov 1> $e1:E [0 1] "[-]" $e2:L]].

(* End_SpecReals *)

(* Tex_Prose
\subsection{Group axioms}
\begin{convention}
Let \verb!G! be a group.
\end{convention}
*)
Section CGroup_axioms.
Variable G : CGroup.

(* Begin_Tex_Verb *)
Lemma cg_rht_inv: (x: G)(Is_inverse Csg_op Zero x (Cg_inv x)).
(* End_Tex_Verb *)
Proof (cg_proof G).

End CGroup_axioms.

(* Tex_Prose
\subsection{Group basics}
General properties of groups.
\begin{convention}
Let \verb!G! be a group.
\end{convention}
*)
Section CGroup_basics.
Variable G : CGroup.

(* Begin_Tex_Verb *)
Lemma cg_rht_inv_unfolded: (x:G)((x [+] [--]x) [=] Zero).
(* End_Tex_Verb *)
Exact (cg_rht_inv G).
Qed.

(* Begin_Tex_Verb *)
Lemma cg_minus_correct: (x: G)(x [-] x) [=] Zero.
(* End_Tex_Verb *)
Intros.
Unfold cg_minus.
Apply cg_rht_inv_unfolded.
Qed.
Hints Resolve cg_rht_inv_unfolded cg_minus_correct : algebra.

(* Begin_Tex_Verb *)
Lemma cg_lft_inv: (x: G)(Is_inverse Csg_op Zero ([--]x) x).
(* End_Tex_Verb *)
Intro x.
Red.
Step_final (x [+] [--]x).
Qed.

(* Begin_Tex_Verb *)
Lemma cg_lft_inv_unfolded: (x:G) ([--]x [+] x) [=] Zero.
(* End_Tex_Verb *)
Proof cg_lft_inv.
Hints Resolve cg_lft_inv_unfolded : algebra.

(* Hints for Auto *)
(* Begin_Tex_Verb *)
Lemma cg_minus_unfolded: (x,y:G) (x [-] y) [=] (x [+] [--]y).
(* End_Tex_Verb *)
Intros. Apply eq_reflexive_unfolded.
Qed.
Hints Resolve cg_minus_unfolded : algebra.

(* Begin_Tex_Verb *)
Lemma cg_minus_wd: (x,x',y,y':G)
  (x [=] x')->(y [=] y')->(x[-]y [=] x'[-]y').
(* End_Tex_Verb *)
Intros.
Step x[+][--]y.
Step_final x'[+][--]y'.
Qed.
Hints Resolve cg_minus_wd : algebra_c.

(* Begin_Tex_Verb *)
Lemma cg_minus_strext: (x,x',y,y':G)
  (x[-]y [#] x'[-]y') -> (x [#] x')\/(y [#] y').
(* End_Tex_Verb *)
Intros. Cut (x [#] x')\/([--]y [#] [--]y').
Intro H0.Elim H0.
Left;Trivial.
Right;Exact (un_op_strext G (cg_inv ?)y y' H1).
Apply bin_op_strext_unfolded with (csg_op G). Trivial.
Qed.

(* Begin_Tex_Verb *)
Definition cg_minus_is_csetoid_bin_op : (CSetoid_bin_op G):=
(Build_CSetoid_bin_op G (cg_minus G)
   (cg_minus_wd) (cg_minus_strext)).
(* End_Tex_Verb *)


(* Begin_Tex_Verb *)
Lemma grp_inv_assoc: (x,y:G) (x[+]y)[-]y [=] x.
(* End_Tex_Verb *)
Intros; Unfold cg_minus.
Step x [+] (y [+] ([--]y)).
Step_final x [+] Zero.
Qed.
Hints Resolve grp_inv_assoc : algebra.

(* Begin_Tex_Verb *)
Lemma cg_inv_unique: (x,y:G) ((x [+] y) [=] Zero) -> y [=] [--]x.
(* End_Tex_Verb *)
Proof.
Intros.
Step (Zero [+] y).
Step (([--]x [+] x) [+] y).
Step ([--]x [+] (x [+] y)).
Step_final ([--]x [+] Zero).
Qed.

(* Begin_Tex_Verb *)
Lemma cg_inv_inv: (x:G)[--][--]x [=] x.
(* End_Tex_Verb *)
Proof.
Intros.
Step (Zero [+] [--][--]x).
Step ((x [+] [--]x) [+] [--][--]x).
Step (x [+] ([--]x [+] [--][--]x)).
Step_final (x [+] Zero).
Qed.
Hints Resolve cg_inv_inv : algebra.

(* Begin_Tex_Verb *)
Lemma cg_cancel_lft: (a, b, c:G)((a [+] b) [=] (a [+] c)) -> b [=] c.
(* End_Tex_Verb *)
Proof.
Intros.
Step (Zero [+] b).
Step (([--]a [+] a) [+] b).
Step ([--]a [+] (a [+] b)).
Step ([--]a [+] (a [+] c)).
Step (([--]a [+] a) [+] c).
Step_final (Zero [+] c).
Qed.

(* Begin_Tex_Verb *)
Lemma cg_cancel_rht: (a, b, c: G)((b [+] a) [=] (c [+] a)) -> b [=] c.
(* End_Tex_Verb *)
Proof.
Intros.
Apply (cg_cancel_lft a b c).
Step (b [+] a).
Step_final (c [+] a).
Qed.

(* Begin_Tex_Verb *)
Lemma cg_inv_unique': (x,y:G) ((x [+] y) [=] Zero) -> x [=] [--]y.
(* End_Tex_Verb *)
Proof.
Intros.
Step (x [+] Zero).
Step (x [+] (y [+] [--]y)).
Step ((x [+] y) [+] [--]y).
Step_final (Zero [+] [--]y).
Qed.

(* Begin_Tex_Verb *)
Lemma cg_inv_unique_2 : (x,y:G)(x[-]y [=] Zero)->(x [=] y).
(* End_Tex_Verb *)
Intros.
Generalize (cg_inv_unique ?? H); Intro.
Step [--][--]x.
Step_final [--][--]y.
Qed.

(* Begin_Tex_Verb *)
Lemma cg_zero_inv: [--]Zero::G [=] Zero.
(* End_Tex_Verb *)
Apply eq_symmetric_unfolded; Apply cg_inv_unique; Algebra.
Qed.

Hints Resolve cg_zero_inv.

(* Begin_Tex_Verb *)
Lemma cg_inv_zero : (x:G)x[-]Zero [=] x.
(* End_Tex_Verb *)
Intros.
Unfold cg_minus.
Step_lft x[+]Zero.
Algebra.
Qed.

(* Begin_Tex_Verb *)
Lemma cg_inv_op: (x,y:G) [--](x[+]y) [=] [--]y [+] [--]x.
(* End_Tex_Verb *)
Intros.
Apply (eq_symmetric G).
Apply (cg_inv_unique (x [+] y) ([--]y [+] [--]x)).
Step ((x [+] y) [+] [--]y) [+] [--]x.
Step (x [+] (y [+] [--]y)) [+] [--]x.
Step (x [+] Zero) [+] [--]x.
Step_final (x [+] [--]x).
Qed.

(* Begin_Tex_Verb *)
Lemma csg_op_inv: (x,y:G) [--](x[+]y) [=] [--]x [+] [--]y.
(* End_Tex_Verb *)
Intros.
Stepr [--]y [+] [--]x.
Apply cg_inv_op.
Qed.



(* Tex_Prose
\subsection{Sub-groups}
\begin{convention}
Let \verb!P! a predicate on \verb!G! with
\verb!P Zero! and which is preserved by \verb![+]! and \verb![--]!.
\end{convention}
*)
Section SubCGroups.
Variable P         : G -> Prop.
Variable Punit     : (P Zero).
Variable op_pres_P : (bin_op_pres_pred ? P Csg_op).
Variable inv_pres_P : (un_op_pres_pred ? P Cg_inv).

(* Begin_Tex_Verb *)
Local subcrr : CMonoid := (Build_SubCMonoid ?? Punit op_pres_P).
Local subinv : (CSetoid_un_op subcrr) :=
  (Build_SubCSetoid_un_op ??? inv_pres_P).
(* End_Tex_Verb *)

(* Begin_Tex_Verb *)
Lemma isgrp_scrr: (is_CGroup subcrr subinv).
(* End_Tex_Verb *)
Red. Intro x. Case x. Intros. Simpl. Apply cg_rht_inv_unfolded.
Qed.

(* Begin_Tex_Verb *)
Definition Build_SubCGroup : CGroup := (Build_CGroup subcrr ? isgrp_scrr).
(* End_Tex_Verb *)

End SubCGroups.

End CGroup_basics.

Hints Resolve cg_rht_inv_unfolded cg_lft_inv_unfolded : algebra.
Hints Resolve cg_inv_inv cg_minus_correct cg_zero_inv cg_inv_zero : algebra.
Hints Resolve cg_minus_unfolded grp_inv_assoc cg_inv_op csg_op_inv : algebra.
Hints Resolve cg_minus_wd : algebra_c.

(* Tex_Prose
\subsection{Associative properties of groups}
\begin{convention}
Let \verb!G! be a group.
\end{convention}
*)
Section Assoc_properties.
Variable G : CGroup.

(* Begin_Tex_Verb *)
Lemma assoc_1 : (x,y,z:G)(x[-](y[-]z) [=] (x[-]y)[+]z).
(* End_Tex_Verb *)
Intros; Unfold cg_minus.
Stepr x[+]([--]y[+]z).
Apply (bin_op_wd ? (csg_op G));[Algebra|Idtac].
Step_final ([--]y)[+]([--][--]z).
Qed.

(* Begin_Tex_Verb *)
Lemma assoc_2 : (x,y,z:G)(x[+](y[-]z) [=] (x[+]y)[-]z).
(* End_Tex_Verb *)
Intros; Unfold cg_minus; Algebra.
Qed.

(* Begin_Tex_Verb *)
Lemma minus_plus : (x,y,z:G)((x[-](y[+]z)) [=] ((x[-]y)[-]z)).
(* End_Tex_Verb *)
Intros.
Unfold cg_minus.
Step_final x[+]([--]y[+][--]z).
Qed.

(* Begin_Tex_Verb *)
Lemma zero_minus : (x:G)((Zero [-] x) [=] ([--] x)).
(* End_Tex_Verb *)
Intro.
Unfold cg_minus.
Algebra.
Qed.

(* Begin_Tex_Verb *)
Lemma cg_cancel_mixed:(x,y:G)(x[=]x[-]y[+]y).
(* End_Tex_Verb *)
 Intros.
 Unfold cg_minus.
 Stepr x[+]([--]y[+]y).
 Stepr x[+]Zero.
 Algebra.
Qed.

(* Begin_Tex_Verb *)
Lemma plus_resp_eq:(a,b,c:G)(b[=]c)->(a[+]b[=]a[+]c).
(* End_Tex_Verb *)
Intros.
Apply bin_op_wd_unfolded.
Algebra.
Assumption.
Qed.

End Assoc_properties.

Hints Resolve assoc_1 assoc_2 minus_plus zero_minus: algebra.


(* Tex_Prose
\subsection{Apartness in Constructive Groups}
Specific properties of {\em constructive} groups.
\begin{convention}
Let \verb!G! be a group.
\end{convention}
*)
Section cgroups_apartness.
Variable G : CGroup.

(* Begin_Tex_Verb *)
Lemma cg_add_ap_zero:
  (x,y:G)((x [+] y) [#] Zero) -> (x [#] Zero) \/ (y [#] Zero).
(* End_Tex_Verb *)
Intros.
Cut x[+]y [#] Zero[+]Zero. Intros h.
Apply (bin_op_strext ?? x Zero y Zero h).
Step_ap_rht (Zero::G).
Qed.

(* Begin_Tex_Verb *)
Lemma op_rht_resp_ap: (x,y,z:G)(x [#] y) -> (x [+] z) [#] (y [+] z).
(* End_Tex_Verb *)
Intros.
Cut (x [+] z) [-] z [#] (y [+] z) [-] z.
Intros h.
Case (bin_op_strext ?????? h).
Auto.
Intro contra; Elim (ap_irreflexive ?? contra).
Step_ap_lft x.
Step_ap_rht y.
Qed.

(* Begin_Tex_Verb *)
Lemma op_lft_resp_ap: (x,y,z:G)(y [#] z) -> (x [+] y) [#] (x [+] z).
(* End_Tex_Verb *)
Proof.
Intros.
Step_ap_lft y[+]x.
Step_ap_rht z[+]x.
Apply op_rht_resp_ap; Assumption.
Qed.

(* Begin_Tex_Verb *)
Lemma cg_ap_cancel_rht: (x,y,z:G) ((x [+] z) [#] (y [+] z)) -> x [#] y.
(* End_Tex_Verb *)
Intros.
Step_ap_lft x [+] Zero.
Step_ap_lft x [+] (z[+][--]z).
Step_ap_lft (x [+] z) [+][--]z.
Step_ap_rht y [+] Zero.
Step_ap_rht y [+] (z[+][--]z).
Step_ap_rht (y [+] z) [+][--]z.
Apply (op_rht_resp_ap ?? ([--]z) H).
Qed.

(* Begin_Tex_Verb *)
Lemma plus_cancel_ap_rht : (x,y,z:G)((x[+]z) [#] (y[+]z)) -> x[#]y.
(* End_Tex_Verb *)
Proof cg_ap_cancel_rht.

(* Begin_Tex_Verb *)
Lemma cg_ap_cancel_lft: (x,y,z:G) ((x [+] y) [#] (x [+] z)) -> y [#] z.
(* End_Tex_Verb *)
Intros.
Apply ap_symmetric_unfolded.
Apply cg_ap_cancel_rht with x.
Apply ap_symmetric_unfolded.
Step_ap_lft x[+]y.
Step_ap_rht x[+]z.
Qed.


(* Begin_Tex_Verb *)
Lemma plus_cancel_ap_lft : (x,y,z:G)((z[+]x) [#] (z[+]y)) -> x[#]y.
(* End_Tex_Verb *)
Intros.
Apply cg_ap_cancel_lft with z.
Assumption.
Qed.

(* Begin_Tex_Verb *)
Lemma minus_ap_zero: (x,y:G)(x [#] y) -> (x[-]y) [#] Zero.
(* End_Tex_Verb *)
Intros.
Step_ap_rht y[-]y.
Unfold cg_minus.
Apply op_rht_resp_ap; Assumption.
Qed.

(* Begin_Tex_Verb *)
Lemma zero_minus_apart: (x,y:G)((x[-]y) [#] Zero) -> x [#] y.
(* End_Tex_Verb *)
Unfold cg_minus. Intros.
Cut x[+][--]y [#] y[+][--]y. Intros h.
Apply (cg_ap_cancel_rht ??? h).
Step_ap_rht (Zero::G).
Qed.

(* Begin_Tex_Verb *)
Lemma min_resp_ap_zero: (x:G)(x [#] Zero) -> [--]x [#] Zero.
(* End_Tex_Verb *)
Intros.
Step_ap_lft Zero[+][--]x.
Step_ap_lft Zero[-]x.
Apply minus_ap_zero.
Apply (ap_symmetric G).
Auto.
Qed.

(* Begin_Tex_Verb *)
Lemma min_resp_ap : (x,y:G)(x[#]y) -> ([--]x) [#] ([--]y).
(* End_Tex_Verb *)
Intros.
Apply cg_ap_cancel_lft with x[+]y.
Step_ap_lft (y[+]x)[+][--]x.
Step_ap_lft y[+](x[+][--]x).
Step_ap_lft y[+]Zero.
Step_ap_lft y.
Step_ap_rht x[+](y[+][--]y).
Step_ap_rht x[+]Zero.
Step_ap_rht x.
Apply ap_symmetric_unfolded.
Assumption.
Qed.

(* Begin_Tex_Verb *)
Lemma minus_resp_ap_lft : (x,y,z:G)(x[#]y) -> (z[-]x) [#] (z[-]y).
(* End_Tex_Verb *)
Intros.
Unfold cg_minus.
Apply op_lft_resp_ap.
Apply min_resp_ap.
Assumption.
Qed.

(* Begin_Tex_Verb *)
Lemma minus_resp_ap_rht : (x,y,z:G)(x[#]y) -> (x[-]z) [#] (y[-]z).
(* End_Tex_Verb *)
Intros.
Unfold cg_minus.
Apply op_rht_resp_ap.
Assumption.
Qed.

(* Begin_Tex_Verb *)
Lemma minus_cancel_ap_rht : (x,y,z:G)((x[-]z) [#] (y[-]z)) -> x[#]y.
(* End_Tex_Verb *)
Unfold cg_minus.
Intros.
Generalize (plus_cancel_ap_rht ??? H); Intro.
Assumption.
Qed.

End cgroups_apartness.
Hints Resolve op_rht_resp_ap op_lft_resp_ap : algebra.
Hints Resolve minus_ap_zero zero_minus_apart min_resp_ap_zero :algebra.


