Section GaussIntegers.
(** First we define a predicate for the algebraic numbers which are gauss integers. *)
Definition gaussInteger := [qualify a x | ('Re x \in Cint) && ('Im x \in Cint)].
(**  There follows the boilerplate to use the proof GI_subring in order to canonically provide a subring structure to the predicate gaussInteger.  *)
Fact GI_key : pred_key gaussInteger. Proof. by []. Qed.
Canonical GI_keyed := KeyedQualifier GI_key.
Canonical GI_opprPred := OpprPred GI_subring.
Canonical GI_addrPred := AddrPred GI_subring.
Canonical GI_mulrPred := MulrPred GI_subring.
Canonical GI_zmodPred := ZmodPred GI_subring.
Canonical GI_semiringPred := SemiringPred GI_subring.
Canonical GI_smulrPred := SmulrPred GI_subring.
Canonical GI_subringPred := SubringPred GI_subring.
(**  Finally, we define the type of Gauss Integer, as a sigma type of algebraic numbers. We soon prove that this is in fact a sub type.  *)
Record GI := GIof {
algGI : algC;
algGIP : algGI \is a gaussInteger }.
(** We make the defining property of GI a Hint *)
Hint Resolve algGIP : core.
(**  We provide the subtype property.  - This makes it possible to use the generic operator "val" to get an algC from a Gauss Integer.  *)
Canonical GI_subType := [subType for algGI].

(** We deduce that the real and imaginary parts of a GI are integers *)
Lemma GIRe (x : GI) : 'Re (val x) \in Cint.