Hint Resolve object_methods_local_facts : saturate_local.
Definition object_mpred (history: list Z) (self: val) : mpred :=
EX instance: object_invariant, EX mtable: val,
(object_methods instance mtable *
field_at Ews (Tstruct _object noattr) [StructField _mtable] mtable self*
instance history self).
Definition foo_invariant : object_invariant :=
(fun (history: list Z) p =>
withspacer Ews (sizeof size_t + sizeof tint) (2 * sizeof size_t) (field_at Ews (Tstruct _foo_object noattr)
[StructField _data] (Vint (Int.repr (2*fold_right Z.add 0 history)))) p
*  malloc_token Ews (Tstruct _foo_object noattr) p).
Definition foo_reset_spec :=
DECLARE _foo_reset (reset_spec foo_invariant).
Definition foo_twiddle_spec :=
DECLARE _foo_twiddle  (twiddle_spec foo_invariant).
Definition make_foo_spec :=
DECLARE _make_foo
WITH gv: globals
PRE [ ]
PROP () LOCAL (gvars gv)
SEP (mem_mgr gv; object_methods foo_invariant (gv _foo_methods))
POST [ tobject ]
EX p: val, PROP () LOCAL (temp ret_temp p)
SEP (mem_mgr gv; object_mpred nil p; object_methods foo_invariant (gv _foo_methods)).
Definition main_spec :=
DECLARE _main
WITH gv: globals
PRE  [] main_pre prog nil gv
POST [ tint ]
EX i:Z, PROP(0<=i<=6) LOCAL (temp ret_temp (Vint (Int.repr i))) SEP(TT).
Definition Gprog : funspecs :=   ltac:(with_library prog [
foo_reset_spec; foo_twiddle_spec; make_foo_spec; main_spec]).

(* Specifications: *)
Lemma object_mpred_i:
forall (history: list Z) (self: val) (instance: object_invariant) (mtable: val),
object_methods instance mtable *
field_at Ews (Tstruct _object noattr) [StructField _mtable] mtable self *
instance history self
|-- object_mpred history self.
Lemma body_foo_reset: semax_body Vprog Gprog f_foo_reset foo_reset_spec.
Lemma body_foo_twiddle: semax_body Vprog Gprog f_foo_twiddle foo_twiddle_spec.
Lemma split_object_methods:
forall instance m,
object_methods instance m |-- object_methods instance m * object_methods instance m.
Lemma body_make_foo: semax_body Vprog Gprog f_make_foo make_foo_spec.
Lemma make_object_methods:
forall sh instance reset twiddle mtable,
readable_share sh ->
func_ptr' (reset_spec instance) reset *
func_ptr' (twiddle_spec instance) twiddle *
data_at sh (Tstruct _methods noattr) (reset, twiddle) mtable
|-- object_methods instance mtable.