Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
why3
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
112
Issues
112
List
Boards
Labels
Milestones
Merge Requests
14
Merge Requests
14
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Why3
why3
Commits
10e4b2f1
Commit
10e4b2f1
authored
Jan 06, 2017
by
Andrei Paskevich
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Vc: write more comments
parent
1f87dba1
Changes
1
Hide whitespace changes
Inline
Sidebyside
Showing
1 changed file
with
69 additions
and
4 deletions
+69
4
src/mlw/vc.ml
src/mlw/vc.ml
+69
4
No files found.
src/mlw/vc.ml
View file @
10e4b2f1
...
...
@@ 701,7 +701,7 @@ let rec k_expr env lps ({e_loc = loc} as e) res xmap =
if
Slab
.
mem
wp_label
e
.
e_label
then
Ktag
(
WP
,
k
)
else
k
and
k_fun
env
lps
?
(
oldies
=
Mpv
.
empty
)
?
(
xmap
=
Mexn
.
empty
)
cty
e
=
(* ASSUME pre ; LET o
arg = arg ; TRY e ; STOP post WITH
xpost *)
(* ASSUME pre ; LET o
= arg ; TRY e ; STOP post WITH STOP
xpost *)
let
res
,
q
=
wp_of_post
expl_post
cty
.
cty_result
cty
.
cty_post
in
let
xq
=
complete_xpost
cty
e
.
e_effect
xmap
in
let
xq
=
Mexn
.
mapi
(
fun
xs
ql
>
...
...
@@ 1014,7 +1014,51 @@ let sp_combine_map sp1 sp2 =
Some
(
sp_combine
sp1
wr1
sp2
wr2
))
sp1
sp2
(* compute compact verification conditions, in the style
of the Flanagan and Saxe paper (POPL'01). *)
of the Flanagan and Saxe paper (POPL'01).
Here is how it works, on a small example:
sp_expr kn k
rdm = [0 > {v1; v2}; 1 > {v1; v3}]
dst = [v1 > u1; v2 > u2; v3 > u3]
= (wp, [0 > (sp_0, [v1 > u1]);
1 > (sp_1, [v3 > u3])], {v0; v1})
[sp_expr kn k rdm dst] returns a triple [(wp, sp+wr, rd)].
The mapping [rdm] provides the postreads set for every
possible outcome of [k]. If [k] ends normally (outcome 0),
the subsequent execution will read program variables [v1]
and [v2]. If [k] terminates with an exception (outcome 1),
the subsequent execution will read [v1] and [v3].
The mapping [dst] provides postwrite names for every
mutable variable in [rdm]. If [k] modifies [v1] (on any
execution path), the final value must be put in [u1],
and similarly for [v2] and [v3].
The set [rd] contains every previously defined or declared
variable that may be read by [k] or by the subsequent code
for any outcome of [k]. In our example, [k] and the code
after [k] depends on [v0] and [v1]; the variables [v2] and
[v3] are defined or declared by [k] itself and thus do not
appear in [rd].
The formula [wp] is a safety precondition of [k], logically
equivalent to [WP(k,true)]. Every free variable in [wp] is
in [rd].
The mapping [sp+wr] provides the postcondition [sp_i] and
the actual write effect [wr_i] for every outcome [i] of [k].
The write effect [wr_i] is necessarily a submap of [dst]
restricted to the corresponding postread set [rdm(i)].
For example, it is possible that [k] also modifies [v3]
on the normal execution path, but since [v3] is not read
after the normal termination of [k], it is not in [wr_0].
Every free variable in [sp_i] is either in [rd] or in
the range of [wr_i], or otherwise in [rdm(i)]. Every
variable in the range of [wr_i] is free in [sp_i]. *)
let
rec
sp_expr
kn
k
rdm
dst
=
match
k
with

Kseq
(
Klet
(
v
,
t
,
f
)
,
0
,
k2
)
>
let
wp2
,
sp2
,
rd2
=
sp_expr
kn
k2
rdm
dst
in
...
...
@@ 1025,6 +1069,9 @@ let rec sp_expr kn k rdm dst = match k with
wp
,
Mint
.
inter
close
sp2
rdm
,
Spv
.
remove
v
rd1

Kseq
(
k1
,
i
,
k2
)
>
let
wp2
,
sp2
,
rd2
=
sp_expr
kn
k2
rdm
dst
in
(* the dst parameter for k1 must include a fresh final
name for every variable modified by k2 (on any path),
and for every variable read by k2 that is not in dst *)
let
get_wr
_
(
_
,
w
)
m
=
Mpv
.
set_union
w
m
in
let
wr2
=
Mint
.
fold
get_wr
sp2
Mpv
.
empty
in
let
fresh_wr2
v
_
=
clone_pv
v
in
...
...
@@ 1033,24 +1080,42 @@ let rec sp_expr kn k rdm dst = match k with
let
wp1
,
sp1
,
rd1
=
sp_expr
kn
k1
(
Mint
.
add
i
rd2
rdm
)
(
Mpv
.
set_union
(
Mpv
.
set_union
(
Mpv
.
mapi
fresh_wr2
wr2
)
(
Mpv
.
mapi_filter
fresh_rd2
(
Mpv
.
set_diff
rd2
dst
)))
dst
)
in
(* retrieve the postcondition and the write effect for the
outcome i: they prepend everything that happens in k2 *)
let
sp0
,
wr0
=
Mint
.
find
i
sp1
in
let
bound
=
Spv
.
diff
rd2
rd1
in
(* in (sp0 > wp2) we bind everything that is not in rd1,
knowing that variables that are not in rd2 are already
bound in sp0. We also bind all the final names. *)
let
concat
rd
wr
=
List
.
rev_append
(
List
.
rev_map
(
fun
v
>
v
.
pv_vs
)
(
Spv
.
elements
rd
))
(
Mpv
.
values
wr
)
in
let
bound
=
Spv
.
diff
rd2
rd1
in
let
wp2
=
(* variables in wp2 must be adjusted wrt. wr0 *)
let
adj
=
adjustment
wr0
and
vl
=
concat
bound
wr0
in
wp_forall
vl
(
sp_implies
sp0
(
t_subst
adj
wp2
))
in
(* compute (sp0 /\ sp2_j) for every outcome j of k2 *)
let
close
(
sp
,
wr
)
rd
=
(* retrieve the write effects in wr0 that are visible
in the postreads of k2, i.e., are not masked by
a write in k2 on the corresponding execution path *)
let
wr0_dst
=
Mpv
.
set_inter
dst
(
Mpv
.
set_diff
(
Mpv
.
set_inter
wr0
rd
)
wr
)
in
let
wr
=
Mpv
.
set_union
wr
wr0_dst
in
let
wr
=
Mpv
.
set_union
wr0_dst
wr
in
(* we must not bind variables that are visible in the
postreads of k2, so we remove the postreads from
bound, and we remove the visible writes from wr0 *)
let
vl
=
concat
(
Spv
.
diff
bound
rd
)
(
Mpv
.
set_diff
wr0
wr0_dst
)
in
(* visible writes in sp0 are not masked by wr, and so
must be advanced to dst. Variables in sp must then
be adjusted wrt. this "advanced" write effect. *)
let
adj
=
adjustment
(
Mpv
.
set_union
wr0_dst
wr0
)
in
let
sp0
=
t_subst
(
advancement
wr0
wr0_dst
)
sp0
in
sp_exists
vl
(
sp_and
sp0
(
t_subst
adj
sp
))
,
wr
in
let
close
_
sp
rd
=
Some
(
close
sp
rd
)
in
let
sp2
=
Mint
.
inter
close
sp2
rdm
in
(* finally, the postcondition and the write effect for
every other outcome of k1 must be advanced to dst *)
let
advance
(
sp
,
wr
)
=
let
dst
=
Mpv
.
set_inter
dst
wr
in
t_subst
(
advancement
wr
dst
)
sp
,
dst
in
...
...
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