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