let add ((d1,z1) as dpd) k z =
let d = Dpd.add d1 k in
let z = match z1, z with
| None, _ -> z1
| _, None -> z
| Some zz1, Some zz2 ->
(* we are losing some precision here because for instance :
* (zz1, addr) + (zz2, data) = (zz1 U zz2, data+addr) *)
let zz = Locations.Zone.join zz1 zz2 in
match zz with
| Locations.Zone.Top(_p, _o) -> None
| _ -> (* To share values as much as possible *)
if (zz == zz1) then z1
else if (zz == zz2) then z
else Some zz
in if (d == d1) && (z == z1) then dpd else d, z