let rec isolate y ((a, b) as e) =
assert(Term.subterm y (mk_sub a b));
if Term.is_var a then
if Term.eq y a then
if Term.subterm y b then
isolate_in_unsolved y e
else
e
else
if Term.subterm y b then
isolate_in_unsolved y e
else
isolate_in_solved y e
else
isolate_in_unsolved y e
and isolate_in_solved y (x, a) =
assert (Term.subterm y a && not(Term.subterm x a));
let (p, pre, q, y, post) = destructure y a in
assert(not(Q.is_zero q));
let b = mk_multq (Q.inv q) (mk_sub x (mk_addq p (mk_addl (pre @ post)))) in
(y, b)
and isolate_in_unsolved x ((a, b) as e) =
assert(Term.subterm x a || Term.subterm x b);
let a_sub_b = mk_sub a b in
assert(not(is_num a_sub_b));
let (p, pre, q, x, post) = destructure x a_sub_b in
assert(not(Q.is_zero q));
let c = mk_multq (Q.minus (Q.inv q))
(mk_addq p (mk_addl (pre @ post)))
in
(x, c)
and destructure y a =
let rec loop pre post =
match post with
| [m] ->
let q = coefficient_of_mono m
and y' = variable_of_mono m in
if Term.eq y y' then
(pre, q, y, [])
else
raise Not_found
| m :: post' ->
let q = coefficient_of_mono m
and y' = variable_of_mono m in
if Term.eq y y' then
(pre, q, y, post')
else
loop (m :: pre) post'
| [] ->
raise Not_found
in
let p = constant_of a
and ml = nonconstant_monomials_of a in
let (pre, q, y, post) = loop [] ml in
(p, pre, q, y, post)