let join =
let symetric_merge =
M.symetric_merge
~cache:("map_Lattice",8192) ~decide_none ~decide_some
in
fun m1 m2 ->
if m1 == m2 then m1 else
let result =
match m1, m2 with
| Top(x1,a1), Top(x2,a2) ->
Top(Top_Param.join x1 x2, Origin.join a1 a2)
| Top (Top_Param.Top,_) as x, Map _
| Map _, (Top (Top_Param.Top,_) as x) ->
x
| Top (Top_Param.Set t,a), Map m | Map m, Top (Top_Param.Set t,a) ->
inject_top_origin a
(M.fold
(fun k _ acc -> Top_Param.O.add k acc)
m
t)
| Map mm1, Map mm2 ->
let result = Map (symetric_merge mm1 mm2) in
assert (
let n = succ !check_join_assert in
check_join_assert := n;
n land 63 <> 0 ||
(let merge_key k v acc =
M.add k (V.join v (find_or_bottom k mm2)) acc
in
let r2 = Map (M.fold merge_key mm1 mm2) in
if equal result r2 then
true
else begin
Format.printf "Map_Lattice.join incorrect %a (%d;%x) %a (%d;%x) -> %a (%d;%x) %a (%d;%x)@."
pretty m1 (hash m1) (Extlib.address_of_value m1)
pretty m2 (hash m2) (Extlib.address_of_value m2)
pretty result (hash result) (Extlib.address_of_value result)
pretty r2 (hash r2) (Extlib.address_of_value r2);
false;
end));
result
in
result