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'.
Hint Resolve k_R_precise v_R_precise.
Opaque size.
Opaque Znth.
Hint Resolve wf_empty.
Hint Resolve f_pred_precise f_pred_positive.
Fixpoint join_hists (h1 h2 : list (hist * hist)) :=
match (h1, h2) with
| ((k1, v1) :: rest1, (k2, v2) :: rest2) => (k1 ++ k2, v1 ++ v2) :: join_hists rest1 rest2
| _ => []
end.
Definition hists_mono (h1 h2 : list (hist * hist)) := Forall2 (fun a b =>
(exists l, fst b = fst a ++ l) /\ (exists l, snd b = snd a ++ l)) h1 h2.
Instance hists_mono_refl : RelationClasses.Reflexive hists_mono.
Hint Resolve hists_mono_refl.
Instance hists_mono_trans : RelationClasses.Transitive hists_mono.
Transparent Znth.
Opaque combine.

(* It would be nice if we could maintain the invariant that the map has no duplicates and is well-chained, and indeed, the algorithm should maintain these properties. However, the per-slot histories do not obviously present a way to prove this: if a new key has "mysteriously appeared" (i.e., been added by another thread), we don't have a good way of knowing that it's well-chained. *)
(* We can, however, allow for the possibility that there is garbage in the map, and consider the abstract map to be those elements that can be successfully looked up, rather than all pairs in the map. In practice, this *should* come down to the same thing, but how could we prove it? *)
Lemma set_item_trace_map : forall h k v i h' (Hwf : wf_hists h) (Hlenh : Zlength h = size)
(Htrace : set_item_trace h k v i h') (Hk : k <> 0) (Hrepk : repable_signed k) (Hrepv : repable_signed v),
wf_hists h' /\ let m' := make_map (upd_Znth i h' (Znth i h ([], []))) in
map_incl (make_map h) m' /\ set m' k v = Some (make_map h').