Set Bullet Behavior "Strict Subproofs".
Instance CompSpecs : compspecs. make_compspecs prog. Defined.
Definition Vprog : varspecs. mk_varspecs prog. Defined.
Definition release2_spec := DECLARE _release2 release2_spec.
Definition freelock2_spec := DECLARE _freelock2 (freelock2_spec _).
Definition spawn_spec := DECLARE _spawn spawn_spec.
Definition integer_hash_spec :=
DECLARE _integer_hash
WITH i : Z
PRE [ _i OF tint ]
PROP () LOCAL (temp _i (vint i)) SEP ()
POST [ tint ]
PROP () LOCAL (temp ret_temp (vint (i * 654435761))) SEP ().
(* One might think it should just return an unknown number, but in fact it needs to follow a known hash function at the logic level to be useful. *)
Definition tentry := Tstruct _entry noattr.
Instance hf1 : hash_fun := { size := 16384; hash i := (i * 654435761) mod 16384 }.
Opaque upto.
Ltac cancel_for_forward_call ::= repeat (rewrite ?sepcon_andp_prop', ?sepcon_andp_prop);
repeat (apply andp_right; [auto; apply prop_right; auto|]); fast_cancel.
Ltac entailer_for_return ::= go_lower; entailer'.

Lemma update_entries_hist : forall sh entries ghosts h i hk hv pki pvi gki gvi
(Hlen : Zlength entries = Zlength h) (Hleng : Zlength ghosts = Zlength entries)
(Hpi : Znth i entries (Vundef, Vundef) = (pki, pvi)) (Hgi : Znth i ghosts (Vundef, Vundef) = (gki, gvi))
(Hi : 0 <= i < Zlength entries),
atomic_entries sh entries ghosts (upd_Znth i h (hk, hv)) =
fold_right sepcon emp (upd_Znth i (map (fun x => let '((pk, pv), (gk, gv), (hk, hv)) := x in
atomic_loc_hist sh pk gk 0 k_R hk * atomic_loc_hist sh pv gv 0 v_R hv) (combine (combine entries ghosts) h))
(atomic_loc_hist sh pki gki 0 k_R hk * atomic_loc_hist sh pvi gvi 0 v_R hv)).