(** * 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)).

Lemma opp_opp :
forall x : G,
opp (opp x) = x.