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
Package Registry
Model registry
Operate
Environments
Terraform modules
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
tlsomers
Actris
Commits
c1ed805c
Commit
c1ed805c
authored
4 years ago
by
Jonas Kastberg
Browse files
Options
Downloads
Patches
Plain Diff
Added typing example for uncheckable mapper
parent
98c1df36
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
_CoqProject
+1
-0
1 addition, 0 deletions
_CoqProject
theories/logrel/examples/mapper_list.v
+496
-0
496 additions, 0 deletions
theories/logrel/examples/mapper_list.v
with
497 additions
and
0 deletions
_CoqProject
+
1
−
0
View file @
c1ed805c
...
...
@@ -44,3 +44,4 @@ theories/logrel/examples/pair.v
theories/logrel/examples/rec_subtyping.v
theories/logrel/examples/choice_subtyping.v
theories/logrel/examples/mapper.v
theories/logrel/examples/mapper_list.v
\ No newline at end of file
This diff is collapsed.
Click to expand it.
theories/logrel/examples/mapper_list.v
0 → 100644
+
496
−
0
View file @
c1ed805c
From
actris
.
channel
Require
Import
proofmode
proto
channel
.
From
actris
.
logrel
Require
Import
session_types
subtyping_rules
term_typing_judgment
term_typing_rules
session_typing_rules
environments
telescopes
napp
.
From
actris
.
utils
Require
Import
llist
.
From
actris
.
logrel
.
lib
Require
Import
par_start
.
From
iris
.
proofmode
Require
Import
tactics
.
Definition
mapper_service_aux
:
expr
:=
λ
:
"f"
"c"
,
(
rec
:
"go"
"f"
"c"
:=
(
branch
[
1
%
Z
;
2
%
Z
])
"c"
(
λ
:
"c"
,
let
:
"v"
:=
recv
"c"
in
send
"c"
(
"f"
"v"
);;
"go"
"f"
"c"
)
(
λ
:
"c"
,
#
()))
"f"
"c"
.
Definition
mapper_service
:
expr
:=
λ
:
"c"
,
let
:
"f"
:=
recv
"c"
in
mapper_service_aux
"f"
"c"
.
Definition
send_all
:
val
:=
rec
:
"go"
"c"
"xs"
:=
if
:
lisnil
"xs"
then
#
()
else
send
"c"
#
1
;;
send
"c"
(
lpop
"xs"
);;
"go"
"c"
"xs"
.
Definition
recv_all
:
val
:=
rec
:
"go"
"c"
"ys"
"n"
:=
if
:
"n"
=
#
0
then
#
()
else
let
:
"x"
:=
recv
"c"
in
"go"
"c"
"ys"
(
"n"
-#
1
);;
lcons
"x"
"ys"
.
Definition
mapper_client
:
expr
:=
(
λ
:
"f"
"xs"
"c"
,
send
"c"
"f"
;;
let
:
"n"
:=
llength
"xs"
in
send_all
"c"
"xs"
;;
recv_all
"c"
"xs"
"n"
;;
send
"c"
#
2
%
Z
;;
"xs"
)
%
E
.
Definition
mapper_prog
:
expr
:=
(
λ
:
"f"
"xs"
,
par_start
(
mapper_service
)
(
mapper_client
"f"
"xs"
))
%
E
.
Section
mapper_example
.
Context
`{
heapG
Σ
,
chanG
Σ
}
.
Definition
mapper_type_rec_service_aux
(
A
:
ltty
Σ
)
(
B
:
ltty
Σ
)
(
rec
:
lsty
Σ
)
:
lsty
Σ
:=
lty_branch
(
<
[
1
%
Z
:=
(
<
??
>
TY
A
;
<!!>
TY
B
;
rec
)
%
lty
]
>
(
<
[
2
%
Z
:=
END
%
lty
]
>∅
))
.
Instance
mapper_type_rec_service_contractive
A
B
:
Contractive
(
mapper_type_rec_service_aux
A
B
)
.
Proof
.
solve_proto_contractive
.
Qed
.
Definition
mapper_type_rec_service
A
B
:
lsty
Σ
:=
lty_rec
(
mapper_type_rec_service_aux
A
B
)
.
Lemma
ltyped_mapper_aux_service
Γ
A
B
:
⊢
Γ
⊨
mapper_service_aux
:
(
A
→
B
)
⊸
lty_chan
(
mapper_type_rec_service
A
B
)
⊸
()
⫤
Γ
.
Proof
.
iApply
(
ltyped_lam
[])
.
iApply
(
ltyped_lam
[
EnvItem
"f"
_])
.
iApply
ltyped_app
;
[
by
iApply
ltyped_var
|
]
.
iApply
ltyped_app
;
[
by
iApply
ltyped_var
|
]
.
iApply
(
ltyped_subsumption
_
_
_
_
_
_
((
A
→
B
)
→
lty_chan
(
mapper_type_rec_service
A
B
)
⊸
())
%
lty
);
[
|
iApply
lty_le_copy_elim
|
iApply
env_le_refl
|
]
.
{
iApply
env_le_cons
.
iApply
lty_le_copy_inv_elim
.
iApply
env_le_refl
.
}
iApply
ltyped_post_nil
.
iApply
(
ltyped_rec
[])
.
iApply
(
ltyped_lam
[
EnvItem
"go"
_;
EnvItem
"f"
_])
.
iApply
ltyped_post_nil
.
iApply
ltyped_app
.
{
iApply
(
ltyped_lam
[])
.
iApply
ltyped_post_nil
.
iApply
ltyped_unit
.
}
iApply
ltyped_app
.
{
simpl
.
rewrite
!
(
Permutation_swap
(
EnvItem
"f"
_))
!
(
Permutation_swap
(
EnvItem
"go"
_))
.
iApply
(
ltyped_lam
[
EnvItem
"go"
_;
EnvItem
"f"
_])
.
iApply
ltyped_post_nil
.
iApply
ltyped_let
;
[
by
iApply
ltyped_recv
|
]
.
iApply
ltyped_seq
.
{
iApply
(
ltyped_send
_
[
EnvItem
"f"
_;
EnvItem
"v"
_;
EnvItem
"c"
_;
EnvItem
"go"
_]);
[
done
|
]
.
iApply
ltyped_app_copy
;
[
by
iApply
ltyped_var
|
]=>
/=.
rewrite
!
(
Permutation_swap
(
EnvItem
"f"
_))
.
by
iApply
ltyped_var
.
}
simpl
.
rewrite
!
(
Permutation_swap
(
EnvItem
"f"
_))
.
iApply
ltyped_subsumption
;
[
|
iApply
lty_le_refl
|
iApply
env_le_refl
|
]
.
{
iApply
env_le_cons
;
[
|
iApply
env_le_refl
]
.
iApply
lty_le_copy_inv_elim_copyable
.
iApply
lty_copyable_arr_copy
.
}
iApply
ltyped_app
;
[
by
iApply
ltyped_var
|
]
.
iApply
ltyped_app
;
[
by
iApply
ltyped_var
|
]
.
simpl
.
rewrite
!
(
Permutation_swap
(
EnvItem
"go"
_))
.
iApply
ltyped_subsumption
;
[
iApply
env_le_refl
|
|
iApply
env_le_refl
|
]
.
{
iApply
lty_le_copy_elim
.
}
by
iApply
ltyped_var
.
}
iApply
ltyped_app
;
[
by
iApply
ltyped_var
|
]
.
iApply
ltyped_subsumption
;
[
iApply
env_le_refl
|
|
iApply
env_le_refl
|
]
.
{
iApply
lty_le_arr
;
[
|
iApply
lty_le_refl
]
.
iApply
lty_le_chan
.
iApply
lty_le_l
;
[
iApply
lty_le_rec_unfold
|
iApply
lty_le_refl
]
.
}
iApply
ltyped_branch
.
intros
x
.
rewrite
-
elem_of_dom
.
set_solver
.
Qed
.
Definition
mapper_type_service
:
lsty
Σ
:=
<
??
A
B
>
TY
A
→
B
;
mapper_type_rec_service
A
B
.
Lemma
ltyped_mapper_service
Γ
:
⊢
Γ
⊨
mapper_service
:
lty_chan
(
mapper_type_service
)
⊸
()
⫤
Γ
.
Proof
.
iApply
(
ltyped_lam
[])
.
iApply
ltyped_post_nil
.
iApply
ltyped_recv_texist
;
[
done
|
apply
_
|
]
.
iIntros
(
Ys
)
.
iApply
ltyped_app
;
[
by
iApply
ltyped_var
|
]
.
iApply
ltyped_app
;
[
by
iApply
ltyped_var
|
]
.
pose
proof
(
ltys_S_inv
Ys
)
as
[
A
[
Ks
HYs
]]
.
pose
proof
(
ltys_S_inv
Ks
)
as
[
B
[
Ks'
HKs
]]
.
pose
proof
(
ltys_O_inv
Ks'
)
as
HKs'
.
rewrite
HYs
HKs
HKs'
/=.
iApply
(
ltyped_subsumption
_
[]);
[
iApply
env_le_nil
|
iApply
lty_le_refl
|
iApply
env_le_refl
|
]
.
iApply
ltyped_mapper_aux_service
.
Qed
.
Definition
mapper_type_rec_client_aux
(
A
:
ltty
Σ
)
(
B
:
ltty
Σ
)
(
rec
:
lsty
Σ
)
:
lsty
Σ
:=
lty_select
(
<
[
1
%
Z
:=
(
<!!>
TY
A
;
<
??
>
TY
B
;
rec
)
%
lty
]
>
(
<
[
2
%
Z
:=
END
%
lty
]
>∅
))
.
Instance
mapper_type_rec_client_contractive
A
B
:
Contractive
(
mapper_type_rec_client_aux
A
B
)
.
Proof
.
solve_proto_contractive
.
Qed
.
Definition
mapper_type_rec_client
A
B
:
lsty
Σ
:=
lty_rec
(
mapper_type_rec_client_aux
A
B
)
.
Global
Instance
mapper_type_rec_client_unfold
A
B
:
ProtoUnfold
(
lsty_car
(
mapper_type_rec_client
A
B
))
(
lsty_car
(
mapper_type_rec_client_aux
A
B
(
mapper_type_rec_client
A
B
)))
.
Proof
.
apply
proto_unfold_eq
,
(
fixpoint_unfold
(
mapper_type_rec_client_aux
A
B
))
.
Qed
.
Definition
mapper_type_client
:
lsty
Σ
:=
<!!
A
B
>
TY
A
→
B
;
mapper_type_rec_client
A
B
.
Definition
lty_list_aux
(
A
:
ltty
Σ
)
(
X
:
ltty
Σ
)
:
ltty
Σ
:=
(()
+
(
A
*
ref_uniq
X
))
%
lty
.
Instance
lty_list_aux_contractive
A
:
Contractive
(
lty_list_aux
A
)
.
Proof
.
solve_proto_contractive
.
Qed
.
Definition
lty_list
(
A
:
ltty
Σ
)
:
ltty
Σ
:=
lty_rec
(
lty_list_aux
A
)
.
Notation
"'list' A"
:=
(
lty_list
A
)
(
at
level
10
)
:
lty_scope
.
Definition
list_pred
(
A
:
ltty
Σ
)
:
val
→
val
→
iProp
Σ
:=
(
λ
v
w
:
val
,
⌜
v
=
w
⌝
∗
ltty_car
A
v
)
%
I
.
Lemma
llength_spec
A
(
l
:
loc
)
:
⊢
{{{
ltty_car
(
ref_uniq
(
list
A
))
#
l
}}}
llength
#
l
{{{
xs
(
n
:
Z
),
RET
#
n
;
⌜
Z
.
of_nat
(
length
xs
)
=
n
⌝
∗
llist
(
λ
v
w
,
⌜
v
=
w
⌝
∗
ltty_car
A
v
)
l
xs
}}}
.
Proof
.
iIntros
"!>"
(
Φ
)
"Hl HΦ"
.
iLöb
as
"IH"
forall
(
l
Φ
)
.
iDestruct
"Hl"
as
(
ltmp
l'
[
=
])
"[Hl Hl']"
;
rewrite
-
H2
.
wp_lam
.
rewrite
{
2
}
/
lty_list
/
lty_rec
/
lty_list_aux
fixpoint_unfold
.
iDestruct
"Hl'"
as
"[Hl' | Hl']"
.
-
iDestruct
"Hl'"
as
(
xs
->
)
"Hl'"
.
wp_load
.
wp_pures
.
iAssert
(
llist
(
list_pred
A
)
l
[])
%
I
with
"[Hl Hl']"
as
"Hl"
.
{
rewrite
/
llist
.
iDestruct
"Hl'"
as
%->
.
iApply
"Hl"
.
}
iApply
"HΦ"
.
eauto
with
iFrame
.
-
iDestruct
"Hl'"
as
(
xs
->
)
"Hl'"
.
wp_load
.
wp_pures
.
iDestruct
"Hl'"
as
(
x
vl'
->
)
"[HA Hl']"
.
iDestruct
"Hl'"
as
(
l'
xs
->
)
"[Hl' Hl'']"
.
wp_apply
(
"IH"
with
"[Hl' Hl'']"
)
.
{
iExists
_,
_
.
iFrame
"Hl' Hl''"
.
done
.
}
iIntros
(
ys
n
)
"[<- H]"
.
iAssert
(
llist
(
list_pred
A
)
l
(
x
::
ys
))
%
I
with
"[Hl HA H]"
as
"Hl"
.
{
iExists
x
,
l'
.
eauto
with
iFrame
.
}
wp_pures
.
iApply
"HΦ"
.
iFrame
"Hl"
.
by
rewrite
(
Nat2Z
.
inj_add
1
)
.
Qed
.
Definition
send_type
(
A
:
ltty
Σ
)
:
lsty
Σ
:=
(
lty_select
(
<
[
1
%
Z
:=
<!!>
TY
A
;
END
]
>∅
))
%
lty
.
Definition
recv_type
(
B
:
ltty
Σ
)
:
lsty
Σ
:=
(
<
??
>
TY
B
;
END
)
%
lty
.
Lemma
mapper_rec_client_unfold_app
A
B
:
⊢
mapper_type_rec_client
A
B
<:
(
send_type
A
<++>
(
recv_type
B
<++>
mapper_type_rec_client
A
B
))
%
lty
.
Proof
.
rewrite
{
1
}
/
mapper_type_rec_client
/
lty_rec
fixpoint_unfold
.
replace
(
fixpoint
(
mapper_type_rec_client_aux
A
B
))
with
(
mapper_type_rec_client
A
B
)
by
eauto
.
rewrite
/
mapper_type_rec_client_aux
.
iApply
lty_le_trans
.
{
iApply
lty_le_select_subseteq
.
apply
insert_mono
,
insert_subseteq
=>
//.
}
rewrite
/
send_type
/
recv_type
.
iPoseProof
(
lty_le_app_select
)
as
"[_ Hle]"
.
iApply
(
lty_le_trans
);
last
by
iApply
"Hle"
.
rewrite
fmap_insert
fmap_empty
.
rewrite
lty_app_send
lty_app_end_l
.
rewrite
lty_app_recv
lty_app_end_l
.
iApply
lty_le_refl
.
Qed
.
Lemma
recv_send_swap
A
B
:
⊢
(
recv_type
B
<++>
send_type
A
<:
send_type
A
<++>
recv_type
B
)
%
lty
.
Proof
.
iApply
lty_le_trans
.
rewrite
lty_app_recv
lty_app_end_l
.
iApply
lty_le_swap_recv_select
.
rewrite
fmap_insert
fmap_empty
.
iPoseProof
(
lty_le_app_select
)
as
"[_ Hle]"
.
iApply
(
lty_le_trans
);
last
by
iApply
"Hle"
.
rewrite
fmap_insert
fmap_empty
.
iApply
lty_le_select
.
iApply
big_sepM2_insert
=>
//.
iSplit
=>
//.
rewrite
lty_app_send
lty_app_end_l
.
iApply
lty_le_swap_recv_send
.
Qed
.
Lemma
mapper_type_rec_client_unfold_app_n
A
B
n
:
⊢
mapper_type_rec_client
A
B
<:
lty_napp
(
send_type
A
)
n
<++>
(
lty_napp
(
recv_type
B
)
n
<++>
mapper_type_rec_client
A
B
)
.
Proof
.
iInduction
n
as
[|
n
]
"IH"
;
simpl
;
[
|
]
.
{
rewrite
/
send_type
/
recv_type
/=.
do
2
rewrite
lty_app_end_l
.
iApply
lty_le_refl
.
}
rewrite
-
lty_napp_flip
-
lty_napp_flip
.
iEval
(
rewrite
-
assoc
)
.
iApply
lty_le_trans
;
last
first
.
{
iApply
lty_le_app
;
[
iApply
lty_le_refl
|
]
.
iEval
(
rewrite
-
assoc
assoc
)
.
iApply
lty_le_app
;
[
|
iApply
lty_le_refl
]
.
iApply
napp_swap
.
iApply
recv_send_swap
.
}
iEval
(
rewrite
-
assoc
)
.
iApply
(
lty_le_trans
with
"IH"
)
.
iApply
lty_le_app
;
[
iApply
lty_le_refl
|
]
.
iApply
lty_le_app
;
[
iApply
lty_le_refl
|
]
.
iApply
mapper_rec_client_unfold_app
.
Qed
.
Lemma
recv_send_swap_n
A
B
n
:
⊢
(
lty_napp
(
recv_type
B
)
n
<++>
mapper_type_rec_client
A
B
)
<:
(
send_type
A
<++>
(
lty_napp
(
recv_type
B
)
(
S
n
)
<++>
mapper_type_rec_client
A
B
))
.
Proof
.
iApply
lty_le_trans
.
{
iApply
lty_le_app
;
[
iApply
lty_le_refl
|
iApply
mapper_rec_client_unfold_app
]
.
}
iEval
(
rewrite
assoc
)
.
iApply
lty_le_trans
.
{
iApply
lty_le_app
;
[
|
iApply
lty_le_refl
]
.
iApply
napp_swap
.
iApply
recv_send_swap
.
}
iEval
(
rewrite
-
assoc
(
assoc
_
(
lty_napp
_
_)))
.
rewrite
-
lty_napp_S_r
.
iApply
lty_le_refl
.
Qed
.
Lemma
send_all_spec_upfront
A
c
l
xs
ty
:
{{{
llist
(
list_pred
A
)
l
xs
∗
c
↣
lsty_car
(
lty_napp
(
send_type
A
)
(
length
xs
)
<++>
ty
)
}}}
send_all
c
#
l
{{{
RET
#
();
llist
(
list_pred
A
)
l
[]
∗
c
↣
lsty_car
ty
}}}
.
Proof
.
iIntros
(
Φ
)
"[Hl Hc] HΦ"
.
iInduction
xs
as
[|
x
xs
]
"IH"
.
{
wp_lam
.
wp_apply
(
lisnil_spec
with
"Hl"
);
iIntros
"Hl"
;
wp_pures
.
iApply
"HΦ"
.
iFrame
.
}
wp_lam
.
wp_apply
(
lisnil_spec
with
"Hl"
);
iIntros
"Hl"
.
wp_send
with
"[]"
;
first
by
eauto
.
rewrite
lookup_total_insert
.
wp_apply
(
lpop_spec
with
"Hl"
);
iIntros
(
v
)
"[HIx Hl]"
.
wp_send
with
"[HIx]"
.
{
iDestruct
"HIx"
as
(
->
)
"$HIx"
.
}
wp_apply
(
"IH"
with
"Hl Hc"
)
.
done
.
Qed
.
Lemma
send_all_spec_aux
A
B
c
l
xs
n
:
{{{
llist
(
list_pred
A
)
l
xs
∗
c
↣
lsty_car
(
lty_napp
(
recv_type
B
)
n
<++>
(
mapper_type_rec_client
A
B
))
}}}
send_all
c
#
l
{{{
RET
#
();
llist
(
list_pred
A
)
l
[]
∗
c
↣
lsty_car
(
lty_napp
(
recv_type
B
)
(
length
xs
+
n
)
<++>
(
mapper_type_rec_client
A
B
))
}}}
.
Proof
.
iIntros
(
Φ
)
"[Hl Hc] HΦ"
.
iInduction
xs
as
[|
x
xs
]
"IH"
forall
(
n
)
.
{
wp_lam
.
wp_apply
(
lisnil_spec
with
"Hl"
);
iIntros
"Hl"
;
wp_pures
.
iApply
"HΦ"
.
iFrame
.
}
wp_lam
.
wp_apply
(
lisnil_spec
with
"Hl"
);
iIntros
"Hl"
.
simpl
.
iDestruct
(
iProto_mapsto_le
c
with
"Hc []"
)
as
"Hc"
.
{
iApply
recv_send_swap_n
.
}
wp_send
with
"[]"
;
first
by
eauto
.
rewrite
lookup_total_insert
.
wp_apply
(
lpop_spec
with
"Hl"
);
iIntros
(
v
)
"[HIx Hl]"
.
wp_send
with
"[HIx]"
.
{
iDestruct
"HIx"
as
(
->
)
"$HIx"
.
}
wp_apply
(
"IH"
$!
(
S
n
)
with
"Hl Hc"
)
.
by
rewrite
Nat
.
add_succ_r
.
Qed
.
Lemma
send_all_spec_ad_hoc
A
B
c
l
xs
:
{{{
llist
(
list_pred
A
)
l
xs
∗
c
↣
lsty_car
(
mapper_type_rec_client
A
B
)
}}}
send_all
c
#
l
{{{
RET
#
();
llist
(
list_pred
A
)
l
[]
∗
c
↣
lsty_car
(
lty_napp
(
recv_type
B
)
(
length
xs
)
<++>
(
mapper_type_rec_client
A
B
))
}}}
.
Proof
.
iIntros
(
Φ
)
"[Hl Hc] HΦ"
.
iApply
(
send_all_spec_aux
_
_
_
_
_
0
with
"[$Hl Hc]"
)
.
{
simpl
.
by
rewrite
lty_app_end_l
.
}
iIntros
"!> [Hl Hc]"
.
iApply
"HΦ"
.
rewrite
-
(
plus_n_O
(
length
xs
))
.
iFrame
.
Qed
.
Lemma
recv_all_spec
B
c
ty
l
n
:
{{{
llist
(
list_pred
B
)
l
[]
∗
c
↣
lsty_car
(
lty_napp
(
recv_type
B
)
n
<++>
ty
)
}}}
recv_all
c
#
l
#
n
{{{
ys
,
RET
#
();
⌜
n
=
length
ys
⌝
∗
llist
(
list_pred
B
)
l
ys
∗
c
↣
lsty_car
ty
}}}
.
Proof
.
iIntros
(
Φ
)
"[Hl Hc] HΦ"
.
iLöb
as
"IH"
forall
(
n
Φ
)
.
destruct
n
.
{
wp_lam
.
wp_pures
.
iApply
"HΦ"
.
by
iFrame
.
}
wp_lam
.
wp_recv
(
w
)
as
"Hw"
.
wp_pures
.
rewrite
Nat2Z
.
inj_succ
.
replace
(
Z
.
succ
(
Z
.
of_nat
(
n
))
-
1
)
%
Z
with
(
Z
.
of_nat
(
n
))
by
lia
.
wp_apply
(
"IH"
with
"Hl Hc"
)
.
iIntros
(
ys
)
"(% & Hl & Hc)"
.
wp_apply
(
lcons_spec
with
"[$Hl $Hw//]"
)
.
iIntros
"Hl"
.
iApply
"HΦ"
.
iFrame
.
iPureIntro
.
by
rewrite
H1
.
Qed
.
Lemma
ltyped_mapper_client_ad_hoc
Γ
(
A
B
:
ltty
Σ
)
:
⊢
Γ
⊨
mapper_client
:
(
A
→
B
)
⊸
ref_uniq
(
lty_list
A
)
⊸
chan
mapper_type_client
⊸
ref_uniq
(
lty_list
B
)
.
Proof
.
iApply
(
ltyped_lam
[])
.
iApply
(
ltyped_lam
[
EnvItem
"f"
_])
.
iApply
(
ltyped_lam
[
EnvItem
"xs"
_;
EnvItem
"f"
_])
.
iIntros
(
vs
)
"!> HΓ /="
.
rewrite
(
lookup_delete_ne
_
"n"
"c"
)=>
//.
rewrite
(
lookup_delete_ne
_
"n"
"xs"
)=>
//.
rewrite
lookup_delete
=>
//.
iDestruct
(
env_ltyped_cons
_
_
"c"
with
"HΓ"
)
as
(
vc
->
)
"[Hc HΓ]"
.
iDestruct
(
env_ltyped_cons
_
_
"xs"
with
"HΓ"
)
as
(
vl
->
)
"[Hl HΓ]"
.
iDestruct
(
env_ltyped_cons
_
_
"f"
with
"HΓ"
)
as
(
vf
->
)
"[Hf HΓ]"
.
wp_send
with
"[Hf//]"
.
iDestruct
"Hl"
as
(
l'
v
->
)
"[Hl Hv]"
.
wp_apply
(
llength_spec
with
"[Hl Hv]"
)
.
{
iExists
l'
,
v
.
eauto
with
iFrame
.
}
iIntros
(
xs
n
)
"[<- Hl]"
.
wp_pures
.
wp_apply
(
send_all_spec_ad_hoc
with
"[$Hl $Hc]"
)
.
iIntros
"[Hl Hc]"
.
wp_apply
(
recv_all_spec
with
"[Hl $Hc //]"
)
.
iIntros
(
ys
)
.
iDestruct
1
as
(
Hlen
)
"[Hl Hc]"
.
rewrite
/
mapper_type_rec_client
/
lty_rec
fixpoint_unfold
.
wp_send
with
"[]"
;
first
by
eauto
.
wp_pures
.
iFrame
.
rewrite
/
lty_list
.
iRevert
(
Hlen
)
.
iInduction
ys
as
[|
y
ys
]
"IH"
forall
(
l'
xs
);
iIntros
(
Hlen
)
.
-
iExists
l'
,
NONEV
.
rewrite
/
llist
.
iFrame
"Hl"
.
iSplit
=>
//.
rewrite
/
lty_rec
.
rewrite
(
fixpoint_unfold
(
lty_list_aux
B
))
.
iLeft
.
eauto
.
-
iDestruct
"Hl"
as
(
vb
l''
)
"[[-> HB] [Hl' Hrec]]"
.
iExists
l'
,
_
.
iFrame
"Hl'"
.
iSplit
=>
//.
rewrite
/
lty_rec
.
rewrite
{
2
}(
fixpoint_unfold
(
lty_list_aux
B
))
.
iRight
.
iExists
_
.
iSplit
=>
//.
iExists
_,
_
.
iSplit
=>
//.
iFrame
"HB"
.
by
iApply
(
"IH"
with
"Hrec Hc"
)
.
Qed
.
Lemma
ltyped_mapper_client_upfront
Γ
(
A
B
:
ltty
Σ
)
:
⊢
Γ
⊨
mapper_client
:
(
A
→
B
)
⊸
ref_uniq
(
lty_list
A
)
⊸
chan
mapper_type_client
⊸
ref_uniq
(
lty_list
B
)
.
Proof
.
iApply
(
ltyped_lam
[])
.
iApply
(
ltyped_lam
[
EnvItem
"f"
_])
.
iApply
(
ltyped_lam
[
EnvItem
"xs"
_;
EnvItem
"f"
_])
.
iIntros
(
vs
)
"!> HΓ /="
.
rewrite
(
lookup_delete_ne
_
"n"
"c"
)=>
//.
rewrite
(
lookup_delete_ne
_
"n"
"xs"
)=>
//.
rewrite
(
lookup_delete
)=>
//.
iDestruct
(
env_ltyped_cons
_
_
"c"
with
"HΓ"
)
as
(
vc
->
)
"[Hc HΓ]"
.
iDestruct
(
env_ltyped_cons
_
_
"xs"
with
"HΓ"
)
as
(
vl
->
)
"[Hl HΓ]"
.
iDestruct
(
env_ltyped_cons
_
_
"f"
with
"HΓ"
)
as
(
vf
->
)
"[Hf HΓ]"
.
wp_send
with
"[Hf//]"
.
iDestruct
"Hl"
as
(
l'
v
->
)
"[Hl Hv]"
.
wp_apply
(
llength_spec
with
"[Hl Hv]"
)
.
{
iExists
l'
,
v
.
eauto
with
iFrame
.
}
iIntros
(
xs
n
)
"[<- Hl]"
.
wp_pures
.
iDestruct
(
iProto_mapsto_le
vc
with
"Hc []"
)
as
"Hc"
.
{
iApply
(
mapper_type_rec_client_unfold_app_n
A
B
(
length
xs
))
.
}
wp_apply
(
send_all_spec_upfront
with
"[$Hl $Hc]"
)
.
iIntros
"[Hl Hc]"
.
wp_apply
(
recv_all_spec
with
"[Hl $Hc //]"
)
.
iIntros
(
ys
)
.
iDestruct
1
as
(
Hlen
)
"[Hl Hc]"
.
rewrite
/
mapper_type_rec_client
/
lty_rec
fixpoint_unfold
.
wp_send
with
"[]"
;
first
by
eauto
.
wp_pures
.
iFrame
.
rewrite
/
lty_list
.
iRevert
(
Hlen
)
.
iInduction
ys
as
[|
y
ys
]
"IH"
forall
(
l'
xs
);
iIntros
(
Hlen
)
.
-
iExists
l'
,
NONEV
.
rewrite
/
llist
.
iFrame
"Hl"
.
iSplit
=>
//.
rewrite
/
lty_rec
.
rewrite
(
fixpoint_unfold
(
lty_list_aux
B
))
.
iLeft
.
eauto
.
-
iDestruct
"Hl"
as
(
vb
l''
)
"[[-> HB] [Hl' Hrec]]"
.
iExists
l'
,
_
.
iFrame
"Hl'"
.
iSplit
=>
//.
rewrite
/
lty_rec
{
2
}(
fixpoint_unfold
(
lty_list_aux
B
))
.
iRight
.
iExists
_
.
iSplit
=>
//.
iExists
_,
_
.
iSplit
=>
//.
iFrame
"HB"
.
by
iApply
(
"IH"
with
"Hrec Hc"
)
.
Qed
.
Lemma
lty_le_mapper_type_client_dual
:
⊢
lty_dual
mapper_type_service
<:
mapper_type_client
.
Proof
.
rewrite
/
mapper_type_client
/
mapper_type_service
.
iApply
lty_le_l
;
[
iApply
lty_le_dual_recv_exist
|
]=>
/=.
iIntros
(
A
B
)
.
iExists
A
,
B
.
iModIntro
.
iLöb
as
"IH"
.
iApply
lty_le_r
;
[
|
iApply
lty_bi_le_sym
;
iApply
lty_le_rec_unfold
]
.
iApply
lty_le_dual_l
.
iApply
lty_le_r
;
[
|
iApply
lty_bi_le_sym
;
iApply
lty_le_rec_unfold
]
.
iApply
lty_le_l
;
[
iApply
lty_le_dual_select
|
]
.
iApply
lty_le_branch
.
rewrite
fmap_insert
fmap_insert
fmap_empty
.
iApply
big_sepM2_insert
=>
//.
iSplit
.
-
iApply
lty_le_l
;
[
iApply
lty_le_dual_send
|
]
.
iApply
lty_le_recv
;
[
iApply
lty_le_refl
|
]
.
iApply
lty_le_l
;
[
iApply
lty_le_dual_recv
|
]
.
iApply
lty_le_send
;
[
iApply
lty_le_refl
|
]
.
iIntros
"!>!>!>"
.
iApply
lty_le_dual_l
.
iApply
"IH"
.
-
iApply
big_sepM2_insert
=>
//.
iSplit
=>
//.
iApply
lty_le_l
;
[
iApply
lty_le_dual_end
|
iApply
lty_le_refl
]
.
Qed
.
Section
with_spawn
.
Context
`{
!
spawnG
Σ
}
.
Lemma
ltyped_mapper_prog
A
B
e1
e2
Γ
Γ'
Γ''
:
(
Γ
⊨
e2
:
ref_uniq
(
lty_list
A
)
⫤
Γ'
)
-∗
(
Γ'
⊨
e1
:
(
A
→
B
)
⫤
Γ''
)
-∗
Γ
⊨
par_start
(
mapper_service
)
(
mapper_client
e1
e2
)
:
(()
*
(
ref_uniq
(
lty_list
B
)))
⫤
Γ''
.
Proof
.
iIntros
"He2 He1"
.
iApply
(
ltyped_app
with
"[He2 He1]"
)
.
{
iApply
(
ltyped_app
with
"He2"
)
.
iApply
(
ltyped_app
with
"He1"
)
.
iApply
ltyped_mapper_client_ad_hoc
.
}
iApply
ltyped_app
.
{
iApply
ltyped_mapper_service
.
}
iApply
ltyped_subsumption
;
[
iApply
env_le_refl
|
|
iApply
env_le_refl
|
]
.
{
iApply
lty_le_arr
;
[
iApply
lty_le_refl
|
]
.
iApply
lty_le_arr
;
[
|
iApply
lty_le_refl
]
.
iApply
lty_le_arr
;
[
|
iApply
lty_le_refl
]
.
iApply
lty_le_chan
.
iApply
lty_le_mapper_type_client_dual
.
}
iApply
ltyped_par_start
.
Qed
.
End
with_spawn
.
End
mapper_example
.
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