Library ghost
Require Export veric.base.
Require Import msl.rmaps.
Require Import msl.rmaps_lemmas.
Require Import veric.compcert_rmaps.
Require Import veric.res_predicates.
Require Import veric.expr.
Definition GHOSTspec (A: Type) (x: A) : spec :=
fun rsh sh loc =>
allp (jam (eq_dec loc) (fun loc' =>
yesat (SomeP (A::nil) (fun y: (A*unit) => prop(fst y = x)))
(FUN (nil,Tvoid)) rsh sh loc') noat).
Definition ghostp {A: Type} (sh: share) (loc: address) (x: A) : mpred :=
GHOSTspec A x (Share.unrel Share.Lsh sh) (Share.unrel Share.Rsh sh) loc.
Lemma ghostp_unique_sepcon:
forall {A: Type} sh1 sh2 loc (x1 x2: A),
ghostp sh1 loc x1 * ghostp sh2 loc x2 |-- |> !! (x1=x2).
Proof.
intros.
unfold ghostp, GHOSTspec.
intros w [w1 [w2 [? [? ?]]]].
intros w' ?.
simpl in H2.
apply laterR_level in H2.
generalize (join_level _ _ _ H); intros [? ?].
destruct (level w). inv H2.
hnf.
rename H2 into Hw'.
specialize (H0 loc). specialize (H1 loc).
rewrite jam_true in H0 by auto.
rewrite jam_true in H1 by auto.
destruct H0 as [p ?]. destruct H1 as [p' ?].
hnf in H0,H1.
apply (resource_at_join _ _ _ loc) in H.
rewrite H0 in H; rewrite H1 in H.
simpl in H.
rewrite H3 in H. rewrite H4 in H.
assert (SomeP (A :: nil)
(approx (S n) oo (fun y : A * unit => (!!(fst y = x1))%pred)) =
SomeP (A :: nil)
(approx (S n) oo (fun y : A * unit => (!!(fst y = x2))%pred))).
clear - H.
match goal with |- ?B = ?C => forget B as b; forget C as c end.
inversion H; auto.
clear H.
apply SomeP_inj in H2.
assert ((approx (S n) oo (fun y : A * unit => (!!(fst y = x1))%pred)) (x1,tt) w' =
(approx (S n) oo (fun y : A * unit => (!!(fst y = x2))%pred)) (x1,tt) w').
rewrite H2; auto.
clear H2.
unfold approx, compose in H.
inv H.
assert ((level w' < S n)%nat /\ x1 = x1) by (split; auto).
rewrite H5 in H.
destruct H; auto.
Qed.
Lemma ghostp_unique_andp:
forall {A: Type} sh loc (x1 x2: A),
ghostp sh loc x1 && ghostp sh loc x2 |-- |> !! (x1=x2).
Proof.
intros.
unfold ghostp, GHOSTspec.
intros w [? ?].
rename H0 into H1; rename H into H0.
specialize (H0 loc). specialize (H1 loc).
rewrite jam_true in H0 by auto.
rewrite jam_true in H1 by auto.
destruct H0 as [p H0]. destruct H1 as [p' H1].
hnf in H0,H1.
rewrite H0 in H1.
simpl in H1.
intros w' H2.
simpl in H2.
apply laterR_level in H2.
destruct (level w). inv H2.
hnf.
rename H2 into Hw'.
assert (SomeP (A :: nil)
(approx (S n) oo (fun y : A * unit => (!!(fst y = x1))%pred)) =
SomeP (A :: nil)
(approx (S n) oo (fun y : A * unit => (!!(fst y = x2))%pred))).
clear - H1.
match goal with |- ?B = ?C => forget B as b; forget C as c end.
inversion H1; auto.
clear H1.
apply SomeP_inj in H.
assert ((approx (S n) oo (fun y : A * unit => (!!(fst y = x1))%pred)) (x1,tt) w' =
(approx (S n) oo (fun y : A * unit => (!!(fst y = x2))%pred)) (x1,tt) w').
rewrite H; auto.
clear H.
unfold approx, compose in H1.
inv H1.
assert ((level w' < S n)%nat /\ x1 = x1) by (split; auto).
rewrite H2 in H.
destruct H; auto.
Qed.
Definition make_GHOSTspec:
forall A (rsh : share) (sh: pshare) loc (x: A) (lev: nat),
exists m: rmap, GHOSTspec A x rsh (pshare_sh sh) loc m /\ level m = lev.
Proof.
intros.
assert (AV.valid (res_option oo
(fun l => if eq_dec l loc
then YES rsh sh (FUN(nil,Tvoid))
(SomeP (A::nil) (approx lev oo (fun y: (A*unit) => prop(fst y = x))))
else NO Share.bot))).
intros b ofs.
unfold res_option, compose.
if_tac; auto.
destruct (make_rmap _ H lev) as [phi [? ?]].
extensionality l.
unfold compose, resource_fmap; simpl.
if_tac; auto.
simpl.
f_equal. f_equal.
extensionality a. unfold compose.
change ((approx lev oo approx lev) (prop (fst a = x)) = approx lev (prop (fst a = x))).
rewrite approx_oo_approx; auto.
exists phi.
split; auto.
hnf.
intro l.
hnf.
if_tac.
subst l.
hnf.
exists (pshare_nonunit sh).
hnf.
rewrite H1. rewrite if_true. f_equal.
destruct sh; simpl. apply exist_ext. auto.
simpl. f_equal.
rewrite H0; auto. auto.
do 3 red; rewrite H1.
rewrite if_false by auto.
apply NO_identity.
Qed.
Lemma make_ghostp:
forall A (x: A) loc (lev: nat),
exists m : rmap, ghostp Share.top loc x m /\ level m = lev.
Proof.
intros.
unfold ghostp.
destruct (make_GHOSTspec A (Share.unrel Share.Lsh Share.top) pfullshare loc x lev) as [m [? ?]].
exists m; split; auto.
rewrite Share.contains_Rsh_e.
apply H.
apply top_correct'.
Qed.