D.iris_extra.proofmode_pupd
Automation for the "persistent update" modalities.
This reduces goal like ⊢ <PB> P1 -∗ <PB> P2 -∗ <PB> Q to ⊢ □ P1 -* □ P2 -∗ □ Q, by running all ghost updates and (optionally) introducing the ghost update modality. Support for <PF{E}> works similarly, so we focus on <PB> in these docs.<PB> P1 -∗ <PB> P2 -∗ <PB> Qreduce to boxed wands like
□ (□ P1 -* □ P2 -∗ <PB> Q)but ElimModal does not allow generating boxed wands:
Class ElimModal {PROP : bi} (φ : Prop) (p p' : bool) (P P' : PROP) (Q Q' : PROP) := elim_modal : φ → □?p P ∗ (□?p' P' -∗ Q') ⊢ Q.
From D Require Export iris_prelude iris_extra.pupd.
Implicit Type (Σ : gFunctors) (E : coPset).
Class ElimPersModal {PROP : bi} (P Q P' Q' : PROP) :=
elim_pers_modal : (□(P' -∗ Q') ⊢ P -∗ Q).
#[global] Hint Mode ElimPersModal + + + - - : typeclass_instances.
#[global] Arguments elim_pers_modal {_}.
Class StripPUpd {PROP : bi} (P Q : PROP) :=
strip_pupd : P ⊢ Q.
#[global] Hint Mode StripPUpd + - + : typeclass_instances.
#[global] Arguments strip_pupd {_}.
Section instances.
Context {PROP : bi}.
Implicit Type (P Q R : PROP).
(* Fallback to allow skipping intuitionistic hypotheses *)
#[global] Instance elim_pers_modal_wand_noelim P Q Q' R R' `{!Persistent P, !Affine P} :
ElimPersModal Q R Q' R' →
ElimPersModal P (Q -∗ R) P (Q' -∗ R') | 50.
Proof.
rewrite /ElimPersModal.
iIntros (W) "#W #P Q".
iApply (W with "(W P) Q").
Qed.
#[global] Instance strip_pupd_wand P Q R :
StripPUpd P Q →
StripPUpd (R -∗ P) (R -∗ Q).
Proof.
rewrite /StripPUpd.
iIntros (PQ) "RP R".
iApply (PQ with "(RP R)").
Qed.
#[global] Instance strip_pupd_box_mono P Q :
StripPUpd P Q →
StripPUpd (□ P) (□ Q) | 10.
Proof. apply bi.intuitionistically_mono'. Qed.
Section bupd.
Context `{!BiBUpd PROP}.
#[global] Instance elim_pers_modal_int_bupd_int P R :
ElimPersModal (<PB> P) (<PB> R) (□ P) (<PB> R).
Proof.
rewrite /ElimPersModal.
iIntros "W P". iApply (PB_bind with "P W").
Qed.
(* Meant to strip modalities from all premises, unlike elim_pers_modal_wand.
Alternative to elim_pers_modal_wand_all *)
#[global] Instance elim_pers_modal_wand_elim P Q R R' :
(∀ Q, ElimPersModal (<PB> Q) R (□ Q) R') →
ElimPersModal (<PB> P) (<PB> Q -∗ R) (□ P) (□ Q -∗ R').
Proof.
rewrite /ElimPersModal.
iIntros (W) "#W #P #Q".
iApply (W (P ∧ Q)%I). {
iIntros "!> {P Q} #[P Q]".
iApply ("W" with "P Q").
}
iApply (PB_and_curry with "P Q").
Qed.
#[global] Instance strip_pbupd P : StripPUpd (□ P) (<PB> P).
Proof. apply PB_return. Qed.
End bupd.
Section fupd.
Context `{!BiFUpd PROP} E.
#[global] Instance elim_pers_modal_int_fupd_int P R :
ElimPersModal (<PF{E}> P) (<PF{E}> R) (□ P) (<PF{E}> R).
Proof.
rewrite /ElimPersModal.
iIntros "W P". iApply (PF_bind with "P W").
Qed.
(* Meant to strip modalities from all premises, unlike elim_pers_modal_wand.
Alternative to elim_pers_modal_wand_all *)
#[global] Instance elim_pers_modal_fupd_wand_elim P Q R R' :
(∀ Q, ElimPersModal (<PF{E}> Q) R (□ Q) R') →
ElimPersModal (<PF{E}> P) (<PF{E}> Q -∗ R) (□ P) (□ Q -∗ R').
Proof.
rewrite /ElimPersModal.
iIntros (W) "#W #P #Q".
iApply (W (P ∧ Q)%I). {
iIntros "!> {P Q} #[P Q]".
iApply ("W" with "P Q").
}
iApply (PF_and_curry with "P Q").
Qed.
#[global] Instance strip_pfupd P : StripPUpd (□ P) (<PF{E}> P).
Proof. apply PF_return. Qed.
End fupd.
End instances.
Ltac pupd' :=
try (iApply elim_pers_modal; []; iModIntro (□ _)%I).
Ltac strip :=
iApply (strip_pupd with "[-]"); [].
Ltac pupd :=
try (pupd'; strip).
Implicit Type (Σ : gFunctors) (E : coPset).
Class ElimPersModal {PROP : bi} (P Q P' Q' : PROP) :=
elim_pers_modal : (□(P' -∗ Q') ⊢ P -∗ Q).
#[global] Hint Mode ElimPersModal + + + - - : typeclass_instances.
#[global] Arguments elim_pers_modal {_}.
Class StripPUpd {PROP : bi} (P Q : PROP) :=
strip_pupd : P ⊢ Q.
#[global] Hint Mode StripPUpd + - + : typeclass_instances.
#[global] Arguments strip_pupd {_}.
Section instances.
Context {PROP : bi}.
Implicit Type (P Q R : PROP).
(* Fallback to allow skipping intuitionistic hypotheses *)
#[global] Instance elim_pers_modal_wand_noelim P Q Q' R R' `{!Persistent P, !Affine P} :
ElimPersModal Q R Q' R' →
ElimPersModal P (Q -∗ R) P (Q' -∗ R') | 50.
Proof.
rewrite /ElimPersModal.
iIntros (W) "#W #P Q".
iApply (W with "(W P) Q").
Qed.
#[global] Instance strip_pupd_wand P Q R :
StripPUpd P Q →
StripPUpd (R -∗ P) (R -∗ Q).
Proof.
rewrite /StripPUpd.
iIntros (PQ) "RP R".
iApply (PQ with "(RP R)").
Qed.
#[global] Instance strip_pupd_box_mono P Q :
StripPUpd P Q →
StripPUpd (□ P) (□ Q) | 10.
Proof. apply bi.intuitionistically_mono'. Qed.
Section bupd.
Context `{!BiBUpd PROP}.
#[global] Instance elim_pers_modal_int_bupd_int P R :
ElimPersModal (<PB> P) (<PB> R) (□ P) (<PB> R).
Proof.
rewrite /ElimPersModal.
iIntros "W P". iApply (PB_bind with "P W").
Qed.
(* Meant to strip modalities from all premises, unlike elim_pers_modal_wand.
Alternative to elim_pers_modal_wand_all *)
#[global] Instance elim_pers_modal_wand_elim P Q R R' :
(∀ Q, ElimPersModal (<PB> Q) R (□ Q) R') →
ElimPersModal (<PB> P) (<PB> Q -∗ R) (□ P) (□ Q -∗ R').
Proof.
rewrite /ElimPersModal.
iIntros (W) "#W #P #Q".
iApply (W (P ∧ Q)%I). {
iIntros "!> {P Q} #[P Q]".
iApply ("W" with "P Q").
}
iApply (PB_and_curry with "P Q").
Qed.
#[global] Instance strip_pbupd P : StripPUpd (□ P) (<PB> P).
Proof. apply PB_return. Qed.
End bupd.
Section fupd.
Context `{!BiFUpd PROP} E.
#[global] Instance elim_pers_modal_int_fupd_int P R :
ElimPersModal (<PF{E}> P) (<PF{E}> R) (□ P) (<PF{E}> R).
Proof.
rewrite /ElimPersModal.
iIntros "W P". iApply (PF_bind with "P W").
Qed.
(* Meant to strip modalities from all premises, unlike elim_pers_modal_wand.
Alternative to elim_pers_modal_wand_all *)
#[global] Instance elim_pers_modal_fupd_wand_elim P Q R R' :
(∀ Q, ElimPersModal (<PF{E}> Q) R (□ Q) R') →
ElimPersModal (<PF{E}> P) (<PF{E}> Q -∗ R) (□ P) (□ Q -∗ R').
Proof.
rewrite /ElimPersModal.
iIntros (W) "#W #P #Q".
iApply (W (P ∧ Q)%I). {
iIntros "!> {P Q} #[P Q]".
iApply ("W" with "P Q").
}
iApply (PF_and_curry with "P Q").
Qed.
#[global] Instance strip_pfupd P : StripPUpd (□ P) (<PF{E}> P).
Proof. apply PF_return. Qed.
End fupd.
End instances.
Ltac pupd' :=
try (iApply elim_pers_modal; []; iModIntro (□ _)%I).
Ltac strip :=
iApply (strip_pupd with "[-]"); [].
Ltac pupd :=
try (pupd'; strip).