End UnitRingPseudoDivision.
End UnitRing.
Module IdomainDefs.
Section IDomainPseudoDivisionDefs.
Variable R : idomainType.
Implicit Type p q r d : {poly R}.
Definition edivp_expanded_def p q :=
let: (k, d, r) as edvpq := redivp p q in
if lead_coef q \in GRing.unit then
(0%N, (lead_coef q)^-k *: d, (lead_coef q)^-k *: r)
else edvpq.
Fact edivp_key : unit. Proof. by []. Qed.
Definition edivp := locked_with edivp_key edivp_expanded_def.
Canonical edivp_unlockable := [unlockable fun edivp].
Definition divp p q := ((edivp p q).1).2.
Definition modp p q := (edivp p q).2.
Definition scalp p q := ((edivp p q).1).1.
Definition dvdp p q := modp q p == 0.
Definition eqp p q :=  (dvdp p q) && (dvdp q p).
End IDomainPseudoDivisionDefs.
Notation "m %/ d" := (divp m d) : ring_scope.
Notation "m %% d" := (modp m d) : ring_scope.
Notation "p %| q" := (dvdp p q) : ring_scope.
Notation "p %= q" := (eqp p q) : ring_scope.
End IdomainDefs.
Module WeakIdomain.
Section WeakTheoryForIDomainPseudoDivision.
Variable R : idomainType.
Implicit Type p q r d : {poly R}.

(* Specifications: *)
Lemma edivp_def p q : edivp p q = (scalp p q, divp p q, modp p q).
Lemma modpE p q :
p %% q = if lead_coef q \in GRing.unit
then (lead_coef q)^-(rscalp p q) *: (rmodp p q)
else rmodp p q.
Lemma scalpE p q :
scalp p q = if lead_coef q \in GRing.unit then 0%N else rscalp p q.
Lemma dvdpE p q : p %| q = rdvdp p q.
Lemma lc_expn_scalp_neq0 p q : lead_coef q ^+ scalp p q != 0.
Hint Resolve lc_expn_scalp_neq0 : core.