vault backup: 2023-11-20 13:06:22
This commit is contained in:
parent
36338fff98
commit
205f1eabdd
1 changed files with 98 additions and 0 deletions
|
@ -86,3 +86,101 @@ end
|
|||
```
|
||||
|
||||
|
||||
```c
|
||||
|
||||
(*
|
||||
The selection sort algorithm sorts an array
|
||||
by successively placing in each position the
|
||||
“next minimum” element, as follows:
|
||||
|
||||
[40, 20, 10, 30, 60, 0, 80]
|
||||
[0, 20, 10, 30, 60, 40, 80]
|
||||
[0, 10, 20, 30, 60, 40, 80]
|
||||
[0, 10, 20, 30, 60, 40, 80]
|
||||
[0, 10, 20, 30, 60, 40, 80]
|
||||
[0, 10, 20, 30, 40, 60, 80]
|
||||
[0, 10, 20, 30, 40, 60, 80]
|
||||
[0, 10, 20, 30, 40, 60, 80]
|
||||
|
||||
1. Complete the contract of function swap, writing
|
||||
adequate pre- and post-conditions.
|
||||
Recall that "length a" gives you the allocated length
|
||||
of array a.
|
||||
2. Write a contract for function select.
|
||||
Write also one or more loop invariants that allow
|
||||
you to prove the correctness of the function.
|
||||
Note that a loop variant is not required, since
|
||||
"for" loops are bounded.
|
||||
3. Write one or more loop invariants that allow you to prove
|
||||
the correctness of selection_sort_1.
|
||||
You may need to modify the contract of select in order
|
||||
for the loop invariant of selection_sort_1 to be proved.
|
||||
4. Finally, write the algorithm selection_sort_2, which does
|
||||
not use the function select. It will have a nested loop;
|
||||
write invariants for both loops and prove the correctness
|
||||
of the algorithm.
|
||||
*)
|
||||
|
||||
|
||||
module SelectionSort
|
||||
|
||||
use int.Int
|
||||
use ref.Ref
|
||||
use array.Array
|
||||
use array.IntArraySorted
|
||||
use array.ArrayPermut
|
||||
use array.ArrayEq
|
||||
|
||||
|
||||
|
||||
let swap (a: array int) (i: int) (j: int)
|
||||
requires { 0 <= i< length a && 0 <= j< length a }
|
||||
ensures { (old a)[i] = a[j] && (old a)[j] = a[i] }
|
||||
ensures { forall k:int. 0<=k<length a -> k<>i -> k<>j -> (old a)[i] = a[j]}
|
||||
ensures { permut_all (old a) a }
|
||||
= let v = a[i] in
|
||||
a[i] <- a[j];
|
||||
a[j] <- v
|
||||
|
||||
|
||||
|
||||
(* returns the index of a minimum of
|
||||
the segment of a between indexes i and length a -1.
|
||||
*)
|
||||
let select (a: array int) (i: int) : int
|
||||
requires { 0 <= i < length a}
|
||||
ensures { i <= result < length a }
|
||||
ensures { forall k:int. 0<=k<length a -> a[result] <= a[k]}
|
||||
= let ref min = i in
|
||||
for j = i + 1 to length a - 1 do
|
||||
invariant { i <= min < j }
|
||||
invariant { forall k:int. i <= k < j -> a[min] <= a[k] }
|
||||
if a[j] < a[min] then min <- j
|
||||
done;
|
||||
min
|
||||
|
||||
|
||||
|
||||
let selection_sort_1 (a: array int)
|
||||
ensures { sorted a }
|
||||
ensures { permut_all (old a) a }
|
||||
= for i = 0 to length a - 1 do
|
||||
invariant { ... }
|
||||
let min = select a i
|
||||
in if min <> i then swap a min i
|
||||
done
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
let selection_sort_2 (a: array int) =
|
||||
ensures { sorted a }
|
||||
ensures { permut_all (old a) a }
|
||||
...
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
```
|
Loading…
Reference in a new issue