Instance v_prot g : protocol (v_T Share.bot g) (v_T gsh2 g).Notation v_T' g := (v_T Share.bot g, v_T gsh2 g).Notation v_state i lg l s := (protocol_A l s map_incl (v_T' (Znth i lg))).(* We don't need histories for keys, but we do need to know that a non-zero key is persistent. *)
Definition zero_ord a b := a = 0 \/ a = b.Instance zero_RA : Ghost := { valid a := True;
  Join_G a b c := if eq_dec a 0 then c = b else a = c /\ zero_ord b c }.Instance zero_order : PCM_order zero_ord.Instance k_prot g : protocol (k_T Share.bot g) (k_T gsh2 g).Notation k_T' g := (k_T Share.bot g, k_T gsh2 g).Notation k_state i lg l s := (protocol_A l s zero_ord (k_T' (Znth i lg))).(* lookup doesn't really depend on the type of values. *)
Definition lookup' {B} (T : list (Z * B)) := lookup (combine (map fst T) (repeat 0 (Z.to_nat size))).Definition wf_table (T : list (Z * (Z -> option Z))) := forall k i, k <> 0 -> fst (Znth i T) = k ->
  lookup' T k = Some i.Definition hashtable_A T lgk lgv entries :=
  fold_right sepcon emp (map (hashtable_entry_A T lgk lgv entries) (upto (Z.to_nat size))).Definition HT_upd (H : Z -> option (Z -> option Z)) k v H' := exists lv, H' = map_upd H k lv /\ value_of lv v /\
  match H k with Some lv0 => map_incl lv0 lv | None => True end.Definition table_incl (T1 T2 : list (Z * (Z -> option Z))) := forall i,
  zero_ord (fst (Znth i T1)) (fst (Znth i T2)) /\
  map_incl (snd (Znth i T1)) (snd (Znth i T2)).Inductive hashtable_hist_el :=
  | HSet (k : Z) (v : Z) | HGet (k : Z) (v : Z) | HAdd (k : Z) (v : Z) (r : bool).Inductive hashtable_hist_el :=
  | HSet (k : Z) (v : Z) | HGet (k : Z) (v : Z) | HAdd (k : Z) (v : Z) (r : bool).Inductive hashtable_hist_el :=
  | HSet (k : Z) (v : Z) | HGet (k : Z) (v : Z) | HAdd (k : Z) (v : Z) (r : bool).Inductive hashtable_hist_el :=
  | HSet (k : Z) (v : Z) | HGet (k : Z) (v : Z) | HAdd (k : Z) (v : Z) (r : bool).Notation hist := (list (nat * hashtable_hist_el)).Definition f_lock_pred N tsh sh gsh entries gh g lgk lgv p t locksp lockt resultsp res :=
  selflock (f_lock_inv N sh gsh entries gh g lgk lgv p t locksp lockt resultsp res) tsh lockt.

(* Specifications: *)
Lemma body_integer_hash: semax_body Vprog Gprog f_integer_hash integer_hash_spec.
Lemma hashtable_entry_A_duplicable : forall T lgk lgv entries i, duplicable (hashtable_entry_A T lgk lgv entries i).
Lemma hashtable_A_duplicable : forall T lgk lgv entries, duplicable (hashtable_A T lgk lgv entries).
Lemma zero_ord_0 : forall z, zero_ord 0 z.
Lemma lookup'_succeeds : forall k i i1 (T : list (Z * (Z -> option Z))) (Hk : k <> 0) (Hi : 0 <= i < size) (Hi1 : (i + hash k) mod size = i1 mod size) (HT : Zlength T = size) (Hfail : Forall (fun x => fst x <> 0 /\ fst x <> k) (sublist 0 i (rebase T (hash k)))) (Hhit : fst (Znth (i1 mod size) T) = k \/ fst (Znth (i1 mod size) T) = 0), lookup' T k = Some (i1 mod size).
Lemma wf_table_upd : forall T k v i (Hwf : wf_table T) (HT : Zlength T = size) (Hi : lookup' T k = Some i) (Hk : k <> 0), wf_table (upd_Znth i T (k, v)).