let euclid_div_poly =
let rec
f = function
p1, p2 -> (* not (is_null_poly (p2)) *)
if is_null_poly (p1)
then (null_poly (), null_poly ())
else
let
d1 = degree (p1)
and
d2 = degree (p2)
in
if d1 < d2
then (null_poly (), p1)
else
let
a1 = leading_coef (p1)
and
a2 = leading_coef (p2)
in
(* not (eq_rat (a1, cons_rat (", ")))
& not (eq_rat (a2, cons_rat (", "))) *)
let
a = div_rat (a1, a2)
in
(* not (eq_rat (a, cons_rat (", "))) & d1 - d2 >= 0 *)
let
m = monomial (a, d1 - d2)
in
let
p = mult_poly (rat_times_poly (cons_rat ("-1", "1"), m), p2)
in
let
p1_1 = add_poly (p1, p)
in
let
(q, r) = f (p1_1, p2)
in
(add_poly (m, q), r)
in
function
p1, p2 -> if not (is_null_poly (p2))
then f (p1, p2)
else failwith ("euclid_div_poly : requires a non-null polynomial as its second argument")