Require Export VST.msl.iter_sepcon.
Require Export VST.concurrency.semax_conc_pred.
Require Export VST.concurrency.semax_conc.
Require Export VST.floyd.proofauto.
Require Export VST.floyd.sublist.
(* general list lemmas *)
Notation vint z := (Vint (Int.repr z)).
Notation vptrofs z := (Vptrofs (Ptrofs.repr z)).
Hint Resolve repable_0.
Definition complete MAX l := l ++ repeat (vptrofs 0) (Z.to_nat MAX - length l).
Definition remove_at {A} i (l : list A) := firstn i l ++ skipn (S i) l.
Open Scope logic.
Definition rotate {A} (l : list A) n m := sublist (m - n) (Zlength l) l ++
sublist 0 (m - n) l.
(* Lemma Znth_indep : forall {A} i (l : list A) d d', 0 <= i < Zlength l -> Znth i l d = Znth i l d'. *)
Fixpoint upto n :=
match n with
| O => []
| S n' => 0 :: map Z.succ (upto n')
end.
Opaque Z.of_nat.
(* Lemma Znth_map' : forall {A B} i (f : A -> B) al b, Znth i (map f al) (f b) = f (Znth i al b). *)
Transparent Z.of_nat.
Hint Resolve incl_nil.
Definition nil_dec {A} (l : list A) : {l = []} + {l <> []}.
Arguments eq_dec _ _ _ _ : simpl never.
Fixpoint extend {A} (l : list A) ls :=
match l, ls with
| x :: xs, y :: ys => (x :: y) :: extend xs ys
| _, _ => ls
end.
Fixpoint extendr {A} (l : list A) ls :=
match l, ls with
| x :: xs, y :: ys => (y ++ [x]) :: extendr xs ys
| _, _ => ls
end.
(* We could also consider an alpha-renaming axiom, although this may be unnecessary. *)
Hint Resolve lock_inv_isptr cond_var_isptr : saturate_local.
Hint Resolve unreadable_bot.
Definition join_Bot := join_Bot.
(* It's often useful to split Tsh in half. *)
Definition gsh1 := fst (slice.cleave Tsh).
Definition gsh2 := snd (slice.cleave Tsh).
Hint Resolve readable_gsh1 readable_gsh2 gsh1_gsh2_join.
Hint Resolve gsh1_not_bot gsh2_not_bot.
(* Lemma data_at_Tsh_conflict : forall {cs : compspecs} sh t v v' p, sepalg.nonidentity sh -> 0 < sizeof t -> data_at Tsh t v p * data_at sh t v' p |-- FF. *)
Definition remove_Znth {A} i (al : list A) := sublist 0 i al ++ sublist (i + 1) (Zlength al) al.
Instance Inhabitant_share : Inhabitant share := Share.bot. (* TODO: remove this, it's already in sublist.v *)
Instance Inhabitant_mpred : Inhabitant mpred := @FF mpred Nveric. (* TODO: remove this, it's already in sublist.v *)

(* This isn't true if the type contains any unions, since in fact the type of the data could be different. Lemma data_at_rec_value_cohere : forall {cs : compspecs} sh1 sh2 t v1 v2 p, readable_share sh1 -> readable_share sh2 -> data_at_rec sh1 t v1 p * data_at_rec sh2 t v2 p |-- data_at_rec sh1 t v1 p * data_at_rec sh2 t v1 p.  Corollary field_at_value_cohere : forall {cs : compspecs} sh1 sh2 t gfs v1 v2 p, readable_share sh1 -> field_at sh1 t gfs v1 p * field_at sh2 t gfs v2 p |-- field_at sh1 t gfs v1 p * field_at sh2 t gfs v1 p.  Corollary data_at_value_cohere : forall {cs : compspecs} sh1 sh2 t v1 v2 p, readable_share sh1 -> data_at sh1 t v1 p * data_at sh2 t v2 p |-- data_at sh1 t v1 p * data_at sh2 t v1 p.  Corollary data_at__cohere : forall {cs : compspecs} sh1 sh2 t v p, readable_share sh1 -> data_at sh1 t v p * data_at_ sh2 t p = data_at sh1 t v p * data_at sh2 t v p.  Lemma data_at__shares_join : forall {cs} sh t v p shs sh1 (Hsplit : sepalg_list.list_join sh1 shs sh) (Hreadable1 : readable_share sh1) (Hreadable : Forall readable_share shs), @data_at cs sh1 t v p * fold_right sepcon emp (map (fun sh => data_at_ sh t p) shs) |-- data_at sh t v p.  Lemma extract_nth_sepcon : forall l i, 0 <= i < Zlength l -> fold_right sepcon emp l = Znth i l * fold_right sepcon emp (upd_Znth i l emp).  Lemma replace_nth_sepcon : forall P l i, P * fold_right sepcon emp (upd_Znth i l emp) = fold_right sepcon emp (upd_Znth i l P).  Lemma sepcon_derives_prop : forall P Q R, P |-- !!R -> P * Q |-- !!R.  Lemma sepcon_map : forall {A} P Q (l : list A), fold_right sepcon emp (map (fun x => P x * Q x) l) = fold_right sepcon emp (map P l) * fold_right sepcon emp (map Q l).  Lemma sepcon_list_derives : forall l1 l2 (Hlen : Zlength l1 = Zlength l2) (Heq : forall i, 0 <= i < Zlength l1 -> Znth i l1 |-- Znth i l2), fold_right sepcon emp l1 |-- fold_right sepcon emp l2.  Lemma sepcon_rotate : forall lP m n, 0 <= n - m < Zlength lP -> fold_right sepcon emp lP = fold_right sepcon emp (rotate lP m n).  (* wand lemmas *)
Lemma wand_eq : forall P Q R, P = Q * R -> P = Q * (Q -* P).