Section OrdinalGI.
Variable n : nat.
Inductive ordinalGI : predArgType := OrdinalGI x of ('N x < n)%N.
Coercion GI_of_ord i := let: OrdinalGI m _ := i in m.
Canonical ordinalGI_subType := [subType for GI_of_ord].
Definition ordinalGI_eqMixin := Eval hnf in [eqMixin of ordinalGI by <:].
Canonical ordinalGI_eqType := Eval hnf in EqType ordinalGI ordinalGI_eqMixin.
Definition ordinalGI_choiceMixin := [choiceMixin of ordinalGI by <:].
Canonical ordinalGI_choiceType :=
Eval hnf in ChoiceType ordinalGI ordinalGI_choiceMixin.
Definition ordinalGI_countMixin := [countMixin of ordinalGI by <:].
Canonical ordinalGI_countType :=
Eval hnf in CountType ordinalGI ordinalGI_countMixin.
Canonical ordinalGI_subCountType := [subCountType of ordinalGI].
Fact int_norm_nat x y m :
x \in Cint ->  y \in Cint ->
`|x| ^+ 2 + `|y| ^+ 2 < m%:R -> (x + m%:R \in Cnat) && (x + m%:R < m.*2%:R).
Definition ordinalGI_finMixin :=
Eval hnf in UniqFinMixin ordGI_enum_uniq mem_ordGI_enum.
Canonical ordinalGI_finType := Eval hnf in FinType ordinalGI ordinalGI_finMixin.
Canonical ordinalGI_subFinType := Eval hnf in [subFinType of ordinalGI].
End OrdinalGI.
Definition primeGI (x : GI) :=
(1 < 'N x)%N && [forall y : ordinalGI ('N x), (y %| x) ==> ('N y == 1%N)].
Definition primesGI (x : GI) :=
[seq i <- [seq GI_of_ord i| i : ordinalGI ('N x).+1] |
primeGI i && (i %| x)].
Definition pdivGI x : GI := head 1 (primesGI x).
Fixpoint logGI_rec p x n :=
if (p %| x) then
if n is n1.+1 then (logGI_rec p (x %/ p) n1).+1 else 0%N
else 0%N.
Definition logGI p x :=
if primeGI p then logGI_rec p x ('N x) else 0%N.
Definition coprimeGI (x y : GI) := 'N(gcdGI x y) == 1%N.

Lemma gcdGI_mull_equiv (m n p q : GI) :
coprimeGI m n -> m * n  = p * q -> m %= gcdGI m p * gcdGI m q.