source: CIVL/examples/loop_invariants/foVeOOS/twoEqualElements/two_equal_elements.c

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: 2.4 KB
RevLine 
[2fa0abd]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
15
16#define NULL (void*)0
17
18/* equality between an integer and a possibly null int* */
19/*@ predicate eq_opt{L}(integer x, int *o) =
20 @ o != \null && x == *o ;
21 @*/
22
23/* A duplet in array a is a pair of indexes (i,j) in the bounds of array
24 a such that a[i] = a[j] */
25/*@ predicate is_duplet{L}(int *a, integer len, integer i, integer j) =
26 @ 0 <= i < j < len && a[i] == a[j];
27 @*/
28
29/* duplet(a) returns the indexes (i,j) of a duplet in a.
30 * moreover, if except is not null, the value of this duplet must
31 * be different from it.
32 */
33/*@ requires 2 <= len &&
34 @ \valid_range(a,0,len-1) && \valid(pi) && \valid(pj) &&
35 @ ( except == \null || \valid(except)) &&
36 @ \exists integer i,j;
37 @ is_duplet(a,len,i,j) && ! eq_opt(a[i],except) ;
38 @ assigns *pi,*pj;
39 @ ensures
40 @ is_duplet(a,len,*pi,*pj) &&
41 @ ! eq_opt(a[*pi],except);
42 @*/
43void duplet(int *a, int len, int *except, int *pi, int *pj) {
44 /*@ loop invariant 0 <= i <= len-1 &&
45 @ \forall integer k,l; 0 <= k < i && k < l < len ==>
46 @ ! eq_opt(a[k],except) ==> ! is_duplet(a,len,k,l);
47 @ loop variant len - i;
48 @*/
49 for(int i=0; i <= len - 2; i++) {
50 int v = a[i];
51 if (except == NULL || *except != v) {
52 /*@ loop invariant i+1 <= j <= len &&
53 @ \forall integer l; i < l < j ==> ! is_duplet(a,len,i,l);
54 @ loop variant len - j;
55 @*/
56 for (int j=i+1; j < len; j++) {
57 if (a[j] == v) {
58 *pi = i; *pj = j; return;
59 }
60 }
61 }
62 }
63 // assert \forall integer i j; ! is_duplet(a,i,j);
64 //@ assert \false;
65}
66
67/*@ requires 4 <= len &&
68 @ \valid_range(a,0,len-1) && \valid(pi) && \valid(pj) &&
69 @ \valid(pk) && \valid(pl) &&
70 @ \exists integer i,j,k,l;
71 @ is_duplet(a,len,i,j) && is_duplet(a,len,k,l) && a[i] != a[k];
72 @ assigns *pi,*pj,*pk,*pl;
73 @ ensures is_duplet(a,len,*pi,*pj) &&
74 @ is_duplet(a,len,*pk,*pl) &&
75 @ a[*pi] != a[*pk];
76 @*/
77void duplets(int a[], int len, int *pi, int *pj, int *pk, int *pl) {
78 duplet(a,len,NULL,pi,pj);
79 duplet(a,len,&a[*pi],pk,pl);
80}
81
Note: See TracBrowser for help on using the repository browser.