let mult i j =
if is_empty i || is_empty j then
mk_empty
else
match d_singleton i, d_singleton j with
| Some(q), Some(p) ->
mk_singleton (Q.mult q p)
| Some(q), None ->
multq q j
| None, Some(p) ->
multq p i
| None, None ->
let d = Dom.union i.dom j.dom in
let (lo, hi) =
match i.lo, i.hi, j.lo, j.hi with
| None, None, _, _ ->
(None, None)
| _, _, None, None ->
(None, None)
| None, Some(q, alpha), None, Some(p, beta) ->
if Q.le q Q.zero && Q.le p Q.zero then
(Some(alpha && beta, Q.mult q p), None)
else
(None, None)
| Some(alpha1,q1), None, Some(alpha2,q2), None ->
if Q.ge q1 Q.zero && Q.ge q2 Q.zero then
(Some(alpha1 && alpha2, Q.mult q1 q2), None)
else
(None, None)
| None, Some(p, beta), Some(alpha, q), None ->
if Q.le p Q.zero && Q.le Q.zero p then
(None, Some(Q.mult q p, alpha && beta))
else
(None, None)
| Some(alpha, q), None, None, Some(p, beta) ->
if Q.le p Q.zero && Q.le Q.zero p then
(None, Some(Q.mult q p, alpha && beta))
else
(None, None)
| Some(alpha1, q1), Some(p1, beta1), Some(alpha2, q2), Some(p2, beta2) ->
(None, None)
| _ ->
(None, None)
in
make (d, lo, hi)