Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Joshua Yanovski
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
.
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
.