let rec make (d, lo, hi) =
let lower (alpha, q) =
match d with
| Dom.Int when not(alpha && Q.is_integer q) ->
(true, Q.of_z(Q.floor(Q.add q Q.one)))
| _ ->
(alpha, q)
and upper (p, beta) =
match d with
| Dom.Int when not(beta && Q.is_integer p) ->
(Q.of_z(Q.ceil(Q.sub p Q.one)), true)
| _ ->
(p, beta)
in
match lo, hi with
| None, None ->
mk_dom d
| None, Some(p, beta) ->
let (p', beta') = upper (p, beta) in
{ dom = d; lo = None; hi = Some(p', beta') }
| Some(alpha, q), None ->
let (alpha', q') = lower (alpha, q) in
{ dom = d; lo = Some(alpha', q'); hi = None }
| Some(alpha, q), Some(p, beta) ->
let (alpha', q') = lower (alpha, q)
and (p', beta') = upper (p, beta) in
if alpha' && beta' && Q.gt q' p' then
mk_empty
else if not(alpha' && beta') && Q.ge q' p' then
mk_empty
else
{ dom = d; lo = Some(alpha', q'); hi = Some(p', beta') }