Hint Resolve f_pred_precise f_pred_positive.

(* Specifications: *)
Lemma body_f : semax_body Vprog Gprog f_f f_spec.
Lemma lock_struct : forall p, data_at_ Tsh (Tstruct _lock_t noattr) p |-- data_at_ Tsh tlock p.
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.
Lemma join_hists_spec : forall h1 h2 i, Zlength h1 = Zlength h2 ->
Znth i (join_hists h1 h2) ([], []) =
(fst (Znth i h1 ([], [])) ++ fst (Znth i h2 ([], [])),
(snd (Znth i h1 ([], [])) ++ snd (Znth i h2 ([], [])))).
Lemma join_empty : forall h, Zlength h = size -> join_hists empty_hists h = h.
Lemma atomic_entries_join : forall sh1 sh2 sh entries ghosts hists1 hists2 hists
(Hjoin : sepalg.join sh1 sh2 sh) (Hhists : join_hists hists1 hists2 = hists)
(Hghosts : Zlength ghosts = Zlength entries)
(Hlen : Zlength entries = Zlength hists1) (Hlen1 : Zlength hists1 = Zlength hists2)
(Hsh1 : readable_share sh1) (Hsh2 : readable_share sh2),
atomic_entries sh1 entries ghosts hists1 * atomic_entries sh2 entries ghosts hists2 =
!!(forall i, disjoint (fst (Znth i hists1 ([], []))) (fst (Znth i hists2 ([], []))) /\
disjoint (snd (Znth i hists1 ([], []))) (snd (Znth i hists2 ([], [])))) &&
atomic_entries sh entries ghosts hists.
Corollary atomic_entries_join_nil : forall sh1 sh2 sh entries ghosts
(Hjoin : sepalg.join sh1 sh2 sh) (Hlen : Zlength entries = size) (Hleng : Zlength ghosts = size)
(Hsh1 : readable_share sh1) (Hsh2 : readable_share sh2),
atomic_entries sh1 entries ghosts empty_hists * atomic_entries sh2 entries ghosts empty_hists =
atomic_entries sh entries ghosts empty_hists.
Lemma join_hists_length : forall h1 h2, Zlength h1 = Zlength h2 ->
Zlength (join_hists h1 h2) = Zlength h1.
Corollary fold_join_hists_length : forall lh h, Forall (fun h' => Zlength h' = Zlength h) lh ->
Zlength (fold_right join_hists h lh) = Zlength h.
Corollary join_hists_empty_length : forall lh, Forall (fun h => Zlength h = size) lh ->
Zlength (fold_right join_hists empty_hists lh) = size.
Lemma join_empty_r : forall h, Zlength h = size -> join_hists h empty_hists = h.
Lemma join_hists_assoc : forall a b c, join_hists a (join_hists b c) = join_hists (join_hists a b) c.
Lemma join_hists_base : forall l h, Zlength h = size ->
fold_right join_hists (join_hists h empty_hists) l = join_hists (fold_right join_hists empty_hists l) h.
Lemma add_rest_hists : forall k i h h' (Hrest : forall j,
(In j (indices (hash k) i) -> failed_CAS k (Znth j h ([], [])) (Znth j h' ([], []))) /\
(~ In j (indices (hash k) i) -> j <> i -> Znth j h' ([], []) = Znth j h ([], []))) j (Hj : j <> i),
exists rest, Znth j h' ([], []) = (fst (Znth j h ([], [])) ++ rest, snd (Znth j h ([], []))) /\
Forall (fun e => forall v, ~writes e v) (map snd rest).
Lemma key_hists_fail : forall h k v i h' j (Hfail : add_item_trace h k v i false h')
(Hk : k <> 0) (Hrep : repable_signed k),
exists rest, Znth j h' ([], []) = (fst (Znth j h ([], [])) ++ rest, snd (Znth j h ([], []))) /\
Forall (fun e => forall v, ~writes e v) (map snd rest).
Lemma add_item_trace_map : forall h k v i s h' (Hlenh : Zlength h = size)
(Htrace : add_item_trace h k v i s h') (Hk : k <> 0) (Hrepk : repable_signed k) (Hrepv : repable_signed v),
let m' := make_map (upd_Znth i h' (Znth i h ([], []))) in
map_incl (make_map h) m' /\ lookup m' k = Some i /\
if s then get (make_map h) k = None /\ make_map h' = upd_Znth i m' (k, v)
else make_map h' = upd_Znth i m' (k, make_int (value_of_hist (snd (Znth i h' ([], []))))).
Lemma join_empty_hists : forall h n, Zlength h = size -> fold_right join_hists h (repeat empty_hists n) = h.
Lemma Znth_join_hists : forall i lh (Hlen : Forall (fun h => Zlength h = size) lh),
Znth i (fold_right join_hists empty_hists lh) ([], []) =
(concat (map fst (map (fun h => Znth i h ([], [])) lh)),
concat (map snd (map (fun h => Znth i h ([], [])) lh))).
Lemma add_items_hist_length : forall h lr, Forall (fun '(la, h') => add_items_trace h la h') lr ->
Forall (fun h' => Zlength h' = Zlength h) (map snd lr).
Corollary add_items_empty_hist_length : forall lr,
Forall (fun '(la, h') => add_items_trace empty_hists la h') lr ->
Forall (fun h' => Zlength h' = size) (map snd lr).
Lemma apply_hist_app : forall h1 h2 H H', apply_hist H (h1 ++ h2) H' <->
exists H1, apply_hist H h1 H1 /\ apply_hist H1 h2 H'.
Lemma hashtable_A_forget : forall T lgk lgv entries, Forall (fun '(_, lv) => map_incl (singleton 0 0) lv) T ->
Zlength T = size ->
view_shift (hashtable_A T lgk lgv entries)
(hashtable_A (repeat (0, singleton 0 0) (Z.to_nat size)) lgk lgv entries).
Lemma body_f : semax_body Vprog Gprog f_f f_spec.
Lemma lock_struct : forall p, data_at_ Tsh (Tstruct _lock_t noattr) p |-- data_at_ Tsh tlock p.
Lemma add_fails : forall k v b l H H' (HH : apply_hist H l H') (Hadd : In (HAdd k v b) l)
(Hk : H k <> None), b = false.
Lemma only_one_add_succeeds : forall k v1 v2 l i1 i2 H0 H (HH : apply_hist H0 l H)
(Hin1 : Znth i1 l (HGet 0 0) = HAdd k v1 true) (Hin2 : Znth i2 l (HGet 0 0) = HAdd k v2 true),
i2 = i1 /\ v2 = v1.
Lemma one_add_succeeds : forall k v b l H0 H (HH : apply_hist H0 l H) (Hk : H0 k = None)
(Hin : In (HAdd k v b) l) (Hout : forall v, ~In (HSet k v) l), exists v', In (HAdd k v' true) l.
Lemma filter_find_count : forall {A} (f : A -> bool) d l li (Hunique : NoDup li)
(Hli : forall i, In i li -> f (Znth i l d) = true) (Hrest : forall i, ~In i li -> f (Znth i l d) = false),
Zlength (filter f l) = Zlength li.
Lemma hists_eq : forall lr (Hlr : Forall (fun '(h, ls) => add_events []
[HAdd 1 1 (Znth 0 ls false); HAdd 2 1 (Znth 1 ls false); HAdd 3 1 (Znth 2 ls false)] h) lr)
(Hlens : Forall (fun '(_, ls) => Zlength ls = 3) lr),
map snd lr = map (fun x => map (fun e => match snd e with | HAdd _ _ b => b | _ => false end) (fst x)) lr.
Lemma add_three : forall lr HT l (Hlr : Zlength lr = 3)
(Hhists : Forall (fun '(h, ls) => add_events [] [HAdd 1 1 (Znth 0 ls false); HAdd 2 1 (Znth 1 ls false);
HAdd 3 1 (Znth 2 ls false)] h) lr) (Hlens : Forall (fun '(_, ls) => Zlength ls = 3) lr)
(Hl : hist_list (concat (map fst lr)) l) (HHT : apply_hist empty_map l HT),
Zlength (filter id (concat (map snd lr))) = 3.
Lemma hashtable_A_join : forall lgk lgv entries,
hashtable_A (repeat (0, singleton 0 0) (Z.to_nat size)) lgk lgv entries * hashtable_A (repeat (0, singleton 0 0) (Z.to_nat size)) lgk lgv entries =
hashtable_A (repeat (0, singleton 0 0) (Z.to_nat size)) lgk lgv entries.
Lemma body_main : semax_body Vprog Gprog f_main main_spec.