Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Marianna Rapoport
iris-coq
Commits
1b85d654
Commit
1b85d654
authored
Oct 21, 2016
by
Robbert Krebbers
Browse files
Rename rvs -> bupd (basic update), pvs -> fupd (fancy update).
And also rename the corresponding proof mode tactics.
parent
aec84909
Changes
43
Hide whitespace changes
Inline
Side-by-side
ProofMode.md
View file @
1b85d654
...
...
@@ -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, a
n 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 shift
s, and pure connectives.
existential quantifiers, implications and wand, always
,
later
and update
modalitie
s, 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 a
n 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 a
n 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 a
n 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
...
...
_CoqProject
View file @
1b85d654
...
...
@@ -69,7 +69,7 @@ program_logic/lifting.v
program_logic/invariants.v
program_logic/wsat.v
program_logic/weakestpre.v
program_logic/
pviewshift
s.v
program_logic/
fancy_update
s.v
program_logic/hoare.v
program_logic/viewshifts.v
program_logic/language.v
...
...
algebra/double_negation.v
View file @
1b85d654
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_nn
vs
{
M
}
(
P
:
uPred
M
)
:
uPred
M
:
=
Definition
uPred_nn
upd
{
M
}
(
P
:
uPred
M
)
:
uPred
M
:
=
∀
n
,
(
P
-
★
▷
^
n
False
)
-
★
▷
^
n
False
.
Notation
"|=n=> Q"
:
=
(
uPred_nn
vs
Q
)
Notation
"|=n=> Q"
:
=
(
uPred_nn
upd
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 nn
vs
.
(* It is easy to show that most of the basic properties of
bupd
that
are used throughout Iris hold for nn
upd
.
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 nn
vs
is of the form
here is slightly different, because nn
upd
is of the form
∀ n, (- -★ (Q n)) -★ (Q n), but the proofs carry over straightforwardly.
*)
Lemma
nn
vs
_intro
P
:
P
=
n
=>
P
.
Lemma
nn
upd
_intro
P
:
P
=
n
=>
P
.
Proof
.
apply
forall_intro
=>?.
apply
wand_intro_l
,
wand_elim_l
.
Qed
.
Lemma
nn
vs
_mono
P
Q
:
(
P
⊢
Q
)
→
(|=
n
=>
P
)
=
n
=>
Q
.
Lemma
nn
upd
_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_nn
vs
(
forall_elim
n
).
rewrite
/
uPred_nn
upd
(
forall_elim
n
).
apply
wand_elim_r
.
Qed
.
Lemma
nn
vs
_frame_r
P
R
:
(|=
n
=>
P
)
★
R
=
n
=>
P
★
R
.
Lemma
nn
upd
_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_nn
vs
(
forall_elim
n
).
rewrite
/
uPred_nn
upd
(
forall_elim
n
).
by
rewrite
-
assoc
wand_elim_r
wand_elim_l
.
Qed
.
Lemma
nn
vs
_ownM_updateP
x
(
Φ
:
M
→
Prop
)
:
Lemma
nn
upd
_ownM_updateP
x
(
Φ
:
M
→
Prop
)
:
x
~~>
:
Φ
→
uPred_ownM
x
=
n
=>
∃
y
,
■
Φ
y
∧
uPred_ownM
y
.
Proof
.
intros
H
rvs
.
split
.
rewrite
/
uPred_nn
vs
.
repeat
uPred
.
unseal
.
intros
H
bupd
.
split
.
rewrite
/
uPred_nn
upd
.
repeat
uPred
.
unseal
.
intros
n
y
?
Hown
a
.
red
;
rewrite
//=
=>
n'
yf
??.
inversion
Hown
as
(
x'
&
Hequiv
).
edestruct
(
H
rvs
n'
(
Some
(
x'
⋅
yf
)))
as
(
y'
&?&?)
;
eauto
.
edestruct
(
H
bupd
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
nn
vs
_trans
P
:
(|=
n
=>
|=
n
=>
P
)
⊢
(|=
n
=>
P
).
Remark
nn
upd
_trans
P
:
(|=
n
=>
|=
n
=>
P
)
⊢
(|=
n
=>
P
).
Proof
.
rewrite
/
uPred_nn
vs
.
rewrite
/
uPred_nn
upd
.
apply
forall_intro
=>
a
.
apply
wand_intro_l
.
rewrite
(
forall_elim
a
).
rewrite
(
nn
vs
_intro
(
P
-
★
_
)).
rewrite
/
uPred_nn
vs
.
rewrite
(
nn
upd
_intro
(
P
-
★
_
)).
rewrite
/
uPred_nn
upd
.
(* 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
nn
vs
is the limit of a the following sequence:
nn
upd
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 nn
vs
is transitive. *)
is transitive. It turns out that this implies that nn
upd
is transitive. *)
(* The definition of the sequence above: *)
Fixpoint
uPred_nn
vs
_k
{
M
}
k
(
P
:
uPred
M
)
:
uPred
M
:
=
Fixpoint
uPred_nn
upd
_k
{
M
}
k
(
P
:
uPred
M
)
:
uPred
M
:
=
((
P
-
★
▷
^
k
False
)
-
★
▷
^
k
False
)
∧
match
k
with
O
=>
True
|
S
k'
=>
uPred_nn
vs
_k
k'
P
|
S
k'
=>
uPred_nn
upd
_k
k'
P
end
.
Notation
"|=n=>_ k Q"
:
=
(
uPred_nn
vs
_k
k
Q
)
Notation
"|=n=>_ k Q"
:
=
(
uPred_nn
upd
_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 -- nn
vs
implies nn
vs
_k for each k *)
Lemma
nn
vs
_trunc1
k
P
:
(|=
n
=>
P
)
⊢
|=
n
=>
_k
P
.
(* One direction of the limiting process is easy -- nn
upd
implies nn
upd
_k for each k *)
Lemma
nn
upd
_trunc1
k
P
:
(|=
n
=>
P
)
⊢
|=
n
=>
_k
P
.
Proof
.
induction
k
.
-
rewrite
/
uPred_nn
vs
_k
/
uPred_nn
vs
.
-
rewrite
/
uPred_nn
upd
_k
/
uPred_nn
upd
.
rewrite
(
forall_elim
0
)
//=
right_id
//.
-
simpl
.
apply
and_intro
;
auto
.
rewrite
/
uPred_nn
vs
.
rewrite
/
uPred_nn
upd
.
rewrite
(
forall_elim
(
S
k
))
//=.
Qed
.
Lemma
nn
vs
_k_elim
n
k
P
:
n
≤
k
→
((|=
n
=>
_k
P
)
★
(
P
-
★
(
▷
^
n
False
))
⊢
(
▷
^
n
False
))%
I
.
Lemma
nn
upd
_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
nn
vs
_k_unfold
k
P
:
Lemma
nn
upd
_k_unfold
k
P
:
(|=
n
=>
_
(
S
k
)
P
)
⊣
⊢
((
P
-
★
(
▷
^(
S
k
)
False
))
-
★
(
▷
^(
S
k
)
False
))
∧
(|=
n
=>
_k
P
).
Proof
.
done
.
Qed
.
Lemma
nn
vs
_k_unfold'
k
P
n
x
:
Lemma
nn
upd
_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
nn
vs
_k_weaken
k
P
:
(|=
n
=>
_
(
S
k
)
P
)
⊢
|=
n
=>
_k
P
.
Proof
.
by
rewrite
nn
vs
_k_unfold
and_elim_r
.
Qed
.
Lemma
nn
upd
_k_weaken
k
P
:
(|=
n
=>
_
(
S
k
)
P
)
⊢
|=
n
=>
_k
P
.
Proof
.
by
rewrite
nn
upd
_k_unfold
and_elim_r
.
Qed
.
(* Now we are ready to show nn
vs
is the limit -- ie, for each k, it is within distance k
(* Now we are ready to show nn
upd
is the limit -- ie, for each k, it is within distance k
of the kth term of the sequence *)
Lemma
nn
vs_nnvs
_k_dist
k
P
:
(|=
n
=>
P
)%
I
≡
{
k
}
≡
(|=
n
=>
_k
P
)%
I
.
Lemma
nn
upd_nnupd
_k_dist
k
P
:
(|=
n
=>
P
)%
I
≡
{
k
}
≡
(|=
n
=>
_k
P
)%
I
.
split
;
intros
n'
x
Hle
Hx
.
split
.
-
by
apply
(
nn
vs
_trunc1
k
).
-
by
apply
(
nn
upd
_trunc1
k
).
-
revert
n'
x
Hle
Hx
;
induction
k
;
intros
n'
x
Hle
Hx
;
rewrite
?nn
vs
_k_unfold'
/
uPred_nn
vs
.
rewrite
?nn
upd
_k_unfold'
/
uPred_nn
upd
.
*
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
:
nn
vs
_k_elim
.
unseal
.
intros
Hnn
vs
k
.
****
move
:
nn
upd
_k_elim
.
unseal
.
intros
Hnn
upd
k
.
eapply
laterN_big
;
eauto
.
unseal
.
eapply
(
Hnn
vs
k
n
k
)
;
first
omega
;
eauto
.
eapply
(
Hnn
upd
k
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
.
(* nn
vs
_k has a number of structural properties, including transitivity *)
Lemma
nn
vs
_k_intro
k
P
:
P
⊢
(|=
n
=>
_k
P
).
(* nn
upd
_k has a number of structural properties, including transitivity *)
Lemma
nn
upd
_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
nn
vs
_k_mono
k
P
Q
:
(
P
⊢
Q
)
→
(|=
n
=>
_k
P
)
⊢
(|=
n
=>
_k
Q
).
Lemma
nn
upd
_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
nn
vs
_k_mono'
k
:
Proper
((
⊢
)
==>
(
⊢
))
(@
uPred_nn
vs
_k
M
k
).
Proof
.
by
intros
P
P'
HP
;
apply
nn
vs
_k_mono
.
Qed
.
Instance
nn
upd
_k_mono'
k
:
Proper
((
⊢
)
==>
(
⊢
))
(@
uPred_nn
upd
_k
M
k
).
Proof
.
by
intros
P
P'
HP
;
apply
nn
upd
_k_mono
.
Qed
.
Instance
nn
vs
_k_ne
k
n
:
Proper
(
dist
n
==>
dist
n
)
(@
uPred_nn
vs
_k
M
k
).
Instance
nn
upd
_k_ne
k
n
:
Proper
(
dist
n
==>
dist
n
)
(@
uPred_nn
upd
_k
M
k
).
Proof
.
induction
k
;
rewrite
//=
?right_id
=>
P
P'
HP
;
by
rewrite
HP
.
Qed
.
Lemma
nn
vs
_k_proper
k
P
Q
:
(
P
⊣
⊢
Q
)
→
(|=
n
=>
_k
P
)
⊣
⊢
(|=
n
=>
_k
Q
).
Proof
.
intros
HP
;
apply
(
anti_symm
(
⊢
))
;
eapply
nn
vs
_k_mono
;
by
rewrite
HP
.
Qed
.
Instance
nn
vs
_k_proper'
k
:
Proper
((
⊣
⊢
)
==>
(
⊣
⊢
))
(@
uPred_nn
vs
_k
M
k
).
Proof
.
by
intros
P
P'
HP
;
apply
nn
vs
_k_proper
.
Qed
.
Lemma
nn
upd
_k_proper
k
P
Q
:
(
P
⊣
⊢
Q
)
→
(|=
n
=>
_k
P
)
⊣
⊢
(|=
n
=>
_k
Q
).
Proof
.
intros
HP
;
apply
(
anti_symm
(
⊢
))
;
eapply
nn
upd
_k_mono
;
by
rewrite
HP
.
Qed
.
Instance
nn
upd
_k_proper'
k
:
Proper
((
⊣
⊢
)
==>
(
⊣
⊢
))
(@
uPred_nn
upd
_k
M
k
).
Proof
.
by
intros
P
P'
HP
;
apply
nn
upd
_k_proper
.
Qed
.
Lemma
nn
vs
_k_trans
k
P
:
(|=
n
=>
_k
|=
n
=>
_k
P
)
⊢
(|=
n
=>
_k
P
).
Lemma
nn
upd
_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
}(
nn
vs
_k_intro
0
(
P
-
★
False
)%
I
)
//=
?right_id
.
apply
wand_elim_r
.
-
rewrite
{
2
}(
nn
vs
_k_unfold
k
P
).
rewrite
{
1
}(
nn
upd
_k_intro
0
(
P
-
★
False
)%
I
)
//=
?right_id
.
apply
wand_elim_r
.
-
rewrite
{
2
}(
nn
upd
_k_unfold
k
P
).
apply
and_intro
.
*
rewrite
(
nn
vs
_k_unfold
k
P
).
rewrite
and_elim_l
.
rewrite
nn
vs
_k_unfold
.
rewrite
and_elim_l
.
*
rewrite
(
nn
upd
_k_unfold
k
P
).
rewrite
and_elim_l
.
rewrite
nn
upd
_k_unfold
.
rewrite
and_elim_l
.
apply
wand_intro_l
.
rewrite
{
1
}(
nn
vs
_k_intro
(
S
k
)
(
P
-
★
▷
^(
S
k
)
(
False
)%
I
)).
rewrite
nn
vs
_k_unfold
and_elim_l
.
apply
wand_elim_r
.
*
do
2
rewrite
nn
vs
_k_weaken
//.
rewrite
{
1
}(
nn
upd
_k_intro
(
S
k
)
(
P
-
★
▷
^(
S
k
)
(
False
)%
I
)).
rewrite
nn
upd
_k_unfold
and_elim_l
.
apply
wand_elim_r
.
*
do
2
rewrite
nn
upd
_k_weaken
//.
Qed
.
Lemma
nn
vs
_trans
P
:
(|=
n
=>
|=
n
=>
P
)
=
n
=>
P
.
Lemma
nn
upd
_trans
P
:
(|=
n
=>
|=
n
=>
P
)
=
n
=>
P
.
Proof
.
split
=>
n
x
?
Hnn
.
eapply
nn
vs_nnvs
_k_dist
in
Hnn
;
eauto
.
eapply
(
nn
vs
_k_ne
(
n
)
n
((|=
n
=>
_
(
n
)
P
)%
I
))
in
Hnn
;
eauto
;
[|
symmetry
;
eapply
nn
vs_nnvs
_k_dist
].
eapply
nn
vs_nnvs
_k_dist
;
eauto
.
by
apply
nn
vs
_k_trans
.
eapply
nn
upd_nnupd
_k_dist
in
Hnn
;
eauto
.
eapply
(
nn
upd
_k_ne
(
n
)
n
((|=
n
=>
_
(
n
)
P
)%
I
))
in
Hnn
;
eauto
;
[|
symmetry
;
eapply
nn
upd_nnupd
_k_dist
].
eapply
nn
upd_nnupd
_k_dist
;
eauto
.
by
apply
nn
upd
_k_trans
.
Qed
.
(* Now that we have shown nn
vs
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 nn
vs
is similar to the proof of
nn
vs
_ownM_updateP *)
(* Now that we have shown nn
upd
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 nn
upd
is similar to the proof of
nn
upd
_ownM_updateP *)
Lemma
rvs_nnvs
P
:
(|=
r
=>
P
)
⊢
|=
n
=>
P
.
Lemma
bupd_nnupd
P
:
(|=
r
=>
P
)
⊢
|=
n
=>
P
.
Proof
.
split
.
rewrite
/
uPred_nn
vs
.
repeat
uPred
.
unseal
.
intros
n
x
?
H
rvs
a
.
split
.
rewrite
/
uPred_nn
upd
.
repeat
uPred
.
unseal
.
intros
n
x
?
H
bupd
a
.
red
;
rewrite
//=
=>
n'
yf
??.
edestruct
H
rvs
as
(
x'
&?&?)
;
eauto
.
edestruct
H
bupd
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
nn
vs_rvs
P
:
(|=
n
=>
P
)
⊢
(|=
r
=>
P
).
Lemma
nn
upd_bupd
P
:
(|=
n
=>
P
)
⊢
(|=
r
=>
P
).
Proof
.
rewrite
/
uPred_nn
vs
.
rewrite
/
uPred_nn
upd
.
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 nn
vs
. We could combine
the adequacy lemma for
rvs
with the previous result to get adquacy for nn
vs
, but
(* We might wonder whether we can prove an adequacy lemma for nn
upd
. We could combine
the adequacy lemma for
bupd
with the previous result to get adquacy for nn
upd
, 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
nn
vs
would imply double negation elimination, which is classical: *)
nn
upd
would imply double negation elimination, which is classical: *)
Lemma
nn
vs
_dne
φ
:
True
⊢
(|=
n
=>
(
■
(
¬¬
φ
→
φ
))
:
uPred
M
)%
I
.
Lemma
nn
upd
_dne
φ
:
True
⊢
(|=
n
=>
(
■
(
¬¬
φ
→
φ
))
:
uPred
M
)%
I
.
Proof
.
rewrite
/
uPred_nn
vs
.
apply
forall_intro
=>
n
.
rewrite
/
uPred_nn
upd
.
apply
forall_intro
=>
n
.
apply
wand_intro_l
.
rewrite
?right_id
.
assert
(
∀
φ
,
¬¬¬¬
φ
→
¬¬
φ
)
by
naive_solver
.
assert
(
Hdne
:
¬¬
(
¬¬
φ
→
φ
))
by
naive_solver
.
split
.
unseal
.
intros
n'
??
H
vs
.
split
.
unseal
.
intros
n'
??
H
upd
.
case
(
decide
(
n'
<
n
)).
-
intros
.
move
:
laterN_small
.
unseal
.
naive_solver
.
-
intros
.
assert
(
n
≤
n'
).
omega
.
exfalso
.
specialize
(
H
vs
n'
∅
).
exfalso
.
specialize
(
H
upd
n'
∅
).
eapply
Hdne
.
intros
Hfal
.
eapply
laterN_big
;
eauto
.
unseal
.
rewrite
right_id
in
H
vs
*
;
naive_solver
.
unseal
.
rewrite
right_id
in
H
upd
*
;
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_nn
vs
.
unseal
=>
k
P
x
Hx
Hf1
Hf2
.
-
rewrite
/
uPred_nn
upd
.
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
.
algebra/upred.v
View file @
1b85d654
...
...
@@ -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
.