source: CIVL/examples/loop_invariants/verifyThisUB/longestRepeatedSubstring/lrs-bad_invariant.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: 5.9 KB
RevLine 
[2fa0abd]1/*
2 * Function 'sort', 'lcp2', 'compare' are all abstracted.
3 *
4 * Command: civl verify -collectSymbolicConstants lrs_deductive.cvl
5 */
6#include <stdlib.h>
7#include <string.h>
8#include <civlc.cvh>
9#include <assert.h>
10
11#pragma CIVL ACSL
12
13$input int N;
14$assume(N > 0);
15$input int X1[N];
16
17/* string 'x' is not greater than string 'y' with the specific length */
18/*@
[d70594d]19 @ predicate ngt_len(int * X1, int N, int x, int y, int l) =
[2fa0abd]20 @ 0 <= l && l <= N && x + l <= N && y + l <= N
21 @ && (x + l == N || (y + l < N ==> X1[y+l] > X1[x+l]))
22 @ && (\forall int k1; 0 <= k1 && k1 < l ==> X1[(x)+k1] == X1[(y)+k1]);
23 */
24
25/* string 'x' is NOT greater than string 'y' */
26/*@
[d70594d]27 @ predicate ngt(int X1, int N, int x, int y) =
28 @ (\exists int l; ngt_len(X1, N, x, y, l) &&
29 @ !(\exists int o; ngt_len(X1, N, x, y, o) && o != l)
[2fa0abd]30 @ );
31 @*/
32
33int lcp(int *arr, int n, int x, int y) {
34 int l = 0;
35
36 /*@ loop invariant 0 <= l && l <= n;
37 @ loop invariant 0 <= x + l && x + l <= n;
38 @ loop invariant 0 <= y + l && y + l <= n;
39 @ loop invariant \forall int i; 0 <= i && i < l ==> arr[x+i]==arr[y+i];
40 @ loop assigns l;
41 @*/
42 while (x+l<n && y+l<n && arr[x+l]==arr[y+l]) {
43 l++;
44 }
45 return l;
46}
47
48/* returns:
49 * 0 if x and y points to the same suffix;
50 * poistive value if x "is greater than" y;
51 * negative or zero value if x "is NO greater than" y;
52 */
53int compare(int *a, int n, int x, int y) {
54 if (x == y) return 0;
55
56 int c = $choose_int(2);
57 int ret;
58
59 $havoc(&ret);
60 if (c == 0) {
[d70594d]61 $assume(ngt(a, n, x, y) && ret <= 0);
[2fa0abd]62 return ret;
63 } else {
[d70594d]64 $assume(ngt(a, n, y, x) && ret > 0);
[2fa0abd]65 return ret;
66 }
67}
68
69void sort(int *a, int n, int *data) {
70 /*@ loop invariant 1 <= i && i <= n;
[d70594d]71 @ loop invariant \forall int k; 1 <= k && k < i ==> ngt(a, n, data[k-1],data[k]);
[2fa0abd]72 @ loop invariant \forall int k; 0 <= k && k < n ==> 0 <= data[k] && data[k] < n; // data elements are valid
73 @ loop invariant \forall int t, k; 0 <= k && k < n && 0 <= t && t < n && k != t ==>
74 @ data[k] != data[t];
75 @ loop assigns i, data[0 .. n-1];
76 @*/
77 for(int i = 1; i < n; i++) {
78 int comp = compare(a, n, data[i - 1], data[i]);
79
80 /*@ loop invariant 0 <= j && j <= i;
81 @ loop invariant \forall int k; 0 <= k && k < n ==> 0 <= data[k] && data[k] < n; // data elements are valid
82 @ loop invariant \forall int t, k; 0 <= k && k < n && 0 <= t && t < n && k != t ==>
83 @ data[k] != data[t];
[d70594d]84 @ loop invariant \forall int k; j < k && k <= i ==> ngt(a, n, data[k-1],data[k]);
85 @ loop invariant \forall int k; 0 < k && k < j ==> ngt(a, n, data[k-1],data[k]);
86 @ loop invariant comp <= 0 ==> (\forall int k; 0 < k && k <= j ==> ngt(a, n, data[k-1],data[k]));
87 @ loop invariant (comp > 0 && 0 < j) ==> ngt(a, n, data[j], data[j-1]);
88 @ loop invariant (comp > 0 && 0 < j && j < i) ==> ngt(a, n, data[j-1], data[j+1]) ;
[2fa0abd]89 @ loop assigns j, comp, data[0 .. n-1];
90 @*/
91 for(int j = i; j > 0 && comp > 0;) {
92 // swap:
93 int tmp = data[j];
94
95 data[j] = data[j-1];
96 data[j-1] = tmp;
97 j--;
98 if (j > 0)
99 comp = compare(a, n, data[j - 1], data[j]);
100 }
101 }
[d70594d]102 $assert($forall (int i : 1 .. N-1) ngt(a, n, data[i - 1], data[i]));
[2fa0abd]103}
104
105/* An abstraction of the 'sort' function */
106void sort2(int *a, int n, int *data) {
107 int new_data[n];
108
109 memcpy(data, new_data, sizeof(int) * n);
[d70594d]110 $assume($forall (int i : 1 .. N-1) ngt(a, n, data[i - 1], data[i]));
[2fa0abd]111 $assume($forall (int i : 0 .. N-1) 0 <= data[i] && data[i] < n);
112 $assume($forall (int i : 0 .. N-1)
113 ($forall (int j | 0 <= j && j < N && j != i) data[i] != data[j])
114 );
115}
116
117int lcp2(int *a, int n, int index, int* suffixes) {
118 //return lcp(a,n,suffixes[index], suffixes[index-1]);
119 int ret;
120
121 $havoc(&ret);
[d70594d]122 $assume(ngt_len(a, n, suffixes[index-1], suffixes[index], ret));
[2fa0abd]123 return ret;
124}
125
126/**
127result[0]: index
128result[1]: length
129*/
130void lrs(int* a, int n, int *result) {
131 int suffixes[n];
132
133 /*@ loop invariant 0 <= i && i <= n;
134 @ loop invariant \forall int t; 0 <= t && t < i ==> suffixes[t] == t;
135 @ loop assigns suffixes[0 .. n-1], i;
136 @*/
137 for(int i=0; i<n; i++) {
138 suffixes[i] = i;
139 }
140
141 sort2(a, n, suffixes);
142 result[0] = suffixes[0];
143 result[1] = 0;
144 /*@ loop invariant 1 <= i && i <= n;
145 @ loop invariant 0 <= result[1] && result[1] <= n && (result[0] + result[1]) <= n &&
146 @ 0 <= result[0] && result[0] < n;
147 @ loop invariant \forall int k; 1 <= k && k < i ==> (
[d70594d]148 @ \exists int l; ngt_len(a, n, suffixes[k-1], suffixes[k], l) &&
149 @ !(\exists int l2; ngt_len(a, n, suffixes[k-1], suffixes[k], l2) && l2 != l) &&
[2fa0abd]150 @ l <= result[1]
151 @ );
152 @ loop invariant \exists int k; 0 <= k && k < i && result[0] == suffixes[k] &&
[d70594d]153 @ (k > 0 ==> ngt_len(a, n, suffixes[k-1], result[0], result[1]));
154 @ loop invariant \exists int k; 0 <= k && k < n && ngt_len(a, n, suffixes[k], result[0], result[1]);
[2fa0abd]155 @ loop assigns i, result[0 .. 1];
156 @*/
157 for(int i=1; i<n; i++) {
158 int len = lcp2(a, n, i,suffixes);
159
160 if(len > result[1]) {
161 result[0] = suffixes[i];
162 result[1] = len;
163 }
164 }
165 $assert($exists (int i : 0 .. n-1) suffixes[i] == result[0]);
[d70594d]166 $assert((result[0] != suffixes[0]) => ($exists (int i : 0 .. n-1) ngt_len(a, n, suffixes[i], result[0], result[1])));
167 $assert($forall (int i : 1 .. n-1) ngt(a, n, suffixes[i-1], suffixes[i]));
[2fa0abd]168 $assert($forall (int i : 1 .. n-1)
169 ($exists (int l)
[d70594d]170 ngt_len(a, n, suffixes[i-1], suffixes[i], l) &&
171 !($exists (int l2) ngt_len(a, n, suffixes[i-1], suffixes[i], l2) && l2 != l) &&
[2fa0abd]172 l <= result[1]
173 ));
174}
175
176int main() {
177 int result[2] = {0, 0};
178 lrs(X1, N, result);
179}
180
Note: See TracBrowser for help on using the repository browser.