Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
L
lambda-rust
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
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
Simon Spies
lambda-rust
Commits
4376ac7f
Commit
4376ac7f
authored
4 years ago
by
Ralf Jung
Browse files
Options
Downloads
Patches
Plain Diff
add BrandedVec proof by Joshua Yanovski
parent
ac7ba2d6
No related branches found
No related tags found
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
_CoqProject
+1
-0
1 addition, 0 deletions
_CoqProject
theories/lang/notation.v
+2
-0
2 additions, 0 deletions
theories/lang/notation.v
theories/typing/lib/brandedvec.v
+418
-0
418 additions, 0 deletions
theories/typing/lib/brandedvec.v
theories/typing/type.v
+18
-0
18 additions, 0 deletions
theories/typing/type.v
with
439 additions
and
0 deletions
_CoqProject
+
1
−
0
View file @
4376ac7f
...
...
@@ -69,6 +69,7 @@ theories/typing/lib/rc/weak.v
theories/typing/lib/arc.v
theories/typing/lib/swap.v
theories/typing/lib/diverging_static.v
theories/typing/lib/brandedvec.v
theories/typing/lib/mutex/mutex.v
theories/typing/lib/mutex/mutexguard.v
theories/typing/lib/refcell/refcell.v
...
...
This diff is collapsed.
Click to expand it.
theories/lang/notation.v
+
2
−
0
View file @
4376ac7f
...
...
@@ -35,6 +35,8 @@ Notation "e1 - e2" := (BinOp MinusOp e1%E e2%E)
(
at
level
50
,
left
associativity
)
:
expr_scope
.
Notation
"e1 ≤ e2"
:=
(
BinOp
LeOp
e1
%
E
e2
%
E
)
(
at
level
70
)
:
expr_scope
.
Notation
"e1 < e2"
:=
(
e1
+#
1
≤
e2
)
%
E
(
at
level
70
)
:
expr_scope
.
Notation
"e1 = e2"
:=
(
BinOp
EqOp
e1
%
E
e2
%
E
)
(
at
level
70
)
:
expr_scope
.
(* The unicode ← is already part of the notation "_ ← _; _" for bind. *)
...
...
This diff is collapsed.
Click to expand it.
theories/typing/lib/brandedvec.v
0 → 100644
+
418
−
0
View file @
4376ac7f
From
iris
.
algebra
Require
Import
auth
numbers
.
From
iris
.
proofmode
Require
Import
tactics
.
From
lrust
.
lang
Require
Import
proofmode
notation
lib
.
new_delete
.
From
lrust
.
lifetime
Require
Import
meta
.
From
lrust
.
typing
Require
Import
typing
.
From
lrust
.
typing
.
lib
Require
Import
option
.
Set
Default
Proof
Using
"Type"
.
Definition
brandidx_stR
:=
max_natUR
.
Class
brandidxG
Σ
:=
BrandedIdxG
{
brandidx_inG
:>
inG
Σ
(
authR
brandidx_stR
);
brandidx_gsingletonG
:>
lft_metaG
Σ
;
}
.
Definition
brandidxΣ
:
gFunctors
:=
#
[
GFunctor
(
authR
brandidx_stR
);
lft_metaΣ
]
.
Instance
subG_brandidxΣ
{
Σ
}
:
subG
brandidxΣ
Σ
→
brandidxG
Σ
.
Proof
.
solve_inG
.
Qed
.
Definition
brandidxN
:=
lrustN
.
@
"brandix"
.
Definition
brandvecN
:=
lrustN
.
@
"brandvec"
.
Section
brandedvec
.
Context
`{
!
typeG
Σ
,
!
brandidxG
Σ
}
.
Implicit
Types
(
q
:
Qp
)
(
α
:
lft
)
(
γ
:
gname
)
(
n
m
:
nat
)
.
Local
Notation
iProp
:=
(
iProp
Σ
)
.
Definition
brandvec_inv
α
n
:
iProp
:=
(
∃
γ
,
lft_meta
α
γ
∗
own
γ
(
●
MaxNat
n
))
%
I
.
Program
Definition
brandvec
(
α
:
lft
)
:
type
:=
{|
ty_size
:=
int
.(
ty_size
);
ty_own
tid
vl
:=
(
∃
n
,
brandvec_inv
α
n
∗
⌜
vl
=
[
#
n
]
⌝
)
%
I
;
ty_shr
κ
tid
l
:=
(
∃
n
,
&
at
{
κ
,
brandvecN
}(
brandvec_inv
α
n
)
∗
&
frac
{
κ
}(
λ
q
,
l
↦∗
{
q
}
[
#
n
]))
%
I
;
|}
.
Next
Obligation
.
iIntros
"* H"
.
iDestruct
"H"
as
(?)
"[_ %]"
.
by
subst
.
Qed
.
Next
Obligation
.
iIntros
(
ty
E
κ
l
tid
q
?)
"#LFT Hown Hκ"
.
iMod
(
bor_exists
with
"LFT Hown"
)
as
(
vl
)
"Hown"
;
first
solve_ndisj
.
iMod
(
bor_sep
with
"LFT Hown"
)
as
"[Hshr Hown]"
;
first
solve_ndisj
.
iMod
(
bor_exists
with
"LFT Hown"
)
as
(
n
)
"Hown"
;
first
solve_ndisj
.
iMod
(
bor_sep
with
"LFT Hown"
)
as
"[Hghost Hown]"
;
first
solve_ndisj
.
iMod
(
bor_share
_
brandvecN
with
"Hghost"
)
as
"Hghost"
;
first
solve_ndisj
.
iMod
(
bor_persistent
with
"LFT Hown Hκ"
)
as
"[> % $]"
;
first
solve_ndisj
.
subst
.
iExists
n
.
iFrame
.
by
iApply
(
bor_fracture
with
"LFT"
);
first
solve_ndisj
.
Qed
.
Next
Obligation
.
iIntros
(
ty
??
tid
l
)
"#H⊑ H"
.
iDestruct
"H"
as
(
n
)
"[Hghost Hown]"
.
iExists
n
.
iSplitR
"Hown"
.
-
by
iApply
(
at_bor_shorten
with
"H⊑"
)
.
-
by
iApply
(
frac_bor_shorten
with
"H⊑"
)
.
Qed
.
Global
Instance
brandvec_wf
α
:
TyWf
(
brandvec
α
)
:=
{
ty_lfts
:=
[
α
];
ty_wf_E
:=
[]
}
.
Global
Instance
brandvec_ne
:
NonExpansive
brandvec
.
Proof
.
solve_proper
.
Qed
.
Global
Instance
brandvec_mono
E
L
:
Proper
(
lctx_lft_eq
E
L
==>
subtype
E
L
)
brandvec
.
Proof
.
apply
lft_invariant_subtype
.
Qed
.
Global
Instance
brandvec_equiv
E
L
:
Proper
(
lctx_lft_eq
E
L
==>
eqtype
E
L
)
brandvec
.
Proof
.
apply
lft_invariant_eqtype
.
Qed
.
Global
Instance
brandvec_send
α
:
Send
(
brandvec
α
)
.
Proof
.
by
unfold
brandvec
,
Send
.
Qed
.
Global
Instance
brandvec_sync
α
:
Sync
(
brandvec
α
)
.
Proof
.
by
unfold
brandvec
,
Sync
.
Qed
.
(** [γ] is (a lower bound of) the length of the vector; as an in-bounds index,
that must be at least one more than the index value. *)
Definition
brandidx_inv
α
m
:
iProp
:=
(
∃
γ
,
lft_meta
α
γ
∗
own
γ
(
◯
MaxNat
(
m
+
1
)
%
nat
))
%
I
.
Program
Definition
brandidx
α
:=
{|
ty_size
:=
int
.(
ty_size
);
ty_own
tid
vl
:=
(
∃
m
,
brandidx_inv
α
m
∗
⌜
vl
=
[
#
m
]
⌝
)
%
I
;
ty_shr
κ
tid
l
:=
(
∃
m
,
&
frac
{
κ
}(
λ
q
,
l
↦∗
{
q
}
[
#
m
])
∗
brandidx_inv
α
m
)
%
I
;
|}
.
Next
Obligation
.
iIntros
"* H"
.
iDestruct
"H"
as
(?)
"[_ %]"
.
by
subst
.
Qed
.
Next
Obligation
.
iIntros
(
ty
E
κ
l
tid
q
?)
"#LFT Hown Hκ"
.
iMod
(
bor_exists
with
"LFT Hown"
)
as
(
vl
)
"Hown"
;
first
solve_ndisj
.
iMod
(
bor_sep
with
"LFT Hown"
)
as
"[Hown Hghost]"
;
first
solve_ndisj
.
iMod
(
bor_persistent
with
"LFT Hghost Hκ"
)
as
"[>Hghost $]"
;
first
solve_ndisj
.
iDestruct
"Hghost"
as
(
m
)
"[Hghost %]"
.
subst
vl
.
iExists
m
.
iFrame
.
by
iApply
(
bor_fracture
with
"LFT"
);
first
solve_ndisj
.
Qed
.
Next
Obligation
.
iIntros
(
ty
??
tid
l
)
"#H⊑ H"
.
iDestruct
"H"
as
(
m
)
"[H ?]"
.
iExists
m
.
iFrame
.
by
iApply
(
frac_bor_shorten
with
"H⊑"
)
.
Qed
.
Global
Instance
brandidx_wf
α
:
TyWf
(
brandidx
α
)
:=
{
ty_lfts
:=
[
α
];
ty_wf_E
:=
[]
}
.
Global
Instance
brandidx_ne
:
NonExpansive
brandidx
.
Proof
.
solve_proper
.
Qed
.
Global
Instance
brandidx_mono
E
L
:
Proper
(
lctx_lft_eq
E
L
==>
subtype
E
L
)
brandidx
.
Proof
.
apply
lft_invariant_subtype
.
Qed
.
Global
Instance
brandidx_equiv
E
L
:
Proper
(
lctx_lft_eq
E
L
==>
eqtype
E
L
)
brandidx
.
Proof
.
apply
lft_invariant_eqtype
.
Qed
.
Global
Instance
brandidx_send
α
:
Send
(
brandidx
α
)
.
Proof
.
by
unfold
brandidx
,
Send
.
Qed
.
Global
Instance
brandidx_sync
α
:
Sync
(
brandidx
α
)
.
Proof
.
by
unfold
brandidx
,
Sync
.
Qed
.
Global
Instance
brandidx_copy
α
:
Copy
(
brandidx
α
)
.
Proof
.
split
;
first
by
apply
_
.
iIntros
(
κ
tid
E
?
l
q
?
HF
)
"#LFT #Hshr Htok Hlft"
.
iDestruct
(
na_own_acc
with
"Htok"
)
as
"[$ Htok]"
;
first
solve_ndisj
.
iDestruct
"Hshr"
as
(
γ
)
"[Hmem Hinv]"
.
iMod
(
frac_bor_acc
with
"LFT Hmem Hlft"
)
as
(
q'
)
"[>Hmt Hclose]"
;
first
solve_ndisj
.
iDestruct
"Hmt"
as
"[Hmt1 Hmt2]"
.
iModIntro
.
iExists
_
.
iSplitL
"Hmt1"
.
{
iExists
[_]
.
iNext
.
iFrame
.
iExists
_
.
eauto
with
iFrame
.
}
iIntros
"Htok2 Hmt1"
.
iDestruct
"Hmt1"
as
(
vl'
)
"[>Hmt1 #Hown']"
.
iDestruct
(
"Htok"
with
"Htok2"
)
as
"$"
.
iAssert
(
▷
⌜
1
=
length
vl'
⌝
)
%
I
as
">%"
.
{
iNext
.
iDestruct
(
ty_size_eq
with
"Hown'"
)
as
%->
.
done
.
}
destruct
vl'
as
[|
v'
vl'
];
first
done
.
destruct
vl'
as
[|];
last
first
.
{
simpl
in
*.
lia
.
}
rewrite
!
heap_mapsto_vec_singleton
.
iDestruct
(
heap_mapsto_agree
with
"[$Hmt1 $Hmt2]"
)
as
%->
.
iCombine
"Hmt1"
"Hmt2"
as
"Hmt"
.
iApply
"Hclose"
.
done
.
Qed
.
Lemma
brandinv_brandidx_lb
α
m
n
:
brandvec_inv
α
n
-∗
brandidx_inv
α
m
-∗
⌜
m
<
n
⌝%
nat
.
Proof
.
iIntros
"Hn Hm"
.
iDestruct
"Hn"
as
(
γn
)
"(Hidx1 & Hn)"
.
iDestruct
"Hm"
as
(
γm
)
"(Hidx2 & Hm)"
.
iDestruct
(
lft_meta_agree
with
"Hidx1 Hidx2"
)
as
%<-.
iDestruct
(
own_valid_2
with
"Hn Hm"
)
as
%
[?
%
max_nat_included
?]
%
auth_both_valid_discrete
.
iPureIntro
.
simpl
in
*.
lia
.
Qed
.
End
brandedvec
.
Section
typing
.
Context
`{
!
typeG
Σ
,
!
brandidxG
Σ
}
.
Implicit
Types
(
q
:
Qp
)
(
α
:
lft
)
(
γ
:
gname
)
(
n
m
:
nat
)
.
Local
Notation
iProp
:=
(
iProp
Σ
)
.
Definition
brandvec_new
(
call_once
:
val
)
(
R_F
:
type
)
:
val
:=
funrec
:
<>
[
"f"
]
:=
let
:
"call_once"
:=
call_once
in
letalloc
:
"n"
<-
#
0
in
letcall
:
"r"
:=
"call_once"
[
"f"
;
"n"
]
%
E
in
letalloc
:
"r'"
<-
{
R_F
.(
ty_size
)}
!
"r"
in
delete
[
#
R_F
.(
ty_size
);
"r"
];;
return
:
[
"r'"
]
.
Lemma
brandvec_new_type
F
R_F
call_once
`{
!
TyWf
F
,
!
TyWf
R_F
}
:
typed_val
call_once
(
fn
(
∀
α
,
∅
;
F
,
brandvec
α
)
→
R_F
)
→
typed_val
(
brandvec_new
call_once
R_F
)
(
fn
(
∅
;
F
)
→
R_F
)
.
Proof
.
iIntros
(
Hf
E
L
)
.
iApply
type_fn
;
[
solve_typing
..|]
.
iIntros
"/= !#"
.
iIntros
(_
ϝ
ret
args
)
.
inv_vec
args
=>
env
.
simpl_subst
.
iApply
type_let
;
[
apply
Hf
|
solve_typing
|]
.
iIntros
(
f
);
simpl_subst
.
iIntros
(
tid
qmax
)
"#LFT #HE Hna HL Hc (Hf & Henv & _)"
.
wp_let
.
wp_op
.
wp_case
.
wp_alloc
n
as
"Hn"
"Hdead"
.
wp_let
.
rewrite
!
heap_mapsto_vec_singleton
.
wp_write
.
iAssert
(
∀
E
:
coPset
,
⌜↑
lftN
⊆
E
⌝
→
|
=
{
E
}=>
∃
α
,
tctx_elt_interp
tid
((
LitV
n
:
expr
)
◁
box
(
brandvec
α
))
∗
1
.[
α
])
%
I
with
"[Hn Hdead]"
as
"Hn'"
.
{
iIntros
(
E'
Hlft
)
.
iMod
(
own_alloc
(
●
(
MaxNat
0
)))
as
(
γ
)
"Hown"
;
first
by
apply
auth_auth_valid
.
iMod
(
lft_create_meta
γ
with
"LFT"
)
as
(
α
)
"[#Hsing [Htok #Hα]]"
;
first
done
.
iExists
α
.
rewrite
!
tctx_hasty_val
.
rewrite
ownptr_own
.
rewrite
-
heap_mapsto_vec_singleton
.
iFrame
"Htok"
.
iExists
n
,
(
Vector
.
cons
(
LitV
0
)
Vector
.
nil
)
.
iSplitR
;
first
done
.
simpl
.
rewrite
freeable_sz_full
.
iFrame
.
iExists
0
%
nat
.
iSplitL
;
last
done
.
iExists
γ
;
iSplitR
;
by
eauto
.
}
iMod
(
"Hn'"
with
"[%]"
)
as
(
α
)
"[Hn Htok]"
;
[
solve_typing
..|]
.
wp_let
.
iMod
(
lctx_lft_alive_tok
ϝ
with
"HE HL"
)
as
(
qϝf
)
"(Hϝf & HL & Hclosef)"
;
[
solve_typing
..|]
.
iDestruct
(
lft_intersect_acc
with
"Htok Hϝf"
)
as
(?)
"[Hαϝ Hcloseα]"
.
rewrite
!
tctx_hasty_val
.
iApply
(
type_call_iris
_
[
α
;
ϝ
]
α
[_;_]
_
_
_
_
with
"LFT HE Hna [Hαϝ] Hf [Hn Henv]"
);
try
solve_typing
.
+
by
rewrite
/=
right_id
.
+
rewrite
/=
right_id
.
rewrite
!
tctx_hasty_val
.
by
iFrame
.
+
iIntros
(
r
)
"Hna Hf Hown"
.
simpl_subst
.
iDestruct
(
"Hcloseα"
with
"[Hf]"
)
as
"[Htok Hf]"
;
first
by
rewrite
right_id
.
iMod
(
"Hclosef"
with
"Hf HL"
)
as
"HL"
.
wp_let
.
iApply
(
type_type
_
_
_
[
r
◁
box
R_F
]
with
"[] LFT HE Hna HL Hc"
);
try
solve_typing
;
last
by
rewrite
!
tctx_interp_singleton
tctx_hasty_val
.
iApply
type_letalloc_n
;
[
solve_typing
..|]
.
iIntros
(
r'
)
.
simpl_subst
.
iApply
type_delete
;
[
solve_typing
..|]
.
iApply
type_jump
;
solve_typing
.
Qed
.
Definition
brandvec_get_index
:
val
:=
funrec
:
<>
[
"v"
;
"i"
]
:=
let
:
"r"
:=
new
[
#
2
]
in
let
:
"v'"
:=
!
"v"
in
let
:
"i'"
:=
!
"i"
in
delete
[
#
1
;
"v"
];;
delete
[
#
1
;
"i"
];;
let
:
"inbounds"
:=
(
if
:
#
0
≤
"i'"
then
"i'"
<
!
"v'"
else
#
false
)
in
if
:
"inbounds"
then
"r"
<-
{
Σ
some
}
"i'"
;;
return
:
[
"r"
]
else
"r"
<-
{
Σ
none
}
();;
return
:
[
"r"
]
.
Lemma
brandvec_get_index_type
:
typed_val
brandvec_get_index
(
fn
(
∀
'
(
α
,
β
),
∅
;
&
shr
{
β
}
(
brandvec
α
),
int
)
→
option
(
brandidx
α
))
%
T
.
Proof
.
intros
E
L
.
iApply
type_fn
;
[
solve_typing
..|]
.
iIntros
"/= !#"
.
iIntros
([
α
β
]
ϝ
ret
args
)
.
inv_vec
args
=>
v
i
.
simpl_subst
.
iApply
(
type_new
2
);
[
solve_typing
..|];
iIntros
(
r
);
simpl_subst
.
iApply
type_deref
;
[
solve_typing
..|]
.
iIntros
(
v'
);
simpl_subst
.
iApply
type_deref
;
[
solve_typing
..|]
.
iIntros
(
i'
);
simpl_subst
.
iApply
type_delete
;
[
solve_typing
..|]
.
iApply
type_delete
;
[
solve_typing
..|]
.
iIntros
(
tid
qmax
)
"#LFT #HE Hna HL Hk (#Hi' & #Hv' & Hr & _)"
.
rewrite
!
tctx_hasty_val
.
clear
.
destruct
i'
as
[[|
|
i'
]|];
try
done
.
iClear
"Hi'"
.
wp_op
.
rewrite
bool_decide_decide
.
destruct
(
decide
(
0
≤
i'
))
as
[
Hpos
|
Hneg
];
last
first
.
{
wp_case
.
wp_let
.
wp_case
.
iApply
(
type_type
_
_
_
[
r
◁
box
(
uninit
2
)
]
with
"[] LFT HE Hna HL Hk [-]"
);
last
first
.
{
rewrite
tctx_interp_singleton
tctx_hasty_val
.
done
.
}
iApply
(
type_sum_unit
(
option
(
brandidx
_)));
[
solve_typing
..|]
.
iApply
type_jump
;
solve_typing
.
}
destruct
(
Z_of_nat_complete
_
Hpos
)
as
[
i
->
]
.
clear
Hpos
.
wp_case
.
wp_op
.
iDestruct
(
shr_is_ptr
with
"Hv'"
)
as
%
[
l
?]
.
simplify_eq
.
iDestruct
"Hv'"
as
(
m
)
"#[Hghost Hmem]"
.
iMod
(
lctx_lft_alive_tok
β
with
"HE HL"
)
as
(
qβ
)
"(Hβ & HL & Hclose)"
;
[
solve_typing
..|]
.
iMod
(
frac_bor_acc
with
"LFT Hmem Hβ"
)
as
(
qβ'
)
"[>Hn'↦ Hcloseβ]"
;
first
done
.
rewrite
!
heap_mapsto_vec_singleton
.
wp_read
.
iMod
(
"Hcloseβ"
with
"Hn'↦"
)
as
"Hβ"
.
wp_op
.
rewrite
bool_decide_decide
.
destruct
(
decide
(
i
+
1
≤
m
))
as
[
Hle
|
Hoob
];
last
first
.
{
wp_let
.
wp_case
.
iMod
(
"Hclose"
with
"Hβ HL"
)
as
"HL"
.
iApply
(
type_type
_
_
_
[
r
◁
box
(
uninit
2
)
]
with
"[] LFT HE Hna HL Hk [-]"
);
last
first
.
{
rewrite
tctx_interp_singleton
tctx_hasty_val
.
done
.
}
iApply
(
type_sum_unit
(
option
(
brandidx
_)));
[
solve_typing
..|]
.
iApply
type_jump
;
solve_typing
.
}
wp_let
.
wp_case
.
iApply
fupd_wp
.
iMod
(
at_bor_acc_tok
with
"LFT Hghost Hβ"
)
as
"[>Hidx Hcloseg]"
;
[
solve_ndisj
..|]
.
iDestruct
"Hidx"
as
(
γ
)
"(#Hidx & Hown)"
.
iAssert
(|
==>
own
γ
(
●
(
MaxNat
m
))
∗
own
γ
(
◯
(
MaxNat
m
)))
%
I
with
"[Hown]"
as
"> [Hown Hlb]"
.
{
rewrite
-
own_op
.
iApply
(
own_update
with
"Hown"
)
.
apply
auth_update_alloc
.
by
apply
max_nat_local_update
.
}
iMod
(
"Hcloseg"
with
"[Hown]"
)
as
"Hβ"
.
{
iExists
_
.
eauto
with
iFrame
.
}
iMod
(
"Hclose"
with
"Hβ HL"
)
as
"HL"
.
iApply
(
type_type
_
_
_
[
r
◁
box
(
uninit
2
);
#
i
◁
brandidx
_
]
with
"[] LFT HE Hna HL Hk [-]"
);
last
first
.
{
rewrite
tctx_interp_cons
tctx_interp_singleton
tctx_hasty_val
.
iFrame
.
rewrite
tctx_hasty_val'
;
last
done
.
iExists
_
.
iSplit
;
last
done
.
iExists
_
.
iFrame
"Hidx"
.
iApply
base_logic
.
lib
.
own
.
own_mono
;
last
done
.
apply
:
auth_frag_mono
.
apply
max_nat_included
.
simpl
.
lia
.
}
iApply
(
type_sum_assign
(
option
(
brandidx
_)));
[
solve_typing
..|]
.
iApply
type_jump
;
solve_typing
.
Qed
.
Definition
brandidx_get
:
val
:=
funrec
:
<>
[
"s"
;
"c"
]
:=
let
:
"len"
:=
!
"s"
in
let
:
"idx"
:=
!
"c"
in
delete
[
#
1
;
"s"
];;
delete
[
#
1
;
"c"
];;
if
:
!
"idx"
<
!
"len"
then
let
:
"r"
:=
new
[
#
0
]
in
return
:
[
"r"
]
else
!#☠
(* stuck *)
.
Lemma
brandidx_get_type
:
typed_val
brandidx_get
(
fn
(
∀
'
(
α
,
β
),
∅
;
&
shr
{
β
}
(
brandvec
α
),
&
shr
{
β
}
(
brandidx
α
))
→
unit
)
%
T
.
Proof
.
intros
E
L
.
iApply
type_fn
;
[
solve_typing
..|]
.
iIntros
"/= !#"
.
iIntros
([
α
β
]
ϝ
ret
args
)
.
inv_vec
args
=>
s
c
.
simpl_subst
.
iApply
type_deref
;
[
solve_typing
..|]
.
iIntros
(
n
);
simpl_subst
.
iApply
type_deref
;
[
solve_typing
..|]
.
iIntros
(
m
);
simpl_subst
.
iApply
type_delete
;
[
solve_typing
..|]
.
iApply
type_delete
;
[
solve_typing
..|]
.
iIntros
(
tid
qmax
)
"#LFT #HE Hna HL HC (Hm & Hn & _)"
.
rewrite
!
tctx_hasty_val
.
iDestruct
(
shr_is_ptr
with
"Hm"
)
as
%
[
lm
?]
.
simplify_eq
.
iDestruct
(
shr_is_ptr
with
"Hn"
)
as
%
[
ln
?]
.
simplify_eq
.
simpl
in
*.
iDestruct
"Hm"
as
(
m
)
"[Hm Hmidx]"
.
iDestruct
"Hn"
as
(
n
)
"[Hnidx Hn]"
.
iMod
(
lctx_lft_alive_tok
β
with
"HE HL"
)
as
(
qβ
)
"((Hβ1 & Hβ2 & Hβ3) & HL & Hclose)"
;
[
solve_typing
..|]
.
iMod
(
frac_bor_acc
with
"LFT Hn Hβ1"
)
as
(
qβn
)
"[>Hn↦ Hcloseβ1]"
;
first
solve_ndisj
.
iMod
(
frac_bor_acc
with
"LFT Hm Hβ2"
)
as
(
qβm
)
"[>Hm↦ Hcloseβ2]"
;
first
solve_ndisj
.
rewrite
!
heap_mapsto_vec_singleton
.
wp_read
.
wp_op
.
wp_read
.
wp_op
.
wp_case
.
iApply
fupd_wp
.
iMod
(
at_bor_acc_tok
with
"LFT Hnidx Hβ3"
)
as
"[>Hnidx Hcloseβ3]"
;
[
solve_ndisj
..|]
.
iDestruct
(
brandinv_brandidx_lb
with
"Hnidx Hmidx"
)
as
%
Hle
.
iMod
(
"Hcloseβ3"
with
"Hnidx"
)
as
"Hβ3"
.
iMod
(
"Hcloseβ2"
with
"Hm↦"
)
as
"Hβ2"
.
iMod
(
"Hcloseβ1"
with
"Hn↦"
)
as
"Hβ1"
.
iCombine
"Hβ2 Hβ3"
as
"Hβ2"
.
iMod
(
"Hclose"
with
"[$Hβ1 $Hβ2] HL"
)
as
"HL"
.
rewrite
bool_decide_true
;
last
by
lia
.
iApply
(
type_type
_
_
_
[]
with
"[] LFT HE Hna HL HC []"
);
last
by
rewrite
tctx_interp_nil
.
iApply
(
type_new
_);
[
solve_typing
..|];
iIntros
(
r
);
simpl_subst
.
iApply
type_jump
;
solve_typing
.
Qed
.
Definition
brandvec_push
:
val
:=
funrec
:
<>
[
"s"
]
:=
let
:
"n"
:=
!
"s"
in
delete
[
#
1
;
"s"
];;
let
:
"r"
:=
new
[
#
1
]
in
let
:
"oldlen"
:=
!
"n"
in
"n"
<-
"oldlen"
+#
1
;;
"r"
<-
"oldlen"
;;
return
:
[
"r"
]
.
Lemma
brandvec_push_type
:
typed_val
brandvec_push
(
fn
(
∀
'
(
α
,
β
),
∅
;
&
uniq
{
β
}
(
brandvec
α
))
→
brandidx
α
)
.
Proof
.
intros
E
L
.
iApply
type_fn
;
[
solve_typing
..|]
.
iIntros
"/= !#"
.
iIntros
([
α
β
]
ϝ
ret
args
)
.
inv_vec
args
=>
(*n *)
s
.
simpl_subst
.
iApply
type_deref
;
[
solve_typing
..|]
.
iIntros
(
n
);
simpl_subst
.
iApply
type_delete
;
[
solve_typing
..|]
.
iApply
(
type_new
_);
[
solve_typing
..|];
iIntros
(
r
);
simpl_subst
.
iIntros
(
tid
qmax
)
"#LFT #HE Hna HL HC (Hr & Hn & _)"
.
rewrite
!
tctx_hasty_val
.
iDestruct
(
uniq_is_ptr
with
"Hn"
)
as
%
[
ln
H
]
.
simplify_eq
.
iMod
(
lctx_lft_alive_tok
β
with
"HE HL"
)
as
(
qβ
)
"(Hβ & HL & Hclose)"
;
[
solve_typing
..|]
.
iMod
(
bor_acc
with
"LFT Hn Hβ"
)
as
"[H↦ Hclose']"
;
first
solve_ndisj
.
iDestruct
"H↦"
as
(
vl
)
"[> H↦ Hn]"
.
iDestruct
"Hn"
as
(
n
)
"[Hn > %]"
.
simplify_eq
.
rewrite
!
heap_mapsto_vec_singleton
.
wp_read
.
wp_let
.
wp_op
.
wp_write
.
iDestruct
"Hn"
as
(
γ
)
"[#Hidx Hown]"
.
iMod
(
own_update
_
_
(
●
MaxNat
(
n
+
1
)
⋅
_)
with
"Hown"
)
as
"[Hown Hlb]"
.
{
apply
auth_update_alloc
.
apply
max_nat_local_update
.
simpl
.
lia
.
}
iDestruct
"Hlb"
as
"#Hlb"
.
iMod
(
"Hclose'"
with
"[H↦ Hidx Hown]"
)
as
"[Hn Hβ]"
.
{
iExists
(
#
(
n
+
1
)::
nil
)
.
rewrite
heap_mapsto_vec_singleton
.
iFrame
"∗"
.
iIntros
"!>"
.
iExists
(
n
+
1
)
%
nat
.
iSplitL
;
last
by
(
iPureIntro
;
do
3
f_equal
;
lia
)
.
iExists
γ
.
eauto
with
iFrame
.
}
iMod
(
"Hclose"
with
"Hβ HL"
)
as
"HL"
.
iApply
(
type_type
_
_
_
[
r
◁
box
(
uninit
1
);
#
n
◁
brandidx
_]
with
"[] LFT HE Hna HL HC [Hr]"
);
last
first
.
{
rewrite
tctx_interp_cons
tctx_interp_singleton
tctx_hasty_val
.
iFrame
.
rewrite
tctx_hasty_val'
;
last
done
.
iExists
_
.
iSplit
;
last
done
.
iExists
_
.
eauto
with
iFrame
.
}
iApply
type_assign
;
[
solve_typing
..|]
.
iApply
type_jump
;
solve_typing
.
Qed
.
End
typing
.
This diff is collapsed.
Click to expand it.
theories/typing/type.v
+
18
−
0
View file @
4376ac7f
...
...
@@ -615,6 +615,20 @@ Section subtyping.
iDestruct
(
llctx_interp_acc_noend
with
"HL"
)
as
"[$ _]"
.
Qed
.
Lemma
lft_invariant_subtype
E
L
T
:
Proper
(
lctx_lft_eq
E
L
==>
subtype
E
L
)
T
.
Proof
.
iIntros
(
x
y
[
Hxy
Hyx
]
qmax
qL
)
"L"
.
iPoseProof
(
Hxy
with
"L"
)
as
"#Hxy"
.
iPoseProof
(
Hyx
with
"L"
)
as
"#Hyx"
.
iIntros
"!> #E"
.
clear
Hxy
Hyx
.
iDestruct
(
"Hxy"
with
"E"
)
as
%
Hxy
.
iDestruct
(
"Hyx"
with
"E"
)
as
%
Hyx
.
iClear
"Hyx Hxy"
.
rewrite
(
anti_symm
_
_
_
Hxy
Hyx
)
.
iApply
type_incl_refl
.
Qed
.
Lemma
type_equal_incl
ty1
ty2
:
type_equal
ty1
ty2
⊣⊢
type_incl
ty1
ty2
∗
type_incl
ty2
ty1
.
Proof
.
...
...
@@ -644,6 +658,10 @@ Section subtyping.
-
iApply
(
type_incl_trans
_
ty2
);
done
.
Qed
.
Lemma
lft_invariant_eqtype
E
L
T
:
Proper
(
lctx_lft_eq
E
L
==>
eqtype
E
L
)
T
.
Proof
.
split
;
by
apply
lft_invariant_subtype
.
Qed
.
Lemma
equiv_subtype
E
L
ty1
ty2
:
ty1
≡
ty2
→
subtype
E
L
ty1
ty2
.
Proof
.
unfold
subtype
,
type_incl
=>
EQ
.
setoid_rewrite
EQ
.
apply
subtype_refl
.
Qed
.
...
...
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