(* We could also consider an alpha-renaming axiom, although this may be unnecessary. *)

(* 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)).