source: CIVL/examples/loop_invariants/verifyThisUB/pairInsertSort/pairInsertSort.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: 6.2 KB
Line 
1/* VerifyThis 2017: CIVL Solution to Challenge 1 : Pair Insertion Sort
2 * Stephen Siegel
3 *
4 * Modification by Ziqing Luo:
5 * 1. Got rid of the upper bound over n.
6 *
7 * 2. Manual side-effect removing. The loop invariants transformer
8 * relies on the fact of side-effect free in loop conditions. It
9 * copies and moves the loop conditions hence side-effects can make
10 * it wrong. Applying side-effect remover introduces jump statements
11 * which are not handled well by the loop invariants transformer.
12 */
13#include <stdio.h>
14#include <string.h>
15#pragma CIVL ACSL
16
17$input int n; // size of array
18$assume(1<=n);
19$input int A[n];
20$input int LEFT;
21$input int RIGHT;
22$assume(1<=LEFT && LEFT < RIGHT && RIGHT<n-1);
23
24/* 'p' is a permutation of 'q', where both 'p' and 'q' are arrays of
25 * length 'len': */
26/*@ predicate permut(int * p, int * q, int l, int u);
27 @
28 @ predicate slice_eq(int * a, int * b, int l, int u) =
29 @ \forall int i; l <= i && i < u ==> a[i] == b[i];
30 @*/
31
32int main() {
33 // this is the "sentinel" assumption...
34 $assume($forall (int j : LEFT .. RIGHT) A[j] >= A[LEFT-1]);
35
36 int a[n], pre_a[n];
37
38 memcpy(a, A, n * sizeof(int));
39 printf("n=%d\n", n);
40
41 int left = LEFT, right = RIGHT;
42 int k = left;
43
44 memcpy(pre_a, a, sizeof(int) * n);
45 left++;
46 /*@ loop invariant 2 <= left && left <= right + 2;
47 @ loop invariant k == left - 1;
48 @ loop invariant LEFT <= k && k <= RIGHT+1 && k == left - 1;
49 @ loop invariant \forall int t; LEFT <= t && t < k ==> a[t - 1] <= a[t];
50 @ loop invariant \forall int t; LEFT <= t && t <= RIGHT ==> a[LEFT-1] <= a[t];
51 @ loop invariant permut(pre_a, a, LEFT, k);
52 @ loop invariant slice_eq(pre_a, a, k, RIGHT+1);
53 @ loop assigns k, left, a[LEFT .. n-1];
54 @*/
55 for (; left <= right; k = left++) {
56 int a1 = a[k], a2 = a[left];
57
58 if (a1 < a2) {
59 a2 = a1; a1 = a[left];
60 }
61 k--;
62
63 // ghost variable:
64 int ghost_a[n];
65
66 // ghost variable update
67 memcpy(ghost_a, a, n * sizeof(int));
68 // end of ghost variable update
69
70 /*@ loop invariant LEFT - 1 <= k && k < left - 1;
71 @ loop invariant a1 < a[k] ==> k >= LEFT;
72 @ loop invariant \forall int t; LEFT <= t && t <= k ==> a[t - 1] <= a[t];
73 @ loop invariant \forall int t; k + 3 < t && t <= left ==> a[t - 1] <= a[t];
74 @ loop invariant \forall int t; LEFT <= t && t <= RIGHT ==> a[LEFT-1] <= a[t];
75 @ loop invariant k + 3 <= left ==> a[k + 3] >= a1 && a[k+3] >= a[k];
76 @ loop invariant slice_eq(pre_a, a, left+1, RIGHT+1);
77 @ loop invariant permut(pre_a, ghost_a, LEFT, left+1);
78 @ loop assigns k, a[LEFT .. n-1], ghost_a[0 .. n-1];
79 @*/
80 while (a1 < a[k]) {
81 a[k + 2] = a[k];
82 k--;
83 // ghost variable update
84 memcpy(ghost_a, a, n * sizeof(int));
85 ghost_a[k+2] = a1;
86 ghost_a[k+1] = a2;
87 // end of ghost variable update
88 }
89 a[++k + 1] = a1;
90 k--;
91
92 // ghost variable update
93 memcpy(ghost_a, a, n * sizeof(int));
94 ghost_a[k+1] = a2;
95 // end of ghost variable update
96
97 /*@ loop invariant LEFT - 1 <= k && k < left - 1;
98 @ loop invariant a2 < a[k] ==> k >= LEFT;
99 @ loop invariant \forall int t; LEFT <= t && t <= k ==> a[t - 1] <= a[t];
100 @ loop invariant \forall int t; k + 2 < t && t <= left ==> a[t - 1] <= a[t];
101 @ loop invariant \forall int t; LEFT <= t && t <= RIGHT ==> a[LEFT-1] <= a[t];
102 @ loop invariant k + 2 <= left ==> a[k + 2] >= a2 && a[k + 2] >= a[k];
103 @ loop invariant slice_eq(pre_a, a, left+1, RIGHT + 1);
104 @ loop invariant permut(pre_a, ghost_a, LEFT, left+1);
105 @ loop assigns k, a[LEFT .. n-1], ghost_a[0 .. n-1];
106 @*/
107 while (a2 < a[k]) {
108 printf("k=%d, LEFT=%d\n", k, LEFT);
109 a[k + 1] = a[k];
110 k--;
111 // ghost variable update
112 memcpy(ghost_a, a, n * sizeof(int));
113 ghost_a[k+1] = a2;
114 // end of ghost variable update
115 }
116 a[k + 1] = a2;
117 left++;
118 }
119
120 $assert( $forall (int i : LEFT .. RIGHT-2) a[i] <= a[i+1] );
121
122 int last = a[right--];
123
124 /*@ loop invariant LEFT-1 <= right && right <= RIGHT-1;
125 @ loop invariant right < RIGHT-1 ==>
126 @ (\forall int i; LEFT <= i && i <= RIGHT ==>
127 @ a[i-1] <= a[i]);
128 @ loop invariant right == RIGHT-1 ==>
129 @ (\forall int i; LEFT <= i && i <= RIGHT-1 ==>
130 @ a[i-1] <= a[i]);
131 @ loop invariant right < RIGHT-1 ==> last < a[right+1];
132 @ loop assigns right, a[LEFT .. RIGHT];
133 @*/
134 while (last < a[right]) {
135 a[right + 1] = a[right];
136 right--;
137 }
138 a[right + 1] = last;
139 $assert( $forall (int i : LEFT .. RIGHT-1) a[i] <= a[i+1] );
140}
141/*
142 CIVL v1.15.1+ of 2018-04-10 -- http://vsl.cis.udel.edu/civl
143 === Command ===
144 civl verify -loop -enablePrintf=false challenge1_ub.cvl
145
146 === Stats ===
147 time (s) : 61.05
148 memory (bytes) : 1091567616
149 max process count : 1
150 states : 1066
151 states saved : 908
152 state matches : 27
153 transitions : 1092
154 trace steps : 660
155 valid calls : 484
156 provers : cvc4, z3, cvc3
157 prover calls : 425
158
159 === Result ===
160 The standard properties hold for all executions.
161*/
162
163/*
164VerifyThis2017 siegel$ civl-1.11 verify -inputN=6 challenge1d.cvl
165CIVL v1.11 of 2017-07-07 -- http://vsl.cis.udel.edu/civl
166n=6
167k=X_LEFT+1, LEFT=X_LEFT
168k=X_LEFT, LEFT=X_LEFT
169k=X_LEFT, LEFT=X_LEFT
170k=X_LEFT+1, LEFT=X_LEFT
171k=X_LEFT, LEFT=X_LEFT
172k=X_LEFT, LEFT=X_LEFT
173k=X_LEFT+1, LEFT=X_LEFT
174k=X_LEFT, LEFT=X_LEFT
17517s: mem=281Mb trans=452 traceSteps=241 explored=452 saved=304 prove=540
176k=X_LEFT, LEFT=X_LEFT
177k=X_LEFT+1, LEFT=X_LEFT
178k=X_LEFT, LEFT=X_LEFT
179k=X_LEFT, LEFT=X_LEFT
180n=6
181n=5
182n=6
183n=5
18432s: mem=382Mb trans=991 traceSteps=533 explored=991 saved=676 prove=1153
185n=4
186
187=== Command ===
188civl verify -inputN=6 challenge1d.cvl
189
190=== Stats ===
191 time (s) : 33.3
192 memory (bytes) : 401080320
193 max process count : 1
194 states : 1072
195 states saved : 729
196 state matches : 0
197 transitions : 1071
198 trace steps : 574
199 valid calls : 1950
200 provers : cvc4, z3
201 prover calls : 1237
202
203=== Result ===
204The standard properties hold for all executions.
205 */
206
Note: See TracBrowser for help on using the repository browser.