-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmax_min.c
58 lines (57 loc) · 1.68 KB
/
max_min.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/*@ requires \valid(a+(0..size-1));
requires \valid(max);
requires \valid(min);
behavior zero_size:
assumes size == 0;
assigns \nothing;
ensures max == \old(max) && min == \old(min);
behavior one_size:
assumes size == 1;
assigns *max, *min;
ensures *max == a;
ensures *max == *min;
ensures **max == **min;
behavior size:
assumes size > 1;
assigns *max, *min;
ensures \exists integer i; 0 <= i < size && (a + i) == *max;
ensures \exists integer i; 0 <= i < size && (a + i) == *min;
ensures **max >= **min;
ensures \forall integer i; 0 <= i < size ==> **max >= a[i] >= **min;
complete behaviors;
disjoint behaviors;
*/
void max_min(int a[], unsigned size, int **max, int **min)
{
if (size > 0) {
unsigned i;
*max = &a[0];
*min = *max;
/*@ loop invariant 1 <= i <= size;
loop invariant \exists integer j; 0 <= j < i && (a+j) == *max;
loop invariant \exists integer j; 0 <= j < i && (a+j) == *min;
loop invariant **max >= **min;
loop invariant \forall integer j; 0 <= j < i ==> **max >= a[j] >= **min;
loop assigns *max, *min;
loop variant size - i;
*/
for(i = 1; i < size; ++i) {
if (**max < a[i]) {
*max = &a[i];
} else if (**min > a[i]) {
*min = &a[i];
}
}
}
}
#ifdef OUT_OF_TASK
#include <stdio.h>
int main(void)
{
int a[] = {3,5,3,1,5,11,7,8,9,10};
int *max, *min;
max_min(a, sizeof(a)/sizeof(a[0]), &max, &min);
printf("max: el: %ld val: %d; min: el: %ld val: %d\n", max - a, *max, min - a, *min);
return 0;
}
#endif