Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
E
examples
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Simon Friis Vindum
examples
Commits
07bd8590
Commit
07bd8590
authored
Mar 26, 2020
by
Simon Friis Vindum
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Finish dequeue non-empty case when CAS succeeds
parent
ab73c379
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
82 additions
and
22 deletions
+82
-22
theories/logrel/F_mu_ref_conc/examples/queue/MS_queue.v
theories/logrel/F_mu_ref_conc/examples/queue/MS_queue.v
+2
-2
theories/logrel/F_mu_ref_conc/examples/queue/refinement.v
theories/logrel/F_mu_ref_conc/examples/queue/refinement.v
+80
-20
No files found.
theories/logrel/F_mu_ref_conc/examples/queue/MS_queue.v
View file @
07bd8590
...
@@ -34,14 +34,14 @@ Definition MS_dequeue :=
...
@@ -34,14 +34,14 @@ Definition MS_dequeue :=
(
LetIn
(
LetIn
(* c = *)
(
getValue
(
Unfold
(
Load
((
Var
0
(* n *)
)))))
(* c = *)
(
getValue
(
Unfold
(
Load
((
Var
0
(* n *)
)))))
(
Case
(
Case
(
Unfold
(
Load
(
Load
(
Snd
(
Var
0
(*
n
*)
)))))
(* Get next node after sentinel *)
(
Unfold
(
Load
(
Load
(
Snd
(
Var
0
(*
c
*)
)))))
(* Get next node after sentinel *)
(* Snd n = InjL Unit => *)
(* Snd n = InjL Unit => *)
none
(* The queue is empty, return none *)
none
(* The queue is empty, return none *)
(* Snd n = InjR n' => *)
(* Snd n = InjR n' => *)
(
If
(
If
(
CAS
(
Var
5
(* head *)
)
(
Var
2
(* n *)
)
(
Load
(
Snd
(
Var
1
(* n' *)
))))
(
CAS
(
Var
5
(* head *)
)
(
Var
2
(* n *)
)
(
Load
(
Snd
(
Var
1
(* n' *)
))))
(* (CAS (Var 5 (* head *)) (Var 2 (* n *)) (Var 0 (* n' *))) *)
(* (CAS (Var 5 (* head *)) (Var 2 (* n *)) (Var 0 (* n' *))) *)
(
some
(
getValue
(
Fst
(
Var
1
(* n
*)
))))
(
some
(
getValue
(
Fst
(
Var
0
(* n'
*)
))))
(
App
(
Var
3
(* try *)
)
Unit
)
(
App
(
Var
3
(* try *)
)
Unit
)
)
)
)
)
...
...
theories/logrel/F_mu_ref_conc/examples/queue/refinement.v
View file @
07bd8590
...
@@ -23,7 +23,7 @@ Section Queue_refinement.
...
@@ -23,7 +23,7 @@ Section Queue_refinement.
⌜
n
=
LocV
ℓ⌝
∗
ℓ
↦ᵢ
{
q
}
(
FoldV
v
)
⌜
n
=
LocV
ℓ⌝
∗
ℓ
↦ᵢ
{
q
}
(
FoldV
v
)
∗
(
⌜
v
=
noneV
⌝
∗
(
⌜
v
=
noneV
⌝
∨
(
∃
(
n'
:
valO
)
ℓ
tail
,
∨
(
∃
(
n'
:
valO
)
ℓ
tail
,
⌜
v
=
someV
(
PairV
v
(
LocV
ℓ
tail
))
⌝
∗
ℓ
tail
↦ᵢ
n'
∗
▷
(
P
n'
))
⌜
v
=
someV
(
PairV
(
InjRV
v
)
(
LocV
ℓ
tail
))
⌝
∗
ℓ
tail
↦ᵢ
n'
∗
▷
(
P
n'
))
))%
I
.
))%
I
.
Solve
Obligations
with
solve_proper
.
Solve
Obligations
with
solve_proper
.
...
@@ -33,12 +33,15 @@ Section Queue_refinement.
...
@@ -33,12 +33,15 @@ Section Queue_refinement.
Definition
nodeInv
:
valO
-
n
>
iPropO
Σ
:
=
fixpoint
(
nodeInv_pre
).
Definition
nodeInv
:
valO
-
n
>
iPropO
Σ
:
=
fixpoint
(
nodeInv_pre
).
Definition
isStackList
(
ℓ
:
loc
)
(
xs
:
list
val
)
:
iProp
Σ
:
=
Fixpoint
isCGQueue_go
(
xs
:
list
val
)
:
val
:
=
match
xs
with
match
xs
with
|
nil
=>
ℓ
↦ₛ
FoldV
noneV
|
nil
=>
FoldV
noneV
|
x
::
xs'
=>
True
(* FIXME *
)
|
x
::
xs'
=>
FoldV
(
InjRV
(
PairV
x
(
isCGQueue_go
xs'
))
)
end
.
end
.
Definition
isCGQueue
(
ℓ
:
loc
)
(
xs
:
list
val
)
:
iProp
Σ
:
=
ℓ
↦ₛ
(
isCGQueue_go
xs
).
(* Represents the information that the location ℓ points to a series of nodes
(* Represents the information that the location ℓ points to a series of nodes
correscponding to the list `xs`.
correscponding to the list `xs`.
*)
*)
...
@@ -47,21 +50,22 @@ Section Queue_refinement.
...
@@ -47,21 +50,22 @@ Section Queue_refinement.
|
nil
=>
ℓ
↦ᵢ
FoldV
noneV
|
nil
=>
ℓ
↦ᵢ
FoldV
noneV
|
x
::
xs'
=>
|
x
::
xs'
=>
(
∃
ℓ
tail
ℓ
next
,
(
∃
ℓ
tail
ℓ
next
,
ℓ
↦ᵢ
{
q
}
FoldV
(
someV
(
PairV
x
(
LocV
ℓ
tail
)))
ℓ
↦ᵢ
{
q
}
FoldV
(
someV
(
PairV
(
InjRV
x
)
(
LocV
ℓ
tail
)))
∗
ℓ
tail
↦ᵢ
{
q
}
(
LocV
ℓ
next
)
∗
ℓ
tail
↦ᵢ
{
q
}
(
LocV
ℓ
next
)
∗
isNodeList
q
ℓ
next
xs'
)
∗
isNodeList
q
ℓ
next
xs'
)
end
.
end
.
(* Represents that the location ℓ points to a series of nodes corresponding to
(* Represents that the location ℓ points to a series of nodes corresponding to
the list `xs` _and potentially more nodes_. The difference between this and
the list `xs` _and potentially more nodes_. The difference between this and
isStackList is that this predicates does not say exactly what the end, i.e.
isNodeList is that this predicates does not say exactly what the end is,
the final node, is because this may change. *)
i.e. the final node, is because this may change. Loosely speaking this
represent the persistent information in isNodeList. *)
Fixpoint
firstXsValues
q
(
ℓ
:
loc
)
(
xs
:
list
val
)
:
iProp
Σ
:
=
Fixpoint
firstXsValues
q
(
ℓ
:
loc
)
(
xs
:
list
val
)
:
iProp
Σ
:
=
match
xs
with
match
xs
with
|
nil
=>
True
(* Here we should be able to say that ℓ is either another node or the end. *)
|
nil
=>
True
(* Here we should be able to say that ℓ is either another node or the end. *)
|
x
::
xs'
=>
|
x
::
xs'
=>
(
∃
ℓ
tail
ℓ
next
,
(
∃
ℓ
tail
ℓ
next
,
ℓ
↦ᵢ
{
q
}
FoldV
(
someV
(
PairV
x
(
LocV
ℓ
tail
)))
ℓ
↦ᵢ
{
q
}
FoldV
(
someV
(
PairV
(
InjRV
x
)
(
LocV
ℓ
tail
)))
∗
ℓ
tail
↦ᵢ
{
q
}
(
LocV
ℓ
next
)
∗
ℓ
tail
↦ᵢ
{
q
}
(
LocV
ℓ
next
)
∗
firstXsValues
q
ℓ
next
xs'
)
∗
firstXsValues
q
ℓ
next
xs'
)
end
.
end
.
...
@@ -85,7 +89,7 @@ Section Queue_refinement.
...
@@ -85,7 +89,7 @@ Section Queue_refinement.
∗
ℓ
hdPt
↦ᵢ
{
q
}
(
LocV
ℓ
hd
)
∗
ℓ
hdPt
↦ᵢ
{
q
}
(
LocV
ℓ
hd
)
∗
isNodeList
p
ℓ
hd
xs
ᵢ
)%
I
.
∗
isNodeList
p
ℓ
hd
xs
ᵢ
)%
I
.
(* Definition is
StackList
(τi : D) (ℓ : loc) (xs : list val) (xs' : list val) : iProp Σ := *)
(* Definition is
CGQueue
(τi : D) (ℓ : loc) (xs : list val) (xs' : list val) : iProp Σ := *)
(* (⌜True⌝)%I. *)
(* (⌜True⌝)%I. *)
Fixpoint
xsLink
(
τ
i
:
D
)
(
xs
ᵢ
xs
ₛ
:
list
val
)
:
iProp
Σ
:
=
Fixpoint
xsLink
(
τ
i
:
D
)
(
xs
ᵢ
xs
ₛ
:
list
val
)
:
iProp
Σ
:
=
...
@@ -98,12 +102,45 @@ Section Queue_refinement.
...
@@ -98,12 +102,45 @@ Section Queue_refinement.
Definition
invariant
τ
i
hd
sHd
ℓ
lock
:
iProp
Σ
:
=
Definition
invariant
τ
i
hd
sHd
ℓ
lock
:
iProp
Σ
:
=
(
∃
ℓ
hd
ℓ
'
xs
ᵢ
xs
ₛ
,
(
∃
ℓ
hd
ℓ
'
xs
ᵢ
xs
ₛ
,
⌜
hd
=
Loc
ℓ
hd
⌝
∗
isMSQueue
τ
i
ℓ
hd
xs
ᵢ
⌜
hd
=
Loc
ℓ
hd
⌝
∗
isMSQueue
τ
i
ℓ
hd
xs
ᵢ
∗
⌜
sHd
=
Loc
ℓ
'
⌝
∗
is
StackList
ℓ
'
xs
ₛ
∗
⌜
sHd
=
Loc
ℓ
'
⌝
∗
is
CGQueue
ℓ
'
xs
ₛ
∗
ℓ
lock
↦ₛ
(#
♭
v
false
)
∗
ℓ
lock
↦ₛ
(#
♭
v
false
)
∗
xsLink
τ
i
xs
ᵢ
xs
ₛ
∗
xsLink
τ
i
xs
ᵢ
xs
ₛ
∗
⌜
length
xs
ᵢ
=
length
xs
ₛ⌝
∗
⌜
length
xs
ᵢ
=
length
xs
ₛ⌝
)%
I
.
)%
I
.
Lemma
steps_CG_dequeue_cons
E
j
K
x
xs
ℓ
ℓ
lock
:
nclose
specN
⊆
E
→
spec_ctx
∗
j
⤇
fill
K
(
App
(
CG_dequeue
(
Loc
ℓ
)
(
Loc
ℓ
lock
))
Unit
)
∗
isCGQueue
ℓ
(
x
::
xs
)
∗
ℓ
lock
↦ₛ
(#
♭
v
false
)
⊢
|={
E
}=>
j
⤇
fill
K
(
InjR
(
of_val
x
))
∗
isCGQueue
ℓ
(
xs
)
∗
ℓ
lock
↦ₛ
(#
♭
v
false
).
Proof
.
iIntros
(
HNE
)
"(#spec & Hj & isQueue & lofal)"
.
rewrite
/
isCGQueue
/
CG_dequeue
.
simpl
.
iMod
(
steps_with_lock
_
_
_
_
_
(
ℓ
↦ₛ
FoldV
(
InjRV
(
PairV
x
_
)))%
I
_
(
InjRV
x
)
UnitV
with
"[$Hj $isQueue $lofal]"
)
as
"Hj"
;
eauto
.
iIntros
(
K'
)
"(#Hspec & isQueue & Hj)"
.
iMod
(
do_step_pure
with
"[$Hj]"
)
as
"Hj"
;
eauto
.
iMod
(
step_load
_
_
(
UnfoldCtx
::
CaseCtx
_
_
::
K'
)
with
"[Hj $isQueue]"
)
as
"[Hj isQueue]"
;
eauto
.
simpl
.
iMod
(
do_step_pure
_
_
(
CaseCtx
_
_
::
K'
)
with
"[$Hj]"
)
as
"Hj"
;
eauto
.
simpl
.
iMod
(
do_step_pure
with
"[$Hj]"
)
as
"Hj"
;
eauto
.
simpl
.
iMod
(
do_step_pure
_
_
(
StoreRCtx
(
LocV
_
)
::
SeqCtx
_
::
K'
)
with
"[$Hj]"
)
as
"Hj"
;
eauto
.
simpl
.
iMod
(
step_store
_
_
(
SeqCtx
_
::
K'
)
with
"[$Hj $isQueue]"
)
as
"[Hj isQueue]"
;
eauto
.
{
rewrite
/=
!
to_of_val
//.
}
simpl
.
iMod
(
do_step_pure
with
"[$Hj]"
)
as
"Hj"
;
eauto
.
iMod
(
do_step_pure
_
_
(
InjRCtx
::
K'
)
with
"[$Hj]"
)
as
"Hj"
;
eauto
.
iModIntro
.
iFrame
.
Qed
.
Lemma
MS_CG_counter_refinement
:
Lemma
MS_CG_counter_refinement
:
[]
⊨
MS_queue
≤
log
≤
CG_queue
:
[]
⊨
MS_queue
≤
log
≤
CG_queue
:
(
TForall
(
TProd
(
TForall
(
TProd
...
@@ -245,7 +282,7 @@ Section Queue_refinement.
...
@@ -245,7 +282,7 @@ Section Queue_refinement.
iApply
(
wp_load
with
"hdPts"
).
iNext
.
iIntros
"hdPts"
.
iApply
(
wp_load
with
"hdPts"
).
iNext
.
iIntros
"hdPts"
.
simpl
.
simpl
.
rename
ℓ
q
into
ℓ
q'
.
rename
ℓ
q
into
ℓ
q'
.
iInv
queueN
as
(
ℓ
q
ℓ
'
2
xs2
xs
'
2
)
"(>-> & isMSQ & >-> & Hsq & lofal & Hlink & >%)"
"Hclose"
.
iInv
queueN
as
(
ℓ
q
ℓ
'
2
xs2
xs
ₛ
2
)
"(>-> & isMSQ & >-> & Hsq & lofal & Hlink & >%)"
"Hclose"
.
(* clear. *)
(* clear. *)
iDestruct
"isMSQ"
as
(
ℓ
sentinel2
v2
ℓ
hdPt2
ℓ
hd2
q2
p2
)
iDestruct
"isMSQ"
as
(
ℓ
sentinel2
v2
ℓ
hdPt2
ℓ
hd2
q2
p2
)
"(qPts & sentinelPts' & hdPts2 & isNodeList)"
.
"(qPts & sentinelPts' & hdPts2 & isNodeList)"
.
...
@@ -268,23 +305,46 @@ Section Queue_refinement.
...
@@ -268,23 +305,46 @@ Section Queue_refinement.
with the same element. *)
with the same element. *)
destruct
xs2
as
[|
x2'
xs2'
]
;
simpl
.
destruct
xs2
as
[|
x2'
xs2'
]
;
simpl
.
{
iDestruct
(
mapsto_agree
with
"isNodeList hdPts'"
)
as
%[=->].
}
{
iDestruct
(
mapsto_agree
with
"isNodeList hdPts'"
)
as
%[=->].
}
iDestruct
"isNodeList"
as
(
ℓ
tail
ℓ
next
)
"[hdPts'' isNodeList']"
.
destruct
xs
ₛ
2
as
[|
x
ₛ
2
'
xs
ₛ
2
'
]
;
simpl
.
{
inversion
H4
.
}
iDestruct
"isNodeList"
as
(
ℓ
tail
ℓ
next
)
"[hdPts'' isNodeList]"
.
iAssert
(
⌜
x
=
x2'
⌝
)%
I
as
%<-.
iAssert
(
⌜
x
=
x2'
⌝
)%
I
as
%<-.
{
iDestruct
(
mapsto_agree
with
"hdPts' hdPts''"
)
as
%[=<-].
done
.
}
{
iDestruct
(
mapsto_agree
with
"hdPts' hdPts''"
)
as
%[=<-].
done
.
}
(* We must now reestablish the invariant. *)
iDestruct
"Hlink"
as
"[Hτi Hlink]"
.
iMod
(
"Hclose"
with
"[qPts lofal Hlink Hsq isNodeList']"
)
as
"_"
.
(* We step through the specificaion code. *)
iMod
(
steps_CG_dequeue_cons
with
"[$Hspec $Hj $Hsq $lofal]"
)
as
"(Hj & Hsq & lofal)"
.
{
solve_ndisj
.
}
(* FIXME: I think the brackets can be removed here. *)
(* We are now ready to reestablish the invariant. *)
iMod
(
"Hclose"
with
"[qPts lofal Hlink Hsq isNodeList hdPts'']"
)
as
"_"
.
{
iNext
.
{
iNext
.
rewrite
/
invariant
.
rewrite
/
invariant
.
iExists
_
,
_
,
xs
'
,
xs
ₛ
'
.
iExists
_
,
_
,
xs
2'
,
xs
ₛ
2
'
.
iFrame
.
iFrame
.
iSplit
;
auto
.
iSplit
;
auto
.
iSplitL
"qPts hdPts'' isNodeList"
.
{
iExists
_
,
_
,
_
,
_
,
_
,
_
.
iFrame
.
}
iSplit
;
auto
.
iSplit
;
auto
.
rewrite
/
isMSQueue
.
iExists
_
,
_
,
_
,
_
,
_
,
_
.
iFrame
.
}
}
*
(* Step over the remainder of the code. *)
iApply
(
wp_load
with
"qPts"
).
iNext
.
iIntros
"qPts"
.
iModIntro
.
simpl
.
iApply
wp_pure_step_later
;
auto
.
iNext
.
iApply
(
wp_bind
(
fill
[
CaseCtx
_
_;
InjRCtx
])).
iApply
wp_pure_step_later
;
auto
.
iNext
.
iApply
wp_value
.
simpl
.
iApply
(
wp_bind
(
fill
[
InjRCtx
])).
iApply
wp_pure_step_later
;
auto
.
iNext
.
simpl
.
iApply
wp_value
.
iApply
wp_value
.
iExists
(
InjRV
_
).
iFrame
.
iRight
.
iExists
(
_
,
_
).
iFrame
.
auto
.
*
(* The queue no longer points to the same sentinel *)
(* iApply (wp_load with "qPts"). iNext. iIntros "qPts". *)
admit
.
admit
.
-
(* enqueue *)
-
(* enqueue *)
iIntros
([
v1
v2
])
"!> #Hrel"
.
iIntros
([
v1
v2
])
"!> #Hrel"
.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment