Professional Documents
Culture Documents
1 Introduction
The example contains a simple implementation of the selection sort algorithm. It
will be shown that on certain preconditions the implementation works correct, i.e
the result is a sorted array that is a permutation of the given array. Consequently
the problem of verifying the implementation can be divided into the following
two subproblems:
1. Precondition
The given array should be not empty:
requires(a6=null & a.length>0)
2. Postcondition
The array is sorted:
ensures(∀ int i: 0≤i & i<a.length-1 ⇒ a[i]≥a[i+1])
3. Loop invariant for the outer loop divided into three main conjunctions:
1
A) The separation must be within the array:
0≤pos & pos≤a.length
A) Definition of the sorted part
∀ int x: x≥0 & x<pos-1 ⇒ a[x]≥a[x+1]
A) For the unsorted part it is necessary that every element is less than or equal
to all elements of the sorted part:
∀ int x: x≥0 & x≤pos-1 ⇒ (∀ int y: y≥pos & y<a.length ⇒
a[x]≥a[y])
4. Loop invariant for the inner loop divided into three main conjunctions:
2
2. B) boolean perm(int [] a, int [] b)
.
:↔ ∀n : mult(a, n, 0, a.length) = mult(b, n, 0, b.length)
∀ int x ∀ int y : x ≥ 0 & x < a.length & y ≥ 0 & y < a.length & perm(a, b)
→ {a[x] := a[y] || a[y] := a[x]}perm(a, b))
Remark: The rule permT ransistion is proved by means of the proof obligations
that can be found in “permTrans.key”, “multPart.key” and “unwindEnd.key”.
All of these proofs involve inductions on natural numbers but do not incorporate
programs. Therefore they are not considered in this documentation.
inReachableState
→
∀ S o r t s e l f l v { s e l f := s e l f l v }
(
s e l f . a 6= null
& s e l f 6= null
& s e l f .< c r e a t e d > = TRUE
& s e l f . a 6= null
& s e l f . a . length > 0
→
< s e l f . demo ( ) ;>
(
∀ jint i
(
0≤ i & i < s e l f . a . l e n g t h −1
→ s e l f . a [ i ] ≥ s e l f . a [ i +1]
)
)
)
For proving this formula in KeY no interaction with the user is necessary. The
invariants given in JML (see 2.1) are used to instantiate the invariant rules of
the two while-loops. The resulting obligation is automatically closed after 3273
steps on 26 branches.
3
inReachableState is a special predicate which summarizes a conjunction of sev-
eral predicates in KeY to shorten the length of the proof obligation. These
predicates answer the purpose to model states which are reachable by Java
Card programs [BHS07, page 105].
A modified version of the selection sort example can be found in the folder
“ArrayIsSorted” which shows only that the resulting array is sorted: All decla-
rations of rules, predicates and functions have been removed in “sortAlg.key”,
because the JML-blocks in “Sort.java” are effectual for this part of the proof.
inReachableState
→
∀ S o r t s e l f l v { s e l f := s e l f l v }{\ f o r int i ;
deepCopyArrayA [ i ] := s e l f . a [ i ] }
(
s e l f . a 6= deepCopyArrayA
& s e l f . a 6= null
& deepCopyArrayA 6= null
& perm ( s e l f . a , deepCopyArrayA )
& s e l f 6= null
& s e l f .< c r e a t e d > = TRUE
& s e l f . a 6= null
& s e l f . a . length> 0
→
< s e l f . demo ( ) ;>
(
perm ( s e l f . a , deepCopyArrayA )
)
)
}
After expanding demo() and simplifying the statement, the loop invariant
4
perm [ \ f o r ( j i n t [ ] o ; int i ) o [ i ] ; \ f o r ( j i n t [ ] o ) o .
l e n g t h ] ( s e l f . a , deepCopyArrayA )
must be proved for the outer loop. In KeY this is equally done to the proof of
A), with the exception that the invariant must be introduced manually (see 3).
As you can see at the definition of perm (see 2.2) the valuation of perm only
depends on the values of a[i], b[i], a.length, b.length (∀ int i). This explicit
dependencies allows the calculus to ignore heap changes which are outside of this
dependency set without expanding the definition. As recently as the calculus
reaches the swapping
int temp=a [ i d x ] ;
a [ i d x ]=a [ pos ] ;
a [ pos ]=tmp ;
the definition of perm must be expanded, because perm is by definition de-
pended on these variables used in the swapping. At this point the rule permT ransition
must be applied to prove that the swapping is correct (For more information
about dependencies see [BHS08]).
A modified version of the selection sort example can be found in the folder
“ArrayIsPermutation”: As far as possible the JML-blocks have been reduced in
“Sort.java” to show only the permutation property.
5
8. Restart the prover. The proof should be closed after up to 20000 steps.
Explanation: By setting ’Loop Treatment’ to none in Step 1 it is guar-
anteed that the prover will not use automatically the weak form of the loop
invariant for the outer loop. In Step 2 the prover begins to apply the typical
rules, like expanding the program and dissolving the modality, to the problem
until the rule ’Loop invariant’ would be the next best choice. At this point the
prover stops and hands the control over to the user. When the user applies
the rule ‘Loop invariant‘ to the outer loop in step 3, the instantiation window
opens (Remark: without choosing ’Minimize Interaction’ in Step 1 the window
would not have been opened, but the instantiation would have been done auto-
matically). In field ’inv (formula)’ the user can find an invariant which nearly
equates to the invariant that can be found in ”Sort.java“. Because the invari-
ant for the inner loop does not need to extend, the option ’Loop Treatment’ is
reseted to invariant in Step 5. For step 6-8 see 2.4.
References
[BHS07] Bernhard Beckert, Reiner Hähnle, and Peter H. Schmitt, editors. Veri-
fication of Object-Oriented Software: The KeY Approach. LNCS 4334.
Springer-Verlag, 2007.
[BHS08] Richard Bubel, Reiner Hähnle, and Peter H. Schmitt. Specification
predicates with explicit dependency information. In Bernhard Beckert,
editor, Proceedings, 5th International Verification Workshop (VER-
IFY’08), volume 372 of CEUR Workshop Proceedings, pages 28–43.
CEUR-WS.org, 2008.