Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
A
Actris
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Iris
Actris
Commits
eb7e35d1
Commit
eb7e35d1
authored
6 years ago
by
Jonas Kastberg Hinrichsen
Browse files
Options
Downloads
Patches
Plain Diff
Updated specs to logical atomicity.
Generalized buffer CMRA to work for any type.
parent
37857a80
No related branches found
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
_CoqProject
+1
-0
1 addition, 0 deletions
_CoqProject
theories/auth_excl.v
+54
-0
54 additions, 0 deletions
theories/auth_excl.v
theories/channel.v
+160
-228
160 additions, 228 deletions
theories/channel.v
with
215 additions
and
228 deletions
_CoqProject
+
1
−
0
View file @
eb7e35d1
...
@@ -2,5 +2,6 @@
...
@@ -2,5 +2,6 @@
-arg -w -arg -notation-overridden,-redundant-canonical-projection,-several-object-files
-arg -w -arg -notation-overridden,-redundant-canonical-projection,-several-object-files
theories/list.v
theories/list.v
theories/buffer.v
theories/buffer.v
theories/auth_excl.v
theories/channel.v
theories/channel.v
This diff is collapsed.
Click to expand it.
theories/
buffer
.v
→
theories/
auth_excl
.v
+
54
−
0
View file @
eb7e35d1
...
@@ -4,53 +4,51 @@ From iris.algebra Require Import excl auth.
...
@@ -4,53 +4,51 @@ From iris.algebra Require Import excl auth.
From
iris
.
base_logic
.
lib
Require
Import
auth
.
From
iris
.
base_logic
.
lib
Require
Import
auth
.
Set
Default
Proof
Using
"Type"
.
Set
Default
Proof
Using
"Type"
.
(* Buffer CMRA *)
Definition
exclUR
(
A
:
Type
)
:
ucmraT
:=
Definition
buff_type
:=
list
val
.
optionUR
(
exclR
(
leibnizC
A
))
.
Definition
buffUR
:
ucmraT
:=
Class
auth_exclG
(
A
:
Type
)
(
Σ
:
gFunctors
)
:=
optionUR
(
exclR
(
leibnizC
(
buff_type
)))
.
AuthExclG
{
exclG_authG
:>
authG
Σ
(
exclUR
A
);
}
.
Definition
to_buff
(
b
:
buff_t
ype
)
:
buffUR
:=
Definition
auth_exclΣ
(
A
:
T
ype
)
:
gFunctors
:=
Excl'
(
b
:
leibnizC
buff_type
)
.
#
[
GFunctor
(
authR
(
exclUR
A
))]
.
Class
buffG
(
Σ
:
gFunctors
)
:=
BuffG
{
Instance
subG_auth_exclG
(
A
:
Type
)
{
Σ
}
:
buffG_authG
:>
authG
Σ
buffUR
;
subG
(
auth_exclΣ
A
)
Σ
→
(
auth_exclG
A
)
Σ
.
}
.
Definition
buffΣ
:
gFunctors
:=
#
[
GFunctor
(
authR
buffUR
)]
.
Instance
subG_buffG
{
Σ
}
:
subG
buffΣ
Σ
→
buffG
Σ
.
Proof
.
solve_inG
.
Qed
.
Proof
.
solve_inG
.
Qed
.
Section
buff
.
Definition
to_auth_excl
{
A
:
Type
}
(
a
:
A
)
:
exclUR
A
:=
Context
`{
!
buffG
Σ
}
(
N
:
namespace
)
.
Excl'
(
a
:
leibnizC
A
)
.
Section
auth_excl
.
Context
`{
!
auth_exclG
A
Σ
}
(
N
:
namespace
)
.
Lemma
excl_eq
γ
x
y
:
Lemma
excl_eq
γ
x
y
:
own
γ
(
●
to_
buff
y
)
-∗
own
γ
(
◯
to_
buff
x
)
-∗
⌜
x
=
y
⌝%
I
.
own
γ
(
●
to_
auth_excl
y
)
-∗
own
γ
(
◯
to_
auth_excl
x
)
-∗
⌜
x
=
y
⌝%
I
.
Proof
.
Proof
.
iIntros
"Hauth Hfrag"
.
iIntros
"Hauth Hfrag"
.
iDestruct
(
own_valid_2
with
"Hauth Hfrag"
)
as
%
Hvalid
.
iDestruct
(
own_valid_2
with
"Hauth Hfrag"
)
as
%
Hvalid
.
apply
auth_valid_discrete_2
in
Hvalid
.
apply
auth_valid_discrete_2
in
Hvalid
.
destruct
Hvalid
as
[
Hincl
_]
.
destruct
Hvalid
as
[
Hincl
_]
.
apply
Excl_included
in
Hincl
.
apply
Excl_included
in
Hincl
.
unfold
to_
buff
.
unfold
to_
auth_excl
.
rewrite
Hincl
.
rewrite
Hincl
.
iFrame
.
iFrame
.
eauto
.
eauto
.
Qed
.
Qed
.
Lemma
excl_update
γ
x
y
z
:
Lemma
excl_update
γ
x
y
z
:
own
γ
(
●
to_
buff
y
)
-∗
own
γ
(
◯
to_
buff
x
)
-∗
|
==>
own
γ
(
●
to_
buff
z
)
∗
own
γ
(
◯
to_
buff
z
)
.
own
γ
(
●
to_
auth_excl
y
)
-∗
own
γ
(
◯
to_
auth_excl
x
)
-∗
|
==>
own
γ
(
●
to_
auth_excl
z
)
∗
own
γ
(
◯
to_
auth_excl
z
)
.
Proof
.
Proof
.
iIntros
"Hauth Hfrag"
.
iIntros
"Hauth Hfrag"
.
iDestruct
(
own_update_2
with
"Hauth Hfrag"
)
as
"H"
.
iDestruct
(
own_update_2
with
"Hauth Hfrag"
)
as
"H"
.
{
eapply
(
auth_update
_
_
(
to_
buff
z
)
(
to_buff
z
))
.
{
eapply
(
auth_update
_
_
(
to_
auth_excl
z
)
(
to_auth_excl
z
))
.
eapply
option_local_update
.
eapply
option_local_update
.
eapply
exclusive_local_update
.
done
.
}
eapply
exclusive_local_update
.
done
.
}
rewrite
own_op
.
rewrite
own_op
.
done
.
done
.
Qed
.
Qed
.
End
buff
.
End
auth_excl
.
This diff is collapsed.
Click to expand it.
theories/channel.v
+
160
−
228
View file @
eb7e35d1
...
@@ -7,10 +7,9 @@ From iris.base_logic.lib Require Import auth.
...
@@ -7,10 +7,9 @@ From iris.base_logic.lib Require Import auth.
From
iris
.
heap_lang
.
lib
Require
Import
lock
.
From
iris
.
heap_lang
.
lib
Require
Import
lock
.
From
iris
.
heap_lang
.
lib
Require
Import
spin_lock
.
From
iris
.
heap_lang
.
lib
Require
Import
spin_lock
.
From
osiris
Require
Import
list
.
From
osiris
Require
Import
list
.
From
osiris
Require
Import
buffer
.
From
osiris
Require
Import
auth_excl
.
Set
Default
Proof
Using
"Type"
.
Set
Default
Proof
Using
"Type"
.
Definition
new_list
:
val
:=
Definition
new_list
:
val
:=
λ
:
<>
,
lnil
#
()
.
λ
:
<>
,
lnil
#
()
.
...
@@ -61,7 +60,7 @@ Definition recv : val :=
...
@@ -61,7 +60,7 @@ Definition recv : val :=
end
.
end
.
Section
channel
.
Section
channel
.
Context
`{
!
heapG
Σ
,
!
lockG
Σ
,
!
buffG
Σ
}
(
N
:
namespace
)
.
Context
`{
!
heapG
Σ
,
!
lockG
Σ
,
!
auth_exclG
(
list
val
)
Σ
}
(
N
:
namespace
)
.
Definition
is_list_ref
(
l
:
val
)
(
xs
:
list
val
)
:
iProp
Σ
:=
Definition
is_list_ref
(
l
:
val
)
(
xs
:
list
val
)
:
iProp
Σ
:=
(
∃
l'
:
loc
,
∃
hd
:
val
,
⌜
l
=
#
l'
⌝
∧
l'
↦
hd
∗
⌜
is_list
hd
xs
⌝
)
%
I
.
(
∃
l'
:
loc
,
∃
hd
:
val
,
⌜
l
=
#
l'
⌝
∧
l'
↦
hd
∗
⌜
is_list
hd
xs
⌝
)
%
I
.
...
@@ -69,275 +68,208 @@ Section channel.
...
@@ -69,275 +68,208 @@ Section channel.
Definition
is_side
(
s
:
val
)
:
Prop
:=
Definition
is_side
(
s
:
val
)
:
Prop
:=
s
=
left
∨
s
=
right
.
s
=
left
∨
s
=
right
.
Definition
is_chan
(
lkγ
lsγ
rsγ
:
gname
)
(
c
:
val
)
(
ls
rs
:
list
val
)
:
iProp
Σ
:=
Record
chan_name
:=
Chan_name
{
(
∃
l
r
lk
:
val
,
⌜
c
=
((
l
,
r
),
lk
)
%
V
⌝
∧
chan_lock_name
:
gname
;
own
lsγ
(
◯
to_buff
ls
)
∗
own
rsγ
(
◯
to_buff
rs
)
∗
chan_l_name
:
gname
;
is_lock
N
lkγ
lk
chan_r_name
:
gname
(
∃
ls
rs
,
}
.
is_list_ref
l
ls
∗
own
lsγ
(
●
to_buff
ls
)
∗
is_list_ref
r
rs
∗
own
rsγ
(
●
to_buff
rs
)))
%
I
.
Definition
chan_ctx
(
γ
:
chan_name
)
(
c
:
val
)
:
iProp
Σ
:=
(
∃
l
r
lk
:
val
,
⌜
c
=
((
l
,
r
),
lk
)
%
V
⌝
∧
is_lock
N
(
chan_lock_name
γ
)
lk
(
∃
ls
rs
,
is_list_ref
l
ls
∗
own
(
chan_l_name
γ
)
(
●
to_auth_excl
ls
)
∗
is_list_ref
r
rs
∗
own
(
chan_r_name
γ
)
(
●
to_auth_excl
rs
)))
%
I
.
Definition
is_chan
(
γ
:
chan_name
)
(
c
:
val
)
(
ls
rs
:
list
val
)
:
iProp
Σ
:=
(
∃
l
r
lk
:
val
,
⌜
c
=
((
l
,
r
),
lk
)
%
V
⌝
∧
own
(
chan_l_name
γ
)
(
◯
to_auth_excl
ls
)
∗
own
(
chan_r_name
γ
)
(
◯
to_auth_excl
rs
))
%
I
.
Lemma
new_chan_spec
:
Lemma
new_chan_spec
:
{{{
True
}}}
{{{
True
}}}
new_chan
#
()
new_chan
#
()
{{{
c
lkγ
lsγ
rs
γ
,
RET
c
;
is_chan
lkγ
lsγ
rsγ
c
[]
[]
}}}
.
{{{
c
γ
,
RET
c
;
is_chan
γ
c
[]
[]
∗
chan_ctx
γ
c
}}}
.
Proof
.
Proof
.
iIntros
(
Φ
)
"_ HΦ"
.
rewrite
-
wp_fupd
/
newlock
/
new_list
/=
.
iIntros
(
Φ
)
"_ HΦ"
.
rewrite
/
is_chan
/
chan_ctx
/
is_lock
.
repeat
wp_lam
.
wp_alloc
lk
as
"Hlk"
.
repeat
wp_lam
.
wp_alloc
lk
as
"Hlk"
.
iMod
(
own_alloc
(
Excl
()))
as
(
lkγ
)
"Hγlk"
;
first
done
.
repeat
wp_lam
.
wp_alloc
r
as
"Hr"
.
repeat
wp_lam
.
wp_alloc
r
as
"Hr"
.
iMod
(
own_alloc
(
Auth
(
Excl'
(
to_auth_excl
[]))
(
to_auth_excl
[])))
as
(
lsγ
)
"Hls"
;
first
done
.
repeat
wp_lam
.
wp_alloc
l
as
"Hl"
.
repeat
wp_lam
.
wp_alloc
l
as
"Hl"
.
wp_pures
.
iMod
(
own_alloc
(
Auth
(
Excl'
(
to_auth_excl
[]))
(
to_auth_excl
[])))
as
(
rsγ
)
"Hrs"
;
first
done
.
iMod
(
own_alloc
(
Excl
()))
as
(
lkγ
)
"Hγlk"
;
first
done
.
rewrite
auth_both_op
own_op
own_op
.
iMod
(
own_alloc
(
Auth
(
Excl'
(
to_buff
[]))
(
to_buff
[])))
as
(
lsγ
)
"Hls"
;
first
done
.
pose
(
Chan_name
lkγ
lsγ
rsγ
)
.
iMod
(
own_alloc
(
Auth
(
Excl'
(
to_buff
[]))
(
to_buff
[])))
as
(
rsγ
)
"Hrs"
;
first
done
.
rewrite
auth_both_op
.
rewrite
own_op
.
rewrite
own_op
.
iDestruct
"Hls"
as
"[Hlsa Hlsf]"
.
iDestruct
"Hls"
as
"[Hlsa Hlsf]"
.
iDestruct
"Hrs"
as
"[Hrsa Hrsf]"
.
iDestruct
"Hrs"
as
"[Hrsa Hrsf]"
.
iMod
(
inv_alloc
N
_
(
lock_inv
lkγ
lk
(
∃
(
ls
rs
:
list
val
),
is_list_ref
#
l
ls
∗
own
lsγ
(
●
to_buff
ls
)
∗
is_list_ref
#
r
rs
∗
own
rsγ
(
●
to_buff
rs
)))
%
I
with
"[Hlk Hγlk Hr Hl Hlsa Hrsa]"
)
as
"Hlk"
.
iMod
(
inv_alloc
N
_
(
lock_inv
lkγ
lk
(
∃
(
ls
rs
:
list
val
),
is_list_ref
#
l
ls
∗
own
lsγ
(
●
to_auth_excl
ls
)
∗
is_list_ref
#
r
rs
∗
own
rsγ
(
●
to_auth_excl
rs
)))
%
I
with
"[Hlk Hγlk Hr Hl Hlsa Hrsa]"
)
as
"Hlk"
.
{
{
iNext
.
iExists
_
.
iFrame
.
iFrame
.
rewrite
/
is_list_ref
/
is_list
/
lock_inv
.
iExists
[],
[]
.
iFrame
.
iNext
.
iExists
_
.
iSplitL
"Hlk"
=>
//=.
iSplitL
"Hγlk"
=>
//=.
iExists
_,
_
.
iFrame
.
iSplitL
"Hl"
=>
//
;
iExists
_,
_;
iSplit
=>
//
;
iFrame
=>
//.
iSplitL
"Hl"
=>
//
;
iExists
_,
_;
iSplit
=>
//
;
iFrame
=>
//.
}
}
iModIntro
.
wp_pures
.
iApply
"HΦ"
.
iSpecialize
(
"HΦ"
$!
(
#
l
,
#
r
,
#
lk
)
%
V
c
)
.
iExists
_,
_,
_
.
iApply
(
"HΦ"
)
.
iFrame
"Hlsf Hrsf"
.
iSplitL
"Hlsf Hrsf"
=>
//
;
iSplit
=>
//.
eauto
10
with
iFrame
.
unfold
is_lock
.
iExists
_
.
iSplit
=>
//.
Qed
.
Qed
.
Definition
send_upd
lkγ
lsγ
rs
γ
c
ls
rs
s
v
:
iProp
Σ
:=
Definition
send_upd
γ
c
ls
rs
s
v
:
iProp
Σ
:=
match
s
with
match
s
with
|
left
=>
is_chan
lkγ
lsγ
rs
γ
c
(
ls
++
[
v
])
rs
|
left
=>
is_chan
γ
c
(
ls
++
[
v
])
rs
|
right
=>
is_chan
lkγ
lsγ
rs
γ
c
ls
(
rs
++
[
v
])
|
right
=>
is_chan
γ
c
ls
(
rs
++
[
v
])
|
_
=>
⌜
False
⌝%
I
|
_
=>
⌜
False
⌝%
I
end
.
end
.
Lemma
send_spec
(
lkγ
lsγ
rsγ
:
gname
)
(
c
v
s
:
val
)
(
ls
rs
:
list
val
)
:
Lemma
send_spec
Φ
E
γ
(
c
v
s
:
val
)
:
{{{
is_chan
lkγ
lsγ
rsγ
c
ls
rs
∗
⌜
is_side
s
⌝%
I
}}}
is_side
s
→
send
c
s
v
chan_ctx
γ
c
-∗
{{{
RET
#
();
send_upd
lkγ
lsγ
rsγ
c
ls
rs
s
v
}}}
.
(|
=
{
⊤
,
E
}=>
∃
ls
rs
,
is_chan
γ
c
ls
rs
∗
(
send_upd
γ
c
ls
rs
s
v
=
{
E
,
⊤
}
=∗
Φ
#
())
)
-∗
WP
send
c
s
v
{{
Φ
}}
.
Proof
.
Proof
.
iIntros
(
Φ
)
"[Hc #Hs] HΦ"
.
iIntros
(
Hside
)
"Hc HΦ"
.
wp_lam
;
wp_pures
.
iRevert
"Hs"
.
iIntros
(
Hs
)
.
iDestruct
"Hc"
as
(
l
r
lk
->
)
"#Hlock"
;
wp_pures
.
rewrite
-
wp_fupd
/
send
/=.
wp_apply
(
acquire_spec
with
"Hlock"
);
iIntros
"[Hlocked Hinv]"
.
iDestruct
"Hc"
as
(
l
r
lk
Hc
)
"[Hlsf [Hrsf #Hlk]]"
.
iDestruct
"Hinv"
as
(
ls
rs
)
"(Hl & Hls & Hr & Hrs)"
.
wp_lam
.
destruct
Hside
as
[
->
|
->
]
.
wp_pures
.
-
wp_pures
.
iDestruct
"Hl"
as
(
ll
lhd
->
)
"(Hl & Hll)"
.
subst
.
wp_load
.
wp_apply
(
lsnoc_spec
with
"Hll"
)
.
wp_bind
(
Snd
_)
.
iIntros
(
hd'
)
"Hll"
.
wp_store
.
wp_pures
.
wp_pures
.
iApply
fupd_wp
.
iMod
"HΦ"
as
(
ls'
rs'
)
"[Hchan HΦ]"
.
wp_bind
(
acquire
lk
)
.
iDestruct
"Hchan"
as
(
l'
r'
lk'
[
=
<-
<-
<-
])
"[Hls' Hrs']"
.
iApply
acquire_spec
=>
//.
iDestruct
(
excl_eq
with
"Hls Hls'"
)
as
%->
.
iNext
.
iMod
(
excl_update
_
_
_
(
ls
++
[
v
])
with
"Hls Hls'"
)
as
"[Hls Hls']"
.
iIntros
"[Hlocked Hl]"
.
iMod
(
"HΦ"
with
"[Hls' Hrs']"
)
as
"HΦ"
.
iDestruct
"Hl"
as
(
ls'
rs'
)
"[Hls [Hlsa [Hrs Hrsa]]]"
.
{
rewrite
/=
/
is_chan
.
eauto
with
iFrame
.
}
iDestruct
(
excl_eq
with
"Hlsa Hlsf"
)
as
%
Heqls
.
rewrite
-
(
Heqls
)
.
iDestruct
(
excl_eq
with
"Hrsa Hrsf"
)
as
%
Heqrs
.
rewrite
-
(
Heqrs
)
.
wp_seq
.
wp_pures
.
inversion
Hs
.
-
iDestruct
"Hls"
as
(
lb
Hb
bhd
)
"[Hl #Hbhd]"
.
iDestruct
(
excl_update
_
_
_
(
ls
++
[
v
])
with
"Hlsa Hlsf"
)
as
">[Hlsa Hlsf]"
.
subst
.
wp_pures
.
wp_bind
(
lsnoc
(
Load
#
lb
)
v
)
.
wp_load
.
iApply
lsnoc_spec
=>
//.
iIntros
(
hd'
Hhd'
)
.
iNext
.
wp_store
.
wp_pures
.
eauto
.
iApply
(
release_spec
N
lkγ
lk
with
"[Hlocked Hl Hlsa Hrsa Hrs]"
)
=>
//.
{
iFrame
;
eauto
.
iSplitR
.
iApply
"Hlk"
.
iFrame
.
iExists
_,
_
.
iFrame
.
iExists
_,
_
.
iSplit
=>
//.
iFrame
.
iPureIntro
=>
//.
}
iModIntro
.
iIntros
(_)
.
iModIntro
.
iApply
"HΦ"
.
iExists
_,
_,
_
.
iSplitR
=>
//.
iSplitL
"Hlsf"
=>
//.
iSplitL
"Hrsf"
=>
//.
-
iDestruct
"Hrs"
as
(
lb
Hb
bhd
)
"[Hr #Hbhd]"
.
iDestruct
(
excl_update
_
_
_
(
rs
++
[
v
])
with
"Hrsa Hrsf"
)
as
">[Hrsa Hrsf]"
.
subst
.
wp_pures
.
wp_bind
(
lsnoc
(
Load
#
lb
)
v
)
.
wp_load
.
iApply
lsnoc_spec
=>
//.
iIntros
(
hd'
Hhd'
)
.
iNext
.
wp_store
.
wp_pures
.
eauto
.
iApply
(
release_spec
N
lkγ
lk
with
"[Hlocked Hr Hlsa Hrsa Hls]"
)
=>
//.
{
iFrame
;
eauto
.
iSplitR
.
iApply
"Hlk"
.
iFrame
.
iExists
_,
_
.
iFrame
.
iExists
_,
_
.
iSplit
=>
//.
iFrame
.
iPureIntro
=>
//.
}
iModIntro
.
iModIntro
.
iIntros
(_)
.
wp_apply
(
release_spec
with
"[-HΦ $Hlock $Hlocked]"
)
.
{
rewrite
/
is_list_ref
.
eauto
10
with
iFrame
.
}
iIntros
"_ //"
.
-
wp_pures
.
iDestruct
"Hr"
as
(
lr
rhd
->
)
"(Hr & Hlr)"
.
wp_load
.
wp_apply
(
lsnoc_spec
with
"Hlr"
)
.
iIntros
(
hd'
)
"Hlr"
.
wp_store
.
wp_pures
.
iApply
fupd_wp
.
iMod
"HΦ"
as
(
ls'
rs'
)
"[Hchan HΦ]"
.
iDestruct
"Hchan"
as
(
l'
r'
lk'
[
=
<-
<-
<-
])
"[Hls' Hrs']"
.
iDestruct
(
excl_eq
with
"Hrs Hrs'"
)
as
%->
.
iMod
(
excl_update
_
_
_
(
rs
++
[
v
])
with
"Hrs Hrs'"
)
as
"[Hrs Hrs']"
.
iMod
(
"HΦ"
with
"[Hls' Hrs']"
)
as
"HΦ"
.
{
rewrite
/=
/
is_chan
.
eauto
with
iFrame
.
}
iModIntro
.
iModIntro
.
iApply
"HΦ"
.
wp_apply
(
release_spec
with
"[-HΦ $Hlock $Hlocked]"
)
.
iExists
_,
_,
_
.
{
rewrite
/
is_list_ref
.
eauto
10
with
iFrame
.
}
iSplitR
=>
//.
iIntros
"_ //"
.
iSplitL
"Hlsf"
=>
//.
iSplitL
"Hrsf"
=>
//.
Qed
.
Qed
.
Definition
try_recv_upd
lkγ
lsγ
rs
γ
c
ls
rs
s
v
:
iProp
Σ
:=
Definition
try_recv_upd
γ
c
ls
rs
s
v
:
iProp
Σ
:=
match
s
with
match
s
with
|
left
=>
match
v
with
|
left
=>
match
v
with
|
NONEV
=>
(
is_chan
lkγ
lsγ
rs
γ
c
ls
rs
∧
⌜
rs
=
[]
⌝
)
%
I
|
NONEV
=>
(
is_chan
γ
c
ls
rs
∧
⌜
rs
=
[]
⌝
)
%
I
|
SOMEV
w
=>
(
∃
rs'
,
is_chan
lkγ
lsγ
rs
γ
c
ls
rs'
∧
⌜
rs
=
w
::
rs'
⌝
)
%
I
|
SOMEV
w
=>
(
∃
rs'
,
is_chan
γ
c
ls
rs'
∧
⌜
rs
=
w
::
rs'
⌝
)
%
I
|
_
=>
⌜
False
⌝%
I
|
_
=>
⌜
False
⌝%
I
end
end
|
right
=>
match
v
with
|
right
=>
match
v
with
|
NONEV
=>
(
is_chan
lkγ
lsγ
rs
γ
c
ls
rs
∧
⌜
ls
=
[]
⌝
)
%
I
|
NONEV
=>
(
is_chan
γ
c
ls
rs
∧
⌜
ls
=
[]
⌝
)
%
I
|
SOMEV
w
=>
(
∃
ls'
,
is_chan
lkγ
lsγ
rs
γ
c
ls'
rs
∧
⌜
ls
=
w
::
ls'
⌝
)
%
I
|
SOMEV
w
=>
(
∃
ls'
,
is_chan
γ
c
ls'
rs
∧
⌜
ls
=
w
::
ls'
⌝
)
%
I
|
_
=>
⌜
False
⌝%
I
|
_
=>
⌜
False
⌝%
I
end
end
|
_
=>
⌜
False
⌝%
I
|
_
=>
⌜
False
⌝%
I
end
.
end
.
Lemma
try_recv_spec
(
lkγ
lsγ
rsγ
:
gname
)
(
c
v
s
:
val
)
(
ls
rs
:
list
val
)
:
Lemma
try_recv_spec
Φ
E
γ
(
c
v
s
:
val
)
:
{{{
is_chan
lkγ
lsγ
rsγ
c
ls
rs
∗
⌜
is_side
s
⌝%
I
}}}
is_side
s
→
try_recv
c
s
chan_ctx
γ
c
-∗
{{{
v
,
RET
v
;
try_recv_upd
lkγ
lsγ
rsγ
c
ls
rs
s
v
}}}
.
(|
=
{
⊤
,
E
}=>
∃
ls
rs
,
is_chan
γ
c
ls
rs
∗
(
∀
v
,
try_recv_upd
γ
c
ls
rs
s
v
=
{
E
,
⊤
}
=∗
Φ
v
)
)
-∗
WP
try_recv
c
s
{{
Φ
}}
.
Proof
.
Proof
.
iIntros
(
Φ
)
"[Hc #Hs] HΦ"
.
iIntros
(
Hside
)
"Hc HΦ"
.
wp_lam
;
wp_pures
.
iRevert
"Hs"
.
iIntros
(
Hs
)
.
iDestruct
"Hc"
as
(
l
r
lk
->
)
"#Hlock"
;
wp_pures
.
rewrite
-
wp_fupd
/
send
/=.
wp_apply
(
acquire_spec
with
"Hlock"
);
iIntros
"[Hlocked Hinv]"
.
iDestruct
"Hc"
as
(
l
r
lk
Hc
)
"[Hlsf [Hrsf #Hlk]]"
.
iDestruct
"Hinv"
as
(
ls
rs
)
"(Hls & Hlsa & Hrs & Hrsa)"
.
subst
.
destruct
Hside
as
[
->
|
->
]
.
wp_lam
.
-
iDestruct
"Hrs"
as
(
rl
rhd
->
)
"[Hrs #Hrhd]"
.
wp_pures
.
wp_bind
(
acquire
_)
.
iApply
acquire_spec
=>
//.
iNext
.
iIntros
"[Hlocked Hl]"
.
iDestruct
"Hl"
as
(
ls'
rs'
)
"[Hls [Hlsa [Hrs Hrsa]]]"
.
iDestruct
(
excl_eq
with
"Hlsa Hlsf"
)
as
%
Heqls
.
rewrite
-
(
Heqls
)
.
iDestruct
(
excl_eq
with
"Hrsa Hrsf"
)
as
%
Heqrs
.
rewrite
-
(
Heqrs
)
.
wp_seq
.
wp_pures
.
inversion
Hs
;
subst
.
-
wp_pures
.
iDestruct
"Hrs"
as
(
rl
Hr
rhd
)
"[Hrs #Hrhd]"
.
wp_pures
.
subst
.
wp_load
.
wp_load
.
iRevert
"Hrhd"
.
iIntros
(
Hrhd
)
.
destruct
rs
.
unfold
is_list
in
Hrhd
.
+
iRevert
"Hrhd"
.
rewrite
/
is_list
.
iIntros
(
->
)
.
destruct
rs'
.
+
subst
.
wp_pures
.
wp_bind
(
release
_)
.
wp_pures
.
iApply
(
release_spec
N
lkγ
lk
with
"[Hlocked Hls Hrs Hlsa Hrsa]"
)
=>
//.
{
iFrame
;
eauto
.
iSplitR
.
iApply
"Hlk"
.
iFrame
.
iExists
_,
_
.
iFrame
.
iExists
_,
_
.
iFrame
=>
//.
}
iNext
.
iIntros
(_)
.
wp_pures
.
wp_pures
.
iApply
fupd_wp
.
iMod
"HΦ"
as
(
ls'
rs'
)
"[Hchan HΦ]"
.
iDestruct
"Hchan"
as
(
l'
r'
lk'
[
=
<-
<-
<-
])
"[Hlsf Hrsf]"
.
iDestruct
(
excl_eq
with
"Hlsa Hlsf"
)
as
%->
.
iDestruct
(
excl_eq
with
"Hrsa Hrsf"
)
as
%->
.
iSpecialize
(
"HΦ"
$!
(
InjLV
#
()))
.
iMod
(
"HΦ"
with
"[Hlsf Hrsf]"
)
as
"HΦ"
.
{
rewrite
/
try_recv_upd
/
is_chan
.
eauto
10
with
iFrame
.
}
iModIntro
.
iModIntro
.
iApply
"HΦ"
.
wp_apply
(
release_spec
with
"[-HΦ $Hlocked $Hlock]"
)
.
iSplit
=>
//.
{
rewrite
/
is_list_ref
/
is_list
.
eauto
10
with
iFrame
.
}
iExists
_,
_,
_
.
iIntros
(_)
.
iSplit
=>
//.
iFrame
.
iApply
"Hlk"
.
+
subst
.
destruct
Hrhd
as
[
hd'
[
Hrhd
Hrhd'
]]
.
subst
.
wp_pures
.
wp_pures
.
wp_store
.
wp_pures
.
by
iApply
"HΦ"
.
iDestruct
(
excl_update
_
_
_
(
rs'
)
with
"Hrsa Hrsf"
)
as
">[Hrsa Hrsf]"
.
+
iRevert
"Hrhd"
.
rewrite
/
is_list
.
iIntros
([
hd'
[
->
Hrhd'
]])
.
wp_bind
(
release
_)
.
wp_pures
.
wp_pures
.
iApply
(
release_spec
N
lkγ
lk
with
"[Hlocked Hls Hrs Hlsa Hrsa]"
)
=>
//.
iApply
fupd_wp
.
{
iMod
"HΦ"
as
(
ls'
rs'
)
"[Hchan HΦ]"
.
iFrame
;
eauto
.
iDestruct
"Hchan"
as
(
l'
r'
lk'
[
=
<-
<-
<-
])
"[Hlsf Hrsf]"
.
iSplitR
.
iApply
"Hlk"
.
iDestruct
(
excl_eq
with
"Hlsa Hlsf"
)
as
%->
.
iFrame
.
iExists
_,
_
.
iFrame
.
iDestruct
(
excl_eq
with
"Hrsa Hrsf"
)
as
%->
.
iExists
_,
_
.
iFrame
=>
//.
iDestruct
(
excl_update
_
_
_
(
rs
)
with
"Hrsa Hrsf"
)
as
">[Hrsa Hrsf]"
.
}
iSpecialize
(
"HΦ"
$!
(
InjRV
(
v0
)))
.
iNext
.
iIntros
(_)
.
iMod
(
"HΦ"
with
"[Hlsf Hrsf]"
)
as
"HΦ"
.
wp_pures
.
{
rewrite
/
try_recv_upd
/
is_chan
.
eauto
10
with
iFrame
.
}
iApply
"HΦ"
.
iExists
_
.
iModIntro
.
iModIntro
.
iSplit
=>
//.
wp_store
.
iExists
_,
_,
_
.
wp_apply
(
release_spec
with
"[-HΦ $Hlocked $Hlock]"
)
.
iSplit
=>
//.
{
rewrite
/
is_list_ref
/
is_list
.
eauto
10
with
iFrame
.
}
iFrame
.
iIntros
(_)
.
iApply
"Hlk"
.
-
wp_pures
.
iDestruct
"Hls"
as
(
ls
Hl
lhd
)
"[Hls #Hlhd]"
.
wp_pures
.
subst
.
wp_load
.
iRevert
"Hlhd"
.
iIntros
(
Hlhd
)
.
unfold
is_list
in
Hlhd
.
destruct
ls'
.
+
subst
.
wp_pures
.
wp_bind
(
release
_)
.
wp_pures
.
wp_pures
.
iApply
(
release_spec
N
lkγ
lk
with
"[Hlocked Hls Hrs Hlsa Hrsa]"
)
=>
//.
by
iApply
"HΦ"
.
{
-
iDestruct
"Hls"
as
(
ll
lhd
->
)
"[Hls #Hlhd]"
.
iFrame
;
eauto
.
wp_load
.
iSplitR
.
iApply
"Hlk"
.
destruct
ls
.
iFrame
.
iExists
_,
_
.
iFrame
.
+
iRevert
"Hlhd"
.
rewrite
/
is_list
.
iIntros
(
->
)
.
iExists
_,
_
.
iFrame
=>
//.
}
iNext
.
iIntros
(_)
.
wp_pures
.
wp_pures
.
iApply
fupd_wp
.
iMod
"HΦ"
as
(
ls'
rs'
)
"[Hchan HΦ]"
.
iDestruct
"Hchan"
as
(
l'
r'
lk'
[
=
<-
<-
<-
])
"[Hlsf Hrsf]"
.
iDestruct
(
excl_eq
with
"Hlsa Hlsf"
)
as
%->
.
iDestruct
(
excl_eq
with
"Hrsa Hrsf"
)
as
%->
.
iSpecialize
(
"HΦ"
$!
(
InjLV
#
()))
.
iMod
(
"HΦ"
with
"[Hlsf Hrsf]"
)
as
"HΦ"
.
{
rewrite
/
try_recv_upd
/
is_chan
.
eauto
10
with
iFrame
.
}
iModIntro
.
iModIntro
.
iApply
"HΦ"
.
wp_apply
(
release_spec
with
"[-HΦ $Hlocked $Hlock]"
)
.
iSplit
=>
//.
{
rewrite
/
is_list_ref
/
is_list
.
eauto
10
with
iFrame
.
}
iExists
_,
_,
_
.
iIntros
(_)
.
iSplit
=>
//.
iFrame
.
iApply
"Hlk"
.
+
subst
.
destruct
Hlhd
as
[
hd'
[
Hlhd
Hlhd'
]]
.
subst
.
wp_pures
.
wp_pures
.
wp_store
.
wp_pures
.
by
iApply
"HΦ"
.
iDestruct
(
excl_update
_
_
_
(
ls'
)
with
"Hlsa Hlsf"
)
as
">[Hlsa Hlsf]"
.
+
iRevert
"Hlhd"
.
rewrite
/
is_list
.
iIntros
([
hd'
[
->
Hlhd'
]])
.
wp_bind
(
release
_)
.
wp_pures
.
wp_pures
.
iApply
(
release_spec
N
lkγ
lk
with
"[Hlocked Hls Hrs Hlsa Hrsa]"
)
=>
//.
iApply
fupd_wp
.
{
iMod
"HΦ"
as
(
ls'
rs'
)
"[Hchan HΦ]"
.
iFrame
;
eauto
.
iDestruct
"Hchan"
as
(
l'
r'
lk'
[
=
<-
<-
<-
])
"[Hlsf Hrsf]"
.
iSplitR
.
iApply
"Hlk"
.
iDestruct
(
excl_eq
with
"Hlsa Hlsf"
)
as
%->
.
iFrame
.
iExists
_,
_
.
iFrame
.
iDestruct
(
excl_eq
with
"Hrsa Hrsf"
)
as
%->
.
iExists
_,
_
.
iFrame
=>
//.
iDestruct
(
excl_update
_
_
_
(
ls
)
with
"Hlsa Hlsf"
)
as
">[Hlsa Hlsf]"
.
}
iSpecialize
(
"HΦ"
$!
(
InjRV
(
v0
)))
.
iNext
.
iIntros
(_)
.
iMod
(
"HΦ"
with
"[Hlsf Hrsf]"
)
as
"HΦ"
.
wp_pures
.
{
rewrite
/
try_recv_upd
/
is_chan
.
eauto
10
with
iFrame
.
}
iApply
"HΦ"
.
iExists
_
.
iModIntro
.
iModIntro
.
iSplit
=>
//.
wp_store
.
iExists
_,
_,
_
.
wp_apply
(
release_spec
with
"[-HΦ $Hlocked $Hlock]"
)
.
iSplit
=>
//.
{
rewrite
/
is_list_ref
/
is_list
.
eauto
10
with
iFrame
.
}
iFrame
.
iIntros
(_)
.
iApply
"Hlk"
.
wp_pures
.
Qed
.
by
iApply
"HΦ"
.
Qed
.
End
channel
.
End
channel
.
\ No newline at end of file
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment