let rec qsolve ((a, b) as e) =
  let a_sub_b = mk_sub a b in
  let p = constant_of a_sub_b
  and ml = nonconstant_monomials_of a_sub_b in
    match ml with
      | [] -> 
          raise (if Q.is_zero p then Exc.Valid else Exc.Inconsistent)
      | [m] ->                             (* [p + q * x = 0] *)
          let q = coefficient_of_mono m
          and x = variable_of_mono m in
            (x, mk_num (Q.div (Q.minus p) q))
      | [m1; m2] ->                        (* [p + q1 * x1 + m2 = 0] *)
          let q1 = coefficient_of_mono m1
          and x1 = variable_of_mono m1 in
            (x1, mk_addq (Q.div (Q.minus p) q1) (mk_multq (Q.minus (Q.inv q1)) m2))
      | m :: ml ->                         (* [p + q * x + ml = 0] *)
          let q = coefficient_of_mono m
          and x = variable_of_mono m in   
          let b = mk_addq (Q.minus (Q.div p q))
                    (mk_multq (Q.minus (Q.inv q))
                       (mk_addl ml))
          in
            if Term.is_var b then
              Term.orient (x, b)
            else 
              (x, b)