Corollary prev_taken_In : forall h, prev_taken h = vint 1 \/ In (AE (prev_taken h) Empty) h.

(* Specifications: *)
Lemma write_val : forall h i v (Hh : apply_hist i (rev h) = Some v), v = Empty \/ v = fst (find_write h i).
Lemma find_write_read : forall i d h (Hread : apply_hist i (rev h) = Some Empty) (Hi : i <> Empty), fst (find_read h d) = fst (find_write h i).
Lemma take_read : forall h v, apply_hist (vint 0) (rev h) = Some v -> prev_taken h = if eq_dec v Empty then snd (last_two_reads h) else fst (last_two_reads h).
Lemma find_write_In : forall d h, fst (find_write h d) = d \/ exists r, In (AE r (fst (find_write h d))) h.
Lemma make_shares_app : forall i l1 l2 shs, Zlength l1 + Zlength l2 <= Zlength shs -> make_shares shs (l1 ++ l2) i = make_shares shs l1 i ++ make_shares (sublist (Zlength l1) (Zlength shs) shs) l2 i.
Lemma make_shares_ext : forall i l l' shs (Hlen : Zlength l = Zlength l') (Hi : forall j, 0 <= j < Zlength l -> Znth j l = i <-> Znth j l' = i), make_shares shs l i = make_shares shs l' i.
Lemma make_shares_minus : forall i lasts sh0 shs sh' sh1 (Hsh' : sepalg_list.list_join sh0 shs sh') (Hsh1 : sepalg_list.list_join sh0 (make_shares shs lasts i) sh1) (Hlen : Zlength shs = Zlength lasts), sepalg_list.list_join sh1 (make_shares_inv shs lasts i) sh'.
Lemma make_shares_add : forall i i' lasts j shs (Hj : 0 <= j < Zlength lasts) (Hi : Znth j lasts = i) (Hi' : i' <> i) (Hlen : Zlength shs >= Zlength lasts), exists shs1 shs2, make_shares shs lasts i = shs1 ++ shs2 /\ make_shares shs (upd_Znth j lasts i') i = shs1 ++ Znth j shs :: shs2.
Lemma make_shares_In : forall i lasts x shs (Hx : 0 <= x < Zlength lasts) (Hi : Znth x lasts <> i) (Hlen : Zlength shs >= Zlength lasts), In (Znth x shs) (make_shares shs lasts i).
Lemma make_shares_inv_In : forall i lasts x shs (Hx : 0 <= x < Zlength lasts) (Hi : Znth x lasts = i) (Hlen : Zlength shs >= Zlength lasts), In (Znth x shs) (make_shares_inv shs lasts i).
Lemma make_shares_sub : forall i lasts shs sh0 sh1 sh2 (Hlen : Zlength shs >= Zlength lasts) (Hsh1 : sepalg_list.list_join sh0 shs sh1) (Hsh2 : sepalg_list.list_join sh0 (make_shares shs lasts i) sh2), sepalg.join_sub sh2 sh1.
Lemma make_shares_join : forall i lasts shs sh0 j sh1 sh2 (Hlen : Zlength shs >= Zlength lasts) (Hsh1 : sepalg_list.list_join sh0 shs sh1) (Hsh2 : sepalg_list.list_join sh0 (make_shares shs lasts i) sh2) (Hin : 0 <= j < Zlength shs) (Hj : Znth j lasts = i), exists sh', sepalg.join sh2 (Znth j shs) sh'.
Lemma make_shares_join' : forall i lasts shs sh0 j sh1 sh2 (Hlen : Zlength shs >= Zlength lasts) (Hsh1 : sepalg_list.list_join sh0 shs sh1) (Hsh2 : sepalg_list.list_join sh0 (make_shares shs lasts i) sh2) (Hin : 0 <= j < Zlength shs) (Hout : Zlength lasts <= j), exists sh', sepalg.join sh2 (Znth j shs) sh'.
Lemma hd_Znth': forall {A} (d: A) al, hd d al = @Znth A d 0 al.
Lemma body_finish_write : semax_body Vprog Gprog f_finish_write finish_write_spec.
Lemma write_val : forall h i v (Hh : apply_hist i (rev h) = Some v), v = Empty \/ v = fst (find_write h i).
Lemma find_write_read : forall i d h (Hread : apply_hist i (rev h) = Some Empty) (Hi : i <> Empty), fst (find_read h d) = fst (find_write h i).
Lemma take_read : forall h v, apply_hist (vint 0) (rev h) = Some v -> prev_taken h = if eq_dec v Empty then snd (last_two_reads h) else fst (last_two_reads h).
Lemma find_write_In : forall d h, fst (find_write h d) = d \/ exists r, In (AE r (fst (find_write h d))) h.
Lemma make_shares_app : forall i l1 l2 shs, Zlength l1 + Zlength l2 <= Zlength shs -> make_shares shs (l1 ++ l2) i = make_shares shs l1 i ++ make_shares (sublist (Zlength l1) (Zlength shs) shs) l2 i.
Lemma make_shares_out : forall b lgood lasts shs (Hb : ~In b lasts) (Hlen1 : Zlength lgood = Zlength shs) (Hlen2 : Zlength lasts = Zlength shs), make_shares shs (combine lgood lasts) b = map snd (filter fst (combine lgood shs)).
Lemma make_shares_ext : forall i d l l' lgood shs (Hlen : Zlength l = Zlength l') (Hi : forall j, 0 <= j < Zlength l -> Znth j l d = i <-> Znth j l' d = i), make_shares shs (combine lgood l) i = make_shares shs (combine lgood l') i.
Lemma make_shares_add : forall i i' d lasts lgood j shs (Hj : 0 <= j < Zlength lasts) (Hi : Znth j lasts d = i) (Hgood : Znth j lgood false = true) (Hi' : i' <> i) (Hlen : Zlength shs >= Zlength lasts), exists shs1 shs2, make_shares shs (combine lgood lasts) i = shs1 ++ shs2 /\ make_shares shs (combine lgood (upd_Znth j lasts i')) i = shs1 ++ Znth j shs Tsh :: shs2.
Lemma make_shares_In : forall i lasts lgood x shs (Hx : 0 <= x < Zlength lasts) (Hi : Znth x lasts 0 <> i) (Hgood : Znth x lgood false = true) (Hlen : Zlength shs >= Zlength lasts), In (Znth x shs Tsh) (make_shares shs (combine lgood lasts) i).
Lemma make_shares_sub : forall i lasts shs sh0 sh1 sh2 (Hlen : Zlength shs >= Zlength lasts) (Hsh1 : sepalg_list.list_join sh0 shs sh1) (Hsh2 : sepalg_list.list_join sh0 (make_shares shs lasts i) sh2), sepalg.join_sub sh2 sh1.
Lemma make_shares_join : forall i d lasts lgood shs sh0 j sh1 sh2 (Hlen : Zlength shs >= Zlength lasts) (Hsh1 : sepalg_list.list_join sh0 shs sh1) (Hsh2 : sepalg_list.list_join sh0 (make_shares shs (combine lgood lasts) i) sh2) (Hin : 0 <= j < Zlength shs) (Hj : Znth j lasts d = i), exists sh', sepalg.join sh2 (Znth j shs Tsh) sh'.
Lemma make_shares_add' : forall i i' d lasts lgood j shs (Hj : 0 <= j < Zlength lasts) (Hi : Znth j lasts d = i) (Hgood : Znth j lgood false = false) (Hlen : Zlength shs >= Zlength lasts), make_shares shs (combine lgood (upd_Znth j lasts i')) i = make_shares shs (combine lgood lasts) i.
Lemma make_shares_ext' : forall i d l l' lgood shs (Hlen : Zlength l = Zlength l') (Hi : forall j, 0 <= j < Zlength l -> Znth j lgood false = true -> Znth j l d = i <-> Znth j l' d = i), make_shares shs (combine lgood l) i = make_shares shs (combine lgood l') i.
Lemma body_finish_write : semax_body Vprog Gprog f_finish_write finish_write_spec.