source: CIVL/examples/loop_invariants/foVeOOS/twoEqualElements/two_equal_elements-bad_assert.cvl

main
Last change on this file was ea777aa, checked in by Alex Wilton <awilton@…>, 3 years ago

Moved examples, include, build_default.properties, common.xml, and README out from dev.civl.com into the root of the repo.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@5704 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 3.0 KB
Line 
1/*
2COST Verification Competition. vladimir@cost-ic0701.org
3
4Challenge 3: Two equal elements
5
6Given: An integer array a of length n+2 with n>=2. It is known that at
7least two values stored in the array appear twice (i.e., there are at
8least two duplets).
9
10Implement and verify a program finding such two values.
11
12You may assume that the array contains values between 0 and n-1.
13*/
14#pragma CIVL ACSL
15#ifndef NULL
16#define NULL (void*)0
17#endif
18
19/* duplet(a) returns the indexes (i,j) of a duplet in a.
20 * moreover, if except is not null, the value of this duplet must
21 * be different from it.
22 */
23
24$input int N;
25$assume(N > 2);
26$input int a[N + 2];
27
28/* A duplet in array a is a pair of indexes (i,j) in the bounds of array
29 a such that a[i] = a[j] */
30
31/*@ predicate is_duplet(int * a, integer len, integer i, integer j) =
32 @ 0 <= i && i < j && j < len && a[i] == a[j];
33 @*/
34
35/* equality between an integer and a possibly null int* */
36#define eq_opt(x, o) (((x)==*(o))&&(o!=NULL))
37
38_Bool duplet(int len, int *except, int *pi, int *pj) {
39 _Bool found = 0;
40
41 /*@ loop invariant 0 <= i && i <= len - 1;
42 @ loop invariant \forall int k, l;
43 @ 0 <= k && k < i-1 &&
44 @ k < l && l < len ==>
45 @ (!eq_opt(a[k], except) ==> !is_duplet(a, len, k, l));
46 @ loop invariant !found ==> (\forall int l;
47 @ 0 < l && i <= l && l < len ==>
48 @ (!eq_opt(a[i-1], except) ==> !is_duplet(a, len, i-1, l))
49 @ );
50 @ loop invariant found ==> (is_duplet(a, len, *pi, *pj) && *pi == i-1 && *pj > *pi && *pj < len &&
51 @ !eq_opt(a[*pi], except)
52 @ );
53 @ loop invariant !found ==> *pi == 0;
54 @ loop invariant i == 0 ==> !found;
55 @ loop assigns *pi, *pj, found, i;
56 @*/
57 for(int i=0; i <= len - 2 && !found; i++) {
58 int v = a[i];
59
60 if (except == NULL || *except != v) {
61 /*@ loop invariant i + 1 <= j && j <= len;
62 @ loop invariant \forall int l; i < l && l < j - 1 ==> !is_duplet(a, len, i, l);
63 @ loop invariant !found ==> !is_duplet(a, len, i, j - 1);
64 @ loop invariant !found ==> *pi == 0;
65 @ loop invariant found ==> (is_duplet(a, len, i, j - 1) && (*pi == i && *pj == j - 1));
66 @ loop assigns *pi, *pj, found, j;
67 @*/
68 for (int j = i + 1; j < len && !found; j++) {
69 if (a[j] == v) {
70 *pi = i;
71 *pj = j;
72 found = 1;
73 }
74 }
75 }
76 }
77 $assert(!found => ($forall (int i, j | 0 <= i && i < j && j < len)
78 !eq_opt(a[i], except) => !is_duplet(a, len, i, j))
79 );
80 $assert(found => ($forall (int i, j | 0 <= i && i < *pi && *pi < j && j < len)
81 !eq_opt(a[i], except) => !is_duplet(a, len, i, j))
82 );
83 $assert(is_duplet(a, len, *pi, *pj));
84 return found;
85}
86
87int pi, pj, pk, pl;
88
89int main() {
90 _Bool found_one = duplet(N, NULL, &pi, &pj);
91 _Bool found_two = duplet(N, &a[pi], &pk, &pl);
92
93 $assert(found_one =>
94 (is_duplet(a, N, pi, pj) && is_duplet(a, N, pk, pl) && a[pi] != a[pk]));
95}
96
Note: See TracBrowser for help on using the repository browser.