Require Export VST.veric.base.
Local Open Scope Z_scope.
Local Open Scope pred.
Program Definition kind_at (k: kind) (l: address) : pred rmap :=
fun m => exists rsh, exists sh, exists pp, m @ l = YES rsh sh k pp.
Next Obligation.
try intro; intros.
destruct H0 as [rsh [sh [pp ?]]].
generalize (eq_sym (resource_at_approx a l)); intro.
generalize (age1_resource_at a a'  H l (a@l) H1); intro.
rewrite H0 in H2. simpl in H2. eauto.
Qed.
Definition spec : Type :=  forall (sh: Share.t) (l: AV.address), pred rmap.
Program Definition yesat_raw (pp: preds) (k: kind)
(sh: share) (rsh: readable_share sh) (l: address) : pred rmap :=
fun phi => phi @ l = YES sh rsh k (preds_fmap (approx (level phi)) (approx (level phi)) pp).
Next Obligation.
try intro; intros.
apply (age1_resource_at a a' H l (YES sh rsh k pp) H0).
Qed.
Obligation Tactic := idtac.
Program Definition yesat (pp: preds) (k: kind) : spec :=
fun (sh: share) (l: AV.address) (m: rmap) =>
exists rsh, yesat_raw pp k sh rsh l m.
Next Obligation.
intros; intro; intros.
destruct H0 as [p ?]; exists p.
apply pred_hereditary with a; auto.
Qed.
Program Definition pureat (pp: preds) (k: kind) (l: AV.address): pred rmap :=
fun phi => phi @ l = PURE k (preds_fmap (approx (level phi)) (approx (level phi)) pp).
Next Obligation.
intros; intro; intros.
apply (age1_resource_at a a' H l (PURE k pp) H0).
Qed.
Ltac do_map_arg :=
match goal with |- ?a = ?b =>
match a with context [map ?x _] =>
match b with context [map ?y _] => replace y with x; auto end end end.
(* NOT TRUE, because the shares might not match Lemma extensionally_yesat: forall pp k sh l, extensionally (yesat pp k sh l) = yesat pp k sh l. *)
Program Definition noat (l: AV.address) : pred rmap :=
fun m => identity (m @ l).
Next Obligation.
intros; intro; intros.
apply (age1_resource_at_identity _ _ l H); auto.
Qed.
Definition resource_share (r: resource) : option share :=
match r with
| YES sh _ _ _ => Some sh
| NO sh _ => Some sh
| PURE _ _ => None
end.
Definition nonlock (r: resource) : Prop :=
match r with
| YES _ _ k _ => isVAL k \/ isFUN k
| NO _ _ => True
| PURE _ _ => False
end.

Lemma resource_share_join_exists: forall r1 r2 r sh1 sh2,
resource_share r1 = Some sh1 ->
resource_share r2 = Some sh2 ->
join r1 r2 r ->
exists sh, join sh1 sh2 sh /\ resource_share r = Some sh.