Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
I
Iris
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Rodolphe Lepigre
Iris
Commits
1b85d654
Commit
1b85d654
authored
Oct 21, 2016
by
Robbert Krebbers
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
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
Showing
43 changed files
with
764 additions
and
567 deletions
+764
-567
ProofMode.md
ProofMode.md
+12
-13
_CoqProject
_CoqProject
+1
-1
algebra/double_negation.v
algebra/double_negation.v
+85
-85
algebra/upred.v
algebra/upred.v
+34
-34
heap_lang/adequacy.v
heap_lang/adequacy.v
+1
-1
heap_lang/heap.v
heap_lang/heap.v
+11
-11
heap_lang/lib/barrier/proof.v
heap_lang/lib/barrier/proof.v
+16
-16
heap_lang/lib/counter.v
heap_lang/lib/counter.v
+24
-24
heap_lang/lib/par.v
heap_lang/lib/par.v
+1
-1
heap_lang/lib/spawn.v
heap_lang/lib/spawn.v
+7
-7
heap_lang/lib/spin_lock.v
heap_lang/lib/spin_lock.v
+8
-8
heap_lang/lib/ticket_lock.v
heap_lang/lib/ticket_lock.v
+19
-19
heap_lang/lifting.v
heap_lang/lifting.v
+5
-5
heap_lang/tactics.v
heap_lang/tactics.v
+1
-1
heap_lang/wp_tactics.v
heap_lang/wp_tactics.v
+6
-6
program_logic/adequacy.v
program_logic/adequacy.v
+25
-25
program_logic/auth.v
program_logic/auth.v
+9
-9
program_logic/boxes.v
program_logic/boxes.v
+16
-16
program_logic/cancelable_invariants.v
program_logic/cancelable_invariants.v
+2
-2
program_logic/counter_examples.v
program_logic/counter_examples.v
+46
-46
program_logic/ectx_lifting.v
program_logic/ectx_lifting.v
+1
-1
program_logic/fancy_updates.v
program_logic/fancy_updates.v
+197
-0
program_logic/ghost_ownership.v
program_logic/ghost_ownership.v
+7
-7
program_logic/hoare.v
program_logic/hoare.v
+3
-3
program_logic/invariants.v
program_logic/invariants.v
+7
-7
program_logic/lifting.v
program_logic/lifting.v
+9
-9
program_logic/sts.v
program_logic/sts.v
+8
-8
program_logic/thread_local.v
program_logic/thread_local.v
+4
-4
program_logic/viewshifts.v
program_logic/viewshifts.v
+3
-3
program_logic/weakestpre.v
program_logic/weakestpre.v
+46
-46
program_logic/wsat.v
program_logic/wsat.v
+9
-9
proofmode/class_instances.v
proofmode/class_instances.v
+20
-20
proofmode/classes.v
proofmode/classes.v
+7
-7
proofmode/coq_tactics.v
proofmode/coq_tactics.v
+9
-9
proofmode/intro_patterns.v
proofmode/intro_patterns.v
+12
-11
proofmode/spec_patterns.v
proofmode/spec_patterns.v
+9
-9
proofmode/tactics.v
proofmode/tactics.v
+43
-43
tests/atomic.v
tests/atomic.v
+14
-14
tests/barrier_client.v
tests/barrier_client.v
+1
-1
tests/counter.v
tests/counter.v
+12
-12
tests/heap_lang.v
tests/heap_lang.v
+1
-1
tests/joining_existentials.v
tests/joining_existentials.v
+3
-3
tests/one_shot.v
tests/one_shot.v
+10
-10
No files found.
ProofMode.md
View file @
1b85d654
...
@@ -5,8 +5,8 @@ Many of the tactics below apply to more goals than described in this document
...
@@ -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
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
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
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
connective appears under a later, a
n update modality, or in the conclusion of a
of a weakest precondition connective
.
weakest precondition
.
Applying hypotheses and lemmas
Applying hypotheses and lemmas
------------------------------
------------------------------
...
@@ -124,14 +124,13 @@ Rewriting
...
@@ -124,14 +124,13 @@ Rewriting
Iris
Iris
----
----
-
`iVsIntro`
: introduction of a raw or primitive view shift.
-
`iUpdIntro`
: introduction of an update modality.
-
`iVs pm_trm as (x1 ... xn) "ipat"`
: run a raw or primitive view shift
-
`iUpd pm_trm as (x1 ... xn) "ipat"`
: run an update modality
`pm_trm`
(if the
`pm_trm`
(if the goal permits, i.e. it is a raw or primitive view shift, or
goal permits, i.e. it can be expanded to an update modality.
a weakest precondition).
-
`iInv N as (x1 ... xn) "ipat"`
: open the invariant
`N`
.
-
`iInv N as (x1 ... xn) "ipat"`
: open the invariant
`N`
.
-
`iTimeless "H"`
: strip a later of a timeless hypothesis
`H`
(if the goal
-
`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
permits, i.e. it is a later, True now,
update modality, or a weakest
weakest
precondition).
precondition).
Miscellaneous
Miscellaneous
-------------
-------------
...
@@ -140,8 +139,8 @@ Miscellaneous
...
@@ -140,8 +139,8 @@ Miscellaneous
introduces pure connectives.
introduces pure connectives.
-
The proof mode adds hints to the core
`eauto`
database so that
`eauto`
-
The proof mode adds hints to the core
`eauto`
database so that
`eauto`
automatically introduces: conjunctions and disjunctions, universal and
automatically introduces: conjunctions and disjunctions, universal and
existential quantifiers, implications and wand, always
and later modalities,
existential quantifiers, implications and wand, always
, later and update
primitive view shift
s, and pure connectives.
modalitie
s, and pure connectives.
Selection patterns
Selection patterns
==================
==================
...
@@ -172,7 +171,7 @@ _introduction patterns_:
...
@@ -172,7 +171,7 @@ _introduction patterns_:
-
`%`
: move the hypothesis to the pure Coq context (anonymously).
-
`%`
: move the hypothesis to the pure Coq context (anonymously).
-
`# ipat`
: move the hypothesis to the persistent context.
-
`# ipat`
: move the hypothesis to the persistent context.
-
`> ipat`
: remove a later of a timeless hypothesis (if the goal permits).
-
`> 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
Apart from this, there are the following introduction patterns that can only
appear at the top level:
appear at the top level:
...
@@ -183,7 +182,7 @@ appear at the top level:
...
@@ -183,7 +182,7 @@ appear at the top level:
-
`!%`
: introduce a pure goal (and leave the proof mode).
-
`!%`
: introduce a pure goal (and leave the proof mode).
-
`!#`
: introduce an always modality (given that the spatial context is empty).
-
`!#`
: introduce an always modality (given that the spatial context is empty).
-
`!>`
: introduce a later (which strips laters from all hypotheses).
-
`!>`
: introduce a later (which strips laters from all hypotheses).
-
`!==>`
: introduce a
view shift.
-
`!==>`
: introduce a
n update modality
-
`/=`
: perform
`simpl`
.
-
`/=`
: perform
`simpl`
.
-
`*`
: introduce all universal quantifiers.
-
`*`
: introduce all universal quantifiers.
-
`**`
: introduce all universal quantifiers, as well as all arrows and wands.
-
`**`
: introduce all universal quantifiers, as well as all arrows and wands.
...
@@ -224,7 +223,7 @@ _specification patterns_ to express splitting of hypotheses:
...
@@ -224,7 +223,7 @@ _specification patterns_ to express splitting of hypotheses:
-
`[-H1 ... Hn]`
: negated form of the above pattern. This pattern does not
-
`[-H1 ... Hn]`
: negated form of the above pattern. This pattern does not
accept hypotheses prefixed with a
`$`
.
accept hypotheses prefixed with a
`$`
.
-
`==>[H1 ... Hn]`
: same as the above pattern, but can only be used if the goal
-
`==>[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.
goal of the premise too.
-
`[#]`
: This pattern can be used when eliminating
`P -★ Q`
with
`P`
-
`[#]`
: This pattern can be used when eliminating
`P -★ Q`
with
`P`
persistent. Using this pattern, all hypotheses are available in the goal for
persistent. Using this pattern, all hypotheses are available in the goal for
...
...
_CoqProject
View file @
1b85d654
...
@@ -69,7 +69,7 @@ program_logic/lifting.v
...
@@ -69,7 +69,7 @@ program_logic/lifting.v
program_logic/invariants.v
program_logic/invariants.v
program_logic/wsat.v
program_logic/wsat.v
program_logic/weakestpre.v
program_logic/weakestpre.v
program_logic/
pviewshift
s.v
program_logic/
fancy_update
s.v
program_logic/hoare.v
program_logic/hoare.v
program_logic/viewshifts.v
program_logic/viewshifts.v
program_logic/language.v
program_logic/language.v
...
...
algebra/double_negation.v
View file @
1b85d654
From
iris
.
algebra
Require
Import
upred
.
From
iris
.
algebra
Require
Import
upred
.
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 *)
step-indexed double-negation when our meta-logic is classical *)
(* To define this, we need a way to talk about iterated later modalities: *)
(* To define this, we need a way to talk about iterated later modalities: *)
...
@@ -12,10 +12,10 @@ Notation "▷^ n P" := (uPred_laterN n P)
...
@@ -12,10 +12,10 @@ Notation "▷^ n P" := (uPred_laterN n P)
(
at
level
20
,
n
at
level
9
,
right
associativity
,
(
at
level
20
,
n
at
level
9
,
right
associativity
,
format
"▷^ n P"
)
:
uPred_scope
.
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
.
∀
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
.
(
at
level
99
,
Q
at
level
200
,
format
"|=n=> Q"
)
:
uPred_scope
.
Notation
"P =n=> Q"
:
=
(
P
⊢
|=
n
=>
Q
)
Notation
"P =n=> Q"
:
=
(
P
⊢
|=
n
=>
Q
)
(
at
level
99
,
Q
at
level
200
,
only
parsing
)
:
C_scope
.
(
at
level
99
,
Q
at
level
200
,
only
parsing
)
:
C_scope
.
...
@@ -27,7 +27,7 @@ Notation "P =n=★ Q" := (P -★ |=n=> Q)%I
...
@@ -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
(2) If our meta-logic is classical, then |=n=> and |=r=> are equivalent
*)
*)
Section
rvs_nnvs
.
Section
bupd_nnupd
.
Context
{
M
:
ucmraT
}.
Context
{
M
:
ucmraT
}.
Implicit
Types
φ
:
Prop
.
Implicit
Types
φ
:
Prop
.
Implicit
Types
P
Q
:
uPred
M
.
Implicit
Types
P
Q
:
uPred
M
.
...
@@ -58,40 +58,40 @@ Proof.
...
@@ -58,40 +58,40 @@ Proof.
eapply
(
uPred_closed
_
_
(
S
n
))
;
eauto
using
cmra_validN_S
.
eapply
(
uPred_closed
_
_
(
S
n
))
;
eauto
using
cmra_validN_S
.
Qed
.
Qed
.
(* It is easy to show that most of the basic properties of
rvs
that
(* It is easy to show that most of the basic properties of
bupd
that
are used throughout Iris hold for nn
vs
.
are used throughout Iris hold for nn
upd
.
In fact, the first three properties that follow hold for any
In fact, the first three properties that follow hold for any
modality of the form (- -★ Q) -★ Q for arbitrary Q. The situation
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.
∀ 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
.
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
.
Proof
.
intros
HPQ
.
apply
forall_intro
=>
n
.
intros
HPQ
.
apply
forall_intro
=>
n
.
apply
wand_intro_l
.
rewrite
-{
1
}
HPQ
.
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
.
apply
wand_elim_r
.
Qed
.
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
.
Proof
.
apply
forall_intro
=>
n
.
apply
wand_intro_r
.
apply
forall_intro
=>
n
.
apply
wand_intro_r
.
rewrite
(
comm
_
P
)
-
wand_curry
.
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
.
by
rewrite
-
assoc
wand_elim_r
wand_elim_l
.
Qed
.
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
.
x
~~>
:
Φ
→
uPred_ownM
x
=
n
=>
∃
y
,
■
Φ
y
∧
uPred_ownM
y
.
Proof
.
Proof
.
intros
H
rvs
.
split
.
rewrite
/
uPred_nnvs
.
repeat
uPred
.
unseal
.
intros
H
bupd
.
split
.
rewrite
/
uPred_nnupd
.
repeat
uPred
.
unseal
.
intros
n
y
?
Hown
a
.
intros
n
y
?
Hown
a
.
red
;
rewrite
//=
=>
n'
yf
??.
red
;
rewrite
//=
=>
n'
yf
??.
inversion
Hown
as
(
x'
&
Hequiv
).
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
).
}
{
by
rewrite
//=
assoc
-(
dist_le
_
_
_
_
Hequiv
).
}
case
(
decide
(
a
≤
n'
)).
case
(
decide
(
a
≤
n'
)).
-
intros
Hle
Hwand
.
-
intros
Hle
Hwand
.
...
@@ -110,18 +110,18 @@ Qed.
...
@@ -110,18 +110,18 @@ Qed.
now over n?
now over n?
*)
*)
Remark
nn
vs
_trans
P
:
(|=
n
=>
|=
n
=>
P
)
⊢
(|=
n
=>
P
).
Remark
nn
upd
_trans
P
:
(|=
n
=>
|=
n
=>
P
)
⊢
(|=
n
=>
P
).
Proof
.
Proof
.
rewrite
/
uPred_nn
vs
.
rewrite
/
uPred_nn
upd
.
apply
forall_intro
=>
a
.
apply
wand_intro_l
.
apply
forall_intro
=>
a
.
apply
wand_intro_l
.
rewrite
(
forall_elim
a
).
rewrite
(
forall_elim
a
).
rewrite
(
nn
vs
_intro
(
P
-
★
_
)).
rewrite
(
nn
upd
_intro
(
P
-
★
_
)).
rewrite
/
uPred_nn
vs
.
rewrite
/
uPred_nn
upd
.
(* Oops -- the exponents of the later modality don't match up! *)
(* Oops -- the exponents of the later modality don't match up! *)
Abort
.
Abort
.
(* Instead, we will need to prove this in the model. We start by showing that
(* 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 ∧ (- -★ False) - ★ False,
(- -★ ▷ False) - ★ ▷ False ∧ (- -★ False) - ★ False,
...
@@ -129,33 +129,33 @@ Abort.
...
@@ -129,33 +129,33 @@ Abort.
...
...
Then, it is easy enough to show that each of the uPreds in this sequence
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: *)
(* 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
)
∧
((
P
-
★
▷
^
k
False
)
-
★
▷
^
k
False
)
∧
match
k
with
match
k
with
O
=>
True
O
=>
True
|
S
k'
=>
uPred_nn
vs
_k
k'
P
|
S
k'
=>
uPred_nn
upd
_k
k'
P
end
.
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
.
(
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 nnvs
_k for each k *)
(* One direction of the limiting process is easy -- nn
upd implies nnupd
_k for each k *)
Lemma
nn
vs
_trunc1
k
P
:
(|=
n
=>
P
)
⊢
|=
n
=>
_k
P
.
Lemma
nn
upd
_trunc1
k
P
:
(|=
n
=>
P
)
⊢
|=
n
=>
_k
P
.
Proof
.
Proof
.
induction
k
.
induction
k
.
-
rewrite
/
uPred_nn
vs_k
/
uPred_nnvs
.
-
rewrite
/
uPred_nn
upd_k
/
uPred_nnupd
.
rewrite
(
forall_elim
0
)
//=
right_id
//.
rewrite
(
forall_elim
0
)
//=
right_id
//.
-
simpl
.
apply
and_intro
;
auto
.
-
simpl
.
apply
and_intro
;
auto
.
rewrite
/
uPred_nn
vs
.
rewrite
/
uPred_nn
upd
.
rewrite
(
forall_elim
(
S
k
))
//=.
rewrite
(
forall_elim
(
S
k
))
//=.
Qed
.
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
.
Proof
.
induction
k
.
induction
k
.
-
inversion
1
;
subst
;
rewrite
//=
?right_id
.
apply
wand_elim_l
.
-
inversion
1
;
subst
;
rewrite
//=
?right_id
.
apply
wand_elim_l
.
...
@@ -164,23 +164,23 @@ Proof.
...
@@ -164,23 +164,23 @@ Proof.
*
rewrite
and_elim_r
IHk
//.
*
rewrite
and_elim_r
IHk
//.
Qed
.
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
).
(|=
n
=>
_
(
S
k
)
P
)
⊣
⊢
((
P
-
★
(
▷
^(
S
k
)
False
))
-
★
(
▷
^(
S
k
)
False
))
∧
(|=
n
=>
_k
P
).
Proof
.
done
.
Qed
.
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
.
(|=
n
=>
_
(
S
k
)
P
)%
I
n
x
↔
(((
P
-
★
(
▷
^(
S
k
)
False
))
-
★
(
▷
^(
S
k
)
False
))
∧
(|=
n
=>
_k
P
))%
I
n
x
.
Proof
.
done
.
Qed
.
Proof
.
done
.
Qed
.
Lemma
nn
vs
_k_weaken
k
P
:
(|=
n
=>
_
(
S
k
)
P
)
⊢
|=
n
=>
_k
P
.
Lemma
nn
upd
_k_weaken
k
P
:
(|=
n
=>
_
(
S
k
)
P
)
⊢
|=
n
=>
_k
P
.
Proof
.
by
rewrite
nn
vs
_k_unfold
and_elim_r
.
Qed
.
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 *)
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
.
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
;
-
revert
n'
x
Hle
Hx
;
induction
k
;
intros
n'
x
Hle
Hx
;
rewrite
?nn
vs_k_unfold'
/
uPred_nnvs
.
rewrite
?nn
upd_k_unfold'
/
uPred_nnupd
.
*
rewrite
//=.
unseal
.
*
rewrite
//=.
unseal
.
inversion
Hle
;
subst
.
inversion
Hle
;
subst
.
intros
(
HnnP
&
_
)
n
k'
x'
??
HPF
.
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.
...
@@ -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
.
***
intros
.
exfalso
.
assert
(
n
≤
k'
).
omega
.
assert
(
n
=
S
k
∨
n
<
S
k
)
as
[->|]
by
omega
.
assert
(
n
=
S
k
∨
n
<
S
k
)
as
[->|]
by
omega
.
****
eapply
laterN_big
;
eauto
;
unseal
.
eapply
HnnP
;
eauto
.
****
eapply
laterN_big
;
eauto
;
unseal
.
eapply
HnnP
;
eauto
.
****
move
:
nn
vs_k_elim
.
unseal
.
intros
Hnnvs
k
.
****
move
:
nn
upd_k_elim
.
unseal
.
intros
Hnnupd
k
.
eapply
laterN_big
;
eauto
.
unseal
.
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
.
exists
x
,
x'
.
split_and
!
;
eauto
.
eapply
uPred_closed
;
eauto
.
eapply
cmra_validN_op_l
;
eauto
.
eapply
cmra_validN_op_l
;
eauto
.
**
intros
HP
.
eapply
IHk
;
auto
.
**
intros
HP
.
eapply
IHk
;
auto
.
move
:
HP
.
unseal
.
intros
(?&?)
;
naive_solver
.
move
:
HP
.
unseal
.
intros
(?&?)
;
naive_solver
.
Qed
.
Qed
.
(* nn
vs
_k has a number of structural properties, including transitivity *)
(* nn
upd
_k has a number of structural properties, including transitivity *)
Lemma
nn
vs
_k_intro
k
P
:
P
⊢
(|=
n
=>
_k
P
).
Lemma
nn
upd
_k_intro
k
P
:
P
⊢
(|=
n
=>
_k
P
).
Proof
.
Proof
.
induction
k
;
rewrite
//=
?right_id
.
induction
k
;
rewrite
//=
?right_id
.
-
apply
wand_intro_l
.
apply
wand_elim_l
.
-
apply
wand_intro_l
.
apply
wand_elim_l
.
...
@@ -217,58 +217,58 @@ Proof.
...
@@ -217,58 +217,58 @@ Proof.
apply
wand_intro_l
.
apply
wand_elim_l
.
apply
wand_intro_l
.
apply
wand_elim_l
.
Qed
.
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
.
Proof
.
induction
k
;
rewrite
//=
?right_id
=>
HPQ
.
induction
k
;
rewrite
//=
?right_id
=>
HPQ
.
-
do
2
(
apply
wand_mono
;
auto
).
-
do
2
(
apply
wand_mono
;
auto
).
-
apply
and_mono
;
auto
;
do
2
(
apply
wand_mono
;
auto
).
-
apply
and_mono
;
auto
;
do
2
(
apply
wand_mono
;
auto
).
Qed
.
Qed
.
Instance
nn
vs_k_mono'
k
:
Proper
((
⊢
)
==>
(
⊢
))
(@
uPred_nnvs
_k
M
k
).
Instance
nn
upd_k_mono'
k
:
Proper
((
⊢
)
==>
(
⊢
))
(@
uPred_nnupd
_k
M
k
).
Proof
.
by
intros
P
P'
HP
;
apply
nn
vs
_k_mono
.
Qed
.
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_nnvs
_k
M
k
).
Instance
nn
upd_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
.
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
).
Lemma
nn
upd
_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
.
Proof
.
intros
HP
;
apply
(
anti_symm
(
⊢
))
;
eapply
nn
upd
_k_mono
;
by
rewrite
HP
.
Qed
.
Instance
nn
vs_k_proper'
k
:
Proper
((
⊣
⊢
)
==>
(
⊣
⊢
))
(@
uPred_nnvs
_k
M
k
).
Instance
nn
upd_k_proper'
k
:
Proper
((
⊣
⊢
)
==>
(
⊣
⊢
))
(@
uPred_nnupd
_k
M
k
).
Proof
.
by
intros
P
P'
HP
;
apply
nn
vs
_k_proper
.
Qed
.
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
.
Proof
.
revert
P
.
revert
P
.
induction
k
;
intros
P
.
induction
k
;
intros
P
.
-
rewrite
//=
?right_id
.
apply
wand_intro_l
.
-
rewrite
//=
?right_id
.
apply
wand_intro_l
.
rewrite
{
1
}(
nn
vs
_k_intro
0
(
P
-
★
False
)%
I
)
//=
?right_id
.
apply
wand_elim_r
.
rewrite
{
1
}(
nn
upd
_k_intro
0
(
P
-
★
False
)%
I
)
//=
?right_id
.
apply
wand_elim_r
.
-
rewrite
{
2
}(
nn
vs
_k_unfold
k
P
).
-
rewrite
{
2
}(
nn
upd
_k_unfold
k
P
).
apply
and_intro
.
apply
and_intro
.
*
rewrite
(
nn
vs
_k_unfold
k
P
).
rewrite
and_elim_l
.
*
rewrite
(
nn
upd
_k_unfold
k
P
).
rewrite
and_elim_l
.
rewrite
nn
vs
_k_unfold
.
rewrite
and_elim_l
.
rewrite
nn
upd
_k_unfold
.
rewrite
and_elim_l
.
apply
wand_intro_l
.
apply
wand_intro_l
.
rewrite
{
1
}(
nn
vs
_k_intro
(
S
k
)
(
P
-
★
▷
^(
S
k
)
(
False
)%
I
)).
rewrite
{
1
}(
nn
upd
_k_intro
(
S
k
)
(
P
-
★
▷
^(
S
k
)
(
False
)%
I
)).
rewrite
nn
vs
_k_unfold
and_elim_l
.
apply
wand_elim_r
.
rewrite
nn
upd
_k_unfold
and_elim_l
.
apply
wand_elim_r
.
*
do
2
rewrite
nn
vs
_k_weaken
//.
*
do
2
rewrite
nn
upd
_k_weaken
//.
Qed
.
Qed
.
Lemma
nn
vs
_trans
P
:
(|=
n
=>
|=
n
=>
P
)
=
n
=>
P
.
Lemma
nn
upd
_trans
P
:
(|=
n
=>
|=
n
=>
P
)
=
n
=>
P
.
Proof
.
Proof
.
split
=>
n
x
?
Hnn
.
split
=>
n
x
?
Hnn
.
eapply
nn
vs_nnvs
_k_dist
in
Hnn
;
eauto
.
eapply
nn
upd_nnupd
_k_dist
in
Hnn
;
eauto
.
eapply
(
nn
vs
_k_ne
(
n
)
n
((|=
n
=>
_
(
n
)
P
)%
I
))
in
Hnn
;
eauto
;
eapply
(
nn
upd
_k_ne
(
n
)
n
((|=
n
=>
_
(
n
)
P
)%
I
))
in
Hnn
;
eauto
;
[|
symmetry
;
eapply
nn
vs_nnvs
_k_dist
].
[|
symmetry
;
eapply
nn
upd_nnupd
_k_dist
].
eapply
nn
vs_nnvs
_k_dist
;
eauto
.
eapply
nn
upd_nnupd
_k_dist
;
eauto
.
by
apply
nn
vs
_k_trans
.
by
apply
nn
upd
_k_trans
.
Qed
.
Qed
.
(* Now that we have shown nn
vs
has all of the desired properties of
(* Now that we have shown nn
upd
has all of the desired properties of
rvs, we go further and show it is in fact equivalent to rvs
! The
bupd, we go further and show it is in fact equivalent to bupd
! The
direction from
rvs to nnvs
is similar to the proof of
direction from
bupd to nnupd
is similar to the proof of
nn
vs
_ownM_updateP *)
nn
upd
_ownM_updateP *)
Lemma
rvs_nnvs
P
:
(|=
r
=>
P
)
⊢
|=
n
=>
P
.
Lemma
bupd_nnupd
P
:
(|=
r
=>
P
)
⊢
|=
n
=>
P
.
Proof
.
Proof
.
split
.
rewrite
/
uPred_nn
vs
.
repeat
uPred
.
unseal
.
intros
n
x
?
Hrvs
a
.
split
.
rewrite
/
uPred_nn
upd
.
repeat
uPred
.
unseal
.
intros
n
x
?
Hbupd
a
.
red
;
rewrite
//=
=>
n'
yf
??.
red
;
rewrite
//=
=>
n'
yf
??.
edestruct
H
rvs
as
(
x'
&?&?)
;
eauto
.
edestruct
H
bupd
as
(
x'
&?&?)
;
eauto
.
case
(
decide
(
a
≤
n'
)).
case
(
decide
(
a
≤
n'
)).
-
intros
Hle
Hwand
.
-
intros
Hle
Hwand
.
exfalso
.
eapply
laterN_big
;
last
(
uPred
.
unseal
;
eapply
(
Hwand
n'
x'
))
;
eauto
.
exfalso
.
eapply
laterN_big
;
last
(
uPred
.
unseal
;
eapply
(
Hwand
n'
x'
))
;
eauto
.
...
@@ -282,9 +282,9 @@ Qed.
...
@@ -282,9 +282,9 @@ Qed.
(* However, the other direction seems to need a classical axiom: *)
(* However, the other direction seems to need a classical axiom: *)
Section
classical
.
Section
classical
.
Context
(
not_all_not_ex
:
∀
(
P
:
M
→
Prop
),
¬
(
∀
n
:
M
,
¬
P
n
)
→
∃
n
:
M
,
P
n
).
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
.
Proof
.
rewrite
/
uPred_nn
vs
.
rewrite
/
uPred_nn
upd
.
split
.
uPred
.
unseal
;
red
;
rewrite
//=.
split
.
uPred
.
unseal
;
red
;
rewrite
//=.
intros
n
x
?
Hforall
k
yf
Hle
?.
intros
n
x
?
Hforall
k
yf
Hle
?.
apply
not_all_not_ex
.
apply
not_all_not_ex
.
...
@@ -300,36 +300,36 @@ Proof.
...
@@ -300,36 +300,36 @@ Proof.
Qed
.
Qed
.
End
classical
.
End
classical
.
(* We might wonder whether we can prove an adequacy lemma for nn
vs
. We could combine
(* We might wonder whether we can prove an adequacy lemma for nn
upd
. We could combine
the adequacy lemma for
rvs with the previous result to get adquacy for nnvs
, but
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
this would rely on the classical axiom we needed to prove the equivalence! Can
we establish adequacy without axioms? Unfortunately not, because adequacy for
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
.
Proof
.
rewrite
/
uPred_nn
vs
.
apply
forall_intro
=>
n
.
rewrite
/
uPred_nn
upd
.
apply
forall_intro
=>
n
.
apply
wand_intro_l
.
rewrite
?right_id
.
apply
wand_intro_l
.
rewrite
?right_id
.
assert
(
∀
φ
,
¬¬¬¬
φ
→
¬¬
φ
)
by
naive_solver
.
assert
(
∀
φ
,
¬¬¬¬
φ
→
¬¬
φ
)
by
naive_solver
.
assert
(
Hdne
:
¬¬
(
¬¬
φ
→
φ
))
by
naive_solver
.
assert
(
Hdne
:
¬¬
(
¬¬
φ
→
φ
))
by
naive_solver
.
split
.
unseal
.
intros
n'
??
H
vs
.
split
.
unseal
.
intros
n'
??
H
upd
.
case
(
decide
(
n'
<
n
)).
case
(
decide
(
n'
<
n
)).
-
intros
.
move
:
laterN_small
.
unseal
.
naive_solver
.
-
intros
.
move
:
laterN_small
.
unseal
.
naive_solver
.
-
intros
.
assert
(
n
≤
n'
).
omega
.
-
intros
.
assert
(
n
≤
n'
).
omega
.
exfalso
.
specialize
(
H
vs
n'
∅
).
exfalso
.
specialize
(
H
upd
n'
∅
).
eapply
Hdne
.
intros
Hfal
.
eapply
Hdne
.
intros
Hfal
.
eapply
laterN_big
;
eauto
.
eapply
laterN_big
;
eauto
.
unseal
.
rewrite
right_id
in
H
vs
*
;
naive_solver
.
unseal
.
rewrite
right_id
in
H
upd
*
;
naive_solver
.
Qed
.
Qed
.
(* Nevertheless, we can prove a weaker form of adequacy (which is equvialent to adequacy
(* 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
:
Lemma
adequacy_helper1
P
n
k
x
:
✓
{
S
n
+
k
}
x
→
¬¬
(
Nat
.
iter
(
S
n
)
(
λ
P
,
|=
n
=>
▷
P
)%
I
P
(
S
n
+
k
)
x
)
✓
{
S
n
+
k
}
x
→
¬¬
(
Nat
.
iter
(
S
n
)
(
λ
P
,
|=
n
=>
▷
P
)%
I
P
(
S
n
+
k
)
x