vault backup: 2023-11-20 13:06:22

This commit is contained in:
Alice 2023-11-20 13:06:22 +00:00
parent 36338fff98
commit 205f1eabdd

View file

@ -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
```