Class Ring_ops(T:Type)
   {ring0:T}
   {ring1:T}
   {add:T->T->T}
   {mul:T->T->T}
   {sub:T->T->T}
   {opp:T->T}
   {ring_eq:T->T->Prop}.#[global]
Instance zero_notation(T:Type)`{Ring_ops T}:Zero T:= ring0.#[global]
Instance one_notation(T:Type)`{Ring_ops T}:One T:= ring1.#[global]
Instance add_notation(T:Type)`{Ring_ops T}:Addition T:= add.#[global]
Instance mul_notation(T:Type)`{Ring_ops T}:@Multiplication T T:= mul.#[global]
Instance sub_notation(T:Type)`{Ring_ops T}:Subtraction T:= sub.#[global]
Instance opp_notation(T:Type)`{Ring_ops T}:Opposite T:= opp.#[global]
Instance eq_notation(T:Type)`{Ring_ops T}:@Equality T:= ring_eq.Class Ring `{Ro:Ring_ops}:={
 ring_setoid: Equivalence _==_;
 ring_plus_comp: Proper (_==_ ==> _==_ ==>_==_) _+_;
 ring_mult_comp: Proper (_==_ ==> _==_ ==>_==_) _*_;
 ring_sub_comp: Proper (_==_ ==> _==_ ==>_==_) _-_;
 ring_opp_comp: Proper (_==_==>_==_) -_;
 ring_add_0_l    : forall x, 0 + x == x;
 ring_add_comm   : forall x y, x + y == y + x;
 ring_add_assoc  : forall x y z, x + (y + z) == (x + y) + z;
 ring_mul_1_l    : forall x, 1 * x == x;
 ring_mul_1_r    : forall x, x * 1 == x;
 ring_mul_assoc  : forall x y z, x * (y * z) == (x * y) * z;
 ring_distr_l    : forall x y z, (x + y) * z == x * z + y * z;
 ring_distr_r    : forall x y z, z * ( x + y) == z * x + z * y;
 ring_sub_def    : forall x y, x - y == x + -y;
 ring_opp_def    : forall x, x + -x == 0
}.Class Ring `{Ro:Ring_ops}:={
 ring_setoid: Equivalence _==_;
 ring_plus_comp: Proper (_==_ ==> _==_ ==>_==_) _+_;
 ring_mult_comp: Proper (_==_ ==> _==_ ==>_==_) _*_;
 ring_sub_comp: Proper (_==_ ==> _==_ ==>_==_) _-_;
 ring_opp_comp: Proper (_==_==>_==_) -_;
 ring_add_0_l    : forall x, 0 + x == x;
 ring_add_comm   : forall x y, x + y == y + x;
 ring_add_assoc  : forall x y z, x + (y + z) == (x + y) + z;
 ring_mul_1_l    : forall x, 1 * x == x;
 ring_mul_1_r    : forall x, x * 1 == x;
 ring_mul_assoc  : forall x y z, x * (y * z) == (x * y) * z;
 ring_distr_l    : forall x y z, (x + y) * z == x * z + y * z;
 ring_distr_r    : forall x y z, z * ( x + y) == z * x + z * y;
 ring_sub_def    : forall x y, x - y == x + -y;
 ring_opp_def    : forall x, x + -x == 0
}.Class Ring `{Ro:Ring_ops}:={
 ring_setoid: Equivalence _==_;
 ring_plus_comp: Proper (_==_ ==> _==_ ==>_==_) _+_;
 ring_mult_comp: Proper (_==_ ==> _==_ ==>_==_) _*_;
 ring_sub_comp: Proper (_==_ ==> _==_ ==>_==_) _-_;
 ring_opp_comp: Proper (_==_==>_==_) -_;
 ring_add_0_l    : forall x, 0 + x == x;
 ring_add_comm   : forall x y, x + y == y + x;
 ring_add_assoc  : forall x y z, x + (y + z) == (x + y) + z;
 ring_mul_1_l    : forall x, 1 * x == x;
 ring_mul_1_r    : forall x, x * 1 == x;
 ring_mul_assoc  : forall x y z, x * (y * z) == (x * y) * z;
 ring_distr_l    : forall x y z, (x + y) * z == x * z + y * z;
 ring_distr_r    : forall x y z, z * ( x + y) == z * x + z * y;
 ring_sub_def    : forall x y, x - y == x + -y;
 ring_opp_def    : forall x, x + -x == 0
}.Class Ring `{Ro:Ring_ops}:={
 ring_setoid: Equivalence _==_;
 ring_plus_comp: Proper (_==_ ==> _==_ ==>_==_) _+_;
 ring_mult_comp: Proper (_==_ ==> _==_ ==>_==_) _*_;
 ring_sub_comp: Proper (_==_ ==> _==_ ==>_==_) _-_;
 ring_opp_comp: Proper (_==_==>_==_) -_;
 ring_add_0_l    : forall x, 0 + x == x;
 ring_add_comm   : forall x y, x + y == y + x;
 ring_add_assoc  : forall x y z, x + (y + z) == (x + y) + z;
 ring_mul_1_l    : forall x, 1 * x == x;
 ring_mul_1_r    : forall x, x * 1 == x;
 ring_mul_assoc  : forall x y z, x * (y * z) == (x * y) * z;
 ring_distr_l    : forall x y z, (x + y) * z == x * z + y * z;
 ring_distr_r    : forall x y z, z * ( x + y) == z * x + z * y;
 ring_sub_def    : forall x y, x - y == x + -y;
 ring_opp_def    : forall x, x + -x == 0
}.Class Ring `{Ro:Ring_ops}:={
 ring_setoid: Equivalence _==_;
 ring_plus_comp: Proper (_==_ ==> _==_ ==>_==_) _+_;
 ring_mult_comp: Proper (_==_ ==> _==_ ==>_==_) _*_;
 ring_sub_comp: Proper (_==_ ==> _==_ ==>_==_) _-_;
 ring_opp_comp: Proper (_==_==>_==_) -_;
 ring_add_0_l    : forall x, 0 + x == x;
 ring_add_comm   : forall x y, x + y == y + x;
 ring_add_assoc  : forall x y z, x + (y + z) == (x + y) + z;
 ring_mul_1_l    : forall x, 1 * x == x;
 ring_mul_1_r    : forall x, x * 1 == x;
 ring_mul_assoc  : forall x y z, x * (y * z) == (x * y) * z;
 ring_distr_l    : forall x y z, (x + y) * z == x * z + y * z;
 ring_distr_r    : forall x y z, z * ( x + y) == z * x + z * y;
 ring_sub_def    : forall x y, x - y == x + -y;
 ring_opp_def    : forall x, x + -x == 0
}.Class Ring `{Ro:Ring_ops}:={
 ring_setoid: Equivalence _==_;
 ring_plus_comp: Proper (_==_ ==> _==_ ==>_==_) _+_;
 ring_mult_comp: Proper (_==_ ==> _==_ ==>_==_) _*_;
 ring_sub_comp: Proper (_==_ ==> _==_ ==>_==_) _-_;
 ring_opp_comp: Proper (_==_==>_==_) -_;
 ring_add_0_l    : forall x, 0 + x == x;
 ring_add_comm   : forall x y, x + y == y + x;
 ring_add_assoc  : forall x y z, x + (y + z) == (x + y) + z;
 ring_mul_1_l    : forall x, 1 * x == x;
 ring_mul_1_r    : forall x, x * 1 == x;
 ring_mul_assoc  : forall x y z, x * (y * z) == (x * y) * z;
 ring_distr_l    : forall x y z, (x + y) * z == x * z + y * z;
 ring_distr_r    : forall x y z, z * ( x + y) == z * x + z * y;
 ring_sub_def    : forall x y, x - y == x + -y;
 ring_opp_def    : forall x, x + -x == 0
}.Class Ring `{Ro:Ring_ops}:={
 ring_setoid: Equivalence _==_;
 ring_plus_comp: Proper (_==_ ==> _==_ ==>_==_) _+_;
 ring_mult_comp: Proper (_==_ ==> _==_ ==>_==_) _*_;
 ring_sub_comp: Proper (_==_ ==> _==_ ==>_==_) _-_;
 ring_opp_comp: Proper (_==_==>_==_) -_;
 ring_add_0_l    : forall x, 0 + x == x;
 ring_add_comm   : forall x y, x + y == y + x;
 ring_add_assoc  : forall x y z, x + (y + z) == (x + y) + z;
 ring_mul_1_l    : forall x, 1 * x == x;
 ring_mul_1_r    : forall x, x * 1 == x;
 ring_mul_assoc  : forall x y z, x * (y * z) == (x * y) * z;
 ring_distr_l    : forall x y z, (x + y) * z == x * z + y * z;
 ring_distr_r    : forall x y z, z * ( x + y) == z * x + z * y;
 ring_sub_def    : forall x y, x - y == x + -y;
 ring_opp_def    : forall x, x + -x == 0
}.Class Ring `{Ro:Ring_ops}:={
 ring_setoid: Equivalence _==_;
 ring_plus_comp: Proper (_==_ ==> _==_ ==>_==_) _+_;
 ring_mult_comp: Proper (_==_ ==> _==_ ==>_==_) _*_;
 ring_sub_comp: Proper (_==_ ==> _==_ ==>_==_) _-_;
 ring_opp_comp: Proper (_==_==>_==_) -_;
 ring_add_0_l    : forall x, 0 + x == x;
 ring_add_comm   : forall x y, x + y == y + x;
 ring_add_assoc  : forall x y z, x + (y + z) == (x + y) + z;
 ring_mul_1_l    : forall x, 1 * x == x;
 ring_mul_1_r    : forall x, x * 1 == x;
 ring_mul_assoc  : forall x y z, x * (y * z) == (x * y) * z;
 ring_distr_l    : forall x y z, (x + y) * z == x * z + y * z;
 ring_distr_r    : forall x y z, z * ( x + y) == z * x + z * y;
 ring_sub_def    : forall x y, x - y == x + -y;
 ring_opp_def    : forall x, x + -x == 0
}.Class Ring `{Ro:Ring_ops}:={
 ring_setoid: Equivalence _==_;
 ring_plus_comp: Proper (_==_ ==> _==_ ==>_==_) _+_;
 ring_mult_comp: Proper (_==_ ==> _==_ ==>_==_) _*_;
 ring_sub_comp: Proper (_==_ ==> _==_ ==>_==_) _-_;
 ring_opp_comp: Proper (_==_==>_==_) -_;
 ring_add_0_l    : forall x, 0 + x == x;
 ring_add_comm   : forall x y, x + y == y + x;
 ring_add_assoc  : forall x y z, x + (y + z) == (x + y) + z;
 ring_mul_1_l    : forall x, 1 * x == x;
 ring_mul_1_r    : forall x, x * 1 == x;
 ring_mul_assoc  : forall x y z, x * (y * z) == (x * y) * z;
 ring_distr_l    : forall x y z, (x + y) * z == x * z + y * z;
 ring_distr_r    : forall x y z, z * ( x + y) == z * x + z * y;
 ring_sub_def    : forall x y, x - y == x + -y;
 ring_opp_def    : forall x, x + -x == 0
}.Class Ring `{Ro:Ring_ops}:={
 ring_setoid: Equivalence _==_;
 ring_plus_comp: Proper (_==_ ==> _==_ ==>_==_) _+_;
 ring_mult_comp: Proper (_==_ ==> _==_ ==>_==_) _*_;
 ring_sub_comp: Proper (_==_ ==> _==_ ==>_==_) _-_;
 ring_opp_comp: Proper (_==_==>_==_) -_;
 ring_add_0_l    : forall x, 0 + x == x;
 ring_add_comm   : forall x y, x + y == y + x;
 ring_add_assoc  : forall x y z, x + (y + z) == (x + y) + z;
 ring_mul_1_l    : forall x, 1 * x == x;
 ring_mul_1_r    : forall x, x * 1 == x;
 ring_mul_assoc  : forall x y z, x * (y * z) == (x * y) * z;
 ring_distr_l    : forall x y z, (x + y) * z == x * z + y * z;
 ring_distr_r    : forall x y z, z * ( x + y) == z * x + z * y;
 ring_sub_def    : forall x y, x - y == x + -y;
 ring_opp_def    : forall x, x + -x == 0
}.Class Ring `{Ro:Ring_ops}:={
 ring_setoid: Equivalence _==_;
 ring_plus_comp: Proper (_==_ ==> _==_ ==>_==_) _+_;
 ring_mult_comp: Proper (_==_ ==> _==_ ==>_==_) _*_;
 ring_sub_comp: Proper (_==_ ==> _==_ ==>_==_) _-_;
 ring_opp_comp: Proper (_==_==>_==_) -_;
 ring_add_0_l    : forall x, 0 + x == x;
 ring_add_comm   : forall x y, x + y == y + x;
 ring_add_assoc  : forall x y z, x + (y + z) == (x + y) + z;
 ring_mul_1_l    : forall x, 1 * x == x;
 ring_mul_1_r    : forall x, x * 1 == x;
 ring_mul_assoc  : forall x y z, x * (y * z) == (x * y) * z;
 ring_distr_l    : forall x y z, (x + y) * z == x * z + y * z;
 ring_distr_r    : forall x y z, z * ( x + y) == z * x + z * y;
 ring_sub_def    : forall x y, x - y == x + -y;
 ring_opp_def    : forall x, x + -x == 0
}.Class Ring `{Ro:Ring_ops}:={
 ring_setoid: Equivalence _==_;
 ring_plus_comp: Proper (_==_ ==> _==_ ==>_==_) _+_;
 ring_mult_comp: Proper (_==_ ==> _==_ ==>_==_) _*_;
 ring_sub_comp: Proper (_==_ ==> _==_ ==>_==_) _-_;
 ring_opp_comp: Proper (_==_==>_==_) -_;
 ring_add_0_l    : forall x, 0 + x == x;
 ring_add_comm   : forall x y, x + y == y + x;
 ring_add_assoc  : forall x y z, x + (y + z) == (x + y) + z;
 ring_mul_1_l    : forall x, 1 * x == x;
 ring_mul_1_r    : forall x, x * 1 == x;
 ring_mul_assoc  : forall x y z, x * (y * z) == (x * y) * z;
 ring_distr_l    : forall x y z, (x + y) * z == x * z + y * z;
 ring_distr_r    : forall x y z, z * ( x + y) == z * x + z * y;
 ring_sub_def    : forall x y, x - y == x + -y;
 ring_opp_def    : forall x, x + -x == 0
}.Class Ring `{Ro:Ring_ops}:={
 ring_setoid: Equivalence _==_;
 ring_plus_comp: Proper (_==_ ==> _==_ ==>_==_) _+_;
 ring_mult_comp: Proper (_==_ ==> _==_ ==>_==_) _*_;
 ring_sub_comp: Proper (_==_ ==> _==_ ==>_==_) _-_;
 ring_opp_comp: Proper (_==_==>_==_) -_;
 ring_add_0_l    : forall x, 0 + x == x;
 ring_add_comm   : forall x y, x + y == y + x;
 ring_add_assoc  : forall x y z, x + (y + z) == (x + y) + z;
 ring_mul_1_l    : forall x, 1 * x == x;
 ring_mul_1_r    : forall x, x * 1 == x;
 ring_mul_assoc  : forall x y z, x * (y * z) == (x * y) * z;
 ring_distr_l    : forall x y z, (x + y) * z == x * z + y * z;
 ring_distr_r    : forall x y z, z * ( x + y) == z * x + z * y;
 ring_sub_def    : forall x y, x - y == x + -y;
 ring_opp_def    : forall x, x + -x == 0
}.Class Ring `{Ro:Ring_ops}:={
 ring_setoid: Equivalence _==_;
 ring_plus_comp: Proper (_==_ ==> _==_ ==>_==_) _+_;
 ring_mult_comp: Proper (_==_ ==> _==_ ==>_==_) _*_;
 ring_sub_comp: Proper (_==_ ==> _==_ ==>_==_) _-_;
 ring_opp_comp: Proper (_==_==>_==_) -_;
 ring_add_0_l    : forall x, 0 + x == x;
 ring_add_comm   : forall x y, x + y == y + x;
 ring_add_assoc  : forall x y z, x + (y + z) == (x + y) + z;
 ring_mul_1_l    : forall x, 1 * x == x;
 ring_mul_1_r    : forall x, x * 1 == x;
 ring_mul_assoc  : forall x y z, x * (y * z) == (x * y) * z;
 ring_distr_l    : forall x y z, (x + y) * z == x * z + y * z;
 ring_distr_r    : forall x y z, z * ( x + y) == z * x + z * y;
 ring_sub_def    : forall x y, x - y == x + -y;
 ring_opp_def    : forall x, x + -x == 0
}.Class Ring `{Ro:Ring_ops}:={
 ring_setoid: Equivalence _==_;
 ring_plus_comp: Proper (_==_ ==> _==_ ==>_==_) _+_;
 ring_mult_comp: Proper (_==_ ==> _==_ ==>_==_) _*_;
 ring_sub_comp: Proper (_==_ ==> _==_ ==>_==_) _-_;
 ring_opp_comp: Proper (_==_==>_==_) -_;
 ring_add_0_l    : forall x, 0 + x == x;
 ring_add_comm   : forall x y, x + y == y + x;
 ring_add_assoc  : forall x y z, x + (y + z) == (x + y) + z;
 ring_mul_1_l    : forall x, 1 * x == x;
 ring_mul_1_r    : forall x, x * 1 == x;
 ring_mul_assoc  : forall x y z, x * (y * z) == (x * y) * z;
 ring_distr_l    : forall x y z, (x + y) * z == x * z + y * z;
 ring_distr_r    : forall x y z, z * ( x + y) == z * x + z * y;
 ring_sub_def    : forall x y, x - y == x + -y;
 ring_opp_def    : forall x, x + -x == 0
}.Class Ring `{Ro:Ring_ops}:={
 ring_setoid: Equivalence _==_;
 ring_plus_comp: Proper (_==_ ==> _==_ ==>_==_) _+_;
 ring_mult_comp: Proper (_==_ ==> _==_ ==>_==_) _*_;
 ring_sub_comp: Proper (_==_ ==> _==_ ==>_==_) _-_;
 ring_opp_comp: Proper (_==_==>_==_) -_;
 ring_add_0_l    : forall x, 0 + x == x;
 ring_add_comm   : forall x y, x + y == y + x;
 ring_add_assoc  : forall x y z, x + (y + z) == (x + y) + z;
 ring_mul_1_l    : forall x, 1 * x == x;
 ring_mul_1_r    : forall x, x * 1 == x;
 ring_mul_assoc  : forall x y z, x * (y * z) == (x * y) * z;
 ring_distr_l    : forall x y z, (x + y) * z == x * z + y * z;
 ring_distr_r    : forall x y z, z * ( x + y) == z * x + z * y;
 ring_sub_def    : forall x y, x - y == x + -y;
 ring_opp_def    : forall x, x + -x == 0
}.Fixpoint pow_pos (x:R) (i:positive) {struct i}: R :=
  match i with
  | xH => x
  | xO i => let p := pow_pos x i in p * p
  | xI i => let p := pow_pos x i in x * (p * p)
  end.Definition pow_N (x:R) (p:N) :=
  match p with
  | N0 => 1
  | Npos p => pow_pos x p
  end.Definition ZN(x:Z):=
  match x with
    Z0 => N0
    |Zpos p | Zneg p => Npos p
end.#[global]
Instance power_ring {R:Type}`{Ring R} : Power:=
  {power x y := pow_N x (ZN y)}.(** Interpretation morphisms definition*)

