Section Theorems.
(** Represents an arbitrary group.  Note: we use Variable rather than Parameter to ensure that the following theorems are generalized w.r.t g. *)
Variable g : Group.
(** Represents the set of group elements. *)
Let E := E g.
(** Represents the monoid structure formed by op over E. *)
Definition op_monoid := Monoid.monoid E 0 {+} op_is_assoc op_id_l op_id_r.
(** Accepts one group element, x, and asserts that x is the left identity element. *)
Definition op_is_id_l := Monoid.op_is_id_l op_monoid.
(** Accepts one group element, x, and asserts that x is the right identity element. *)
Definition op_is_id_r := Monoid.op_is_id_r op_monoid.
(** Accepts one group element, x, and asserts that x is the identity element. *)
Definition op_is_id := Monoid.op_is_id op_monoid.
Proof Monoid.op_id op_monoid.
(** Accepts two group elements, x and y, and asserts that y is x's left inverse. *)
Definition op_is_inv_l := Monoid.op_is_inv_l op_monoid.
(** Accepts two group elements, x and y, and asserts that y is x's right inverse. *)
Definition op_is_inv_r := Monoid.op_is_inv_r op_monoid.
Proof Monoid.op_id_l_uniq op_monoid.
Proof Monoid.op_id_r_uniq op_monoid.
Proof Monoid.op_id_uniq op_monoid.
Proof Monoid.op_intro_l op_monoid.
Proof Monoid.op_intro_r op_monoid.
(** Accepts two group elements, x and y, and asserts that y is x's inverse. *)
Definition op_is_inv := Monoid.op_is_inv op_monoid.
(** Accepts one argument, x, and asserts that x has a left inverse. *)
Definition has_inv_l := Monoid.has_inv_l op_monoid.
(** Accepts one argument, x, and asserts that x has a right inverse. *)
Definition has_inv_r := Monoid.has_inv_r op_monoid.
(** Accepts one argument, x, and asserts that x has an inverse. *)
Definition has_inv := Monoid.has_inv op_monoid.
Proof Monoid.op_inv_l_r_eq op_monoid.
Proof Monoid.op_inv_sym op_monoid.

(** Proves that every group element has an inverse. *)
Theorem op_inv_ex
:  forall x : E, exists y : E, op_is_inv x y.