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)