Class Ring_morphism (C R:Type)`{Cr:Ring C} `{Rr:Ring R}`{Rh:Bracket C R}:= {
    ring_morphism0    : [0] == 0;
    ring_morphism1    : [1] == 1;
    ring_morphism_add : forall x y, [x + y] == [x] + [y];
    ring_morphism_sub : forall x y, [x - y] == [x] - [y];
    ring_morphism_mul : forall x y, [x * y] == [x] * [y];
    ring_morphism_opp : forall  x, [-x] == -[x];
    ring_morphism_eq  : forall x y, x == y -> [x] == [y]}.(** Interpretation morphisms definition*)

Class Ring_morphism (C R:Type)`{Cr:Ring C} `{Rr:Ring R}`{Rh:Bracket C R}:= {
    ring_morphism0    : [0] == 0;
    ring_morphism1    : [1] == 1;
    ring_morphism_add : forall x y, [x + y] == [x] + [y];
    ring_morphism_sub : forall x y, [x - y] == [x] - [y];
    ring_morphism_mul : forall x y, [x * y] == [x] * [y];
    ring_morphism_opp : forall  x, [-x] == -[x];
    ring_morphism_eq  : forall x y, x == y -> [x] == [y]}.(** Interpretation morphisms definition*)

Class Ring_morphism (C R:Type)`{Cr:Ring C} `{Rr:Ring R}`{Rh:Bracket C R}:= {
    ring_morphism0    : [0] == 0;
    ring_morphism1    : [1] == 1;
    ring_morphism_add : forall x y, [x + y] == [x] + [y];
    ring_morphism_sub : forall x y, [x - y] == [x] - [y];
    ring_morphism_mul : forall x y, [x * y] == [x] * [y];
    ring_morphism_opp : forall  x, [-x] == -[x];
    ring_morphism_eq  : forall x y, x == y -> [x] == [y]}.(** Interpretation morphisms definition*)

Class Ring_morphism (C R:Type)`{Cr:Ring C} `{Rr:Ring R}`{Rh:Bracket C R}:= {
    ring_morphism0    : [0] == 0;
    ring_morphism1    : [1] == 1;
    ring_morphism_add : forall x y, [x + y] == [x] + [y];
    ring_morphism_sub : forall x y, [x - y] == [x] - [y];
    ring_morphism_mul : forall x y, [x * y] == [x] * [y];
    ring_morphism_opp : forall  x, [-x] == -[x];
    ring_morphism_eq  : forall x y, x == y -> [x] == [y]}.(** Interpretation morphisms definition*)

