let rec define_access obj pool name path xs mem loc tr =
match tr with
| C_array arr ->
let te = Ctypes.object_of arr.arr_element in
let xi = F.fresh pool "i" (Model Formula.Integer) in
let loc' = M.index loc te (F.var xi) in
let r = M.logic_of_value (M.load_mem mem tr loc) in
let v = D.acc_index (F.unwrap r) (F.var xi) in
let v' = M.logic_of_value (M.load_mem mem te loc') in
let xs' = xs @ [xi] in
let prop =
F.p_forall xs'
(F.p_implies (in_range arr (F.var xi)) (D.equal te v v'))
in
let name' = Pretty_utils.sfprintf "%s_idx" name in
let path' = Pretty_utils.sfprintf "%s[%a]" path F.pp_term (F.var xi) in
add_axiom obj (D.Arrayinfo.location arr) name' path' prop ;
define_access obj pool name' path' xs' mem loc' te
| C_comp comp ->
List.iter
(fun f ->
let te = Ctypes.object_of f.ftype in
let loc' = M.field loc f in
let r = M.logic_of_value (M.load_mem mem tr loc) in
let v = D.acc_field (F.unwrap r) f in
let v' = M.logic_of_value (M.load_mem mem te loc') in
let prop = F.p_forall xs (D.equal te v v') in
let name' = Format.sprintf "%s_%s" name f.fname in
let path' = Format.sprintf "%s.%s" name f.fname in
add_axiom obj (D.Compinfo.location comp) name' path' prop ;
define_access obj pool name' path' xs mem loc' te
) comp.cfields
| _ -> ()