Set Bullet Behavior "Strict Subproofs".
Instance CompSpecs : compspecs. make_compspecs prog. Defined.
Definition Vprog : varspecs. mk_varspecs prog. Defined.
Definition surely_malloc_spec :=
DECLARE _surely_malloc
WITH n:Z
PRE [ _n OF tuint ]
PROP (0 <= n <= Int.max_unsigned)
LOCAL (temp _n (Vint (Int.repr n)))
SEP ()
POST [ tptr tvoid ] EX p:_,
PROP ()
LOCAL (temp ret_temp p)
SEP (malloc_token Tsh n p * memory_block Tsh n p).
Definition tentry := Tstruct _entry noattr.
Definition entry_hists entries hists := fold_right_sepcon (map (fun i =>
let '(hp, e) := (Znth i hists ([], []), Znth i entries Vundef) in
ghost_hist (fst hp) (field_address tentry [StructField _key] e) *
ghost_hist (snd hp) (field_address tentry [StructField _value] e)) (upto 20)).
(* In this case, let map be an association list. *)
Fixpoint index_of (m : list (Z * Z)) (k : Z) :=
match m with
| [] => None
| (k1, v1) :: rest => if eq_dec k1 k then Some 0
else option_map Z.succ (index_of rest k)
end.
Definition set m k v :=
match index_of m k with
| Some i => upd_Znth i m (k, v)
| None => m ++ [(k, v)]
end.
Definition get m k := option_map (fun i => snd (Znth i m (0, 0))) (index_of m k).
Definition value_of e :=
match e with
| Load v => v
| Store v => v
| CAS r c w => if eq_dec r c then w else r
end.
Definition last_value (h : hist) v :=
(* initial condition *)
(h = [] /\ v = vint 0) \/
exists n e, In (n, e) h /\ value_of e = v /\ Forall (fun x => let '(m, _) := x in m <= n)%nat h.

Lemma last_value_new : forall h n e, Forall (fun x => fst x < n)%nat h ->
last_value (h ++ [(n, e)]) (value_of e).