let rec define_update obj pool name path xs mem loc tr r =
match tr with
| C_array arr ->
let xi = F.fresh pool "i" (Model Formula.Integer) in
let te = Ctypes.object_of arr.arr_element in
let mem' = M.store_mem mem tr loc (M.value_of_logic tr r) in
let loc' = M.index loc te (F.var xi) in
let ve = 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 ve v')) in
let name' = Pretty_utils.sfprintf "%s_idx" name in
let path' = Pretty_utils.sfprintf "%s[%a]" path F.pp_var xi in
add_axiom obj (D.Arrayinfo.location arr) name' path' prop ;
define_update obj pool name' path' xs' mem' loc' te ve
| C_comp comp ->
List.iter
(fun f ->
let te = Ctypes.object_of f.ftype in
let mem' = M.store_mem mem tr loc (M.value_of_logic tr r) in
let loc' = M.field loc f in
let ve = 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 ve 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_update obj pool name' path' xs mem loc' te ve
) comp.cfields
| _ -> ()