Section ParamsProp.
Variable p: fparams.
Open Scope field_scope.
(* Properties associated with a params *)
Structure fparamsProp: Type := {
eqK_dec: forall x y: p, if x ?= y then x = y else x <> y;
(* Boolean equality *)
addK_assoc: forall x y z: p, (x + y) + z = x + (y + z);
(* Associativity for + *)
addK_com: forall x y: p, x + y = y + x;
(* Commutativity for + *)
addK0l: forall x: p, 0 + x = x;
(* Left neutral  for + *)
oppKr: forall x: p, x + - x = 0;
(* Right opposite  for + *)
multK_assoc: forall x y z: p, (x * y) * z = x * (y * z);
(* Associativity for * *)
multK_com: forall x y: p, x * y = y * x;
(* Commutativity for * *)
multK1l: forall x: p, 1 * x = x;
(* Left neutral element for * *)
add_multKl: forall x y z: p, (x + y) * z = x * z + y * z;
(* Left distributivity of + over * *)
one_diff_zero: 1 <> 0 :> p;
(* Inverse *)
invKl: forall x: p, x <> 0 -> x * x^-1 = 1
}.
Fixpoint expK  (k: p) (n:nat) {struct n}: p :=
match n with O => 1 | (S n1) => k * expK k n1 end.
Notation "x ^ k" := (expK x k) : field_scope.
(* Derived properties  *)
Variable Hp: fparamsProp.
Implicit Types x y z: p.
Fixpoint n_to_K n :=
match n with O => 0: p | S n => (1 + n_to_K n) end.
Definition Z_to_K (z: Z) :=
match z with
| Z0 => 0
| Zpos _ => n_to_K (Z.abs_nat z)
| Zneg _ => - (n_to_K (Z.abs_nat z))
end.

Lemma Z_to_K_mult (z1 z2: Z):
Z_to_K (z1 * z2)%Z = Z_to_K z1 * Z_to_K z2.