Section Theorems.
(** Represents an arbitrary ring.  Note: we use Variable rather than Parameter to ensure that the following theorems are generalized w.r.t r. *)
Variable r : Ring.
(** Represents the set of group elements.  Note: We use Let to define E as a local abbreviation. *)
Let E := E r.
(** A predicate that accepts one element, x, and asserts that x is nonzero. *)
Definition nonzero (x : E) : Prop := x <> 0.
(** Accepts one ring element, x, and asserts that x is the left identity element. *)
Definition sum_is_id_l := Monoid.is_id_l E sum.
(** Accepts one ring element, x, and asserts that x is the right identity element. *)
Definition sum_is_id_r := Monoid.is_id_r E sum.
(** Accepts one ring element, x, and asserts that x is the identity element. *)
Definition sum_is_id := Monoid.is_id E sum.
(** Represents the abelian group formed by addition over E. *)
Definition sum_abelian_group
:= Abelian_Group.abelian_group E 0 {+} sum_is_assoc sum_is_comm sum_id_l sum_inv_l_ex.
(** Represents the group formed by addition over E. *)
Definition sum_group
:= Abelian_Group.op_group sum_abelian_group.
(** Represents the monoid formed by addition over E. *)
Definition sum_monoid
:= Abelian_Group.op_monoid sum_abelian_group.
Proof Abelian_Group.op_id_r sum_abelian_group.
Proof Abelian_Group.op_id sum_abelian_group.
(** Accepts two elements, x and y, and asserts that y is x's left inverse. *)
Definition sum_is_inv_l
:= Abelian_Group.op_is_inv_l sum_abelian_group.
(** Accepts two elements, x and y, and asserts that y is x's right inverse. *)
Definition sum_is_inv_r
:= Abelian_Group.op_is_inv_r sum_abelian_group.
(** Accepts two elements, x and y, and asserts that y is x's inverse. *)
Definition sum_is_inv
:= Abelian_Group.op_is_inv sum_abelian_group.
(** Accepts one argument, x, and asserts that x has a left inverse. *)
Definition sum_has_inv_l := Abelian_Group.has_inv_l sum_abelian_group.
(** Accepts one argument, x, and asserts that x has a right inverse. *)
Definition sum_has_inv_r := Abelian_Group.has_inv_r sum_abelian_group.
(** Accepts one argument, x, and asserts that x has an inverse. *)
Definition sum_has_inv := Abelian_Group.has_inv sum_abelian_group.
Proof Abelian_Group.op_inv_r_ex sum_abelian_group.
Proof Abelian_Group.op_id_l_uniq sum_abelian_group.
Proof Abelian_Group.op_id_r_uniq sum_abelian_group.
Proof Abelian_Group.op_id_uniq sum_abelian_group.
Proof Abelian_Group.op_inv_l_r_eq sum_abelian_group.
Proof Abelian_Group.op_inv_sym sum_abelian_group.
Proof Abelian_Group.op_inv_uniq sum_abelian_group.
Proof Abelian_Group.op_inv_ex sum_abelian_group.
Proof Abelian_Group.op_inv_uniq_ex sum_abelian_group.
Proof Abelian_Group.op_intro_l sum_abelian_group.
Proof Abelian_Group.op_intro_r sum_abelian_group.
Proof Abelian_Group.op_cancel_l sum_abelian_group.
Proof Abelian_Group.op_cancel_r sum_abelian_group.
Proof Abelian_Group.op_inv_l_uniq sum_abelian_group.
Proof Abelian_Group.op_inv_r_uniq sum_abelian_group.
Proof Abelian_Group.op_inv_0_l sum_abelian_group.
Proof Abelian_Group.op_inv_0_r sum_abelian_group.
Proof Abelian_Group.op_inv_0 sum_abelian_group.
Proof Abelian_Group.op_has_inv_l_0 sum_abelian_group.
Proof Abelian_Group.op_has_inv_r_0 sum_abelian_group.
Proof Abelian_Group.op_has_inv_0 sum_abelian_group.
Proof Abelian_Group.op_inv_0_eq_0 sum_abelian_group.

(** Proves that 0 is the only element whose additive inverse is 0. *)
Theorem sum_inv_0_uniq
:  unique (fun x => sum_is_inv x 0) 0.