(* $Id: CSemiGroups.v,v 1.13 2000/11/07 16:04:07 janz Exp $ *)

Require Export CSetoids.

Tactic Definition Algebra :=
  [<:tactic:<Auto with algebra_r algebra algebra_c algebra_s>>].
Tactic Definition Step_lft [$y] :=
  [<:tactic:<Apply eq_transitive_unfolded with $y;
    [Algebra | Idtac]>>].
Tactic Definition Step [$y] :=
  [<:tactic:<Step_lft $y>>].
Tactic Definition Step_rht [$y] :=
  [<:tactic:<Apply eq_transitive_unfolded with $y;
    [Idtac | Algebra]>>].
Tactic Definition Stepr [$y] :=
  [<:tactic:<Step_rht $y>>].
Tactic Definition Step_final [$y] :=
  [<:tactic:<Apply eq_transitive_unfolded with $y;
    Algebra>>].
Tactic Definition Step_ap_rht [$y] :=
  [<:tactic:<Apply ap_well_def_rht_unfolded with $y;
    Algebra>>].
Tactic Definition Step_ap_lft [$y] :=
  [<:tactic:<Apply ap_well_def_lft_unfolded with $y;
    Algebra>>].

(* Begin_SpecReals *)

(* Tex_Prose
\section{Semi Groups}
*)

(* Tex_Prose
\subsection{Definition of the notion semi group}
*)

(* Begin_Tex_Verb *)
Definition is_CSemi_grp [A:CSetoid; unit: A; op:(CSetoid_bin_op A)] :=
  (Associative op).
(* End_Tex_Verb *)

(* Begin_Tex_Verb *)
Record CSemi_grp : Type :=
  { csg_crr   :> CSetoid;
    csg_unit  :  csg_crr;                      (* non-empty *)
    csg_op    :  (CSetoid_bin_op csg_crr);
    csg_proof :  (is_CSemi_grp csg_crr csg_unit csg_op)
  }.
(* End_Tex_Verb *)

(* Tex_Prose
\begin{notation}
\verb!csg_unit ?! is denoted with \verb!Zero!.
\end{notation}
*)
Syntactic Definition Zero := (csg_unit ?).
Syntax constr level 1:
  csg_unit_constant [<<(csg_unit $e0)>>] -> ["Zero"].

(* Tex_Prose
\begin{notation}
\verb!csg_op ? x y! is denoted with \verb!x [+] y!.
\end{notation}

\begin{nameconvention}
In the {\em names} of lemmas, we will denote \verb!Zero! with \verb!zero!,
and \verb![+]! with \verb!plus!.
We denote \verb![#] Zero! in the names of lemmas by \verb!ap_zero!
(and not, e.g.\ \verb!nonzero!).
\end{nameconvention}
*)
Syntactic Definition Csg_op := (csg_op ?).
Infix 7 "[+]" Csg_op.
Syntax constr level 7:
  csg_op_infix [<<(csbf_fun $_ $_ $_ (csg_op $_) $e1 $e2)>>] ->
    [[<hov 1> $e1:E [0 1] "[+]" $e2:L]].

(* End_SpecReals *)

(* Tex_Prose
\subsection{Semi group axioms}
The axiomatic properties of a semi group.
\begin{convention}
Let \verb!G! be a semi-group.
\end{convention}
*)
Section CSemi_grp_axioms.
Variable G : CSemi_grp.

(* Begin_Tex_Verb *)
Lemma CSemi_grp_is_CSemi_grp : (is_CSemi_grp G Zero Csg_op).
(* End_Tex_Verb *)
Elim G; Intros.
Exact csg_proof0.
Qed.

(* Begin_Tex_Verb *)
Lemma plus_assoc : (Associative (csg_op G)).
(* End_Tex_Verb *)
Exact CSemi_grp_is_CSemi_grp.
Qed.

End CSemi_grp_axioms.

(* Begin_SpecReals *)

(* Tex_Prose
\subsection{Semi group basics}
\begin{convention}
Let \verb!G! be a semi-group.
\end{convention}
*)
Section CSemi_grp_basics.
Variable G : CSemi_grp.

(* End_SpecReals *)

(* Begin_Tex_Verb *)
Lemma plus_assoc_unfolded : (G:CSemi_grp)(x,y,z:G)
                            (x [+] (y [+] z)) [=] ((x [+] y) [+] z).
(* End_Tex_Verb *)
Exact plus_assoc.
Qed.

(* Begin_SpecReals *)

(* Tex_Prose
The predicate "non-zero" is defined as follows.
In lemmas we will continue to write \verb!x [#] Zero!, rather than
\verb!nonZeroP x!, but the predicate is useful for some high-level definitions,
e.g. for the setoid of non-zeros.
*)
(* Begin_Tex_Verb *)
Definition nonZeroP [x:G] : Prop := (x [#] Zero).
(* End_Tex_Verb *)

End CSemi_grp_basics.

Syntactic Definition NonZeroP := (nonZeroP ?).
(* End_SpecReals *)

Hints Resolve plus_assoc_unfolded : algebra.


(* Tex_Prose
\subsection{Sub-semi-groups}
\begin{convention}
Let \verb!csg! a semi-group and \verb!P! a predicate on the semi-group with
\verb!P Zero! and which is preserved by \verb![+]!.
\end{convention}
*)
Section SubCSemi_grps.
Variable csg       : CSemi_grp.
Variable P         : csg -> Prop.
Variable Punit     : (P Zero).
Variable op_pres_P : (bin_op_pres_pred ? P Csg_op).

(* Begin_Tex_Verb *)
Local subcrr : CSetoid := (Build_SubCSetoid ? P).
Definition Build_SubCSemi_grp : CSemi_grp :=
  (Build_CSemi_grp subcrr
                   (Build_subcsetoid_crr ??? Punit)
                   (Build_SubCSetoid_bin_op ??? op_pres_P)
                   (restr_f_assoc ??? op_pres_P (plus_assoc csg))).
(* End_Tex_Verb *)
End SubCSemi_grps.


