let rec define_update obj pool name path xs mem loc tr r =
      match tr with

        | C_array arr ->
            let xi = F.p_fresh pool "i" (Model Formula.Integerin
            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   = F.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)) (M.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 (F.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   = F.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 (M.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 (F.Compinfo.location comp) name' path' prop ;
                 define_update obj pool name' path' xs mem loc' te ve
              ) comp.cfields

        | _ -> ()