let rec is_havoc pool x1 x2 = function
| Empty -> p_equal x1 x2
| Full -> p_true
| Field fs ->
List.fold_left
(fun w (f,r) ->
p_and w (is_havoc pool (e_getfield x1 f) (e_getfield x2 f) r))
p_true fs
| Index(ts,ks) ->
let xs = List.map (LogicLib.fresh pool) ts in
let vs = List.map e_var xs in
let a1_xs = access x1 vs in
let a2_xs = access x2 vs in
let all_diff_then_equal =
forall xs
(p_implies
(p_conj (List.map (fun (cond,_) -> p_not (cond vs)) ks))
(p_equal a1_xs a2_xs)) in
let only_once_then_region =
List.map
(fun (condition,region) ->
forall xs (p_implies condition (is_havoc pool a1_xs a2_xs region))
) (only_one_region vs ks) in
p_conj (all_diff_then_equal :: only_once_then_region)