@@ -167,7 +167,12 @@ module {:options "-functionSyntax:4"} OptimizedMergeSort {
167167 label BEFORE_RETURN:
168168 assert left[.. lo] == old (left[.. lo]) && right[.. lo] == old (right[.. lo]);
169169 if resultPlacement. Left? && where == Right {
170- forall i | lo <= i < hi {
170+ for i := lo to hi
171+ modifies right
172+ invariant left[.. lo] == old (left[.. lo]) && right[.. lo] == old (right[.. lo])
173+ invariant left[hi.. ] == old (left[hi.. ]) && right[hi.. ] == old (right[hi.. ])
174+ invariant right[lo.. i] == left[lo.. i]
175+ {
171176 right[i] := left[i];
172177 }
173178
@@ -178,7 +183,12 @@ module {:options "-functionSyntax:4"} OptimizedMergeSort {
178183 resultPlacement := Right;
179184 }
180185 if resultPlacement. Right? && where == Left {
181- forall i | lo <= i < hi {
186+ for i := lo to hi
187+ modifies left
188+ invariant left[.. lo] == old (left[.. lo]) && right[.. lo] == old (right[.. lo])
189+ invariant left[hi.. ] == old (left[hi.. ]) && right[hi.. ] == old (right[hi.. ])
190+ invariant left[lo.. i] == right[lo.. i]
191+ {
182192 left[i] := right[i];
183193 }
184194
@@ -412,6 +422,14 @@ module {:options "-functionSyntax:4"} OptimizedMergeSort {
412422 label BEFORE_RETURN:
413423 assert left[.. lo] == old (left[.. lo]) && right[.. lo] == old (right[.. lo]);
414424 if resultPlacement. Left? && where == Right {
425+ // A forall comprehension might seem like a nice fit here,
426+ // however this does not good for two reasons.
427+ // First, Dafny currently creates a range fur the full bounds of the bounded number
428+ // see: https://github.com/dafny-lang/dafny/issues/5897
429+ // Second this would create two loops.
430+ // First loop would create the `lo to hi` range of numbers.
431+ // The second loop would then loop over these elements.
432+ // A single loop with
415433 for i := lo to hi
416434 modifies right
417435 invariant left[.. lo] == old (left[.. lo]) && right[.. lo] == old (right[.. lo])
0 commit comments