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.

(* Sometimes, in order to prove precise, we actually need to know that the data is the same as well. *)
(* Do we still need this? Probably not. Lemma mapsto_inj : forall sh t v1 v2 p r1 r2 r (Hsh : readable_share sh) (Hp1 : predicates_hered.app_pred (mapsto sh t p v1) r1) (Hp2 : predicates_hered.app_pred (mapsto sh t p v2) r2) (Hr1 : sepalg.join_sub r1 r) (Hr2 : sepalg.join_sub r2 r) (Hdef1 : v1 <> Vundef) (Hdef2 : v2 <> Vundef), r1 = r2 /\ v1 = v2.  Lemma data_at_int_array_inj : forall {cs} sh z a1 a2 p r1 r2 r (Hsh : readable_share sh) (Hp1 : predicates_hered.app_pred (@data_at_rec cs sh (tarray tint z) a1 p) r1) (Hp2 : predicates_hered.app_pred (@data_at_rec cs sh (tarray tint z) a2 p) r2) (Hr1 : sepalg.join_sub r1 r) (Hr2 : sepalg.join_sub r2 r) (Hdef1 : Forall (fun v => v <> Vundef) a1) (Hdef2 : Forall (fun v => v <> Vundef) a2) (Hlen1 : Zlength a1 = z) (Hlen2 : Zlength a2 = z), r1 = r2 /\ a1 = a2.  Lemma data_at_ptr_array_inj : forall {cs} sh t z a1 a2 p r1 r2 r (Hsh : readable_share sh) (Hp1 : predicates_hered.app_pred (@data_at_rec cs sh (tarray (tptr t) z) a1 p) r1) (Hp2 : predicates_hered.app_pred (@data_at_rec cs sh (tarray (tptr t) z) a2 p) r2) (Hr1 : sepalg.join_sub r1 r) (Hr2 : sepalg.join_sub r2 r) (Hdef1 : Forall (fun v => v <> Vundef) a1) (Hdef2 : Forall (fun v => v <> Vundef) a2) (Hlen1 : Zlength a1 = z) (Hlen2 : Zlength a2 = z), r1 = r2 /\ a1 = a2.  Hint Resolve lock_inv_exclusive selflock_exclusive cond_var_exclusive data_at_exclusive data_at__exclusive field_at_exclusive field_at__exclusive selflock_rec.  Lemma eq_dec_refl : forall {A B} {A_eq : EqDec A} (a : A) (b c : B), (if eq_dec a a then b else c) = b.  (* shares *)
Lemma LKspec_readable lock_size :
0 < lock_size ->
forall R sh p, predicates_hered.derives (res_predicates.LKspec lock_size R sh p)
(!!(readable_share sh)).