Class Ring_morphism (C R:Type)`{Cr:Ring C} `{Rr:Ring R}`{Rh:Bracket C R}:= {
    ring_morphism0    : [0] == 0;
    ring_morphism1    : [1] == 1;
    ring_morphism_add : forall x y, [x + y] == [x] + [y];
    ring_morphism_sub : forall x y, [x - y] == [x] - [y];
    ring_morphism_mul : forall x y, [x * y] == [x] * [y];
    ring_morphism_opp : forall  x, [-x] == -[x];
    ring_morphism_eq  : forall x y, x == y -> [x] == [y]}.(** Interpretation morphisms definition*)

Class Ring_morphism (C R:Type)`{Cr:Ring C} `{Rr:Ring R}`{Rh:Bracket C R}:= {
    ring_morphism0    : [0] == 0;
    ring_morphism1    : [1] == 1;
    ring_morphism_add : forall x y, [x + y] == [x] + [y];
    ring_morphism_sub : forall x y, [x - y] == [x] - [y];
    ring_morphism_mul : forall x y, [x * y] == [x] * [y];
    ring_morphism_opp : forall  x, [-x] == -[x];
    ring_morphism_eq  : forall x y, x == y -> [x] == [y]}.(** Interpretation morphisms definition*)

Class Ring_morphism (C R:Type)`{Cr:Ring C} `{Rr:Ring R}`{Rh:Bracket C R}:= {
    ring_morphism0    : [0] == 0;
    ring_morphism1    : [1] == 1;
    ring_morphism_add : forall x y, [x + y] == [x] + [y];
    ring_morphism_sub : forall x y, [x - y] == [x] - [y];
    ring_morphism_mul : forall x y, [x * y] == [x] * [y];
    ring_morphism_opp : forall  x, [-x] == -[x];
    ring_morphism_eq  : forall x y, x == y -> [x] == [y]}.(** Interpretation morphisms definition*)

Class Ring_morphism (C R:Type)`{Cr:Ring C} `{Rr:Ring R}`{Rh:Bracket C R}:= {
    ring_morphism0    : [0] == 0;
    ring_morphism1    : [1] == 1;
    ring_morphism_add : forall x y, [x + y] == [x] + [y];
    ring_morphism_sub : forall x y, [x - y] == [x] - [y];
    ring_morphism_mul : forall x y, [x * y] == [x] * [y];
    ring_morphism_opp : forall  x, [-x] == -[x];
    ring_morphism_eq  : forall x y, x == y -> [x] == [y]}.

(* Specifications: *)
Lemma pow_pos_comm : forall x j, x * pow_pos x j == pow_pos x j * x.
Lemma pow_pos_succ : forall x j, pow_pos x (Pos.succ j) == x * pow_pos x j.
Lemma pow_pos_add : forall x i j, pow_pos x (i + j) == pow_pos x i * pow_pos x j.