Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Why3
why3
Commits
9369e246
Commit
9369e246
authored
Apr 22, 2015
by
Martin Clochard
Browse files
verifythis parallel gcd: proof for thread interleaving (including termination)
parent
069bd159
Changes
3
Hide whitespace changes
Inline
Side-by-side
examples/verifythis_2015_parallel_gcd.mlw
View file @
9369e246
...
...
@@ -108,7 +108,6 @@ end
(** Threads interleaving.
Code and invariants by Rustan Leino. *)
(***
module Interleaving
use import int.Int
...
...
@@ -117,6 +116,23 @@ module Interleaving
lemma gcd_sub: forall a b: int. gcd a b = gcd a (b - a)
(* Representation of a thread: two local variables
(register copies of the globals) and a program counter:
ReadA:
local_a <- a
ReadB:
local_b <- b
Compare:
if local_a = local_b goto Halt;
if local_a > local_b a := local_a - local_b;
goto ReadA;
Halt:
For the sake of simplicity, every section is considered atomic.
(strictly speaking, section Compare is not, but it interacts
atomically with memory so it would be equivalent)
*)
type state = ReadA | ReadB | Compare | Halt
type thread = {
...
...
@@ -125,24 +141,69 @@ module Interleaving
mutable state : state;
}
predicate inv (th: thread) (a0 b0 a b: int) =
0 < a /\ 0 < b /\ gcd a b = gcd a0 b0 /\
(* Thread invariant. *)
predicate inv (th: thread) (d a b: int) =
0 < a /\ 0 < b /\ gcd a b = d /\
match th.state with
| ReadA -> true
| ReadB -> th.local_a = a
| ReadB -> th.local_a = a
(* No other thread can write in a. *)
| Compare -> th.local_a = a && b <= th.local_b &&
(th.local_b <= th.local_a -> th.local_b = b)
| Halt -> th.local_a = a = b
(* Other thread may have overwritten b, but only in a decreasing
decreasing fashion, and only once under a. *)
| Halt -> th.local_a = a = b (* Final state is stable. *)
end
(* Does running this thread make any progress toward the result ? *)
predicate progress_thread (th:thread) (a b:int) =
a > b \/ (a = b /\ th.state <> Halt)
(* Decreasing ordering on program counter *)
function state_index (s:state) : int = match s with
| ReadA -> 7
| ReadB -> 5
| Compare -> 3
| Halt -> 2
end
(* Synchronisation status. *)
predicate sync (th:thread) (b:int) =
match th.state with Compare -> th.local_b = b | _ -> true end
(* Convert status into an index. *)
function sync_index (th:thread) (b:int) : int =
if sync th b then 0 else 42
(* Thread progression index: if running this thread should make any
progression toward the result, then it will have the following shape:
- A first (optional) loop run for synchronization.
- A second synchronized run until effective progress *)
function prog_index (th:thread) (b:int) : int =
sync_index th b + state_index th.state
val create_thread () : thread
ensures { result.state = ReadA }
let step (th: thread) (ghost a0 b0: int) (a b: ref int)
requires { inv th a0 b0 !a !b }
(* Fair scheduler modelisation: Each time it switch to a thread,
it also writes down the time remaining before it switch to the other.
If it does not switch, this timeout decrease. *)
val ghost scheduled : ref bool
val ghost timer : ref int
val schedule () : bool
writes { scheduled , timer }
ensures { !scheduled = old !scheduled -> 0 <= !timer < old !timer }
ensures { result = !scheduled }
(* Execution of one thread step. *)
let step (th: thread) (ghost d: int) (a b: ref int)
requires { inv th d !a !b }
writes { th, a }
ensures { inv th
a0 b0
!a !b }
ensures { inv th
d
!a !b }
ensures { 0 < !a <= old !a }
ensures { old !a > !a -> old !a >= !a + !b }
ensures { progress_thread th !a !b ->
prog_index (old th) !b > prog_index th !b \/ !a < old !a }
=
match th.state with
| ReadA ->
...
...
@@ -162,20 +223,30 @@ module Interleaving
let parallel_gcd (a0 b0: int) : int
requires { 0 < a0 /\ 0 < b0 }
diverges
ensures { result = gcd a0 b0 }
=
(* shared variables *)
let a = ref a0 in
let b = ref b0 in
let ghost d = gcd a0 b0 in
(* two threads *)
let th1 = create_thread () in
let th2 = create_thread () in
while th1.state <> Halt || th2.state <> Halt do
invariant { inv th1 a0 b0 !a !b /\ inv th2 b0 a0 !b !a }
if any bool then step th1 a0 b0 a b else step th2 b0 a0 b a
invariant { inv th1 d !a !b /\ inv th2 d !b !a }
variant { !a + !b ,
if !a = !b
then prog_index th2 !a + prog_index th1 !b
else if !a < !b
then prog_index th2 !a
else prog_index th1 !b ,
if progress_thread th1 !a !b
then if !scheduled then 1 else 0
else if progress_thread th2 !b !a
then if !scheduled then 0 else 1
else 0 , !timer }
if schedule () then step th1 d a b else step th2 d b a
done;
!a
end
***)
examples/verifythis_2015_parallel_gcd/why3session.xml
View file @
9369e246
...
...
@@ -5,52 +5,54 @@
<prover
id=
"0"
name=
"CVC4"
version=
"1.4"
timelimit=
"6"
memlimit=
"1000"
/>
<prover
id=
"1"
name=
"Z3"
version=
"4.3.1"
timelimit=
"6"
memlimit=
"1000"
/>
<prover
id=
"2"
name=
"Spass"
version=
"3.7"
timelimit=
"6"
memlimit=
"1000"
/>
<prover
id=
"3"
name=
"Alt-Ergo"
version=
"0.95.2"
timelimit=
"6"
memlimit=
"1000"
/>
<prover
id=
"4"
name=
"Vampire"
version=
"0.6"
timelimit=
"6"
memlimit=
"1000"
/>
<prover
id=
"5"
name=
"Alt-Ergo"
version=
"0.99.1"
timelimit=
"5"
memlimit=
"1000"
/>
<prover
id=
"6"
name=
"CVC3"
version=
"2.4.1"
timelimit=
"5"
memlimit=
"1000"
/>
<prover
id=
"7"
name=
"Eprover"
version=
"1.8-001"
timelimit=
"5"
memlimit=
"1000"
/>
<file
name=
"../verifythis_2015_parallel_gcd.mlw"
expanded=
"true"
>
<theory
name=
"ParallelGCD"
sum=
"8319d7f76f67ab787192d931e1a55949"
>
<goal
name=
"gcd_sub"
>
<proof
prover=
"2"
><result
status=
"valid"
time=
"0.05"
/></proof>
<proof
prover=
"4"
><result
status=
"valid"
time=
"0.02"
/></proof>
<proof
prover=
"4"
obsolete=
"true"
><result
status=
"valid"
time=
"0.02"
/></proof>
</goal>
<goal
name=
"WP_parameter parallel_gcd"
expl=
"VC for parallel_gcd"
>
<transf
name=
"split_goal_wp"
>
<goal
name=
"WP_parameter parallel_gcd.1"
expl=
"1. loop invariant init"
>
<proof
prover=
"
3
"
><result
status=
"valid"
time=
"0.01"
steps=
"2"
/></proof>
<proof
prover=
"
5"
timelimit=
"6
"
><result
status=
"valid"
time=
"0.01"
steps=
"2"
/></proof>
</goal>
<goal
name=
"WP_parameter parallel_gcd.2"
expl=
"2. loop invariant preservation"
>
<proof
prover=
"
3
"
><result
status=
"valid"
time=
"0.01"
steps=
"11"
/></proof>
<proof
prover=
"
5"
timelimit=
"6
"
><result
status=
"valid"
time=
"0.01"
steps=
"11"
/></proof>
</goal>
<goal
name=
"WP_parameter parallel_gcd.3"
expl=
"3. loop invariant preservation"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.02"
/></proof>
<proof
prover=
"2"
><result
status=
"valid"
time=
"0.02"
/></proof>
<proof
prover=
"
3
"
><result
status=
"valid"
time=
"0.
03"
steps=
"2
1"
/></proof>
<proof
prover=
"
4
"
><result
status=
"valid"
time=
"0.
12
"
/></proof>
<proof
prover=
"
4"
obsolete=
"true
"
><result
status=
"valid"
time=
"0.1
2
"
/></proof>
<proof
prover=
"
5"
timelimit=
"6
"
><result
status=
"valid"
time=
"0.
03"
steps=
"37
"
/></proof>
</goal>
<goal
name=
"WP_parameter parallel_gcd.4"
expl=
"4. loop invariant preservation"
>
<proof
prover=
"
3
"
><result
status=
"valid"
time=
"0.02"
steps=
"10"
/></proof>
<proof
prover=
"
5"
timelimit=
"6
"
><result
status=
"valid"
time=
"0.02"
steps=
"10"
/></proof>
</goal>
<goal
name=
"WP_parameter parallel_gcd.5"
expl=
"5. loop invariant preservation"
>
<proof
prover=
"
3
"
><result
status=
"valid"
time=
"0.02"
steps=
"10"
/></proof>
<proof
prover=
"
5"
timelimit=
"6
"
><result
status=
"valid"
time=
"0.02"
steps=
"10"
/></proof>
</goal>
<goal
name=
"WP_parameter parallel_gcd.6"
expl=
"6. loop invariant preservation"
>
<proof
prover=
"
3
"
><result
status=
"valid"
time=
"0.01"
steps=
"11"
/></proof>
<proof
prover=
"
5"
timelimit=
"6
"
><result
status=
"valid"
time=
"0.01"
steps=
"11"
/></proof>
</goal>
<goal
name=
"WP_parameter parallel_gcd.7"
expl=
"7. loop invariant preservation"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.02"
/></proof>
<proof
prover=
"2"
timelimit=
"30"
><result
status=
"valid"
time=
"0.09"
/></proof>
<proof
prover=
"
3
"
><result
status=
"valid"
time=
"0.0
2"
steps=
"13
"
/></proof>
<proof
prover=
"
4
"
timelimit=
"
30
"
><result
status=
"valid"
time=
"0.0
9
"
/></proof>
<proof
prover=
"
4"
timelimit=
"30"
obsolete=
"true
"
><result
status=
"valid"
time=
"0.0
9
"
/></proof>
<proof
prover=
"
5
"
timelimit=
"
6
"
><result
status=
"valid"
time=
"0.0
2"
steps=
"13
"
/></proof>
</goal>
<goal
name=
"WP_parameter parallel_gcd.8"
expl=
"8. loop invariant preservation"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.01"
/></proof>
<proof
prover=
"1"
><result
status=
"valid"
time=
"0.01"
/></proof>
<proof
prover=
"
3
"
><result
status=
"valid"
time=
"0.01"
steps=
"10"
/></proof>
<proof
prover=
"
5"
timelimit=
"6
"
><result
status=
"valid"
time=
"0.01"
steps=
"10"
/></proof>
</goal>
<goal
name=
"WP_parameter parallel_gcd.9"
expl=
"9. loop invariant preservation"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.01"
/></proof>
<proof
prover=
"1"
><result
status=
"valid"
time=
"0.00"
/></proof>
<proof
prover=
"
3
"
><result
status=
"valid"
time=
"0.00"
steps=
"10"
/></proof>
<proof
prover=
"
5"
timelimit=
"6
"
><result
status=
"valid"
time=
"0.00"
steps=
"10"
/></proof>
</goal>
<goal
name=
"WP_parameter parallel_gcd.10"
expl=
"10. postcondition"
>
<proof
prover=
"0"
><result
status=
"valid"
time=
"0.03"
/></proof>
...
...
@@ -58,5 +60,133 @@
</transf>
</goal>
</theory>
<theory
name=
"Interleaving"
sum=
"8a7f2e36501d957e8de13171fbd9f63c"
expanded=
"true"
>
<goal
name=
"gcd_sub"
>
<proof
prover=
"7"
><result
status=
"valid"
time=
"0.04"
/></proof>
</goal>
<goal
name=
"WP_parameter step"
expl=
"VC for step"
>
<transf
name=
"split_goal_wp"
>
<goal
name=
"WP_parameter step.1"
expl=
"1. postcondition"
>
<proof
prover=
"5"
><result
status=
"valid"
time=
"0.02"
steps=
"8"
/></proof>
</goal>
<goal
name=
"WP_parameter step.2"
expl=
"2. postcondition"
>
<proof
prover=
"5"
><result
status=
"valid"
time=
"0.01"
steps=
"5"
/></proof>
</goal>
<goal
name=
"WP_parameter step.3"
expl=
"3. postcondition"
>
<proof
prover=
"5"
><result
status=
"valid"
time=
"0.02"
steps=
"4"
/></proof>
</goal>
<goal
name=
"WP_parameter step.4"
expl=
"4. postcondition"
>
<proof
prover=
"5"
><result
status=
"valid"
time=
"0.89"
steps=
"180"
/></proof>
</goal>
<goal
name=
"WP_parameter step.5"
expl=
"5. postcondition"
>
<proof
prover=
"5"
><result
status=
"valid"
time=
"0.02"
steps=
"11"
/></proof>
</goal>
<goal
name=
"WP_parameter step.6"
expl=
"6. postcondition"
>
<proof
prover=
"5"
><result
status=
"valid"
time=
"0.02"
steps=
"5"
/></proof>
</goal>
<goal
name=
"WP_parameter step.7"
expl=
"7. postcondition"
>
<proof
prover=
"5"
><result
status=
"valid"
time=
"0.01"
steps=
"4"
/></proof>
</goal>
<goal
name=
"WP_parameter step.8"
expl=
"8. postcondition"
>
<proof
prover=
"5"
><result
status=
"valid"
time=
"1.86"
steps=
"269"
/></proof>
</goal>
<goal
name=
"WP_parameter step.9"
expl=
"9. postcondition"
>
<proof
prover=
"5"
><result
status=
"valid"
time=
"0.02"
steps=
"14"
/></proof>
</goal>
<goal
name=
"WP_parameter step.10"
expl=
"10. postcondition"
>
<proof
prover=
"5"
><result
status=
"valid"
time=
"0.02"
steps=
"5"
/></proof>
</goal>
<goal
name=
"WP_parameter step.11"
expl=
"11. postcondition"
>
<proof
prover=
"5"
><result
status=
"valid"
time=
"0.02"
steps=
"4"
/></proof>
</goal>
<goal
name=
"WP_parameter step.12"
expl=
"12. postcondition"
>
<proof
prover=
"6"
><result
status=
"valid"
time=
"0.04"
/></proof>
</goal>
<goal
name=
"WP_parameter step.13"
expl=
"13. postcondition"
>
<proof
prover=
"5"
><result
status=
"valid"
time=
"0.94"
steps=
"41"
/></proof>
</goal>
<goal
name=
"WP_parameter step.14"
expl=
"14. postcondition"
>
<proof
prover=
"5"
><result
status=
"valid"
time=
"0.02"
steps=
"11"
/></proof>
</goal>
<goal
name=
"WP_parameter step.15"
expl=
"15. postcondition"
>
<proof
prover=
"5"
><result
status=
"valid"
time=
"0.02"
steps=
"12"
/></proof>
</goal>
<goal
name=
"WP_parameter step.16"
expl=
"16. postcondition"
>
<proof
prover=
"5"
><result
status=
"valid"
time=
"0.02"
steps=
"13"
/></proof>
</goal>
<goal
name=
"WP_parameter step.17"
expl=
"17. postcondition"
>
<proof
prover=
"5"
><result
status=
"valid"
time=
"0.01"
steps=
"11"
/></proof>
</goal>
<goal
name=
"WP_parameter step.18"
expl=
"18. postcondition"
>
<proof
prover=
"5"
><result
status=
"valid"
time=
"0.02"
steps=
"6"
/></proof>
</goal>
<goal
name=
"WP_parameter step.19"
expl=
"19. postcondition"
>
<proof
prover=
"5"
><result
status=
"valid"
time=
"0.01"
steps=
"5"
/></proof>
</goal>
<goal
name=
"WP_parameter step.20"
expl=
"20. postcondition"
>
<proof
prover=
"6"
><result
status=
"valid"
time=
"0.03"
/></proof>
</goal>
<goal
name=
"WP_parameter step.21"
expl=
"21. postcondition"
>
<proof
prover=
"5"
><result
status=
"valid"
time=
"0.01"
steps=
"2"
/></proof>
</goal>
<goal
name=
"WP_parameter step.22"
expl=
"22. postcondition"
>
<proof
prover=
"5"
><result
status=
"valid"
time=
"0.01"
steps=
"3"
/></proof>
</goal>
<goal
name=
"WP_parameter step.23"
expl=
"23. postcondition"
>
<proof
prover=
"5"
><result
status=
"valid"
time=
"0.01"
steps=
"2"
/></proof>
</goal>
<goal
name=
"WP_parameter step.24"
expl=
"24. postcondition"
>
<proof
prover=
"5"
><result
status=
"valid"
time=
"0.01"
steps=
"10"
/></proof>
</goal>
</transf>
</goal>
<goal
name=
"WP_parameter parallel_gcd"
expl=
"VC for parallel_gcd"
>
<transf
name=
"split_goal_wp"
>
<goal
name=
"WP_parameter parallel_gcd.1"
expl=
"1. loop invariant init"
>
<proof
prover=
"5"
><result
status=
"valid"
time=
"0.04"
steps=
"16"
/></proof>
</goal>
<goal
name=
"WP_parameter parallel_gcd.2"
expl=
"2. precondition"
>
<proof
prover=
"5"
><result
status=
"valid"
time=
"0.01"
steps=
"7"
/></proof>
</goal>
<goal
name=
"WP_parameter parallel_gcd.3"
expl=
"3. loop invariant preservation"
>
<proof
prover=
"5"
><result
status=
"valid"
time=
"0.19"
steps=
"98"
/></proof>
</goal>
<goal
name=
"WP_parameter parallel_gcd.4"
expl=
"4. loop variant decrease"
>
<transf
name=
"inline_goal"
>
<goal
name=
"WP_parameter parallel_gcd.4.1"
expl=
"1. loop variant decrease"
>
<transf
name=
"inline_goal"
>
<goal
name=
"WP_parameter parallel_gcd.4.1.1"
expl=
"1. loop variant decrease"
>
<proof
prover=
"0"
timelimit=
"5"
><result
status=
"valid"
time=
"0.13"
/></proof>
</goal>
</transf>
</goal>
</transf>
</goal>
<goal
name=
"WP_parameter parallel_gcd.5"
expl=
"5. precondition"
>
<proof
prover=
"5"
><result
status=
"valid"
time=
"0.01"
steps=
"7"
/></proof>
</goal>
<goal
name=
"WP_parameter parallel_gcd.6"
expl=
"6. loop invariant preservation"
>
<proof
prover=
"5"
><result
status=
"valid"
time=
"0.05"
steps=
"59"
/></proof>
</goal>
<goal
name=
"WP_parameter parallel_gcd.7"
expl=
"7. loop variant decrease"
>
<transf
name=
"inline_goal"
>
<goal
name=
"WP_parameter parallel_gcd.7.1"
expl=
"1. loop variant decrease"
>
<transf
name=
"inline_goal"
>
<goal
name=
"WP_parameter parallel_gcd.7.1.1"
expl=
"1. loop variant decrease"
>
<proof
prover=
"0"
timelimit=
"5"
><result
status=
"valid"
time=
"0.17"
/></proof>
</goal>
</transf>
</goal>
</transf>
</goal>
<goal
name=
"WP_parameter parallel_gcd.8"
expl=
"8. postcondition"
>
<proof
prover=
"1"
timelimit=
"5"
><result
status=
"valid"
time=
"0.03"
/></proof>
<proof
prover=
"2"
timelimit=
"5"
><result
status=
"valid"
time=
"1.10"
/></proof>
<proof
prover=
"6"
><result
status=
"valid"
time=
"0.06"
/></proof>
<proof
prover=
"7"
><result
status=
"valid"
time=
"0.07"
/></proof>
</goal>
</transf>
</goal>
</theory>
</file>
</why3session>
examples/verifythis_2015_parallel_gcd/why3shapes.gz
View file @
9369e246
No preview for this file type
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