Commit ad908d6e authored by Robbert's avatar Robbert

Merge branch 'robbert/super_iModIntro' into 'gen_proofmode'

Super `iModIntro` tactic that generalizes `iAlways`, `iNext`, `iModIntro`, and more

See merge request FP/iris-coq!121
parents 629385ee 3059ff86
Pipeline #7115 passed with stage
in 10 minutes and 52 seconds
......@@ -114,35 +114,26 @@ Separating logic specific tactics
Modalities
----------
- `iModIntro` : introduction of a modality that is an instance of the
`FromModal` type class. Instances include: later, except 0, basic update and
fancy update.
- `iModIntro` : introduction of a modality. The type class `FromModal` is used
to specify which modalities this tactic should introduce. Instances of that
type class include: later, except 0, basic update and fancy update,
persistently, affinely, plainly, absorbingly, absolutely, and relatively.
- `iAlways` : a deprecated alias of `iModIntro`.
- `iNext n` : introduce `n` laters by stripping that number of laters from all
hypotheses. If the argument `n` is not given, it strips one later if the
leftmost conjunct is of the shape `▷ P`, or `n` laters if the leftmost
conjunct is of the shape `▷^n P`.
- `iMod pm_trm as (x1 ... xn) "ipat"` : eliminate a modality `pm_trm` that is
an instance of the `ElimModal` type class. Instances include: later, except 0,
basic update and fancy update.
The persistence and plainness modalities
----------------------------------------
- `iAlways` : introduce a persistence or plainness modality and the spatial
context. In case of a plainness modality, the tactic will prune all persistent
hypotheses that are not plain.
The later modality
------------------
Induction
---------
- `iNext n` : introduce `n` laters by stripping that number of laters from all
hypotheses. If the argument `n` is not given, it strips one later if the
leftmost conjunct is of the shape `▷ P`, or `n` laters if the leftmost
conjunct is of the shape `▷^n P`.
- `iLöb as "IH" forall (x1 ... xn) "selpat"` : perform Löb induction by
generating a hypothesis `IH : ▷ goal`. The tactic generalizes over the Coq
level variables `x1 ... xn`, the hypotheses given by the selection pattern
`selpat`, and the spatial context.
Induction
---------
- `iInduction x as cpat "IH" forall (x1 ... xn) "selpat"` : perform induction on
the Coq term `x`. The Coq introduction pattern is used to name the introduced
variables. The induction hypotheses are inserted into the persistent context
......@@ -229,8 +220,8 @@ appear at the top level:
Items of the selection pattern can be prefixed with `$`, which cause them to
be framed instead of cleared.
- `!%` : introduce a pure goal (and leave the proof mode).
- `!#` : introduce an persistence or plainness modality (by calling `iAlways`).
- `!>` : introduce a modality (by calling `iModIntro`).
- `!>` : introduce a modality by calling `iModIntro`.
- `!#` : introduce a modality by calling `iModIntro` (deprecated).
- `/=` : perform `simpl`.
- `//` : perform `try done` on all goals.
- `//=` : syntactic sugar for `/= //`
......
......@@ -101,6 +101,8 @@ theories/proofmode/notation.v
theories/proofmode/classes.v
theories/proofmode/class_instances.v
theories/proofmode/monpred.v
theories/proofmode/modalities.v
theories/proofmode/modality_instances.v
theories/tests/heap_lang.v
theories/tests/one_shot.v
theories/tests/proofmode.v
......
This diff is collapsed.
From iris.bi Require Export bi.
From iris.proofmode Require Export modalities.
From stdpp Require Import namespaces.
Set Default Proof Using "Type".
Import bi.
......@@ -83,138 +84,22 @@ Arguments IntoPersistent {_} _ _%I _%I : simpl never.
Arguments into_persistent {_} _ _%I _%I {_}.
Hint Mode IntoPersistent + + ! - : typeclass_instances.
(* The `iAlways` tactic is not tied to `persistently` and `affinely`, but can be
instantiated with a variety of comonadic (always-style) modalities.
In order to plug in an always-style modality, one has to decide for both the
persistent and spatial what action should be performed upon introducing the
modality:
- Introduction is only allowed when the context is empty.
- Introduction is only allowed when all hypotheses satisfy some predicate
`C : PROP → Prop` (where `C` should be a type class).
- Introduction will only keep the hypotheses that satisfy some predicate
`C : PROP → Prop` (where `C` should be a type class).
- Introduction will clear the context.
- Introduction will keep the context as-if.
Formally, these actions correspond to the following inductive type: *)
Inductive always_intro_spec (PROP : bi) :=
| AIEnvIsEmpty
| AIEnvForall (C : PROP Prop)
| AIEnvFilter (C : PROP Prop)
| AIEnvClear
| AIEnvId.
Arguments AIEnvIsEmpty {_}.
Arguments AIEnvForall {_} _.
Arguments AIEnvFilter {_} _.
Arguments AIEnvClear {_}.
Arguments AIEnvId {_}.
(* An always-style modality is then a record packing together the modality with
the laws it should satisfy to justify the given actions for both contexts: *)
Record always_modality_mixin {PROP : bi} (M : PROP PROP)
(pspec sspec : always_intro_spec PROP) := {
always_modality_mixin_persistent :
match pspec with
| AIEnvIsEmpty => True
| AIEnvForall C | AIEnvFilter C => P, C P P M ( P)
| AIEnvClear => True
| AIEnvId => P, P M ( P)
end;
always_modality_mixin_spatial :
match sspec with
| AIEnvIsEmpty => True
| AIEnvForall C => P, C P P M P
| AIEnvFilter C => ( P, C P P M P) ( P, Absorbing (M P))
| AIEnvClear => P, Absorbing (M P)
| AIEnvId => False
end;
always_modality_mixin_emp : emp M emp;
always_modality_mixin_mono P Q : (P Q) M P M Q;
always_modality_mixin_and P Q : M P M Q M (P Q);
always_modality_mixin_sep P Q : M P M Q M (P Q)
}.
Record always_modality (PROP : bi) := AlwaysModality {
always_modality_car :> PROP PROP;
always_modality_persistent_spec : always_intro_spec PROP;
always_modality_spatial_spec : always_intro_spec PROP;
always_modality_mixin_of : always_modality_mixin
always_modality_car
always_modality_persistent_spec always_modality_spatial_spec
}.
Arguments AlwaysModality {_} _ {_ _} _.
Arguments always_modality_persistent_spec {_} _.
Arguments always_modality_spatial_spec {_} _.
Section always_modality.
Context {PROP} (M : always_modality PROP).
Lemma always_modality_persistent_forall C P :
always_modality_persistent_spec M = AIEnvForall C C P P M ( P).
Proof. destruct M as [??? []]; naive_solver. Qed.
Lemma always_modality_persistent_filter C P :
always_modality_persistent_spec M = AIEnvFilter C C P P M ( P).
Proof. destruct M as [??? []]; naive_solver. Qed.
Lemma always_modality_persistent_id P :
always_modality_persistent_spec M = AIEnvId P M ( P).
Proof. destruct M as [??? []]; naive_solver. Qed.
Lemma always_modality_spatial_forall C P :
always_modality_spatial_spec M = AIEnvForall C C P P M P.
Proof. destruct M as [??? []]; naive_solver. Qed.
Lemma always_modality_spatial_filter C P :
always_modality_spatial_spec M = AIEnvFilter C C P P M P.
Proof. destruct M as [??? []]; naive_solver. Qed.
Lemma always_modality_spatial_filter_absorbing C P :
always_modality_spatial_spec M = AIEnvFilter C Absorbing (M P).
Proof. destruct M as [??? []]; naive_solver. Qed.
Lemma always_modality_spatial_clear P :
always_modality_spatial_spec M = AIEnvClear Absorbing (M P).
Proof. destruct M as [??? []]; naive_solver. Qed.
Lemma always_modality_spatial_id :
always_modality_spatial_spec M AIEnvId.
Proof. destruct M as [??? []]; naive_solver. Qed.
Lemma always_modality_emp : emp M emp.
Proof. eapply always_modality_mixin_emp, always_modality_mixin_of. Qed.
Lemma always_modality_mono P Q : (P Q) M P M Q.
Proof. eapply always_modality_mixin_mono, always_modality_mixin_of. Qed.
Lemma always_modality_and P Q : M P M Q M (P Q).
Proof. eapply always_modality_mixin_and, always_modality_mixin_of. Qed.
Lemma always_modality_sep P Q : M P M Q M (P Q).
Proof. eapply always_modality_mixin_sep, always_modality_mixin_of. Qed.
Global Instance always_modality_mono' : Proper (() ==> ()) M.
Proof. intros P Q. apply always_modality_mono. Qed.
Global Instance always_modality_flip_mono' : Proper (flip () ==> flip ()) M.
Proof. intros P Q. apply always_modality_mono. Qed.
Global Instance always_modality_proper : Proper (() ==> ()) M.
Proof. intros P Q. rewrite !equiv_spec=> -[??]; eauto using always_modality_mono. Qed.
Lemma always_modality_persistent_forall_big_and C Ps :
always_modality_persistent_spec M = AIEnvForall C
Forall C Ps [] Ps M ( [] Ps).
Proof.
induction 2 as [|P Ps ? _ IH]; simpl.
- by rewrite persistently_pure affinely_True_emp affinely_emp -always_modality_emp.
- rewrite affinely_persistently_and -always_modality_and -IH.
by rewrite {1}(always_modality_persistent_forall _ P).
Qed.
Lemma always_modality_spatial_forall_big_sep C Ps :
always_modality_spatial_spec M = AIEnvForall C
Forall C Ps [] Ps M ([] Ps).
Proof.
induction 2 as [|P Ps ? _ IH]; simpl.
- by rewrite -always_modality_emp.
- by rewrite -always_modality_sep -IH {1}(always_modality_spatial_forall _ P).
Qed.
End always_modality.
Class FromAlways {PROP : bi} (M : always_modality PROP) (P Q : PROP) :=
from_always : M Q P.
Arguments FromAlways {_} _ _%I _%I : simpl never.
Arguments from_always {_} _ _%I _%I {_}.
Hint Mode FromAlways + - ! - : typeclass_instances.
(** The [FromModal M P Q] class is used by the [iModIntro] tactic to transform
a goal [P] into a modality [M] and proposition [Q].
The input is [P] and the outputs are [M] and [Q].
For modalities [M] that do not need to augment the proof mode environment, one
can define an instance [FromModal modality_id (M P) P]. Defining such an
only imposes the proof obligation [P ⊢ M P]. Examples of modalities that have
such an instance are [bupd], [fupd], [except_0], [monPred_relatively] and
[bi_absorbingly]. *)
Class FromModal {PROP1 PROP2 : bi}
(M : modality PROP1 PROP2) (P : PROP2) (Q : PROP1) :=
from_modal : M Q P.
Arguments FromModal {_ _} _ _%I _%I : simpl never.
Arguments from_modal {_ _} _ _%I _%I {_}.
Hint Mode FromModal - + - ! - : typeclass_instances.
Class FromAffinely {PROP : bi} (P Q : PROP) :=
from_affinely : bi_affinely Q P.
......@@ -332,11 +217,6 @@ Arguments IsExcept0 {_} _%I : simpl never.
Arguments is_except_0 {_} _%I {_}.
Hint Mode IsExcept0 + ! : typeclass_instances.
Class FromModal {PROP : bi} (P Q : PROP) := from_modal : Q P.
Arguments FromModal {_} _%I _%I : simpl never.
Arguments from_modal {_} _%I _%I {_}.
Hint Mode FromModal + ! - : typeclass_instances.
Class ElimModal {PROP : bi} (φ : Prop) (P P' : PROP) (Q Q' : PROP) :=
elim_modal : φ P (P' - Q') Q.
Arguments ElimModal {_} _ _%I _%I _%I _%I : simpl never.
......@@ -553,6 +433,16 @@ Arguments FromLaterN {_} _%nat_scope _%I _%I.
Arguments from_laterN {_} _%nat_scope _%I _%I {_}.
Hint Mode FromLaterN + - ! - : typeclass_instances.
(** The class [IntoEmbed P Q] is used to transform hypotheses while introducing
embeddings using [iModIntro].
Input: the proposition [P], output: the proposition [Q] so that [P ⊢ ⎡Q⎤] *)
Class IntoEmbed {PROP PROP' : bi} `{BiEmbed PROP PROP'} (P : PROP') (Q : PROP) :=
into_embed : P Q.
Arguments IntoEmbed {_ _ _} _%I _%I.
Arguments into_embed {_ _ _} _%I _%I {_}.
Hint Mode IntoEmbed + + + ! - : typeclass_instances.
(* We use two type classes for [AsValid], in order to avoid loops in
typeclass search. Indeed, the [as_valid_embed] instance would try
to add an arbitrary number of embeddings. To avoid this, the
......@@ -644,8 +534,8 @@ Instance into_exist_tc_opaque {PROP : bi} {A} (P : PROP) (Φ : A → PROP) :
IntoExist P Φ IntoExist (tc_opaque P) Φ := id.
Instance into_forall_tc_opaque {PROP : bi} {A} (P : PROP) (Φ : A PROP) :
IntoForall P Φ IntoForall (tc_opaque P) Φ := id.
Instance from_modal_tc_opaque {PROP : bi} (P Q : PROP) :
FromModal P Q FromModal (tc_opaque P) Q := id.
Instance from_modal_tc_opaque {PROP : bi} M (P Q : PROP) :
FromModal M P Q FromModal M (tc_opaque P) Q := id.
Instance elim_modal_tc_opaque {PROP : bi} φ (P P' Q Q' : PROP) :
ElimModal φ P P' Q Q' ElimModal φ (tc_opaque P) P' Q Q' := id.
Instance into_inv_tc_opaque {PROP : bi} (P : PROP) N :
......
This diff is collapsed.
From iris.bi Require Export bi.
From stdpp Require Import namespaces.
Set Default Proof Using "Type".
Import bi.
(** The `iModIntro` tactic is not tied the Iris modalities, but can be
instantiated with a variety of modalities.
In order to plug in a modality, one has to decide for both the persistent and
spatial what action should be performed upon introducing the modality:
- Introduction is only allowed when the context is empty.
- Introduction is only allowed when all hypotheses satisfy some predicate
`C : PROP → Prop` (where `C` should be a type class).
- Introduction will transform each hypotheses using a type class
`C : PROP → PROP → Prop`, where the first parameter is the input and the
second parameter is the output. Hypotheses that cannot be transformed (i.e.
for which no instance of `C` can be found) will be cleared.
- Introduction will clear the context.
- Introduction will keep the context as-if.
Formally, these actions correspond to the following inductive type: *)
Inductive modality_intro_spec (PROP1 : bi) : bi Type :=
| MIEnvIsEmpty {PROP2 : bi} : modality_intro_spec PROP1 PROP2
| MIEnvForall (C : PROP1 Prop) : modality_intro_spec PROP1 PROP1
| MIEnvTransform {PROP2 : bi} (C : PROP2 PROP1 Prop) : modality_intro_spec PROP1 PROP2
| MIEnvClear {PROP2} : modality_intro_spec PROP1 PROP2
| MIEnvId : modality_intro_spec PROP1 PROP1.
Arguments MIEnvIsEmpty {_ _}.
Arguments MIEnvForall {_} _.
Arguments MIEnvTransform {_ _} _.
Arguments MIEnvClear {_ _}.
Arguments MIEnvId {_}.
Notation MIEnvFilter C := (MIEnvTransform (TCDiag C)).
Definition modality_intro_spec_persistent {PROP1 PROP2}
(s : modality_intro_spec PROP1 PROP2) : (PROP1 PROP2) Prop :=
match s with
| MIEnvIsEmpty => λ M, True
| MIEnvForall C => λ M,
( P, C P P M ( P))
( P Q, M P M Q M (P Q))
| MIEnvTransform C => λ M,
( P Q, C P Q P M ( Q))
( P Q, M P M Q M (P Q))
| MIEnvClear => λ M, True
| MIEnvId => λ M, P, P M ( P)
end.
Definition modality_intro_spec_spatial {PROP1 PROP2}
(s : modality_intro_spec PROP1 PROP2) : (PROP1 PROP2) Prop :=
match s with
| MIEnvIsEmpty => λ M, True
| MIEnvForall C => λ M, P, C P P M P
| MIEnvTransform C => λ M, P Q, C P Q P M Q
| MIEnvClear => λ M, P, Absorbing (M P)
| MIEnvId => λ M, P, P M P
end.
(* A modality is then a record packing together the modality with the laws it
should satisfy to justify the given actions for both contexts: *)
Record modality_mixin {PROP1 PROP2 : bi} (M : PROP1 PROP2)
(pspec sspec : modality_intro_spec PROP1 PROP2) := {
modality_mixin_persistent : modality_intro_spec_persistent pspec M;
modality_mixin_spatial : modality_intro_spec_spatial sspec M;
modality_mixin_emp : emp M emp;
modality_mixin_mono P Q : (P Q) M P M Q;
modality_mixin_sep P Q : M P M Q M (P Q)
}.
Record modality (PROP1 PROP2 : bi) := Modality {
modality_car :> PROP1 PROP2;
modality_persistent_spec : modality_intro_spec PROP1 PROP2;
modality_spatial_spec : modality_intro_spec PROP1 PROP2;
modality_mixin_of :
modality_mixin modality_car modality_persistent_spec modality_spatial_spec
}.
Arguments Modality {_ _} _ {_ _} _.
Arguments modality_persistent_spec {_ _} _.
Arguments modality_spatial_spec {_ _} _.
Section modality.
Context {PROP1 PROP2} (M : modality PROP1 PROP2).
Lemma modality_persistent_transform C P Q :
modality_persistent_spec M = MIEnvTransform C C P Q P M ( Q).
Proof. destruct M as [??? []]; naive_solver. Qed.
Lemma modality_and_transform C P Q :
modality_persistent_spec M = MIEnvTransform C M P M Q M (P Q).
Proof. destruct M as [??? []]; naive_solver. Qed.
Lemma modality_spatial_transform C P Q :
modality_spatial_spec M = MIEnvTransform C C P Q P M Q.
Proof. destruct M as [??? []]; naive_solver. Qed.
Lemma modality_spatial_clear P :
modality_spatial_spec M = MIEnvClear Absorbing (M P).
Proof. destruct M as [??? []]; naive_solver. Qed.
Lemma modality_emp : emp M emp.
Proof. eapply modality_mixin_emp, modality_mixin_of. Qed.
Lemma modality_mono P Q : (P Q) M P M Q.
Proof. eapply modality_mixin_mono, modality_mixin_of. Qed.
Lemma modality_sep P Q : M P M Q M (P Q).
Proof. eapply modality_mixin_sep, modality_mixin_of. Qed.
Global Instance modality_mono' : Proper (() ==> ()) M.
Proof. intros P Q. apply modality_mono. Qed.
Global Instance modality_flip_mono' : Proper (flip () ==> flip ()) M.
Proof. intros P Q. apply modality_mono. Qed.
Global Instance modality_proper : Proper (() ==> ()) M.
Proof. intros P Q. rewrite !equiv_spec=> -[??]; eauto using modality_mono. Qed.
End modality.
Section modality1.
Context {PROP} (M : modality PROP PROP).
Lemma modality_persistent_forall C P :
modality_persistent_spec M = MIEnvForall C C P P M ( P).
Proof. destruct M as [??? []]; naive_solver. Qed.
Lemma modality_and_forall C P Q :
modality_persistent_spec M = MIEnvForall C M P M Q M (P Q).
Proof. destruct M as [??? []]; naive_solver. Qed.
Lemma modality_persistent_id P :
modality_persistent_spec M = MIEnvId P M ( P).
Proof. destruct M as [??? []]; naive_solver. Qed.
Lemma modality_spatial_forall C P :
modality_spatial_spec M = MIEnvForall C C P P M P.
Proof. destruct M as [??? []]; naive_solver. Qed.
Lemma modality_spatial_id P :
modality_spatial_spec M = MIEnvId P M P.
Proof. destruct M as [??? []]; naive_solver. Qed.
Lemma modality_persistent_forall_big_and C Ps :
modality_persistent_spec M = MIEnvForall C
Forall C Ps [] Ps M ( [] Ps).
Proof.
induction 2 as [|P Ps ? _ IH]; simpl.
- by rewrite persistently_pure affinely_True_emp affinely_emp -modality_emp.
- rewrite affinely_persistently_and -modality_and_forall // -IH.
by rewrite {1}(modality_persistent_forall _ P).
Qed.
Lemma modality_spatial_forall_big_sep C Ps :
modality_spatial_spec M = MIEnvForall C
Forall C Ps [] Ps M ([] Ps).
Proof.
induction 2 as [|P Ps ? _ IH]; simpl.
- by rewrite -modality_emp.
- by rewrite -modality_sep -IH {1}(modality_spatial_forall _ P).
Qed.
End modality1.
(** The identity modality [modality_id] can be used in combination with
[FromModal modality_id] to support introduction for modalities that enjoy
[P ⊢ M P]. This is done by defining an instance [FromModal modality_id (M P) P],
which will instruct [iModIntro] to introduce the modality without modifying the
proof mode context. Examples of such modalities are [bupd], [fupd], [except_0],
[monPred_relatively] and [bi_absorbingly]. *)
Lemma modality_id_mixin {PROP : bi} : modality_mixin (@id PROP) MIEnvId MIEnvId.
Proof. split; simpl; eauto. Qed.
Definition modality_id {PROP : bi} := Modality (@id PROP) modality_id_mixin.
From iris.bi Require Import bi.
From iris.proofmode Require Export classes.
Set Default Proof Using "Type".
Import bi.
Section bi_modalities.
Context {PROP : bi}.
Lemma modality_persistently_mixin :
modality_mixin (@bi_persistently PROP) MIEnvId MIEnvClear.
Proof.
split; simpl; eauto using equiv_entails_sym, persistently_intro,
persistently_mono, persistently_sep_2 with typeclass_instances.
Qed.
Definition modality_persistently :=
Modality _ modality_persistently_mixin.
Lemma modality_affinely_mixin :
modality_mixin (@bi_affinely PROP) MIEnvId (MIEnvForall Affine).
Proof.
split; simpl; eauto using equiv_entails_sym, affinely_intro, affinely_mono,
affinely_sep_2 with typeclass_instances.
Qed.
Definition modality_affinely :=
Modality _ modality_affinely_mixin.
Lemma modality_affinely_persistently_mixin :
modality_mixin (λ P : PROP, P)%I MIEnvId MIEnvIsEmpty.
Proof.
split; simpl; eauto using equiv_entails_sym, affinely_persistently_emp,
affinely_mono, persistently_mono, affinely_persistently_idemp,
affinely_persistently_sep_2 with typeclass_instances.
Qed.
Definition modality_affinely_persistently :=
Modality _ modality_affinely_persistently_mixin.
Lemma modality_plainly_mixin :
modality_mixin (@bi_plainly PROP) (MIEnvForall Plain) MIEnvClear.
Proof.
split; simpl; split_and?; eauto using equiv_entails_sym, plainly_intro,
plainly_mono, plainly_and, plainly_sep_2 with typeclass_instances.
Qed.
Definition modality_plainly :=
Modality _ modality_plainly_mixin.
Lemma modality_affinely_plainly_mixin :
modality_mixin (λ P : PROP, P)%I (MIEnvForall Plain) MIEnvIsEmpty.
Proof.
split; simpl; split_and?; eauto using equiv_entails_sym,
affinely_plainly_emp, affinely_intro,
plainly_intro, affinely_mono, plainly_mono, affinely_plainly_idemp,
affinely_plainly_and, affinely_plainly_sep_2 with typeclass_instances.
Qed.
Definition modality_affinely_plainly :=
Modality _ modality_affinely_plainly_mixin.
Lemma modality_embed_mixin `{BiEmbedding PROP PROP'} :
modality_mixin (@bi_embed PROP PROP' _)
(MIEnvTransform IntoEmbed) (MIEnvTransform IntoEmbed).
Proof.
split; simpl; split_and?;
eauto using equiv_entails_sym, bi_embed_emp, bi_embed_sep, bi_embed_and.
- intros P Q. rewrite /IntoEmbed=> ->.
by rewrite bi_embed_affinely bi_embed_persistently.
- by intros P Q ->.
Qed.
Definition modality_embed `{BiEmbedding PROP PROP'} :=
Modality _ modality_embed_mixin.
End bi_modalities.
Section sbi_modalities.
Context {PROP : sbi}.
Lemma modality_laterN_mixin n :
modality_mixin (@sbi_laterN PROP n)
(MIEnvTransform (MaybeIntoLaterN false n)) (MIEnvTransform (MaybeIntoLaterN false n)).
Proof.
split; simpl; split_and?; eauto using equiv_entails_sym, laterN_intro,
laterN_mono, laterN_and, laterN_sep with typeclass_instances.
rewrite /MaybeIntoLaterN=> P Q ->. by rewrite laterN_affinely_persistently_2.
Qed.
Definition modality_laterN n :=
Modality _ (modality_laterN_mixin n).
End sbi_modalities.
......@@ -14,32 +14,22 @@ Proof. by rewrite /IsBiIndexRel. Qed.
Hint Extern 1 (IsBiIndexRel _ _) => unfold IsBiIndexRel; assumption
: typeclass_instances.
Section always_modalities.
Context {I : biIndex} {PROP : bi}.
Section modalities.
Context {I : biIndex} {PROP : bi}.
Lemma always_modality_absolutely_mixin :
always_modality_mixin (@monPred_absolutely I PROP)
(AIEnvFilter Absolute) (AIEnvForall Absolute).
Lemma modality_absolutely_mixin :
modality_mixin (@monPred_absolutely I PROP)
(MIEnvFilter Absolute) (MIEnvFilter Absolute).
Proof.
split; eauto using bi.equiv_entails_sym, absolute_absolutely,
monPred_absolutely_mono, monPred_absolutely_and,
monPred_absolutely_sep_2 with typeclass_instances.
split; simpl; split_and?; intros;
try match goal with H : TCDiag _ _ _ |- _ => destruct H end;
eauto using bi.equiv_entails_sym, absolute_absolutely,
monPred_absolutely_mono, monPred_absolutely_and,
monPred_absolutely_sep_2 with typeclass_instances.
Qed.
Definition always_modality_absolutely :=
AlwaysModality _ always_modality_absolutely_mixin.
(* We can only filter the spatial context in case the BI is affine *)
Lemma always_modality_absolutely_filter_spatial_mixin `{BiAffine PROP} :
always_modality_mixin (@monPred_absolutely I PROP)
(AIEnvFilter Absolute) (AIEnvFilter Absolute).
Proof.
split; eauto using bi.equiv_entails_sym, absolute_absolutely,
monPred_absolutely_mono, monPred_absolutely_and,
monPred_absolutely_sep_2 with typeclass_instances.
Qed.
Definition always_modality_absolutely_filter_spatial `{BiAffine PROP} :=
AlwaysModality _ always_modality_absolutely_filter_spatial_mixin.
End always_modalities.
Definition modality_absolutely :=
Modality _ modality_absolutely_mixin.
End modalities.
Section bi.
Context {I : biIndex} {PROP : bi}.
......@@ -50,12 +40,12 @@ Implicit Types 𝓟 𝓠 𝓡 : PROP.
Implicit Types φ : Prop.
Implicit Types i j : I.
Global Instance from_always_absolutely P :
FromAlways always_modality_absolutely ( P) P | 1.
Proof. by rewrite /FromAlways. Qed.
Global Instance from_always_absolutely_filter_spatial `{BiAffine PROP} P :
FromAlways always_modality_absolutely_filter_spatial ( P) P | 0.
Proof. by rewrite /FromAlways. Qed.
Global Instance from_modal_absolutely P :
FromModal modality_absolutely ( P) P | 1.
Proof. by rewrite /FromModal. Qed.
Global Instance from_modal_relatively P :
FromModal modality_id ( P) P | 1.
Proof. by rewrite /FromModal /= -monPred_relatively_intro. Qed.
Global Instance make_monPred_at_pure φ i : MakeMonPredAt i ⌜φ⌝ ⌜φ⌝.