Definition zprimitive p := map_poly (divz^~ (zcontents p)) p.

(* Specifications: *)
Lemma zpolyEprim p : p = zcontents p *: zprimitive p.
Lemma zprimitive_eq0 p : (zprimitive p == 0) = (p == 0).
Lemma size_zprimitive p : size (zprimitive p) = size p.
Lemma sgz_lead_primitive p : sgz (lead_coef (zprimitive p)) = (p != 0).
Lemma zcontents_primitive p : zcontents (zprimitive p) = (p != 0).
Lemma zprimitive_id p : zprimitive (zprimitive p) = zprimitive p.
Lemma zprimitive_monic p : p \in monic -> zprimitive p = p.
Lemma zprimitive_min p a q :
p != 0 -> p = a *: q ->
{b | sgz b = sgz (lead_coef q) & q = b *: zprimitive p}.
Lemma zprimitive_irr p a q :
p != 0 -> zprimitive p = a *: q -> a = sgz (lead_coef q).
Lemma zcontentsM p q : zcontents (p * q) = zcontents p * zcontents q.
Lemma zprimitiveM p q : zprimitive (p * q) = zprimitive p * zprimitive q.
Lemma dvdpP_int p q : p %| q -> {r | q = zprimitive p * r}.
Local Notation pZtoQ := (map_poly (intr : int -> rat)).
Lemma size_rat_int_poly p : size (pZtoQ p) = size p.
Lemma dvdp_rat_int p q : (pZtoQ p %| pZtoQ q) = (p %| q).
Lemma dvdpP_rat_int p q :
p %| pZtoQ q ->
{p1 : {poly int} & {a | a != 0 & p = a *: pZtoQ p1} & {r | q = p1 * r}}.