(** * Algebraic spaces *)
(** ** Abelian groups *)
Module AbelianGroup.
Record mixin_of (G : Type) := Mixin {
plus : G -> G -> G ;
opp : G -> G ;
zero : G ;
ax1 : forall x y, plus x y = plus y x ;
ax2 : forall x y z, plus x (plus y z) = plus (plus x y) z ;
ax3 : forall x, plus x zero = x ;
ax4 : forall x, plus x (opp x) = zero
}.
Notation class_of := mixin_of (only parsing).
Section ClassDef.
Structure type := Pack { sort; _ : class_of sort ; _ : Type }.
Local Coercion sort : type >-> Sortclass.
Definition class (cT : type) := let: Pack _ c _ := cT return class_of cT in c.
End ClassDef.
Module Exports.
Coercion sort : type >-> Sortclass.
Notation AbelianGroup := type.
End Exports.
End AbelianGroup.
Export AbelianGroup.Exports.
(** Arithmetic operations *)
Section AbelianGroup1.
Context {G : AbelianGroup}.
Definition zero := AbelianGroup.zero _ (AbelianGroup.class G).
Definition plus := AbelianGroup.plus _ (AbelianGroup.class G).
Definition opp := AbelianGroup.opp _ (AbelianGroup.class G).
Definition minus x y := (plus x (opp y)).

(* Specifications: *)
Lemma plus_comm :
forall x y : G,
plus x y = plus y x.
Lemma plus_assoc :
forall x y z : G,
plus x (plus y z) = plus (plus x y) z.
Lemma plus_zero_r :
forall x : G,
plus x zero = x.
Lemma plus_opp_r :
forall x : G,
plus x (opp x) = zero.
Lemma plus_zero_l :
forall x : G,
plus zero x = x.
Lemma plus_opp_l :
forall x : G,
plus (opp x) x = zero.
Lemma opp_zero :
opp zero = zero.
Lemma minus_zero_r :
forall x : G,
minus x zero = x.
Lemma minus_eq_zero (x : G) :
minus x x = zero.
Lemma plus_reg_l :
forall r x y : G,
plus r x = plus r y -> x = y.
Lemma plus_reg_r :
forall r x y : G,
plus x r = plus y r -> x = y.
Lemma opp_opp :
forall x : G,
opp (opp x) = x.
Lemma opp_plus :
forall x y : G,
opp (plus x y) = plus (opp x) (opp y).
Lemma opp_minus (x y : G) :
opp (minus x y) = minus y x.
Lemma minus_trans (r x y : G) :
minus x y = plus (minus x r) (minus r y).