Commit 1b85d654 authored by Robbert Krebbers's avatar Robbert Krebbers

Rename rvs -> bupd (basic update), pvs -> fupd (fancy update).

And also rename the corresponding proof mode tactics.
parent aec84909
......@@ -5,8 +5,8 @@ Many of the tactics below apply to more goals than described in this document
since the behavior of these tactics can be tuned via instances of the type
classes in the file [proofmode/classes](proofmode/classes.v). Most notable, many
of the tactics can be applied when the to be introduced or to be eliminated
connective appears under a later, a primitive view shift, or in the conclusion
of a weakest precondition connective.
connective appears under a later, an update modality, or in the conclusion of a
weakest precondition.
Applying hypotheses and lemmas
------------------------------
......@@ -124,14 +124,13 @@ Rewriting
Iris
----
- `iVsIntro` : introduction of a raw or primitive view shift.
- `iVs pm_trm as (x1 ... xn) "ipat"` : run a raw or primitive view shift
`pm_trm` (if the goal permits, i.e. it is a raw or primitive view shift, or
a weakest precondition).
- `iUpdIntro` : introduction of an update modality.
- `iUpd pm_trm as (x1 ... xn) "ipat"` : run an update modality `pm_trm` (if the
goal permits, i.e. it can be expanded to an update modality.
- `iInv N as (x1 ... xn) "ipat"` : open the invariant `N`.
- `iTimeless "H"` : strip a later of a timeless hypothesis `H` (if the goal
permits, i.e. it is a later, True now, raw or primitive view shift, or a
weakest precondition).
permits, i.e. it is a later, True now, update modality, or a weakest
precondition).
Miscellaneous
-------------
......@@ -140,8 +139,8 @@ Miscellaneous
introduces pure connectives.
- The proof mode adds hints to the core `eauto` database so that `eauto`
automatically introduces: conjunctions and disjunctions, universal and
existential quantifiers, implications and wand, always and later modalities,
primitive view shifts, and pure connectives.
existential quantifiers, implications and wand, always, later and update
modalities, and pure connectives.
Selection patterns
==================
......@@ -172,7 +171,7 @@ _introduction patterns_:
- `%` : move the hypothesis to the pure Coq context (anonymously).
- `# ipat` : move the hypothesis to the persistent context.
- `> ipat` : remove a later of a timeless hypothesis (if the goal permits).
- `==> ipat` : run a view shift (if the goal permits).
- `==> ipat` : run an update modality (if the goal permits).
Apart from this, there are the following introduction patterns that can only
appear at the top level:
......@@ -183,7 +182,7 @@ appear at the top level:
- `!%` : introduce a pure goal (and leave the proof mode).
- `!#` : introduce an always modality (given that the spatial context is empty).
- `!>` : introduce a later (which strips laters from all hypotheses).
- `!==>` : introduce a view shift.
- `!==>` : introduce an update modality
- `/=` : perform `simpl`.
- `*` : introduce all universal quantifiers.
- `**` : introduce all universal quantifiers, as well as all arrows and wands.
......@@ -224,7 +223,7 @@ _specification patterns_ to express splitting of hypotheses:
- `[-H1 ... Hn]` : negated form of the above pattern. This pattern does not
accept hypotheses prefixed with a `$`.
- `==>[H1 ... Hn]` : same as the above pattern, but can only be used if the goal
is a primitive view shift, in which case the view shift will be kept in the
is an update modality, in which case the update modality will be kept in the
goal of the premise too.
- `[#]` : This pattern can be used when eliminating `P -★ Q` with `P`
persistent. Using this pattern, all hypotheses are available in the goal for
......
......@@ -69,7 +69,7 @@ program_logic/lifting.v
program_logic/invariants.v
program_logic/wsat.v
program_logic/weakestpre.v
program_logic/pviewshifts.v
program_logic/fancy_updates.v
program_logic/hoare.v
program_logic/viewshifts.v
program_logic/language.v
......
From iris.algebra Require Import upred.
Import upred.
(* In this file we show that the rvs can be thought of a kind of
(* In this file we show that the bupd can be thought of a kind of
step-indexed double-negation when our meta-logic is classical *)
(* To define this, we need a way to talk about iterated later modalities: *)
......@@ -12,10 +12,10 @@ Notation "▷^ n P" := (uPred_laterN n P)
(at level 20, n at level 9, right associativity,
format "▷^ n P") : uPred_scope.
Definition uPred_nnvs {M} (P: uPred M) : uPred M :=
Definition uPred_nnupd {M} (P: uPred M) : uPred M :=
n, (P - ^n False) - ^n False.
Notation "|=n=> Q" := (uPred_nnvs Q)
Notation "|=n=> Q" := (uPred_nnupd Q)
(at level 99, Q at level 200, format "|=n=> Q") : uPred_scope.
Notation "P =n=> Q" := (P |=n=> Q)
(at level 99, Q at level 200, only parsing) : C_scope.
......@@ -27,7 +27,7 @@ Notation "P =n=★ Q" := (P -★ |=n=> Q)%I
(2) If our meta-logic is classical, then |=n=> and |=r=> are equivalent
*)
Section rvs_nnvs.
Section bupd_nnupd.
Context {M : ucmraT}.
Implicit Types φ : Prop.
Implicit Types P Q : uPred M.
......@@ -58,40 +58,40 @@ Proof.
eapply (uPred_closed _ _ (S n)); eauto using cmra_validN_S.
Qed.
(* It is easy to show that most of the basic properties of rvs that
are used throughout Iris hold for nnvs.
(* It is easy to show that most of the basic properties of bupd that
are used throughout Iris hold for nnupd.
In fact, the first three properties that follow hold for any
modality of the form (- -★ Q) -★ Q for arbitrary Q. The situation
here is slightly different, because nnvs is of the form
here is slightly different, because nnupd is of the form
∀ n, (- -★ (Q n)) -★ (Q n), but the proofs carry over straightforwardly.
*)
Lemma nnvs_intro P : P =n=> P.
Lemma nnupd_intro P : P =n=> P.
Proof. apply forall_intro=>?. apply wand_intro_l, wand_elim_l. Qed.
Lemma nnvs_mono P Q : (P Q) (|=n=> P) =n=> Q.
Lemma nnupd_mono P Q : (P Q) (|=n=> P) =n=> Q.
Proof.
intros HPQ. apply forall_intro=>n.
apply wand_intro_l. rewrite -{1}HPQ.
rewrite /uPred_nnvs (forall_elim n).
rewrite /uPred_nnupd (forall_elim n).
apply wand_elim_r.
Qed.
Lemma nnvs_frame_r P R : (|=n=> P) R =n=> P R.
Lemma nnupd_frame_r P R : (|=n=> P) R =n=> P R.
Proof.
apply forall_intro=>n. apply wand_intro_r.
rewrite (comm _ P) -wand_curry.
rewrite /uPred_nnvs (forall_elim n).
rewrite /uPred_nnupd (forall_elim n).
by rewrite -assoc wand_elim_r wand_elim_l.
Qed.
Lemma nnvs_ownM_updateP x (Φ : M Prop) :
Lemma nnupd_ownM_updateP x (Φ : M Prop) :
x ~~>: Φ uPred_ownM x =n=> y, Φ y uPred_ownM y.
Proof.
intros Hrvs. split. rewrite /uPred_nnvs. repeat uPred.unseal.
intros Hbupd. split. rewrite /uPred_nnupd. repeat uPred.unseal.
intros n y ? Hown a.
red; rewrite //= => n' yf ??.
inversion Hown as (x'&Hequiv).
edestruct (Hrvs n' (Some (x' yf))) as (y'&?&?); eauto.
edestruct (Hbupd n' (Some (x' yf))) as (y'&?&?); eauto.
{ by rewrite //= assoc -(dist_le _ _ _ _ Hequiv). }
case (decide (a n')).
- intros Hle Hwand.
......@@ -110,18 +110,18 @@ Qed.
now over n?
*)
Remark nnvs_trans P: (|=n=> |=n=> P) (|=n=> P).
Remark nnupd_trans P: (|=n=> |=n=> P) (|=n=> P).
Proof.
rewrite /uPred_nnvs.
rewrite /uPred_nnupd.
apply forall_intro=>a. apply wand_intro_l.
rewrite (forall_elim a).
rewrite (nnvs_intro (P - _)).
rewrite /uPred_nnvs.
rewrite (nnupd_intro (P - _)).
rewrite /uPred_nnupd.
(* Oops -- the exponents of the later modality don't match up! *)
Abort.
(* Instead, we will need to prove this in the model. We start by showing that
nnvs is the limit of a the following sequence:
nnupd is the limit of a the following sequence:
(- -★ False) - ★ False,
(- -★ ▷ False) - ★ ▷ False ∧ (- -★ False) - ★ False,
......@@ -129,33 +129,33 @@ Abort.
...
Then, it is easy enough to show that each of the uPreds in this sequence
is transitive. It turns out that this implies that nnvs is transitive. *)
is transitive. It turns out that this implies that nnupd is transitive. *)
(* The definition of the sequence above: *)
Fixpoint uPred_nnvs_k {M} k (P: uPred M) : uPred M :=
Fixpoint uPred_nnupd_k {M} k (P: uPred M) : uPred M :=
((P - ^k False) - ^k False)
match k with
O => True
| S k' => uPred_nnvs_k k' P
| S k' => uPred_nnupd_k k' P
end.
Notation "|=n=>_ k Q" := (uPred_nnvs_k k Q)
Notation "|=n=>_ k Q" := (uPred_nnupd_k k Q)
(at level 99, k at level 9, Q at level 200, format "|=n=>_ k Q") : uPred_scope.
(* One direction of the limiting process is easy -- nnvs implies nnvs_k for each k *)
Lemma nnvs_trunc1 k P: (|=n=> P) |=n=>_k P.
(* One direction of the limiting process is easy -- nnupd implies nnupd_k for each k *)
Lemma nnupd_trunc1 k P: (|=n=> P) |=n=>_k P.
Proof.
induction k.
- rewrite /uPred_nnvs_k /uPred_nnvs.
- rewrite /uPred_nnupd_k /uPred_nnupd.
rewrite (forall_elim 0) //= right_id //.
- simpl. apply and_intro; auto.
rewrite /uPred_nnvs.
rewrite /uPred_nnupd.
rewrite (forall_elim (S k)) //=.
Qed.
Lemma nnvs_k_elim n k P: n k ((|=n=>_k P) (P - (^n False)) (^n False))%I.
Lemma nnupd_k_elim n k P: n k ((|=n=>_k P) (P - (^n False)) (^n False))%I.
Proof.
induction k.
- inversion 1; subst; rewrite //= ?right_id. apply wand_elim_l.
......@@ -164,23 +164,23 @@ Proof.
* rewrite and_elim_r IHk //.
Qed.
Lemma nnvs_k_unfold k P:
Lemma nnupd_k_unfold k P:
(|=n=>_(S k) P) ((P - (^(S k) False)) - (^(S k) False)) (|=n=>_k P).
Proof. done. Qed.
Lemma nnvs_k_unfold' k P n x:
Lemma nnupd_k_unfold' k P n x:
(|=n=>_(S k) P)%I n x (((P - (^(S k) False)) - (^(S k) False)) (|=n=>_k P))%I n x.
Proof. done. Qed.
Lemma nnvs_k_weaken k P: (|=n=>_(S k) P) |=n=>_k P.
Proof. by rewrite nnvs_k_unfold and_elim_r. Qed.
Lemma nnupd_k_weaken k P: (|=n=>_(S k) P) |=n=>_k P.
Proof. by rewrite nnupd_k_unfold and_elim_r. Qed.
(* Now we are ready to show nnvs is the limit -- ie, for each k, it is within distance k
(* Now we are ready to show nnupd is the limit -- ie, for each k, it is within distance k
of the kth term of the sequence *)
Lemma nnvs_nnvs_k_dist k P: (|=n=> P)%I {k} (|=n=>_k P)%I.
Lemma nnupd_nnupd_k_dist k P: (|=n=> P)%I {k} (|=n=>_k P)%I.
split; intros n' x Hle Hx. split.
- by apply (nnvs_trunc1 k).
- by apply (nnupd_trunc1 k).
- revert n' x Hle Hx; induction k; intros n' x Hle Hx;
rewrite ?nnvs_k_unfold' /uPred_nnvs.
rewrite ?nnupd_k_unfold' /uPred_nnupd.
* rewrite //=. unseal.
inversion Hle; subst.
intros (HnnP&_) n k' x' ?? HPF.
......@@ -199,17 +199,17 @@ Lemma nnvs_nnvs_k_dist k P: (|=n=> P)%I ≡{k}≡ (|=n=>_k P)%I.
*** intros. exfalso. assert (n k'). omega.
assert (n = S k n < S k) as [->|] by omega.
**** eapply laterN_big; eauto; unseal. eapply HnnP; eauto.
**** move:nnvs_k_elim. unseal. intros Hnnvsk.
**** move:nnupd_k_elim. unseal. intros Hnnupdk.
eapply laterN_big; eauto. unseal.
eapply (Hnnvsk n k); first omega; eauto.
eapply (Hnnupdk n k); first omega; eauto.
exists x, x'. split_and!; eauto. eapply uPred_closed; eauto.
eapply cmra_validN_op_l; eauto.
** intros HP. eapply IHk; auto.
move:HP. unseal. intros (?&?); naive_solver.
Qed.
(* nnvs_k has a number of structural properties, including transitivity *)
Lemma nnvs_k_intro k P: P (|=n=>_k P).
(* nnupd_k has a number of structural properties, including transitivity *)
Lemma nnupd_k_intro k P: P (|=n=>_k P).
Proof.
induction k; rewrite //= ?right_id.
- apply wand_intro_l. apply wand_elim_l.
......@@ -217,58 +217,58 @@ Proof.
apply wand_intro_l. apply wand_elim_l.
Qed.
Lemma nnvs_k_mono k P Q: (P Q) (|=n=>_k P) (|=n=>_k Q).
Lemma nnupd_k_mono k P Q: (P Q) (|=n=>_k P) (|=n=>_k Q).
Proof.
induction k; rewrite //= ?right_id=>HPQ.
- do 2 (apply wand_mono; auto).
- apply and_mono; auto; do 2 (apply wand_mono; auto).
Qed.
Instance nnvs_k_mono' k: Proper (() ==> ()) (@uPred_nnvs_k M k).
Proof. by intros P P' HP; apply nnvs_k_mono. Qed.
Instance nnupd_k_mono' k: Proper (() ==> ()) (@uPred_nnupd_k M k).
Proof. by intros P P' HP; apply nnupd_k_mono. Qed.
Instance nnvs_k_ne k n : Proper (dist n ==> dist n) (@uPred_nnvs_k M k).
Instance nnupd_k_ne k n : Proper (dist n ==> dist n) (@uPred_nnupd_k M k).
Proof. induction k; rewrite //= ?right_id=>P P' HP; by rewrite HP. Qed.
Lemma nnvs_k_proper k P Q: (P Q) (|=n=>_k P) (|=n=>_k Q).
Proof. intros HP; apply (anti_symm ()); eapply nnvs_k_mono; by rewrite HP. Qed.
Instance nnvs_k_proper' k: Proper (() ==> ()) (@uPred_nnvs_k M k).
Proof. by intros P P' HP; apply nnvs_k_proper. Qed.
Lemma nnupd_k_proper k P Q: (P Q) (|=n=>_k P) (|=n=>_k Q).
Proof. intros HP; apply (anti_symm ()); eapply nnupd_k_mono; by rewrite HP. Qed.
Instance nnupd_k_proper' k: Proper (() ==> ()) (@uPred_nnupd_k M k).
Proof. by intros P P' HP; apply nnupd_k_proper. Qed.
Lemma nnvs_k_trans k P: (|=n=>_k |=n=>_k P) (|=n=>_k P).
Lemma nnupd_k_trans k P: (|=n=>_k |=n=>_k P) (|=n=>_k P).
Proof.
revert P.
induction k; intros P.
- rewrite //= ?right_id. apply wand_intro_l.
rewrite {1}(nnvs_k_intro 0 (P - False)%I) //= ?right_id. apply wand_elim_r.
- rewrite {2}(nnvs_k_unfold k P).
rewrite {1}(nnupd_k_intro 0 (P - False)%I) //= ?right_id. apply wand_elim_r.
- rewrite {2}(nnupd_k_unfold k P).
apply and_intro.
* rewrite (nnvs_k_unfold k P). rewrite and_elim_l.
rewrite nnvs_k_unfold. rewrite and_elim_l.
* rewrite (nnupd_k_unfold k P). rewrite and_elim_l.
rewrite nnupd_k_unfold. rewrite and_elim_l.
apply wand_intro_l.
rewrite {1}(nnvs_k_intro (S k) (P - ^(S k) (False)%I)).
rewrite nnvs_k_unfold and_elim_l. apply wand_elim_r.
* do 2 rewrite nnvs_k_weaken //.
rewrite {1}(nnupd_k_intro (S k) (P - ^(S k) (False)%I)).
rewrite nnupd_k_unfold and_elim_l. apply wand_elim_r.
* do 2 rewrite nnupd_k_weaken //.
Qed.
Lemma nnvs_trans P : (|=n=> |=n=> P) =n=> P.
Lemma nnupd_trans P : (|=n=> |=n=> P) =n=> P.
Proof.
split=> n x ? Hnn.
eapply nnvs_nnvs_k_dist in Hnn; eauto.
eapply (nnvs_k_ne (n) n ((|=n=>_(n) P)%I)) in Hnn; eauto;
[| symmetry; eapply nnvs_nnvs_k_dist].
eapply nnvs_nnvs_k_dist; eauto.
by apply nnvs_k_trans.
eapply nnupd_nnupd_k_dist in Hnn; eauto.
eapply (nnupd_k_ne (n) n ((|=n=>_(n) P)%I)) in Hnn; eauto;
[| symmetry; eapply nnupd_nnupd_k_dist].
eapply nnupd_nnupd_k_dist; eauto.
by apply nnupd_k_trans.
Qed.
(* Now that we have shown nnvs has all of the desired properties of
rvs, we go further and show it is in fact equivalent to rvs! The
direction from rvs to nnvs is similar to the proof of
nnvs_ownM_updateP *)
(* Now that we have shown nnupd has all of the desired properties of
bupd, we go further and show it is in fact equivalent to bupd! The
direction from bupd to nnupd is similar to the proof of
nnupd_ownM_updateP *)
Lemma rvs_nnvs P: (|=r=> P) |=n=> P.
Lemma bupd_nnupd P: (|=r=> P) |=n=> P.
Proof.
split. rewrite /uPred_nnvs. repeat uPred.unseal. intros n x ? Hrvs a.
split. rewrite /uPred_nnupd. repeat uPred.unseal. intros n x ? Hbupd a.
red; rewrite //= => n' yf ??.
edestruct Hrvs as (x'&?&?); eauto.
edestruct Hbupd as (x'&?&?); eauto.
case (decide (a n')).
- intros Hle Hwand.
exfalso. eapply laterN_big; last (uPred.unseal; eapply (Hwand n' x')); eauto.
......@@ -282,9 +282,9 @@ Qed.
(* However, the other direction seems to need a classical axiom: *)
Section classical.
Context (not_all_not_ex: (P : M Prop), ¬ ( n : M, ¬ P n) n : M, P n).
Lemma nnvs_rvs P: (|=n=> P) (|=r=> P).
Lemma nnupd_bupd P: (|=n=> P) (|=r=> P).
Proof.
rewrite /uPred_nnvs.
rewrite /uPred_nnupd.
split. uPred.unseal; red; rewrite //=.
intros n x ? Hforall k yf Hle ?.
apply not_all_not_ex.
......@@ -300,36 +300,36 @@ Proof.
Qed.
End classical.
(* We might wonder whether we can prove an adequacy lemma for nnvs. We could combine
the adequacy lemma for rvs with the previous result to get adquacy for nnvs, but
(* We might wonder whether we can prove an adequacy lemma for nnupd. We could combine
the adequacy lemma for bupd with the previous result to get adquacy for nnupd, but
this would rely on the classical axiom we needed to prove the equivalence! Can
we establish adequacy without axioms? Unfortunately not, because adequacy for
nnvs would imply double negation elimination, which is classical: *)
nnupd would imply double negation elimination, which is classical: *)
Lemma nnvs_dne φ: True (|=n=> ((¬¬ φ φ)): uPred M)%I.
Lemma nnupd_dne φ: True (|=n=> ((¬¬ φ φ)): uPred M)%I.
Proof.
rewrite /uPred_nnvs. apply forall_intro=>n.
rewrite /uPred_nnupd. apply forall_intro=>n.
apply wand_intro_l. rewrite ?right_id.
assert ( φ, ¬¬¬¬φ ¬¬φ) by naive_solver.
assert (Hdne: ¬¬ (¬¬φ φ)) by naive_solver.
split. unseal. intros n' ?? Hvs.
split. unseal. intros n' ?? Hupd.
case (decide (n' < n)).
- intros. move: laterN_small. unseal. naive_solver.
- intros. assert (n n'). omega.
exfalso. specialize (Hvs n' ).
exfalso. specialize (Hupd n' ).
eapply Hdne. intros Hfal.
eapply laterN_big; eauto.
unseal. rewrite right_id in Hvs *; naive_solver.
unseal. rewrite right_id in Hupd *; naive_solver.
Qed.
(* Nevertheless, we can prove a weaker form of adequacy (which is equvialent to adequacy
under classical axioms) directly without passing through the proofs for rvs: *)
under classical axioms) directly without passing through the proofs for bupd: *)
Lemma adequacy_helper1 P n k x:
{S n + k} x ¬¬ (Nat.iter (S n) (λ P, |=n=> P)%I P (S n + k) x)
¬¬ ( x', {n + k} (x') Nat.iter n (λ P, |=n=> P)%I P (n + k) (x')).
Proof.
revert k P x. induction n.
- rewrite /uPred_nnvs. unseal=> k P x Hx Hf1 Hf2.
- rewrite /uPred_nnupd. unseal=> k P x Hx Hf1 Hf2.
eapply Hf1. intros Hf3.
eapply (laterN_big (S k) (S k)); eauto.
specialize (Hf3 (S k) (S k) ). rewrite right_id in Hf3 *. unseal.
......@@ -373,8 +373,8 @@ Qed.
(* Open question:
Do the basic properties of the |=r=> modality (rvs_intro, rvs_mono, rvs_trans, rvs_frame_r,
rvs_ownM_updateP, and adequacy) uniquely characterize |=r=>?
Do the basic properties of the |=r=> modality (bupd_intro, bupd_mono, rvs_trans, rvs_frame_r,
bupd_ownM_updateP, and adequacy) uniquely characterize |=r=>?
*)
End rvs_nnvs.
\ No newline at end of file
End bupd_nnupd.
......@@ -264,7 +264,7 @@ Definition uPred_cmra_valid {M A} := proj1_sig uPred_cmra_valid_aux M A.
Definition uPred_cmra_valid_eq :
@uPred_cmra_valid = @uPred_cmra_valid_def := proj2_sig uPred_cmra_valid_aux.
Program Definition uPred_rvs_def {M} (Q : uPred M) : uPred M :=
Program Definition uPred_bupd_def {M} (Q : uPred M) : uPred M :=
{| uPred_holds n x := k yf,
k n {k} (x yf) x', {k} (x' yf) Q k x' |}.
Next Obligation.
......@@ -275,9 +275,9 @@ Next Obligation.
apply uPred_mono with x'; eauto using cmra_includedN_l.
Qed.
Next Obligation. naive_solver. Qed.
Definition uPred_rvs_aux : { x | x = @uPred_rvs_def }. by eexists. Qed.
Definition uPred_rvs {M} := proj1_sig uPred_rvs_aux M.
Definition uPred_rvs_eq : @uPred_rvs = @uPred_rvs_def := proj2_sig uPred_rvs_aux.
Definition uPred_bupd_aux : { x | x = @uPred_bupd_def }. by eexists. Qed.
Definition uPred_bupd {M} := proj1_sig uPred_bupd_aux M.
Definition uPred_bupd_eq : @uPred_bupd = @uPred_bupd_def := proj2_sig uPred_bupd_aux.
Notation "P ⊢ Q" := (uPred_entails P%I Q%I)
(at level 99, Q at level 200, right associativity) : C_scope.
......@@ -310,7 +310,7 @@ Notation "▷ P" := (uPred_later P)
(at level 20, right associativity) : uPred_scope.
Infix "≡" := uPred_eq : uPred_scope.
Notation "✓ x" := (uPred_cmra_valid x) (at level 20) : uPred_scope.
Notation "|=r=> Q" := (uPred_rvs Q)
Notation "|=r=> Q" := (uPred_bupd Q)
(at level 99, Q at level 200, format "|=r=> Q") : uPred_scope.
Notation "P =r=> Q" := (P |=r=> Q)
(at level 99, Q at level 200, only parsing) : C_scope.
......@@ -344,7 +344,7 @@ Module uPred.
Definition unseal :=
(uPred_pure_eq, uPred_and_eq, uPred_or_eq, uPred_impl_eq, uPred_forall_eq,
uPred_exist_eq, uPred_eq_eq, uPred_sep_eq, uPred_wand_eq, uPred_always_eq,
uPred_later_eq, uPred_ownM_eq, uPred_cmra_valid_eq, uPred_rvs_eq).
uPred_later_eq, uPred_ownM_eq, uPred_cmra_valid_eq, uPred_bupd_eq).
Ltac unseal := rewrite !unseal /=.
Section uPred_logic.
......@@ -488,14 +488,14 @@ Proof.
Qed.
Global Instance cmra_valid_proper {A : cmraT} :
Proper (() ==> ()) (@uPred_cmra_valid M A) := ne_proper _.
Global Instance rvs_ne n : Proper (dist n ==> dist n) (@uPred_rvs M).
Global Instance bupd_ne n : Proper (dist n ==> dist n) (@uPred_bupd M).
Proof.
intros P Q HPQ.
unseal; split=> n' x; split; intros HP k yf ??;
destruct (HP k yf) as (x'&?&?); auto;
exists x'; split; auto; apply HPQ; eauto using cmra_validN_op_l.
Qed.
Global Instance rvs_proper : Proper (() ==> ()) (@uPred_rvs M) := ne_proper _.
Global Instance bupd_proper : Proper (() ==> ()) (@uPred_bupd M) := ne_proper _.
(** Introduction and elimination rules *)
Lemma pure_intro φ P : φ P φ.
......@@ -1282,21 +1282,21 @@ Lemma always_cmra_valid {A : cmraT} (a : A) : □ ✓ a ⊣⊢ ✓ a.
apply:always_cmra_valid_1.
Qed.
(* Viewshifts *)
Lemma rvs_intro P : P =r=> P.
(* Basic update modality *)
Lemma bupd_intro P : P =r=> P.
Proof.
unseal. split=> n x ? HP k yf ?; exists x; split; first done.
apply uPred_closed with n; eauto using cmra_validN_op_l.
Qed.
Lemma rvs_mono P Q : (P Q) (|=r=> P) =r=> Q.
Lemma bupd_mono P Q : (P Q) (|=r=> P) =r=> Q.
Proof.
unseal. intros HPQ; split=> n x ? HP k yf ??.
destruct (HP k yf) as (x'&?&?); eauto.
exists x'; split; eauto using uPred_in_entails, cmra_validN_op_l.
Qed.
Lemma rvs_trans P : (|=r=> |=r=> P) =r=> P.
Lemma bupd_trans P : (|=r=> |=r=> P) =r=> P.
Proof. unseal; split; naive_solver. Qed.
Lemma rvs_frame_r P R : (|=r=> P) R =r=> P R.
Lemma bupd_frame_r P R : (|=r=> P) R =r=> P R.
Proof.
unseal; split; intros n x ? (x1&x2&Hx&HP&?) k yf ??.
destruct (HP k (x2 yf)) as (x'&?&?); eauto.
......@@ -1305,7 +1305,7 @@ Proof.
exists x', x2; split_and?; auto.
apply uPred_closed with n; eauto 3 using cmra_validN_op_l, cmra_validN_op_r.
Qed.
Lemma rvs_ownM_updateP x (Φ : M Prop) :
Lemma bupd_ownM_updateP x (Φ : M Prop) :
x ~~>: Φ uPred_ownM x =r=> y, Φ y uPred_ownM y.
Proof.
unseal=> Hup; split=> n x2 ? [x3 Hx] k yf ??.
......@@ -1316,27 +1316,27 @@ Proof.
Qed.
(** * Derived rules *)
Global Instance rvs_mono' : Proper (() ==> ()) (@uPred_rvs M).
Proof. intros P Q; apply rvs_mono. Qed.
Global Instance rvs_flip_mono' : Proper (flip () ==> flip ()) (@uPred_rvs M).
Proof. intros P Q; apply rvs_mono. Qed.
Lemma rvs_frame_l R Q : (R |=r=> Q) =r=> R Q.
Proof. rewrite !(comm _ R); apply rvs_frame_r. Qed.
Lemma rvs_wand_l P Q : (P - Q) (|=r=> P) =r=> Q.
Proof. by rewrite rvs_frame_l wand_elim_l. Qed.
Lemma rvs_wand_r P Q : (|=r=> P) (P - Q) =r=> Q.
Proof. by rewrite rvs_frame_r wand_elim_r. Qed.
Lemma rvs_sep P Q : (|=r=> P) (|=r=> Q) =r=> P Q.
Proof. by rewrite rvs_frame_r rvs_frame_l rvs_trans. Qed.
Lemma rvs_ownM_update x y : x ~~> y uPred_ownM x |=r=> uPred_ownM y.
Global Instance bupd_mono' : Proper (() ==> ()) (@uPred_bupd M).
Proof. intros P Q; apply bupd_mono. Qed.
Global Instance bupd_flip_mono' : Proper (flip () ==> flip ()) (@uPred_bupd M).
Proof. intros P Q; apply bupd_mono. Qed.
Lemma bupd_frame_l R Q : (R |=r=> Q) =r=> R Q.
Proof. rewrite !(comm _ R); apply bupd_frame_r. Qed.
Lemma bupd_wand_l P Q : (P - Q) (|=r=> P) =r=> Q.
Proof. by rewrite bupd_frame_l wand_elim_l. Qed.
Lemma bupd_wand_r P Q : (|=r=> P) (P - Q) =r=> Q.
Proof. by rewrite bupd_frame_r wand_elim_r. Qed.
Lemma bupd_sep P Q : (|=r=> P) (|=r=> Q) =r=> P Q.
Proof. by rewrite bupd_frame_r bupd_frame_l bupd_trans. Qed.
Lemma bupd_ownM_update x y : x ~~> y uPred_ownM x |=r=> uPred_ownM y.
Proof.
intros; rewrite (rvs_ownM_updateP _ (y =)); last by apply cmra_update_updateP.
by apply rvs_mono, exist_elim=> y'; apply pure_elim_l=> ->.
intros; rewrite (bupd_ownM_updateP _ (y =)); last by apply cmra_update_updateP.
by apply bupd_mono, exist_elim=> y'; apply pure_elim_l=> ->.
Qed.
Lemma except_last_rvs P : (|=r=> P) (|=r=> P).
Lemma except_last_bupd P : (|=r=> P) (|=r=> P).
Proof.
rewrite /uPred_except_last. apply or_elim; auto using rvs_mono.
by rewrite -rvs_intro -or_intro_l.
rewrite /uPred_except_last. apply or_elim; auto using bupd_mono.
by rewrite -bupd_intro -or_intro_l.
Qed.
(* Products *)
......@@ -1495,8 +1495,8 @@ Proof.
cut ( x, {n} x Nat.iter n (λ P, |=r=> P)%I ( φ)%I n x φ).
{ intros help H. eapply (help ); eauto using ucmra_unit_validN.
eapply H; try unseal; eauto using ucmra_unit_validN. }
unseal. induction n as [|n IH]=> x Hx Hvs; auto.
destruct (Hvs (S n) ) as (x'&?&?); rewrite ?right_id; auto.
unseal. induction n as [|n IH]=> x Hx Hupd; auto.
destruct (Hupd (S n) ) as (x'&?&?); rewrite ?right_id; auto.
eapply IH with x'; eauto using cmra_validN_S, cmra_validN_op_l.
Qed.
......
......@@ -20,7 +20,7 @@ Definition heap_adequacy Σ `{heapPreG Σ} e σ φ :
adequate e σ φ.
Proof.
intros Hwp; eapply (wp_adequacy Σ); iIntros (?) "Hσ".
iVs (auth_alloc to_heap _ heapN _ σ with "[Hσ]") as (γ) "[Hh _]";[|by iNext|].
iUpd (auth_alloc to_heap _ heapN _ σ with "[Hσ]") as (γ) "[Hh _]";[|by iNext|].
{ exact: to_heap_valid. }
set (Hheap := HeapG _ _ _ γ).
iApply (Hwp _). by rewrite /heap_ctx.
......
......@@ -109,10 +109,10 @@ Section heap.
heap_ctx ( l, l v ={E}= Φ (LitV (LitLoc l))) WP Alloc e @ E {{ Φ }}.
Proof.
iIntros (<-%of_to_val ?) "[#Hinv HΦ]". rewrite /heap_ctx.
iVs (auth_empty heap_name) as "Ha".
iVs (auth_open with "[$Hinv $Ha]") as (σ) "(%&Hσ&Hcl)"; first done.
iUpd (auth_empty heap_name) as "Ha".
iUpd (auth_open with "[$Hinv $Ha]") as (σ) "(%&Hσ&Hcl)"; first done.
iApply wp_alloc_pst. iFrame "Hσ". iNext. iIntros (l) "[% Hσ] !==>".
iVs ("Hcl" with "* [Hσ]") as "Ha".
iUpd ("Hcl" with "* [Hσ]") as "Ha".
{ iFrame. iPureIntro. rewrite to_heap_insert.
eapply alloc_singleton_local_update; by auto using lookup_to_heap_None. }
iApply "HΦ". by rewrite heap_mapsto_eq /heap_mapsto_def.
......@@ -125,9 +125,9 @@ Section heap.
Proof.
iIntros (?) "[#Hinv [>Hl HΦ]]".
rewrite /heap_ctx heap_mapsto_eq /heap_mapsto_def.
iVs (auth_open with "[$Hinv $Hl]") as (σ) "(%&Hσ&Hcl)"; first done.
iUpd (auth_open with "[$Hinv $Hl]") as (σ) "(%&Hσ&Hcl)"; first done.
iApply (wp_load_pst _ σ); first eauto using heap_singleton_included.
iIntros "{$Hσ} !> Hσ !==>". iVs ("Hcl" with "* [Hσ]") as "Ha"; first eauto.