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
7ca6ecc9
Commit
7ca6ecc9
authored
5 years ago
by
Robbert Krebbers
Browse files
Options
Downloads
Patches
Plain Diff
WIP.
parent
a180e106
No related branches found
Branches containing commit
No related tags found
1 merge request
!2
Subprotocols with message swapping
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
theories/channel/proto_channel.v
+422
-226
422 additions, 226 deletions
theories/channel/proto_channel.v
theories/channel/proto_model.v
+2
-2
2 additions, 2 deletions
theories/channel/proto_model.v
with
424 additions
and
228 deletions
theories/channel/proto_channel.v
+
422
−
226
View file @
7ca6ecc9
...
@@ -199,34 +199,69 @@ Infix "<++>" := iProto_app (at level 60) : proto_scope.
...
@@ -199,34 +199,69 @@ Infix "<++>" := iProto_app (at level 60) : proto_scope.
Definition
proto_eq_next
{
Σ
}
(
p
:
iProto
Σ
)
:
laterO
(
iProto
Σ
)
-
n
>
iPropO
Σ
:=
Definition
proto_eq_next
{
Σ
}
(
p
:
iProto
Σ
)
:
laterO
(
iProto
Σ
)
-
n
>
iPropO
Σ
:=
OfeMor
(
sbi_internal_eq
(
Next
p
))
.
OfeMor
(
sbi_internal_eq
(
Next
p
))
.
Program
Definition
iProto_le_aux
`{
invG
Σ
}
(
rec
:
iProto
Σ
-
n
>
iProto
Σ
-
n
>
iPropO
Σ
)
:
Definition
iProto_le_pre
{
Σ
}
iProto
Σ
-
n
>
iProto
Σ
-
n
>
iPropO
Σ
:=
λ
ne
p1
p2
,
(
rec
:
iProto
Σ
→
iProto
Σ
→
iProp
Σ
)
(
p1
p2
:
iProto
Σ
)
:
iProp
Σ
:=
((
p1
≡
proto_end
∗
p2
≡
proto_end
)
∨
(
p1
≡
proto_end
∗
p2
≡
proto_end
)
∨
(
∃
pc1
pc2
,
∃
a1
a2
pc1
pc2
,
p1
≡
proto_message
Send
pc1
∗
p2
≡
proto_message
Send
pc2
∗
p1
≡
proto_message
a1
pc1
∗
∀
v
p2'
,
pc2
v
(
proto_eq_next
p2'
)
-∗
p2
≡
proto_message
a2
pc2
∗
∃
p1'
,
▷
rec
p1'
p2'
∗
pc1
v
(
proto_eq_next
p1'
))
∨
match
a1
,
a2
with
(
∃
pc1
pc2
,
|
Receive
,
Receive
=>
p1
≡
proto_message
Receive
pc1
∗
p2
≡
proto_message
Receive
pc2
∗
∀
v
p1'
,
pc1
v
(
proto_eq_next
p1'
)
-∗
∀
v
p1'
,
pc1
v
(
proto_eq_next
p1'
)
-∗
∃
p2'
,
▷
rec
p1'
p2'
∗
pc2
v
(
proto_eq_next
p2'
)
∃
p2'
,
▷
rec
p1'
p2'
∗
pc2
v
(
proto_eq_next
p2'
)))
%
I
.
|
Send
,
Send
=>
∀
v
p2'
,
pc2
v
(
proto_eq_next
p2'
)
-∗
∃
p1'
,
▷
rec
p1'
p2'
∗
pc1
v
(
proto_eq_next
p1'
)
|
Receive
,
Send
=>
∀
v1
v2
p1'
p2'
,
pc1
v1
(
proto_eq_next
p1'
)
-∗
pc2
v2
(
proto_eq_next
p2'
)
-∗
∃
pc1'
pc2'
pt
,
▷
rec
p1'
(
proto_message
Send
pc1'
)
∗
▷
rec
(
proto_message
Receive
pc2'
)
p2'
∗
pc1'
v2
(
proto_eq_next
pt
)
∗
pc2'
v1
(
proto_eq_next
pt
)
|
Send
,
Receive
=>
False
end
.
Instance
iProto_le_pre_ne
{
Σ
}
(
rec
:
iProto
Σ
→
iProto
Σ
→
iProp
Σ
)
:
NonExpansive2
(
iProto_le_pre
rec
)
.
Proof
.
solve_proper
.
Qed
.
Program
Definition
iProto_le_pre'
{
Σ
}
(
rec
:
iProto
Σ
-
n
>
iProto
Σ
-
n
>
iPropO
Σ
)
:
iProto
Σ
-
n
>
iProto
Σ
-
n
>
iPropO
Σ
:=
λ
ne
p1
p2
,
iProto_le_pre
(
λ
p1'
p2'
,
rec
p1'
p2'
)
p1
p2
.
Solve
Obligations
with
solve_proper
.
Solve
Obligations
with
solve_proper
.
Local
Instance
iProto_le_aux_contractive
`{
invG
Σ
}
:
Contractive
(
@
iProto_le_aux
Σ
_)
.
Local
Instance
iProto_le_pre_contractive
{
Σ
}
:
Contractive
(
@
iProto_le_pre'
Σ
)
.
Proof
.
solve_contractive
.
Qed
.
Proof
.
Definition
iProto_le
`{
invG
Σ
}
(
p1
p2
:
iProto
Σ
)
:
iProp
Σ
:=
intros
n
rec1
rec2
Hrec
p1
p2
.
rewrite
/
iProto_le_pre'
/
iProto_le_pre
/=.
fixpoint
iProto_le_aux
p1
p2
.
by
repeat
(
f_contractive
||
f_equiv
)
.
Arguments
iProto_le
{_
_}
_
%
proto
_
%
proto
.
Qed
.
Instance
:
Params
(
@
iProto_le
)
2
:=
{}
.
Definition
iProto_le
{
Σ
}
(
p1
p2
:
iProto
Σ
)
:
iProp
Σ
:=
fixpoint
iProto_le_pre'
p1
p2
.
Arguments
iProto_le
{_}
_
%
proto
_
%
proto
.
Fixpoint
proto_interp
{
Σ
}
(
vs
:
list
val
)
(
p1
p2
:
iProto
Σ
)
:
iProp
Σ
:=
Instance
:
Params
(
@
iProto_le
)
1
:=
{}
.
match
vs
with
|
[]
=>
iProto_dual
p1
≡
p2
Fixpoint
proto_interp_aux
{
Σ
}
(
n
:
nat
)
|
v
::
vs
=>
∃
pc
p2'
,
(
vsl
vsr
:
list
val
)
(
pl
pr
:
iProto
Σ
)
:
iProp
Σ
:=
p2
≡
proto_message
Receive
pc
∗
match
n
with
pc
v
(
proto_eq_next
p2'
)
∗
|
0
=>
∃
p
,
proto_interp
vs
p1
p2'
⌜
vsl
=
[]
⌝
∗
⌜
vsr
=
[]
⌝
∗
iProto_le
p
pl
∗
iProto_le
(
iProto_dual
p
)
pr
|
S
n
=>
(
∃
vl
vsl'
pc
p2'
,
⌜
vsl
=
vl
::
vsl'
⌝
∗
iProto_le
(
proto_message
Receive
pc
)
pr
∗
pc
vl
(
proto_eq_next
p2'
)
∗
proto_interp_aux
n
vsl'
vsr
pl
p2'
)
∨
(
∃
vr
vsr'
pc
p1'
,
⌜
vsr
=
vr
::
vsr'
⌝
∗
iProto_le
(
proto_message
Receive
pc
)
pl
∗
pc
vr
(
proto_eq_next
p1'
)
∗
proto_interp_aux
n
vsl
vsr'
p1'
pr
)
end
.
end
.
Arguments
proto_interp
{_}
_
_
%
proto
_
%
proto
:
simpl
nomatch
.
Definition
proto_interp
{
Σ
}
(
vsl
vsr
:
list
val
)
(
pl
pr
:
iProto
Σ
)
:
iProp
Σ
:=
proto_interp_aux
(
length
vsl
+
length
vsr
)
vsl
vsr
pl
pr
.
Arguments
proto_interp
{_}
_
_
_
%
proto
_
%
proto
:
simpl
nomatch
.
Record
proto_name
:=
ProtName
{
Record
proto_name
:=
ProtName
{
proto_c_name
:
chan_name
;
proto_c_name
:
chan_name
;
...
@@ -247,15 +282,12 @@ Definition proto_own_auth `{!proto_chanG Σ} (γ : proto_name) (s : side)
...
@@ -247,15 +282,12 @@ Definition proto_own_auth `{!proto_chanG Σ} (γ : proto_name) (s : side)
own
(
side_elim
s
proto_l_name
proto_r_name
γ
)
(
●
E
(
Next
(
to_pre_proto
p
)))
.
own
(
side_elim
s
proto_l_name
proto_r_name
γ
)
(
●
E
(
Next
(
to_pre_proto
p
)))
.
Definition
proto_inv
`{
!
invG
Σ
,
proto_chanG
Σ
}
(
γ
:
proto_name
)
:
iProp
Σ
:=
Definition
proto_inv
`{
!
invG
Σ
,
proto_chanG
Σ
}
(
γ
:
proto_name
)
:
iProp
Σ
:=
∃
vsl
vsr
pl
pr
pl'
pr'
,
∃
vsl
vsr
pl
pr
,
chan_own
(
proto_c_name
γ
)
Left
vsl
∗
chan_own
(
proto_c_name
γ
)
Left
vsl
∗
chan_own
(
proto_c_name
γ
)
Right
vsr
∗
chan_own
(
proto_c_name
γ
)
Right
vsr
∗
proto_own_auth
γ
Left
pl'
∗
proto_own_auth
γ
Left
pl
∗
proto_own_auth
γ
Right
pr'
∗
proto_own_auth
γ
Right
pr
∗
▷
(
iProto_le
pl
pl'
∗
▷
proto_interp
vsl
vsr
pl
pr
.
iProto_le
pr
pr'
∗
((
⌜
vsr
=
[]
⌝
∗
proto_interp
vsl
pl
pr
)
∨
(
⌜
vsl
=
[]
⌝
∗
proto_interp
vsr
pr
pl
)))
.
Definition
protoN
:=
nroot
.
@
"proto"
.
Definition
protoN
:=
nroot
.
@
"proto"
.
...
@@ -281,7 +313,7 @@ Notation "c ↣ p" := (mapsto_proto c p)
...
@@ -281,7 +313,7 @@ Notation "c ↣ p" := (mapsto_proto c p)
(** * Proofs *)
(** * Proofs *)
Section
proto
.
Section
proto
.
Context
`{
!
proto_chanG
Σ
,
!
heapG
Σ
}
.
Context
`{
!
proto_chanG
Σ
,
!
heapG
Σ
}
.
Implicit
Types
p
:
iProto
Σ
.
Implicit
Types
p
pl
pr
:
iProto
Σ
.
Implicit
Types
TT
:
tele
.
Implicit
Types
TT
:
tele
.
(** ** Non-expansiveness of operators *)
(** ** Non-expansiveness of operators *)
...
@@ -356,6 +388,7 @@ Section proto.
...
@@ -356,6 +388,7 @@ Section proto.
Lemma
iProto_dual_end
:
iProto_dual
(
Σ
:=
Σ
)
END
≡
END
%
proto
.
Lemma
iProto_dual_end
:
iProto_dual
(
Σ
:=
Σ
)
END
≡
END
%
proto
.
Proof
.
by
rewrite
iProto_end_eq
/
iProto_dual
proto_map_end
.
Qed
.
Proof
.
by
rewrite
iProto_end_eq
/
iProto_dual
proto_map_end
.
Qed
.
Lemma
iProto_dual_message
{
TT
}
a
(
pc
:
TT
→
val
*
iProp
Σ
*
iProto
Σ
)
:
Lemma
iProto_dual_message
{
TT
}
a
(
pc
:
TT
→
val
*
iProp
Σ
*
iProto
Σ
)
:
iProto_dual
(
iProto_message
a
pc
)
iProto_dual
(
iProto_message
a
pc
)
≡
iProto_message
(
action_dual
a
)
(
prod_map
id
iProto_dual
∘
pc
)
.
≡
iProto_message
(
action_dual
a
)
(
prod_map
id
iProto_dual
∘
pc
)
.
...
@@ -372,6 +405,31 @@ Section proto.
...
@@ -372,6 +405,31 @@ Section proto.
by
apply
iProto_message_proper
=>
/=
-
[]
.
by
apply
iProto_message_proper
=>
/=
-
[]
.
Qed
.
Qed
.
(** Helpers for duals *)
Global
Instance
proto_eq_next_ne
:
NonExpansive
(
proto_eq_next
(
Σ
:=
Σ
))
.
Proof
.
solve_proper
.
Qed
.
Global
Instance
proto_eq_next_proper
:
Proper
((
≡
)
==>
(
≡
))
(
proto_eq_next
(
Σ
:=
Σ
))
.
Proof
.
solve_proper
.
Qed
.
Lemma
proto_eq_next_dual
p
:
ofe_mor_map
(
laterO_map
(
proto_map
action_dual
cid
cid
))
cid
(
proto_eq_next
(
iProto_dual
p
))
≡
proto_eq_next
p
.
Proof
.
intros
lp
.
iSplit
;
iIntros
"Hlp /="
;
last
by
iRewrite
-
"Hlp"
.
destruct
(
Next_uninj
lp
)
as
[
p'
->
]
.
rewrite
/
later_map
/=
!
bi
.
later_equivI
.
iNext
.
rewrite
-
{
2
}(
involutive
iProto_dual
p
)
-
{
2
}(
involutive
iProto_dual
p'
)
.
by
iRewrite
"Hlp"
.
Qed
.
Lemma
proto_eq_next_dual'
p
:
ofe_mor_map
(
laterO_map
(
proto_map
action_dual
cid
cid
))
cid
(
proto_eq_next
p
)
≡
proto_eq_next
(
iProto_dual
p
)
.
Proof
.
rewrite
-
(
proto_eq_next_dual
(
iProto_dual
p
))=>
lp
/=.
by
rewrite
involutive
.
Qed
.
(** ** Append *)
(** ** Append *)
Global
Instance
iProto_app_ne
:
NonExpansive2
(
@
iProto_app
Σ
)
.
Global
Instance
iProto_app_ne
:
NonExpansive2
(
@
iProto_app
Σ
)
.
Proof
.
apply
_
.
Qed
.
Proof
.
apply
_
.
Qed
.
...
@@ -410,47 +468,55 @@ Section proto.
...
@@ -410,47 +468,55 @@ Section proto.
Proof
.
by
rewrite
/
iProto_dual
/
iProto_app
proto_map_app
.
Qed
.
Proof
.
by
rewrite
/
iProto_dual
/
iProto_app
proto_map_app
.
Qed
.
(** ** Protocol entailment **)
(** ** Protocol entailment **)
Global
Instance
iProto_le_ne
:
NonExpansive2
(
@
iProto_le
Σ
_
)
.
Global
Instance
iProto_le_ne
:
NonExpansive2
(
@
iProto_le
Σ
)
.
Proof
.
solve_proper
.
Qed
.
Proof
.
solve_proper
.
Qed
.
Global
Instance
iProto_le_proper
:
Proper
((
≡
)
==>
(
≡
)
==>
(
⊣⊢
))
(
@
iProto_le
Σ
_
)
.
Global
Instance
iProto_le_proper
:
Proper
((
≡
)
==>
(
≡
)
==>
(
⊣⊢
))
(
@
iProto_le
Σ
)
.
Proof
.
solve_proper
.
Qed
.
Proof
.
solve_proper
.
Qed
.
Lemma
iProto_le_unfold
p1
p2
:
Lemma
iProto_le_unfold
p1
p2
:
iProto_le
p1
p2
≡
iProto_le_pre
iProto_le
p1
p2
.
iProto_le
p1
p2
≡
iProto_le_aux
(
fixpoint
iProto_le_aux
)
p1
p2
.
Proof
.
apply
:
(
fixpoint_unfold
iProto_le_pre'
)
.
Qed
.
Proof
.
apply
:
(
fixpoint_unfold
iProto_le_aux
)
.
Qed
.
Lemma
iProto_le_refl
p
:
⊢
iProto_le
p
p
.
Lemma
iProto_le_refl
p
:
⊢
iProto_le
p
p
.
Proof
.
Proof
.
iLöb
as
"IH"
forall
(
p
)
.
destruct
(
proto_case
p
)
as
[
->
|([]
&
pc
&
->
)]
.
iLöb
as
"IH"
forall
(
p
)
.
destruct
(
proto_case
p
)
as
[
->
|([]
&
pc
&
->
)]
.
-
rewrite
iProto_le_unfold
.
iLeft
;
by
auto
.
-
rewrite
iProto_le_unfold
.
iLeft
;
by
auto
.
-
rewrite
iProto_le_unfold
.
iRight
;
iLeft
.
iExists
_,
_;
do
2
(
iSplit
;
[
done
|])
.
-
rewrite
iProto_le_unfold
.
iRight
.
iExists
_,
_,
_,
_;
do
2
(
iSplit
;
[
done
|])
.
iIntros
(
v
p'
)
"Hpc"
.
iExists
p'
.
iIntros
"{$Hpc} !>"
.
iApply
"IH"
.
iIntros
(
v
p'
)
"Hpc"
.
iExists
p'
.
iIntros
"{$Hpc} !>"
.
iApply
"IH"
.
-
rewrite
iProto_le_unfold
.
iRight
;
iRight
.
iExists
_,
_;
do
2
(
iSplit
;
[
done
|])
.
-
rewrite
iProto_le_unfold
.
iRight
.
iExists
_,
_,
_,
_;
do
2
(
iSplit
;
[
done
|])
.
iIntros
(
v
p'
)
"Hpc"
.
iExists
p'
.
iIntros
"{$Hpc} !>"
.
iApply
"IH"
.
iIntros
(
v
p'
)
"Hpc"
.
iExists
p'
.
iIntros
"{$Hpc} !>"
.
iApply
"IH"
.
Qed
.
Qed
.
Lemma
iProto_le_end_inv
p
:
iProto_le
p
proto_end
-∗
p
≡
proto_end
.
Lemma
iProto_le_end_inv
p
:
iProto_le
p
proto_end
-∗
p
≡
proto_end
.
Proof
.
Proof
.
rewrite
iProto_le_unfold
.
iIntros
"[[Hp _]|H] //"
.
rewrite
iProto_le_unfold
.
iIntros
"[[Hp _]|H] //"
.
iDestruct
"H"
as
"[H|H]"
;
iDestruct
"H"
as
(
pc1
pc2
)
"(_ & Heq & _)"
;
iDestruct
"H"
as
(
a1
a2
pc1
pc2
)
"(_ & Heq & _)"
.
by
rewrite
proto_end_message_equivI
.
by
iDestruct
(
proto_end_message_equivI
with
"Heq"
)
as
%
[]
.
Qed
.
Qed
.
Lemma
iProto_le_send_inv
p1
pc2
:
Lemma
iProto_le_send_inv
p1
pc2
:
iProto_le
p1
(
proto_message
Send
pc2
)
-∗
∃
pc1
,
iProto_le
p1
(
proto_message
Send
pc2
)
-∗
∃
a1
pc1
,
p1
≡
proto_message
Send
pc1
∗
p1
≡
proto_message
a1
pc1
∗
∀
v
p2'
,
pc2
v
(
proto_eq_next
p2'
)
-∗
match
a1
with
∃
p1'
,
▷
iProto_le
p1'
p2'
∗
pc1
v
(
proto_eq_next
p1'
)
.
|
Send
=>
Proof
.
∀
v
p2'
,
pc2
v
(
proto_eq_next
p2'
)
-∗
rewrite
iProto_le_unfold
.
iIntros
"[[_ Heq]|[H|H]]"
.
∃
p1'
,
▷
iProto_le
p1'
p2'
∗
pc1
v
(
proto_eq_next
p1'
)
-
by
rewrite
proto_message_end_equivI
.
|
Receive
=>
-
iDestruct
"H"
as
(
pc1
pc2'
)
"(Hp1 & Heq & H)"
.
∀
v1
v2
p1'
p2'
,
iDestruct
(
proto_message_equivI
with
"Heq"
)
as
"[_ #Heq]"
.
pc1
v1
(
proto_eq_next
p1'
)
-∗
pc2
v2
(
proto_eq_next
p2'
)
-∗
iExists
pc1
.
iIntros
"{$Hp1}"
(
v
p2'
)
"Hpc"
.
∃
pc1'
pc2'
pt
,
iSpecialize
(
"Heq"
$!
v
)
.
iDestruct
(
bi
.
ofe_morO_equivI
with
"Heq"
)
as
"Heq'"
.
▷
iProto_le
p1'
(
proto_message
Send
pc1'
)
∗
iRewrite
(
"Heq'"
$!
(
proto_eq_next
p2'
))
in
"Hpc"
.
by
iApply
"H"
.
▷
iProto_le
(
proto_message
Receive
pc2'
)
p2'
∗
-
iDestruct
"H"
as
(
pc1
pc2'
)
"(_ & Heq & _)"
.
pc1'
v2
(
proto_eq_next
pt
)
∗
by
iDestruct
(
proto_message_equivI
with
"Heq"
)
as
"[% ?]"
.
pc2'
v1
(
proto_eq_next
pt
)
end
.
Proof
.
rewrite
iProto_le_unfold
.
iIntros
"[[_ Heq]|H]"
.
{
by
iDestruct
(
proto_message_end_equivI
with
"Heq"
)
as
%
[]
.
}
iDestruct
"H"
as
(
a1
a2
pc1
pc2'
)
"(Hp1 & Hp2 & H)"
.
iDestruct
(
proto_message_equivI
with
"Hp2"
)
as
(
<-
)
"{Hp2} #Hpc"
.
iExists
_,
_;
iSplit
;
[
done
|]
.
destruct
a1
.
-
iIntros
(
v
p2'
)
.
by
iRewrite
(
"Hpc"
$!
v
(
proto_eq_next
p2'
))
.
-
iIntros
(
v1
v2
p1'
p2'
)
.
by
iRewrite
(
"Hpc"
$!
v2
(
proto_eq_next
p2'
))
.
Qed
.
Qed
.
Lemma
iProto_le_recv_inv
p1
pc2
:
Lemma
iProto_le_recv_inv
p1
pc2
:
...
@@ -459,16 +525,13 @@ Section proto.
...
@@ -459,16 +525,13 @@ Section proto.
∀
v
p1'
,
pc1
v
(
proto_eq_next
p1'
)
-∗
∀
v
p1'
,
pc1
v
(
proto_eq_next
p1'
)
-∗
∃
p2'
,
▷
iProto_le
p1'
p2'
∗
pc2
v
(
proto_eq_next
p2'
)
.
∃
p2'
,
▷
iProto_le
p1'
p2'
∗
pc2
v
(
proto_eq_next
p2'
)
.
Proof
.
Proof
.
rewrite
iProto_le_unfold
.
iIntros
"[[_ Heq]|[H|H]]"
.
rewrite
iProto_le_unfold
.
iIntros
"[[_ Heq]|H]"
.
-
by
rewrite
proto_message_end_equivI
.
{
by
iDestruct
(
proto_message_end_equivI
with
"Heq"
)
as
%
[]
.
}
-
iDestruct
"H"
as
(
pc1
pc2'
)
"(_ & Heq & _)"
.
iDestruct
"H"
as
(
a1
a2
pc1
pc2'
)
"(Hp1 & Hp2 & H)"
.
by
iDestruct
(
proto_message_equivI
with
"Heq"
)
as
"[% ?]"
.
iDestruct
(
proto_message_equivI
with
"Hp2"
)
as
(
<-
)
"{Hp2} #Hpc2"
.
-
iDestruct
"H"
as
(
pc1
pc2'
)
"(Hp1 & Heq & H)"
.
destruct
a1
;
[
done
|]
.
iExists
_;
iSplit
;
[
done
|]
.
iDestruct
(
proto_message_equivI
with
"Heq"
)
as
"[_ #Heq]"
.
iIntros
(
v
p1'
)
"Hpc"
.
iDestruct
(
"H"
with
"Hpc"
)
as
(
p2'
)
"[Hle Hpc]"
.
iExists
pc1
.
iIntros
"{$Hp1}"
(
v
p1'
)
"Hpc"
.
iExists
p2'
.
iFrame
"Hle"
.
by
iRewrite
(
"Hpc2"
$!
v
(
proto_eq_next
p2'
))
.
iSpecialize
(
"Heq"
$!
v
)
.
iDestruct
(
bi
.
ofe_morO_equivI
with
"Heq"
)
as
"Heq'"
.
iDestruct
(
"H"
with
"Hpc"
)
as
(
p2'
)
"[Hle Hpc]"
.
iExists
p2'
.
iFrame
"Hle"
.
by
iRewrite
(
"Heq'"
$!
(
proto_eq_next
p2'
))
.
Qed
.
Qed
.
Lemma
iProto_le_trans
p1
p2
p3
:
Lemma
iProto_le_trans
p1
p2
p3
:
...
@@ -476,21 +539,32 @@ Section proto.
...
@@ -476,21 +539,32 @@ Section proto.
Proof
.
Proof
.
iIntros
"H1 H2"
.
iLöb
as
"IH"
forall
(
p1
p2
p3
)
.
iIntros
"H1 H2"
.
iLöb
as
"IH"
forall
(
p1
p2
p3
)
.
destruct
(
proto_case
p3
)
as
[
->
|([]
&
pc3
&
->
)]
.
destruct
(
proto_case
p3
)
as
[
->
|([]
&
pc3
&
->
)]
.
-
rewrite
iProto_le_end_inv
.
by
iRewrite
"H2"
in
"H1"
.
-
by
iRewrite
(
iProto_le_end_inv
with
"H2"
)
in
"H1"
.
-
iDestruct
(
iProto_le_send_inv
with
"H2"
)
as
(
pc2
)
"[Hp2 H3]"
.
-
iDestruct
(
iProto_le_send_inv
with
"H2"
)
as
(
a2
pc2
)
"[Hp2 H2]"
.
iRewrite
"Hp2"
in
"H1"
.
iRewrite
"Hp2"
in
"H1"
;
clear
p2
.
destruct
a2
.
iDestruct
(
iProto_le_send_inv
with
"H1"
)
as
(
pc1
)
"[Hp1 H2]"
.
+
iDestruct
(
iProto_le_send_inv
with
"H1"
)
as
(
a1
pc1
)
"[Hp1 H1]"
.
iRewrite
"Hp1"
.
rewrite
iProto_le_unfold
;
iRight
;
iLeft
.
iRewrite
"Hp1"
;
clear
p1
.
rewrite
iProto_le_unfold
;
iRight
.
iExists
_,
_;
do
2
(
iSplit
;
[
done
|])
.
iExists
_,
_,
_,
_;
do
2
(
iSplit
;
[
done
|])
.
destruct
a1
.
iIntros
(
v
p3'
)
"Hpc"
.
*
iIntros
(
v
p3'
)
"Hpc"
.
iDestruct
(
"H3"
with
"Hpc"
)
as
(
p2'
)
"[Hle Hpc]"
.
iDestruct
(
"H2"
with
"Hpc"
)
as
(
p2'
)
"[Hle Hpc]"
.
iDestruct
(
"H2"
with
"Hpc"
)
as
(
p1'
)
"[Hle' Hpc]"
.
iDestruct
(
"H1"
with
"Hpc"
)
as
(
p1'
)
"[Hle' Hpc]"
.
iExists
p1'
.
iIntros
"{$Hpc} !>"
.
by
iApply
(
"IH"
with
"Hle'"
)
.
iExists
p1'
.
iIntros
"{$Hpc} !>"
.
by
iApply
(
"IH"
with
"Hle'"
)
.
*
iIntros
(
v1
v3
p1'
p3'
)
"Hpc1 Hpc3"
.
iDestruct
(
"H2"
with
"Hpc3"
)
as
(
p2'
)
"[Hle Hpc2]"
.
iDestruct
(
"H1"
with
"Hpc1 Hpc2"
)
as
(
pc1'
pc2'
pt
)
"(Hp1' & Hp2' & Hpc)"
.
iExists
pc1'
,
pc2'
,
pt
.
iFrame
"Hp1' Hpc"
.
by
iApply
(
"IH"
with
"Hp2'"
)
.
+
iDestruct
(
iProto_le_recv_inv
with
"H1"
)
as
(
pc1
)
"[Hp1 H1]"
.
iRewrite
"Hp1"
;
clear
p1
.
rewrite
iProto_le_unfold
;
iRight
.
iExists
_,
_,
_,
_;
do
2
(
iSplit
;
[
done
|]);
simpl
.
iIntros
(
v1
v3
p1'
p3'
)
"Hpc1 Hpc3"
.
iDestruct
(
"H1"
with
"Hpc1"
)
as
(
p2'
)
"[Hle Hpc2]"
.
iDestruct
(
"H2"
with
"Hpc2 Hpc3"
)
as
(
pc2'
pc3'
pt
)
"(Hp2' & Hp3' & Hpc)"
.
iExists
pc2'
,
pc3'
,
pt
.
iFrame
"Hp3' Hpc"
.
by
iApply
(
"IH"
with
"Hle"
)
.
-
iDestruct
(
iProto_le_recv_inv
with
"H2"
)
as
(
pc2
)
"[Hp2 H3]"
.
-
iDestruct
(
iProto_le_recv_inv
with
"H2"
)
as
(
pc2
)
"[Hp2 H3]"
.
iRewrite
"Hp2"
in
"H1"
.
iRewrite
"Hp2"
in
"H1"
.
iDestruct
(
iProto_le_recv_inv
with
"H1"
)
as
(
pc1
)
"[Hp1 H2]"
.
iDestruct
(
iProto_le_recv_inv
with
"H1"
)
as
(
pc1
)
"[Hp1 H2]"
.
iRewrite
"Hp1"
.
rewrite
iProto_le_unfold
;
iRight
;
iRight
.
iRewrite
"Hp1"
.
rewrite
iProto_le_unfold
.
iRight
.
iExists
_,
_;
do
2
(
iSplit
;
[
done
|])
.
iExists
_,
_,
_,
_;
do
2
(
iSplit
;
[
done
|])
.
iIntros
(
v
p1'
)
"Hpc"
.
iIntros
(
v
p1'
)
"Hpc"
.
iDestruct
(
"H2"
with
"Hpc"
)
as
(
p2'
)
"[Hle Hpc]"
.
iDestruct
(
"H2"
with
"Hpc"
)
as
(
p2'
)
"[Hle Hpc]"
.
iDestruct
(
"H3"
with
"Hpc"
)
as
(
p3'
)
"[Hle' Hpc]"
.
iDestruct
(
"H3"
with
"Hpc"
)
as
(
p3'
)
"[Hle' Hpc]"
.
...
@@ -505,13 +579,12 @@ Section proto.
...
@@ -505,13 +579,12 @@ Section proto.
▷
iProto_le
(
pc1
x1
).
2
(
pc2
x2
).
2
)
-∗
▷
iProto_le
(
pc1
x1
).
2
(
pc2
x2
).
2
)
-∗
iProto_le
(
iProto_message
Send
pc1
)
(
iProto_message
Send
pc2
)
.
iProto_le
(
iProto_message
Send
pc1
)
(
iProto_message
Send
pc2
)
.
Proof
.
Proof
.
iIntros
"H"
.
rewrite
iProto_le_unfold
iProto_message_eq
.
iRight
;
iLeft
.
iIntros
"H"
.
rewrite
iProto_le_unfold
iProto_message_eq
.
i
Exists
_,
_;
do
2
(
iSplit
;
[
done
|])
.
i
Right
.
iExists
_,
_,
_,
_;
do
2
(
iSplit
;
[
done
|])
.
iIntros
(
v
p2'
)
"/="
.
iDestruct
1
as
(
x2
->
)
"[Hpc #Heq]"
.
iIntros
(
v
p2'
)
"/="
.
iDestruct
1
as
(
x2
->
)
"[Hpc #Heq]"
.
iDestruct
(
"H"
with
"Hpc"
)
as
(
x1
?)
"[Hpc Hle]"
.
iDestruct
(
"H"
with
"Hpc"
)
as
(
x1
?)
"[Hpc Hle]"
.
iExists
(
pc1
x1
).
2
.
iSplitL
"Hle"
.
iExists
(
pc1
x1
).
2
.
iSplitL
"Hle"
.
{
iIntros
"!>"
.
change
(
fixpoint
iProto_le_aux
?p1
?p2
)
with
(
iProto_le
p1
p2
)
.
{
iIntros
"!>"
.
by
iRewrite
"Heq"
.
}
by
iRewrite
"Heq"
.
}
iExists
x1
.
iSplit
;
[
done
|]
.
iSplit
;
[
by
iApply
"Hpc"
|
done
]
.
iExists
x1
.
iSplit
;
[
done
|]
.
iSplit
;
[
by
iApply
"Hpc"
|
done
]
.
Qed
.
Qed
.
...
@@ -523,15 +596,60 @@ Section proto.
...
@@ -523,15 +596,60 @@ Section proto.
▷
iProto_le
(
pc1
x1
).
2
(
pc2
x2
).
2
)
-∗
▷
iProto_le
(
pc1
x1
).
2
(
pc2
x2
).
2
)
-∗
iProto_le
(
iProto_message
Receive
pc1
)
(
iProto_message
Receive
pc2
)
.
iProto_le
(
iProto_message
Receive
pc1
)
(
iProto_message
Receive
pc2
)
.
Proof
.
Proof
.
iIntros
"H"
.
rewrite
iProto_le_unfold
iProto_message_eq
.
iRight
;
iRight
.
iIntros
"H"
.
rewrite
iProto_le_unfold
iProto_message_eq
.
i
Exists
_,
_;
do
2
(
iSplit
;
[
done
|])
.
i
Right
.
iExists
_,
_,
_,
_;
do
2
(
iSplit
;
[
done
|])
.
iIntros
(
v
p1'
)
"/="
.
iDestruct
1
as
(
x1
->
)
"[Hpc #Heq]"
.
iIntros
(
v
p1'
)
"/="
.
iDestruct
1
as
(
x1
->
)
"[Hpc #Heq]"
.
iDestruct
(
"H"
with
"Hpc"
)
as
(
x2
?)
"[Hpc Hle]"
.
iExists
(
pc2
x2
).
2
.
iSplitL
"Hle"
.
iDestruct
(
"H"
with
"Hpc"
)
as
(
x2
?)
"[Hpc Hle]"
.
iExists
(
pc2
x2
).
2
.
iSplitL
"Hle"
.
{
iIntros
"!>"
.
change
(
fixpoint
iProto_le_aux
?p1
?p2
)
with
(
iProto_le
p1
p2
)
.
{
iIntros
"!>"
.
by
iRewrite
"Heq"
.
}
by
iRewrite
"Heq"
.
}
iExists
x2
.
iSplit
;
[
done
|]
.
iSplit
;
[
by
iApply
"Hpc"
|
done
]
.
iExists
x2
.
iSplit
;
[
done
|]
.
iSplit
;
[
by
iApply
"Hpc"
|
done
]
.
Qed
.
Qed
.
Lemma
iProto_swap
{
TT1
TT2
}
(
v1
:
TT1
→
val
)
(
v2
:
TT2
→
val
)
(
P1
:
TT1
→
iProp
Σ
)
(
P2
:
TT2
→
iProp
Σ
)
(
p
:
TT1
→
TT2
→
iProto
Σ
)
:
⊢
iProto_le
(
iProto_message
Receive
(
λ
x1
,
(
v1
x1
,
P1
x1
,
iProto_message
Send
(
λ
x2
,
(
v2
x2
,
P2
x2
,
p
x1
x2
)))))
(
iProto_message
Send
(
λ
x2
,
(
v2
x2
,
P2
x2
,
iProto_message
Receive
(
λ
x1
,
(
v1
x1
,
P1
x1
,
p
x1
x2
)))))
.
Proof
.
rewrite
iProto_le_unfold
iProto_message_eq
.
iRight
.
iExists
_,
_,
_,
_;
do
2
(
iSplit
;
[
done
|]);
simpl
.
iIntros
(
w1
w2
p1'
p2'
)
.
iDestruct
1
as
(
x1
->
)
"[Hpc1 #Hp1']"
;
iDestruct
1
as
(
x2
->
)
"[Hpc2 #Hp2']"
.
iExists
_,
_,
(
p
x1
x2
)
.
iSplitR
;
[
iNext
;
iRewrite
"Hp1'"
;
iApply
iProto_le_refl
|]
.
iSplitR
;
[
iNext
;
iRewrite
"Hp2'"
;
iApply
iProto_le_refl
|];
simpl
.
iSplitL
"Hpc2"
;
eauto
.
Qed
.
Lemma
iProto_dual_le
p1
p2
:
iProto_le
p2
p1
-∗
iProto_le
(
iProto_dual
p1
)
(
iProto_dual
p2
)
.
Proof
.
iIntros
"H"
.
iLöb
as
"IH"
forall
(
p1
p2
)
.
destruct
(
proto_case
p1
)
as
[
->
|([]
&
pc1
&
->
)]
.
-
iRewrite
(
iProto_le_end_inv
with
"H"
)
.
iApply
iProto_le_refl
.
-
iDestruct
(
iProto_le_send_inv
with
"H"
)
as
(
a2
pc2
)
"[Hp2 H]"
.
iRewrite
"Hp2"
;
clear
p2
.
iEval
(
rewrite
/
iProto_dual
!
proto_map_message
/=
)
.
rewrite
iProto_le_unfold
;
iRight
.
iExists
_,
_,
_,
_;
do
2
(
iSplit
;
[
done
|]);
simpl
.
destruct
a2
;
simpl
.
+
iIntros
(
v
p1'
)
"Hpc"
.
rewrite
proto_eq_next_dual'
.
iDestruct
(
"H"
with
"Hpc"
)
as
(
p2''
)
"[H Hpc]"
.
iDestruct
(
"IH"
with
"H"
)
as
"H"
.
rewrite
involutive
.
iExists
(
iProto_dual
p2''
)
.
rewrite
proto_eq_next_dual
.
iFrame
.
+
iIntros
(
v1
v2
p1'
p2'
)
"Hpc1 Hpc2"
.
rewrite
!
proto_eq_next_dual'
.
iDestruct
(
"H"
with
"Hpc2 Hpc1"
)
as
(
pc1'
pc2'
pt
)
"(H1 & H2 & Hpc1 & Hpc2)"
.
iDestruct
(
"IH"
with
"H1"
)
as
"H1"
.
iDestruct
(
"IH"
with
"H2"
)
as
"H2 {IH}"
.
rewrite
!
involutive
/
iProto_dual
!
proto_map_message
.
iExists
_,
_,
(
iProto_dual
pt
)
.
iFrame
.
rewrite
/=
proto_eq_next_dual
.
iFrame
.
-
iDestruct
(
iProto_le_recv_inv
with
"H"
)
as
(
pc2
)
"[Hp2 H]"
.
iRewrite
"Hp2"
;
clear
p2
.
iEval
(
rewrite
/
iProto_dual
!
proto_map_message
/=
)
.
rewrite
iProto_le_unfold
;
iRight
.
iExists
_,
_,
_,
_;
do
2
(
iSplit
;
[
done
|]);
simpl
.
iIntros
(
v
p2'
)
"Hpc"
.
rewrite
proto_eq_next_dual'
.
iDestruct
(
"H"
with
"Hpc"
)
as
(
p2''
)
"[H Hpc]"
.
iDestruct
(
"IH"
with
"H"
)
as
"H"
.
rewrite
involutive
.
iExists
(
iProto_dual
p2''
)
.
rewrite
proto_eq_next_dual
.
iFrame
.
Qed
.
Lemma
iProto_mapsto_le
c
p1
p2
:
c
↣
p1
-∗
iProto_le
p1
p2
-∗
c
↣
p2
.
Lemma
iProto_mapsto_le
c
p1
p2
:
c
↣
p1
-∗
iProto_le
p1
p2
-∗
c
↣
p2
.
Proof
.
Proof
.
rewrite
mapsto_proto_eq
.
iDestruct
1
as
(
s
c1
c2
γ
p1'
->
)
"[Hle H]"
.
rewrite
mapsto_proto_eq
.
iDestruct
1
as
(
s
c1
c2
γ
p1'
->
)
"[Hle H]"
.
...
@@ -540,10 +658,16 @@ Section proto.
...
@@ -540,10 +658,16 @@ Section proto.
Qed
.
Qed
.
(** ** Lemmas about the auxiliary definitions and invariants *)
(** ** Lemmas about the auxiliary definitions and invariants *)
Global
Instance
proto_interp_ne
:
NonExpansive2
(
proto_interp
(
Σ
:=
Σ
)
vs
)
.
Global
Instance
proto_interp_aux_ne
n
vsl
vsr
:
Proof
.
induction
vs
;
solve_proper
.
Qed
.
NonExpansive2
(
proto_interp_aux
(
Σ
:=
Σ
)
n
vsl
vsr
)
.
Global
Instance
proto_interp_proper
vs
:
Proof
.
revert
vsl
vsr
.
induction
n
;
solve_proper
.
Qed
.
Proper
((
≡
)
==>
(
≡
)
==>
(
≡
))
(
proto_interp
(
Σ
:=
Σ
)
vs
)
.
Global
Instance
proto_interp_aux_proper
n
vsl
vsr
:
Proper
((
≡
)
==>
(
≡
)
==>
(
≡
))
(
proto_interp_aux
(
Σ
:=
Σ
)
n
vsl
vsr
)
.
Proof
.
apply
(
ne_proper_2
_)
.
Qed
.
Global
Instance
proto_interp_ne
vsl
vsr
:
NonExpansive2
(
proto_interp
(
Σ
:=
Σ
)
vsl
vsr
)
.
Proof
.
solve_proper
.
Qed
.
Global
Instance
proto_interp_proper
vsl
vsr
:
Proper
((
≡
)
==>
(
≡
)
==>
(
≡
))
(
proto_interp
(
Σ
:=
Σ
)
vsl
vsr
)
.
Proof
.
apply
(
ne_proper_2
_)
.
Qed
.
Proof
.
apply
(
ne_proper_2
_)
.
Qed
.
Global
Instance
to_pre_proto_ne
:
NonExpansive
(
to_pre_proto
(
Σ
:=
Σ
))
.
Global
Instance
to_pre_proto_ne
:
NonExpansive
(
to_pre_proto
(
Σ
:=
Σ
))
.
...
@@ -579,53 +703,157 @@ Section proto.
...
@@ -579,53 +703,157 @@ Section proto.
by
rewrite
own_op
.
by
rewrite
own_op
.
Qed
.
Qed
.
Lemma
proto_eq_next_dual
p
:
(* TODO: Move somewhere else *)
ofe_mor_map
(
laterO_map
(
proto_map
action_dual
cid
cid
))
cid
(
proto_eq_next
(
iProto_dual
p
))
≡
Lemma
false_disj_cong
(
P
Q
Q'
:
iProp
Σ
)
:
proto_eq_next
p
.
(
P
⊢
False
)
→
(
Q
⊣⊢
Q'
)
→
(
P
∨
Q
⊣⊢
Q'
)
.
Proof
.
intros
HP
->
.
apply
(
anti_symm
_)
.
by
rewrite
HP
left_id
.
auto
.
Qed
.
Lemma
pure_sep_cong
(
φ1
φ2
:
Prop
)
(
P1
P2
:
iProp
Σ
)
:
(
φ1
↔
φ2
)
→
(
φ1
→
φ2
→
P1
⊣⊢
P2
)
→
(
⌜
φ1
⌝
∗
P1
)
⊣⊢
(
⌜
φ2
⌝
∗
P2
)
.
Proof
.
intros
->
HP
.
iSplit
;
iDestruct
1
as
(
Hϕ
)
"H"
;
rewrite
HP
;
auto
.
Qed
.
Lemma
proto_interp_unfold
vsl
vsr
pl
pr
:
proto_interp
vsl
vsr
pl
pr
⊣⊢
(
∃
p
,
⌜
vsl
=
[]
⌝
∗
⌜
vsr
=
[]
⌝
∗
iProto_le
p
pl
∗
iProto_le
(
iProto_dual
p
)
pr
)
∨
(
∃
vl
vsl'
pc
pr'
,
⌜
vsl
=
vl
::
vsl'
⌝
∗
iProto_le
(
proto_message
Receive
pc
)
pr
∗
pc
vl
(
proto_eq_next
pr'
)
∗
proto_interp
vsl'
vsr
pl
pr'
)
∨
(
∃
vr
vsr'
pc
pl'
,
⌜
vsr
=
vr
::
vsr'
⌝
∗
iProto_le
(
proto_message
Receive
pc
)
pl
∗
pc
vr
(
proto_eq_next
pl'
)
∗
proto_interp
vsl
vsr'
pl'
pr
)
.
Proof
.
Proof
.
intros
lp
.
iSplit
;
iIntros
"Hlp /="
;
last
by
iRewrite
-
"Hlp"
.
rewrite
{
1
}
/
proto_interp
.
destruct
vsl
as
[|
vl
vsl
];
simpl
.
destruct
(
Next_uninj
lp
)
as
[
p'
->
]
.
-
destruct
vsr
as
[|
vr
vsr
];
simpl
.
rewrite
/
later_map
/=
!
bi
.
later_equivI
.
iNext
.
+
iSplit
;
first
by
auto
.
rewrite
-
{
2
}(
involutive
iProto_dual
p
)
-
{
2
}(
involutive
iProto_dual
p'
)
.
iDestruct
1
as
"[H | [H | H]]"
;
first
by
auto
.
by
iRewrite
"Hlp"
.
*
iDestruct
"H"
as
(?
?
?
?
[
=
])
"_"
.
*
iDestruct
"H"
as
(?
?
?
?
[
=
])
"_"
.
+
symmetry
.
apply
false_disj_cong
.
{
iDestruct
1
as
(?
_
[
=
])
"_"
.
}
repeat
first
[
apply
pure_sep_cong
;
intros
;
simplify_eq
/=
|
f_equiv
];
by
rewrite
?Nat
.
add_succ_r
.
-
symmetry
.
apply
false_disj_cong
.
{
iDestruct
1
as
(?
[
=
])
"_"
.
}
repeat
first
[
apply
pure_sep_cong
;
intros
;
simplify_eq
/=
|
f_equiv
];
by
rewrite
?Nat
.
add_succ_r
.
Qed
.
Qed
.
Lemma
proto_interp_send
v
vs
pc
p1
p2
:
Lemma
proto_interp_nil
p
:
⊢
proto_interp
[]
[]
p
(
iProto_dual
p
)
.
proto_interp
vs
(
proto_message
Send
pc
)
p2
-∗
pc
v
(
proto_eq_next
p1
)
-∗
proto_interp
(
vs
++
[
v
])
p1
p2
.
Proof
.
Proof
.
iIntros
"Heval Hc"
.
iInduction
vs
as
[|
v'
vs
]
"IH"
forall
(
p2
);
simpl
.
rewrite
proto_interp_unfold
.
iLeft
.
iExists
p
.
do
2
(
iSplit
;
[
done
|])
.
-
iDestruct
"Heval"
as
"#Heval"
.
iSplitL
;
iApply
iProto_le_refl
.
iExists
_,
(
iProto_dual
p1
)
.
iSplit
.
{
iRewrite
-
"Heval"
.
by
rewrite
/
iProto_dual
proto_map_message
.
}
rewrite
/=
proto_eq_next_dual
;
auto
.
-
iDestruct
"Heval"
as
(
pc'
p2'
)
"(Heq & Hc' & Heval)"
.
iExists
pc'
,
p2'
.
iFrame
"Heq Hc'"
.
iApply
(
"IH"
with
"Heval Hc"
)
.
Qed
.
Qed
.
Lemma
proto_interp_recv
v
vs
p1
pc
:
Lemma
proto_interp_flip
vsl
vsr
pl
pr
:
proto_interp
(
v
::
vs
)
p1
(
proto_message
Receive
pc
)
-∗
∃
p2
,
proto_interp
vsl
vsr
pl
pr
-∗
proto_interp
vsr
vsl
pr
pl
.
pc
v
(
proto_eq_next
p2
)
∗
proto_interp
vs
p1
p2
.
Proof
.
Proof
.
simpl
.
iDestruct
1
as
(
pc'
p2
)
"(Heq & Hc & Hp2)"
.
iExists
p2
.
iFrame
"Hp2"
.
remember
(
length
vsl
+
length
vsr
)
as
n
eqn
:
Hn
.
iDestruct
(
@
proto_message_equivI
with
"Heq"
)
as
"[_ Heq]"
.
iInduction
(
lt_wf
n
)
as
[
n
_]
"IH"
forall
(
vsl
vsr
pl
pr
Hn
);
subst
.
iSpecialize
(
"Heq"
$!
v
)
.
rewrite
bi
.
ofe_morO_equivI
.
rewrite
!
proto_interp_unfold
.
iIntros
"[H|[H|H]]"
.
by
iRewrite
(
"Heq"
$!
(
proto_eq_next
p2
))
.
-
iClear
"IH"
.
iDestruct
"H"
as
(
p
->
->
)
"[Hp Hp'] /="
.
iLeft
.
iExists
(
iProto_dual
p
)
.
rewrite
involutive
.
iFrame
;
auto
.
-
iDestruct
"H"
as
(
vl
vsl'
pc'
pr'
->
)
"(Hpr & Hpc' & Hinterp)"
.
iRight
;
iRight
.
iExists
vl
,
vsl'
,
pc'
,
pr'
.
iSplit
;
[
done
|];
iFrame
.
iApply
(
"IH"
with
"[%] [//] Hinterp"
);
simpl
;
lia
.
-
iDestruct
"H"
as
(
vr
vsr'
pc'
pl'
->
)
"(Hpl & Hpc' & Hinterp)"
.
iRight
;
iLeft
.
iExists
vr
,
vsr'
,
pc'
,
pl'
.
iSplit
;
[
done
|];
iFrame
.
iApply
(
"IH"
with
"[%] [//] Hinterp"
);
simpl
;
lia
.
Qed
.
Qed
.
Lemma
proto_interp_
False
p
p
c
v
vs
:
Lemma
proto_interp_
le_l
vsl
vsr
p
l
p
l'
pr
:
proto_interp
(
v
::
vs
)
p
(
proto_message
Send
pc
)
-∗
False
.
proto_interp
vsl
vs
r
p
l
pr
-∗
iProto_le
pl
pl'
-∗
proto_interp
vsl
vsr
pl'
pr
.
Proof
.
Proof
.
simpl
.
iDestruct
1
as
(
pc'
p2'
)
"[Heq _]"
.
remember
(
length
vsl
+
length
vsr
)
as
n
eqn
:
Hn
.
by
iDestruct
(
@
proto_message_equivI
with
"Heq"
)
as
"[% _]"
.
iInduction
(
lt_wf
n
)
as
[
n
_]
"IH"
forall
(
vsl
vsr
pl
pr
Hn
);
subst
.
rewrite
!
proto_interp_unfold
.
iIntros
"[H|[H|H]] Hle"
.
-
iClear
"IH"
.
iDestruct
"H"
as
(
p
->
->
)
"[Hp Hp'] /="
.
iLeft
.
iExists
p
.
do
2
(
iSplit
;
[
done
|])
.
iFrame
"Hp'"
.
by
iApply
(
iProto_le_trans
with
"Hp"
)
.
-
iDestruct
"H"
as
(
vl
vsl'
pc'
pr'
->
)
"(Hpr & Hpc' & Hinterp)"
.
iRight
;
iLeft
.
iExists
vl
,
vsl'
,
pc'
,
pr'
.
iSplit
;
[
done
|];
iFrame
.
iApply
(
"IH"
with
"[%] [//] Hinterp Hle"
);
simpl
;
lia
.
-
iClear
"IH"
.
iDestruct
"H"
as
(
vr
vsr'
pc'
pl''
->
)
"(Hpl & Hpc' & Hinterp)"
.
iRight
;
iRight
.
iExists
vr
,
vsr'
,
pc'
,
pl''
.
iSplit
;
[
done
|];
iFrame
.
by
iApply
(
iProto_le_trans
with
"Hpl"
)
.
Qed
.
Lemma
proto_interp_le_r
vsl
vsr
pl
pr
pr'
:
proto_interp
vsl
vsr
pl
pr
-∗
iProto_le
pr
pr'
-∗
proto_interp
vsl
vsr
pl
pr'
.
Proof
.
iIntros
"Hinterp Hle"
.
iApply
proto_interp_flip
.
iApply
(
proto_interp_le_l
with
"[Hinterp] Hle"
)
.
by
iApply
proto_interp_flip
.
Qed
.
Qed
.
Lemma
proto_interp_nil
p1
p2
:
proto_interp
[]
p1
p2
-∗
p1
≡
iProto_dual
p2
.
(*
Proof
.
iIntros
"#H /="
.
iRewrite
-
"H"
.
by
rewrite
involutive
.
Qed
.
Lemma wtf a p1 pc2 :
▷ iProto_le p1 (proto_message a pc2) -∗
Arguments
proto_interp
:
simpl
never
.
◇ ∃ pc2', iProto_le p1 (proto_message a pc2') ∧ ▷ ∀ v pc', pc2 v pc' ≡ pc2' v pc'.
Proof. Admitted.
*)
Lemma
proto_interp_send
vl
pcl
vsl
vsr
pl
pr
pl'
:
proto_interp
vsl
vsr
pl
pr
-∗
iProto_le
pl
(
proto_message
Send
pcl
)
-∗
pcl
vl
(
proto_eq_next
pl'
)
-∗
proto_interp
(
vsl
++
[
vl
])
vsr
pl'
pr
.
Proof
.
iIntros
"H Hle"
.
iDestruct
(
proto_interp_le_l
with
"H Hle"
)
as
"H"
.
clear
pl
.
iIntros
"Hpcl"
.
remember
(
length
vsl
+
length
vsr
)
as
n
eqn
:
Hn
.
iInduction
(
lt_wf
n
)
as
[
n
_]
"IH"
forall
(
pcl
vsl
vsr
pr
pl'
Hn
);
subst
.
rewrite
{
1
}
proto_interp_unfold
.
iDestruct
"H"
as
"[H|[H|H]]"
.
-
iClear
"IH"
.
iDestruct
"H"
as
(
p
->
->
)
"[Hp Hp'] /="
.
iDestruct
(
iProto_dual_le
with
"Hp"
)
as
"Hp"
.
iDestruct
(
iProto_le_trans
with
"Hp Hp'"
)
as
"Hp"
.
rewrite
/
iProto_dual
proto_map_message
/=.
iApply
proto_interp_unfold
.
iRight
;
iLeft
.
iExists
vl
,
[],
_,
(
iProto_dual
pl'
)
.
iSplit
;
[
done
|]
.
iFrame
"Hp"
;
simpl
.
rewrite
proto_eq_next_dual
.
iFrame
"Hpcl"
.
iApply
proto_interp_nil
.
-
iDestruct
"H"
as
(
vl'
vsl'
pc'
pr'
->
)
"(Hpr & Hpc' & H)"
.
iDestruct
(
"IH"
with
"[%] [//] H Hpcl"
)
as
"H"
;
[
simpl
;
lia
|]
.
iApply
(
proto_interp_le_r
with
"[-Hpr] Hpr"
);
clear
pr
.
iApply
proto_interp_unfold
.
iRight
;
iLeft
.
iExists
vl'
,
(
vsl'
++
[
vl
]),
pc'
,
pr'
.
iFrame
.
iSplit
;
[
done
|]
.
iApply
iProto_le_refl
.
-
iDestruct
"H"
as
(
vr'
vsr'
pc'
pl''
->
)
"(Hle & Hpcl' & H)"
.
iDestruct
(
iProto_le_send_inv
with
"Hle"
)
as
(
a
pcl'
)
"[Hpc Hle]"
.
iDestruct
(
proto_message_equivI
with
"Hpc"
)
as
(
<-
)
"Hpc"
.
iRewrite
(
"Hpc"
$!
vr'
(
proto_eq_next
pl''
))
in
"Hpcl'"
;
clear
pc'
.
iDestruct
(
"Hle"
with
"Hpcl' Hpcl"
)
as
(
pc1
pc2
pc'
)
"(Hpl'' & Hpl' & Hpc1 & Hpc2)"
.
(* STUCK HERE
iMod (wtf with "Hpl''") as (pc1') "[Hpl'' #Hpc]".
iDestruct (proto_interp_le_l with "H Hpl''") as "H".
iDestruct ("IH" with "[%] [//] H [Hpc1]") as "H"; [simpl; lia|..].
*)
Admitted
.
Lemma
proto_interp_recv
vl
vsl
vsr
pl
pr
pcr
:
proto_interp
(
vl
::
vsl
)
vsr
pl
pr
-∗
iProto_le
pr
(
proto_message
Receive
pcr
)
-∗
∃
pr
,
pcr
vl
(
proto_eq_next
pr
)
∗
▷
proto_interp
vsl
vsr
pl
pr
.
Proof
.
iIntros
"H Hle"
.
iDestruct
(
proto_interp_le_r
with
"H Hle"
)
as
"H"
.
clear
pr
.
remember
(
length
vsr
)
as
n
eqn
:
Hn
.
iInduction
(
lt_wf
n
)
as
[
n
_]
"IH"
forall
(
vsr
pl
Hn
);
subst
.
rewrite
!
proto_interp_unfold
.
iDestruct
"H"
as
"[H|[H|H]]"
.
-
iClear
"IH"
.
iDestruct
"H"
as
(
p
[
=
])
"_"
.
-
iClear
"IH"
.
iDestruct
"H"
as
(
vl'
vsl'
pc'
pr'
[
=
->
->
])
"(Hpr & Hpc' & Hinterp)"
.
iDestruct
(
iProto_le_recv_inv
with
"Hpr"
)
as
(
pc''
)
"[Hpc Hpr]"
.
iDestruct
(
proto_message_equivI
with
"Hpc"
)
as
(_)
"{Hpc} #Hpc"
.
iDestruct
(
"Hpr"
$!
vl'
pr'
with
"[Hpc']"
)
as
(
pr''
)
"[Hler Hpr]"
.
{
by
iRewrite
-
(
"Hpc"
$!
vl'
(
proto_eq_next
pr'
))
.
}
iExists
pr''
.
iFrame
"Hpr"
.
by
iApply
(
proto_interp_le_r
with
"Hinterp"
)
.
-
iDestruct
"H"
as
(
vr
vsr'
pc'
pl''
->
)
"(Hpl & Hpc' & Hinterp)"
.
iDestruct
(
"IH"
with
"[%] [//] Hinterp"
)
as
(
pr
)
"[Hpc Hinterp]"
;
[
simpl
;
lia
|]
.
iExists
pr
.
iFrame
"Hpc"
.
iApply
proto_interp_unfold
.
iRight
;
iRight
.
eauto
20
with
iFrame
.
Qed
.
(** ** Helper lemma for initialization of a channel *)
(** ** Helper lemma for initialization of a channel *)
Lemma
proto_init
E
cγ
c1
c2
p
:
Lemma
proto_init
E
cγ
c1
c2
p
:
...
@@ -633,7 +861,7 @@ Section proto.
...
@@ -633,7 +861,7 @@ Section proto.
chan_own
cγ
Left
[]
-∗
chan_own
cγ
Right
[]
=
{
E
}
=∗
chan_own
cγ
Left
[]
-∗
chan_own
cγ
Right
[]
=
{
E
}
=∗
c1
↣
p
∗
c2
↣
iProto_dual
p
.
c1
↣
p
∗
c2
↣
iProto_dual
p
.
Proof
.
Proof
.
iIntros
"#
Hcctx
Hcol Hcor"
.
iIntros
"#
?
Hcol Hcor"
.
iMod
(
own_alloc
(
●
E
(
Next
(
to_pre_proto
p
))
⋅
iMod
(
own_alloc
(
●
E
(
Next
(
to_pre_proto
p
))
⋅
◯
E
(
Next
(
to_pre_proto
p
))))
as
(
lγ
)
"[Hlsta Hlstf]"
.
◯
E
(
Next
(
to_pre_proto
p
))))
as
(
lγ
)
"[Hlsta Hlstf]"
.
{
by
apply
excl_auth_valid
.
}
{
by
apply
excl_auth_valid
.
}
...
@@ -641,14 +869,14 @@ Section proto.
...
@@ -641,14 +869,14 @@ Section proto.
◯
E
(
Next
(
to_pre_proto
(
iProto_dual
p
)))))
as
(
rγ
)
"[Hrsta Hrstf]"
.
◯
E
(
Next
(
to_pre_proto
(
iProto_dual
p
)))))
as
(
rγ
)
"[Hrsta Hrstf]"
.
{
by
apply
excl_auth_valid
.
}
{
by
apply
excl_auth_valid
.
}
pose
(
ProtName
cγ
lγ
rγ
)
as
pγ
.
pose
(
ProtName
cγ
lγ
rγ
)
as
pγ
.
iMod
(
inv_alloc
protoN
_
(
proto_inv
pγ
)
with
"[-Hlstf Hrstf
Hcctx
]"
)
as
"#
Hinv
"
.
iMod
(
inv_alloc
protoN
_
(
proto_inv
pγ
)
with
"[-Hlstf Hrstf]"
)
as
"#
?
"
.
{
iNext
.
iExists
[],
[],
p
,
(
iProto_dual
p
),
p
,
(
iProto_dual
p
)
.
iFrame
.
{
iNext
.
iExists
[],
[],
p
,
(
iProto_dual
p
)
.
iFrame
.
do
2
(
iSplitL
;
[
iApply
iP
roto_
le_refl
|])
.
auto
.
}
iApply
p
roto_
interp_nil
.
}
iModIntro
.
rewrite
mapsto_proto_eq
.
iSplitL
"Hlstf"
.
iModIntro
.
rewrite
mapsto_proto_eq
.
iSplitL
"Hlstf"
.
-
iExists
Left
,
c1
,
c2
,
pγ
,
p
.
-
iExists
Left
,
c1
,
c2
,
pγ
,
p
.
iFrame
"Hlstf
Hinv Hcctx
"
.
iSplit
;
[
done
|]
.
iApply
iProto_le_refl
.
iFrame
"Hlstf
#
"
.
iSplit
;
[
done
|]
.
iApply
iProto_le_refl
.
-
iExists
Right
,
c1
,
c2
,
pγ
,
(
iProto_dual
p
)
.
-
iExists
Right
,
c1
,
c2
,
pγ
,
(
iProto_dual
p
)
.
iFrame
"Hrstf
Hinv Hcctx
"
.
iSplit
;
[
done
|]
.
iApply
iProto_le_refl
.
iFrame
"Hrstf
#
"
.
iSplit
;
[
done
|]
.
iApply
iProto_le_refl
.
Qed
.
Qed
.
(** ** Accessor style lemmas, used as helpers to prove the specifications of
(** ** Accessor style lemmas, used as helpers to prove the specifications of
...
@@ -663,51 +891,37 @@ Section proto.
...
@@ -663,51 +891,37 @@ Section proto.
▷
(
chan_own
(
proto_c_name
γ
)
s
(
vs
++
[(
pc
x
).
1
.
1
])
=
{
⊤∖↑
protoN
,
⊤
}
=∗
▷
(
chan_own
(
proto_c_name
γ
)
s
(
vs
++
[(
pc
x
).
1
.
1
])
=
{
⊤∖↑
protoN
,
⊤
}
=∗
c
↣
(
pc
x
).
2
)
.
c
↣
(
pc
x
).
2
)
.
Proof
.
Proof
.
rewrite
{
1
}
mapsto_proto_eq
iProto_message_eq
.
iIntros
"Hc HP"
.
rewrite
{
1
}
mapsto_proto_eq
iProto_message_eq
.
iIntros
"Hc Hpc"
.
iDestruct
"Hc"
as
(
s
c1
c2
γ
p
->
)
"(Hle & Hst & #[Hcctx Hinv])"
.
iDestruct
"Hc"
as
(
s
c1
c2
γ
p
->
)
"(Hle & Hst & #[??])"
.
iExists
s
,
c1
,
c2
,
γ
.
iSplit
;
first
done
.
iFrame
"Hcctx"
.
iExists
s
,
c1
,
c2
,
γ
.
do
2
(
iSplit
;
[
done
|])
.
iDestruct
(
iProto_le_send_inv
with
"Hle"
)
as
(
pc'
)
"[Hp H] /="
.
iInv
protoN
as
(
vsl
vsr
pl
pr
)
iRewrite
"Hp"
in
"Hst"
;
clear
p
.
"(>Hcl & >Hcr & Hstla & Hstra & Hinterp)"
"Hclose"
.
iDestruct
(
"H"
with
"[HP]"
)
as
(
p1'
)
"[Hle HP]"
.
{
iExists
_
.
iFrame
"HP"
.
by
iSplit
.
}
iInv
protoN
as
(
vsl
vsr
pl
pr
pl'
pr'
)
"(>Hcl & >Hcr & Hstla & Hstra & Hlel & Hler & Hinv')"
"Hclose"
.
(* TODO: refactor to avoid twice nearly the same proof *)
(* TODO: refactor to avoid twice nearly the same proof *)
iModIntro
.
destruct
s
.
iModIntro
.
destruct
s
.
-
iExists
_
.
iIntros
"{$Hcl} !> Hcl"
.
-
iExists
_
.
iIntros
"{$Hcl} !> Hcl"
.
iDestruct
(
proto_own_auth_agree
with
"Hstla Hst"
)
as
"#Heq"
.
iDestruct
(
proto_own_auth_agree
with
"Hstla Hst"
)
as
"#Hpl"
.
iAssert
(
▷
iProto_le
pl
(
iProto_message_def
Send
pc
))
%
I
with
"[Hle]"
as
"{Hpl} Hlel"
;
first
by
(
iNext
;
iRewrite
"Hpl"
)
.
iDestruct
(
proto_interp_send
((
pc
x
).
1
.
1
)
with
"Hinterp Hlel [Hpc]"
)
as
"Hinterp"
.
{
iNext
.
iExists
x
.
iFrame
;
auto
.
}
iMod
(
proto_own_auth_update
_
_
_
_
(
pc
x
).
2
with
"Hstla Hst"
)
as
"[Hstla Hst]"
.
iMod
(
proto_own_auth_update
_
_
_
_
(
pc
x
).
2
with
"Hstla Hst"
)
as
"[Hstla Hst]"
.
iMod
(
"Hclose"
with
"[-Hst]"
)
as
"_"
.
iMod
(
"Hclose"
with
"[-Hst]"
)
as
"_"
.
{
iNext
.
iRewrite
"Heq"
in
"Hlel"
.
iClear
(
pl'
)
"Heq"
.
{
iNext
.
iExists
_,
_,
_,
_
.
iFrame
.
}
iDestruct
(
iProto_le_send_inv
with
"Hlel"
)
as
(
pc''
)
"[Hpl H] /="
.
iRewrite
"Hpl"
in
"Hinv'"
;
clear
pl
.
iDestruct
(
"H"
with
"HP"
)
as
(
p1''
)
"[Hlel HP]"
.
iExists
_,
_,
_,
_,
_,
_
.
iFrame
"Hcr Hstra Hstla Hcl Hler"
.
iNext
.
iSplitL
"Hle Hlel"
.
{
by
iApply
(
iProto_le_trans
with
"[$]"
)
.
}
iLeft
.
iDestruct
"Hinv'"
as
"[[-> Heval]|[-> Heval]]"
.
{
iSplit
=>
//.
iApply
(
proto_interp_send
with
"Heval HP"
)
.
}
destruct
vsr
as
[|
vr
vsr
];
last
first
.
{
iDestruct
(
proto_interp_False
with
"Heval"
)
as
%
[]
.
}
iSplit
;
first
done
;
simpl
.
iRewrite
(
proto_interp_nil
with
"Heval"
)
.
iApply
(
proto_interp_send
_
[]
with
"[//] HP"
)
.
}
iModIntro
.
rewrite
mapsto_proto_eq
.
iExists
Left
,
c1
,
c2
,
γ
,
(
pc
x
).
2
.
iModIntro
.
rewrite
mapsto_proto_eq
.
iExists
Left
,
c1
,
c2
,
γ
,
(
pc
x
).
2
.
iFrame
"Hcctx Hinv Hst"
.
iSplit
;
[
done
|]
.
iApply
iProto_le_refl
.
iFrame
"Hst #"
.
iSplit
;
[
done
|]
.
iApply
iProto_le_refl
.
-
(* iExists _. iIntros "{$Hcr} !> Hcr".
-
iExists
_
.
iIntros
"{$Hcr} !> Hcr"
.
iDestruct (proto_own_auth_agree with "Hstra Hst") as "#Heq".
iDestruct
(
proto_own_auth_agree
with
"Hstra Hst"
)
as
"#Hpr"
.
iMod (proto_own_auth_update _ _ _ _ p1' with "Hstra Hst") as "[Hstra Hst]".
iAssert
(
▷
iProto_le
pr
(
iProto_message_def
Send
pc
))
%
I
iMod ("Hclose" with "[-Hst Hle]") as "_".
with
"[Hle]"
as
"{Hpr} Hler"
;
first
by
(
iNext
;
iRewrite
"Hpr"
)
.
{ iNext. iExists _, _, _, _. iFrame "Hcl Hstra Hstla Hcr". iRight.
iDestruct
(
proto_interp_flip
with
"Hinterp"
)
as
"Hinterp"
.
iRewrite "Heq" in "Hinv'".
iDestruct
(
proto_interp_send
((
pc
x
).
1
.
1
)
with
"Hinterp Hler [Hpc]"
)
as
"Hinterp"
.
iDestruct "Hinv'" as "[[-> Heval]|[-> Heval]]"; last first.
{
iNext
.
iExists
x
.
iFrame
;
auto
.
}
{ iSplit=> //. by iApply (proto_interp_send with "Heval [HP]"). }
iMod
(
proto_own_auth_update
_
_
_
_
(
pc
x
).
2
with
"Hstra Hst"
)
as
"[Hstra Hst]"
.
destruct l as [|vl l]; last first.
iMod
(
"Hclose"
with
"[-Hst]"
)
as
"_"
.
{ iDestruct (proto_interp_False with "Heval") as %[]. }
{
iNext
.
iExists
_,
_,
_,
_
.
iFrame
.
by
iApply
proto_interp_flip
.
}
iSplit; first done; simpl. iRewrite (proto_interp_nil with "Heval").
iModIntro
.
rewrite
mapsto_proto_eq
.
iExists
Right
,
c1
,
c2
,
γ
,
(
pc
x
).
2
.
iApply (proto_interp_send _ [] with "[//] HP"). }
iFrame
"Hst #"
.
iSplit
;
[
done
|]
.
iApply
iProto_le_refl
.
iModIntro. rewrite mapsto_proto_eq. iExists Right, c1, c2, γ, p1'.
Qed
.
by iFrame "Hcctx Hinv Hst Hle". *)
admit
.
Admitted
.
Lemma
proto_recv_acc
{
TT
}
c
(
pc
:
TT
→
val
*
iProp
Σ
*
iProto
Σ
)
:
Lemma
proto_recv_acc
{
TT
}
c
(
pc
:
TT
→
val
*
iProp
Σ
*
iProto
Σ
)
:
c
↣
iProto_message
Receive
pc
-∗
c
↣
iProto_message
Receive
pc
-∗
...
@@ -719,74 +933,56 @@ Section proto.
...
@@ -719,74 +933,56 @@ Section proto.
c
↣
iProto_message
Receive
pc
)
∧
c
↣
iProto_message
Receive
pc
)
∧
(
∀
v
vs'
,
(
∀
v
vs'
,
⌜
vs
=
v
::
vs'
⌝
-∗
⌜
vs
=
v
::
vs'
⌝
-∗
chan_own
(
proto_c_name
γ
)
s
vs'
=
{
⊤∖↑
protoN
,
⊤
,
⊤
}
▷=∗
▷
∃
x
:
TT
,
chan_own
(
proto_c_name
γ
)
s
vs'
=
{
⊤∖↑
protoN
,
⊤
}
=∗
▷
▷
∃
x
:
TT
,
⌜
v
=
(
pc
x
).
1
.
1
⌝
∗
c
↣
(
pc
x
).
2
∗
(
pc
x
).
1
.
2
))
.
⌜
v
=
(
pc
x
).
1
.
1
⌝
∗
c
↣
(
pc
x
).
2
∗
(
pc
x
).
1
.
2
))
.
Proof
.
Proof
.
rewrite
{
1
}
mapsto_proto_eq
iProto_message_eq
.
rewrite
{
1
}
mapsto_proto_eq
iProto_message_eq
.
iDestruct
1
as
(
s
c1
c2
γ
p
->
)
"(Hle & Hst & #[Hcctx Hinv])"
.
iDestruct
1
as
(
s
c1
c2
γ
p
->
)
"(Hle & Hst & #[??])"
.
iDestruct
(
iProto_le_recv_inv
with
"Hle"
)
as
(
pc'
)
"[Hp Hle] /="
.
iRewrite
"Hp"
in
"Hst"
.
clear
p
.
iExists
(
side_elim
s
Right
Left
),
c1
,
c2
,
γ
.
iSplit
;
first
by
destruct
s
.
iExists
(
side_elim
s
Right
Left
),
c1
,
c2
,
γ
.
iSplit
;
first
by
destruct
s
.
i
Frame
"Hcctx"
.
i
Split
;
[
done
|]
.
iInv
protoN
as
(
vsl
vsr
pl
pr
pl'
pr'
)
iInv
protoN
as
(
vsl
vsr
pl
pr
)
"(>Hcl & >Hcr & Hstla & Hstra & H
lel & Hler & Hinv'
)"
"Hclose"
.
"(>Hcl & >Hcr & Hstla & Hstra & H
interp
)"
"Hclose"
.
iExists
(
side_elim
s
vsr
vsl
)
.
iModIntro
.
iExists
(
side_elim
s
vsr
vsl
)
.
iModIntro
.
(* TODO: refactor to avoid twice nearly the same proof *)
(* TODO: refactor to avoid twice nearly the same proof *)
destruct
s
;
simpl
.
destruct
s
;
simpl
.
-
iIntros
"{$Hcr} !>"
.
-
iIntros
"{$Hcr} !>"
.
iDestruct
(
proto_own_auth_agree
with
"Hstla Hst"
)
as
"#Hpl
'
"
.
iDestruct
(
proto_own_auth_agree
with
"Hstla Hst"
)
as
"#Hpl"
.
iSplit
.
iSplit
.
+
iIntros
"Hcr"
.
+
iIntros
"Hcr"
.
iMod
(
"Hclose"
with
"[-H
st Hle
]"
)
as
"_"
.
iMod
(
"Hclose"
with
"[-H
le Hst
]"
)
as
"_"
.
{
iNext
.
iExists
vsl
,
vsr
,
_,
_,
_,
_
.
iFrame
.
}
{
iNext
.
iExists
vsl
,
vsr
,
_,
_
.
iFrame
.
}
iModIntro
.
rewrite
mapsto_proto_eq
.
iModIntro
.
rewrite
mapsto_proto_eq
.
iExists
Left
,
c1
,
c2
,
γ
,
(
proto_message
Receive
pc'
)
.
iExists
Left
,
c1
,
c2
,
γ
,
p
.
iFrame
;
auto
.
iFrame
"Hcctx Hinv Hst"
.
iSplit
;
first
done
.
rewrite
iProto_le_unfold
.
iRight
;
auto
10
.
+
iIntros
(
v
vs
->
)
"Hcr"
.
+
iIntros
(
v
vs
->
)
"Hcr"
.
iDestruct
"Hinv'"
as
"[[>% _]|[>-> Heval]]"
;
first
done
.
iDestruct
(
proto_interp_flip
with
"Hinterp"
)
as
"Hinterp"
.
iAssert
(
▷
iProto_le
pl
(
proto_message
Receive
pc'
))
%
I
with
"[Hlel]"
as
"Hlel"
.
iDestruct
(
proto_interp_recv
with
"Hinterp [Hle]"
)
as
(
q
)
"[Hpc Hinterp]"
.
{
iNext
.
by
iRewrite
"Hpl'"
in
"Hlel"
.
}
{
iNext
.
by
iRewrite
"Hpl"
.
}
iDestruct
(
iProto_le_recv_inv
with
"Hlel"
)
as
(
pc''
)
"[#Hpl Hlel] /="
.
iMod
(
proto_own_auth_update
_
_
_
_
q
with
"Hstla Hst"
)
as
"[Hstla Hst]"
.
iAssert
(
▷
proto_interp
(
v
::
vs
)
pr
(
proto_message
Receive
pc''
))
%
I
with
"[Heval]"
as
"Heval"
.
{
iNext
.
by
iRewrite
"Hpl"
in
"Heval"
.
}
iDestruct
(
proto_interp_recv
with
"Heval"
)
as
(
q
)
"[Hpc Heval]"
.
iDestruct
(
"Hlel"
with
"Hpc"
)
as
(
p1''
)
"[Hlel Hpc]"
.
iDestruct
(
"Hle"
with
"Hpc"
)
as
(
p1'''
)
"[Hle Hpc]"
.
iMod
(
proto_own_auth_update
_
_
_
_
p1'''
with
"Hstla Hst"
)
as
"[Hstla Hst]"
.
iMod
(
"Hclose"
with
"[-Hst Hpc]"
)
as
%
_
.
iMod
(
"Hclose"
with
"[-Hst Hpc]"
)
as
%
_
.
{
iExists
_,
_,
q
,
_,
_,
_
.
iFrame
"Hcl Hcr Hstra Hstla Hler"
.
{
iNext
.
iExists
_,
_,
q
,
_
.
iFrame
.
by
iApply
proto_interp_flip
.
}
iIntros
"!> !>"
.
iSplitL
"Hle Hlel"
;
last
by
auto
.
iIntros
"!> !> !>"
.
iDestruct
"Hpc"
as
(
x
->
)
"[Hpc #Hq'] /="
.
by
iApply
(
iProto_le_trans
with
"[$]"
)
.
}
iExists
x
.
iSplit
;
[
done
|]
.
iFrame
"Hpc"
.
iRewrite
-
"Hq'"
.
iIntros
"!> !> !>"
.
iDestruct
"Hpc"
as
(
x
)
"(Hv & HP & #Hf) /="
.
rewrite
mapsto_proto_eq
.
iExists
Left
,
c1
,
c2
,
γ
,
q
.
iIntros
"!>"
.
iExists
x
.
iFrame
"Hv HP"
.
iRewrite
-
"Hf"
.
iFrame
"Hst #"
.
iSplit
;
[
done
|]
.
iApply
iProto_le_refl
.
rewrite
mapsto_proto_eq
.
iExists
Left
,
c1
,
c2
,
γ
,
p1'''
.
-
iIntros
"{$Hcl} !>"
.
iFrame
"Hst Hcctx Hinv"
.
iSplit
;
[
done
|]
.
iApply
iProto_le_refl
.
iDestruct
(
proto_own_auth_agree
with
"Hstra Hst"
)
as
"#Hpr"
.
-
(* iIntros "{$Hcl} !>".
iDestruct (proto_own_auth_agree with "Hstra Hst") as "#Heq".
iSplit
.
iSplit
.
+
iIntros
"Hcl"
.
+
iIntros
"Hcl"
.
iMod ("Hclose" with "[-H
st Hle
]") as "_".
iMod
(
"Hclose"
with
"[-H
le Hst
]"
)
as
"_"
.
{ iNext. iExists l, r, _, _. iFrame. }
{
iNext
.
iExists
vs
l
,
vs
r
,
_,
_
.
iFrame
.
}
iModIntro
.
rewrite
mapsto_proto_eq
.
iModIntro
.
rewrite
mapsto_proto_eq
.
iExists Right, c1, c2, γ, (proto_message Receive pc').
iExists
Right
,
c1
,
c2
,
γ
,
p
.
iFrame
;
auto
.
iFrame "Hcctx Hinv Hst". iSplit; first done.
rewrite iProto_le_unfold. iRight; auto 10.
+
iIntros
(
v
vs
->
)
"Hcl"
.
+
iIntros
(
v
vs
->
)
"Hcl"
.
iDestruct "Hinv'" as "[[-> Heval]|[% _]]"; last done.
iDestruct
(
proto_interp_recv
with
"Hinterp [Hle]"
)
as
(
q
)
"[Hpc Hinterp]"
.
iAssert (▷ proto_interp (v :: vs) pl (proto_message Receive pc'))%I
{
iNext
.
by
iRewrite
"Hpr"
.
}
with "[Heval]" as "Heval".
{ iNext. by iRewrite "Heq" in "Heval". }
iDestruct (proto_interp_recv with "Heval") as (q) "[Hpc Heval]".
iMod
(
proto_own_auth_update
_
_
_
_
q
with
"Hstra Hst"
)
as
"[Hstra Hst]"
.
iMod
(
proto_own_auth_update
_
_
_
_
q
with
"Hstra Hst"
)
as
"[Hstra Hst]"
.
iMod ("Hclose" with "[-Hst Hpc
Hle
]") as %_.
iMod
(
"Hclose"
with
"[-Hst Hpc]"
)
as
%
_
.
{ iExists _, _, _,
_. eauto 10 with
iFrame. }
{
iNext
.
iExists
_,
_,
_,
q
.
iFrame
.
}
iIntros "!> !>". i
Mod ("Hle" with
"Hpc"
)
as (
q'
) "[H
le H]
".
iIntros
"!>
!>
!>"
.
i
Destruct
"Hpc"
as
(
x
->
)
"[H
pc #Hq'] /=
"
.
i
Destruct "H" as (x) "(Hv & HP & Hf) /=
".
i
Exists
x
.
iSplit
;
[
done
|]
.
iFrame
"Hpc"
.
iRewrite
-
"Hq'
"
.
iIntros "!> !>". iExists x. iFrame "Hv HP". iRewrite -"Hf"
.
rewrite
mapsto_proto_eq
.
iExists
Right
,
c1
,
c2
,
γ
,
q
.
rewrite mapsto_proto_eq. iExists Right, c1, c2, γ, q. iFrame; auto
.
iFrame
"Hst #"
.
iSplit
;
[
done
|]
.
iApply
iProto_le_refl
.
Qed.
*)
Admitted
.
Qed
.
(** ** Specifications of [send] and [recv] *)
(** ** Specifications of [send] and [recv] *)
Lemma
new_chan_proto_spec
:
Lemma
new_chan_proto_spec
:
...
@@ -850,8 +1046,8 @@ Section proto.
...
@@ -850,8 +1046,8 @@ Section proto.
iIntros
"!> !>"
.
iMod
(
"H"
with
"Hch"
)
as
"Hch"
.
iApply
"HΨ"
;
auto
.
iIntros
"!> !>"
.
iMod
(
"H"
with
"Hch"
)
as
"Hch"
.
iApply
"HΨ"
;
auto
.
-
iMod
"Hvs"
as
(
vs
)
"[Hch [_ H]]"
.
-
iMod
"Hvs"
as
(
vs
)
"[Hch [_ H]]"
.
iIntros
"!>"
.
iExists
vs
.
iIntros
"{$Hch} !>"
(
v
vs'
->
)
"Hch"
.
iIntros
"!>"
.
iExists
vs
.
iIntros
"{$Hch} !>"
(
v
vs'
->
)
"Hch"
.
iMod
(
"H"
with
"[//] Hch"
)
as
"H"
.
iIntros
"!> !>
"
.
iMod
"H
"
.
iMod
(
"H"
with
"[//] Hch"
)
as
"H"
.
iIntros
"!> !>
!> !>
"
.
iIntros
"!> !>"
.
iDestruct
"H"
as
(
x
->
)
"H"
.
iApply
"HΨ"
;
auto
.
iDestruct
"H"
as
(
x
->
)
"H"
.
iApply
"HΨ"
;
auto
.
Qed
.
Qed
.
Lemma
recv_proto_spec_packed
{
TT
}
c
(
pc
:
TT
→
val
*
iProp
Σ
*
iProto
Σ
)
:
Lemma
recv_proto_spec_packed
{
TT
}
c
(
pc
:
TT
→
val
*
iProp
Σ
*
iProto
Σ
)
:
...
@@ -863,8 +1059,8 @@ Section proto.
...
@@ -863,8 +1059,8 @@ Section proto.
iDestruct
(
proto_recv_acc
with
"Hp"
)
as
(
γ
s
c1
c2
->
)
"[#Hc Hvs]"
.
iDestruct
(
proto_recv_acc
with
"Hp"
)
as
(
γ
s
c1
c2
->
)
"[#Hc Hvs]"
.
wp_apply
(
recv_spec
with
"[$]"
)
.
iMod
"Hvs"
as
(
vs
)
"[Hch [_ H]]"
.
wp_apply
(
recv_spec
with
"[$]"
)
.
iMod
"Hvs"
as
(
vs
)
"[Hch [_ H]]"
.
iModIntro
.
iExists
vs
.
iIntros
"{$Hch} !>"
(
v
vs'
->
)
"Hvs'"
.
iModIntro
.
iExists
vs
.
iIntros
"{$Hch} !>"
(
v
vs'
->
)
"Hvs'"
.
iMod
(
"H"
with
"[//] Hvs'"
)
as
"H"
;
iIntros
"!> !>
"
.
iMod
"H
"
.
iMod
(
"H"
with
"[//] Hvs'"
)
as
"H"
;
iIntros
"!> !>
!> !>
"
.
iIntros
"!> !>"
.
iDestruct
"H"
as
(
x
->
)
"H"
.
by
iApply
"HΨ"
.
iDestruct
"H"
as
(
x
->
)
"H"
.
by
iApply
"HΨ"
.
Qed
.
Qed
.
(** A version written without Texan triples that is more convenient to use
(** A version written without Texan triples that is more convenient to use
...
...
This diff is collapsed.
Click to expand it.
theories/channel/proto_model.v
+
2
−
2
View file @
7ca6ecc9
...
@@ -98,7 +98,7 @@ Instance proto_inhabited {V} `{!Cofe PROPn, !Cofe PROP} :
...
@@ -98,7 +98,7 @@ Instance proto_inhabited {V} `{!Cofe PROPn, !Cofe PROP} :
Lemma
proto_message_equivI
{
SPROP
:
sbi
}
{
V
}
`{
!
Cofe
PROPn
,
!
Cofe
PROP
}
a1
a2
pc1
pc2
:
Lemma
proto_message_equivI
{
SPROP
:
sbi
}
{
V
}
`{
!
Cofe
PROPn
,
!
Cofe
PROP
}
a1
a2
pc1
pc2
:
proto_message
(
V
:=
V
)
(
PROPn
:=
PROPn
)
(
PROP
:=
PROP
)
a1
pc1
≡
proto_message
a2
pc2
proto_message
(
V
:=
V
)
(
PROPn
:=
PROPn
)
(
PROP
:=
PROP
)
a1
pc1
≡
proto_message
a2
pc2
⊣⊢@
{
SPROP
}
⌜
a1
=
a2
⌝
∧
(
∀
v
,
pc1
v
≡
pc2
v
)
.
⊣⊢@
{
SPROP
}
⌜
a1
=
a2
⌝
∧
(
∀
v
pc'
,
pc1
v
pc'
≡
pc2
v
pc'
)
.
Proof
.
Proof
.
trans
(
proto_unfold
(
proto_message
a1
pc1
)
≡
proto_unfold
(
proto_message
a2
pc2
)
:
SPROP
)
%
I
.
trans
(
proto_unfold
(
proto_message
a1
pc1
)
≡
proto_unfold
(
proto_message
a2
pc2
)
:
SPROP
)
%
I
.
{
iSplit
.
{
iSplit
.
...
@@ -106,7 +106,7 @@ Proof.
...
@@ -106,7 +106,7 @@ Proof.
-
iIntros
"Heq"
.
rewrite
-
{
2
}(
proto_fold_unfold
(
proto_message
_
_))
.
-
iIntros
"Heq"
.
rewrite
-
{
2
}(
proto_fold_unfold
(
proto_message
_
_))
.
iRewrite
"Heq"
.
by
rewrite
proto_fold_unfold
.
}
iRewrite
"Heq"
.
by
rewrite
proto_fold_unfold
.
}
rewrite
/
proto_message
!
proto_unfold_fold
bi
.
option_equivI
bi
.
prod_equivI
/=.
rewrite
/
proto_message
!
proto_unfold_fold
bi
.
option_equivI
bi
.
prod_equivI
/=.
by
rewrite
bi
.
discrete_fun_equivI
bi
.
discrete_eq
.
rewrite
bi
.
discrete_fun_equivI
bi
.
discrete_eq
.
by
setoid_rewrite
bi
.
ofe_morO_equivI
.
Qed
.
Qed
.
Lemma
proto_message_end_equivI
{
SPROP
:
sbi
}
{
V
}
`{
!
Cofe
PROPn
,
!
Cofe
PROP
}
a
pc
:
Lemma
proto_message_end_equivI
{
SPROP
:
sbi
}
{
V
}
`{
!
Cofe
PROPn
,
!
Cofe
PROP
}
a
pc
:
proto_message
(
V
:=
V
)
(
PROPn
:=
PROPn
)
(
PROP
:=
PROP
)
a
pc
≡
proto_end
⊢@
{
SPROP
}
False
.
proto_message
(
V
:=
V
)
(
PROPn
:=
PROPn
)
(
PROP
:=
PROP
)
a
pc
≡
proto_end
⊢@
{
SPROP
}
False
.
...
...
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