(** Represents the monoid formed by op over E. *)
Definition op_monoid := Group.op_monoid op_group.(**
  Accepts one argument, x, and asserts that
  x has a left inverse.
*)
Definition has_inv_l := Group.has_inv_l op_group.(**
  Accepts one argument, x, and asserts that
  x has a right inverse.
*)
Definition has_inv_r := Group.has_inv_r op_group.(**
  Accepts one argument, x, and asserts that
  x has an inverse.
*)
Definition has_inv := Group.has_inv op_group.

(* Specifications: *)
Theorem op_inv_l_r_eq : forall x y : E, op_is_inv_l x y -> forall z : E, op_is_inv_r x z -> y = z.
Theorem op_inv_sym : forall x y : E, op_is_inv x y <-> op_is_inv y x.
Theorem op_inv_ex : forall x : E, exists y : E, op_is_inv x y.
Theorem op_intro_l : forall x y z : E, x = y -> z + x = z + y.
Theorem op_intro_r : forall x y z : E, x = y -> x + z = y + z.
Theorem op_cancel_l : forall x y z : E, z + x = z + y -> x = y.
Theorem op_cancel_r : forall x y z : E, x + z = y + z -> x = y.
Theorem op_inv_l_uniq : forall x y z : E, op_is_inv_l x y -> op_is_inv_l x z -> z = y.
Theorem op_inv_r_uniq : forall x y z : E, op_is_inv_r x y -> op_is_inv_r x z -> z = y.
Theorem op_inv_uniq : forall x y z : E, op_is_inv x y -> op_is_inv x z -> z = y.
Theorem op_inv_uniq_ex : forall x : E, exists! y : E, op_is_inv x y.
Theorem op_inv_0_l : op_is_inv_l 0 0.
Theorem op_inv_0_r : op_is_inv_r 0 0.
Theorem op_inv_0 : op_is_inv 0 0.
Theorem op_has_inv_l_0 : has_inv_l 0.
Theorem op_has_inv_r_0 : has_inv_r 0.
Theorem op_has_inv_0 : has_inv 0.
Theorem op_inv_0_eq_0 : forall x : E, op_is_inv x 0 -> x = 0.
Theorem op_inv_0_uniq : unique (fun x => op_is_inv x 0) 0.