@@ -148,11 +148,89 @@ module SortCanon {
148
148
}
149
149
}
150
150
151
- predicate method Below (x: seq <uint8 >, y: seq <uint8 >) {
151
+ predicate Below (x: seq <uint8 >, y: seq <uint8 >) {
152
152
|x| != 0 ==>
153
153
&& |y| != 0
154
154
&& x[0] <= y[0]
155
155
&& (x[0] == y[0] ==> Below (x[1..], y[1..]))
156
+ } by method {
157
+
158
+ // The slice x[1..], y[1..] are un-optimized operations in Dafny.
159
+ // This means that their usage will result in a lot of data copying.
160
+ // Additional, it is very likely that these size of these sequences
161
+ // will be less than uint64.
162
+ // So writing an optimized version that only works on bounded types
163
+ // should further optimized this hot code.
164
+
165
+ if HasUint64Len (x) && HasUint64Len (y) {
166
+ return BoundedBelow (x,y);
167
+ }
168
+
169
+ if |x| == 0 {
170
+ assert Below (x, y);
171
+ return true ;
172
+ }
173
+
174
+ if |y| == 0 {
175
+ assert ! Below (x, y);
176
+ return false ;
177
+ }
178
+
179
+ for i := 0 to |x|
180
+ invariant i <= |y|
181
+ // The function on the initial arguments
182
+ // is equal to function applied to the intermediate arguments.
183
+ invariant Below (x, y) == Below (x[i..], y[i..])
184
+ {
185
+ if |y| <= i {
186
+ return false ;
187
+ } else if y[i] < x[i] {
188
+ return false ;
189
+ } else if x[i] < y[i] {
190
+ return true ;
191
+ } else {
192
+ assert x[i] == y[i];
193
+ }
194
+ }
195
+
196
+ return true ;
197
+ }
198
+
199
+ predicate BoundedBelow (x: seq64 <uint8 >, y: seq64 <uint8 >)
200
+ {
201
+ Below (x,y)
202
+ } by method {
203
+ var xLength := |x| as uint64;
204
+ var yLength := |y| as uint64;
205
+
206
+ if xLength == 0 {
207
+ assert BoundedBelow (x, y);
208
+ return true ;
209
+ }
210
+
211
+ if yLength == 0 {
212
+ assert ! BoundedBelow (x, y);
213
+ return false ;
214
+ }
215
+
216
+ for i := 0 to xLength
217
+ invariant i <= yLength
218
+ // The function on the initial arguments
219
+ // is equal to function applied to the intermediate arguments.
220
+ invariant BoundedBelow (x, y) == BoundedBelow (x[i..], y[i..])
221
+ {
222
+ if yLength <= i {
223
+ return false ;
224
+ } else if y[i] < x[i] {
225
+ return false ;
226
+ } else if x[i] < y[i] {
227
+ return true ;
228
+ } else {
229
+ assert x[i] == y[i];
230
+ }
231
+ }
232
+
233
+ return true ;
156
234
}
157
235
158
236
lemma BelowIsTotal ()
0 commit comments