@@ -85,7 +85,7 @@ module {:options "-functionSyntax:4"} OptimizedMergeSort {
8585 // This lemma works around this
8686 // by proving that the outcomes are always deterministic and the same.
8787 // It does this by proving that given a total ordering,
88- // there is one and only one way to sort a given sequence.
88+ // there is one and only one way to sort a given sequence.
8989 TotalOrderingImpliesSortingIsUnique (right[..], other, lessThanOrEq);
9090 }
9191 }
@@ -412,21 +412,36 @@ module {:options "-functionSyntax:4"} OptimizedMergeSort {
412412 label BEFORE_RETURN:
413413 assert left[.. lo] == old (left[.. lo]) && right[.. lo] == old (right[.. lo]);
414414 if resultPlacement. Left? && where == Right {
415- forall i | lo <= i < hi {
415+ for i := lo to hi
416+ modifies right
417+ invariant left[.. lo] == old (left[.. lo]) && right[.. lo] == old (right[.. lo])
418+ invariant left[hi.. ] == old (left[hi.. ]) && right[hi.. ] == old (right[hi.. ])
419+ invariant right[lo.. i] == left[lo.. i]
420+ {
416421 right[i] := left[i];
417422 }
418423
419- assert right[lo.. hi] == mergedResult;
424+ assert right[lo.. hi] == mergedResult by {
425+ assert mergedResult == left[lo.. hi];
426+ }
420427 assert left[.. ] == old @BEFORE_RETURN (left[..]);
421428 assert right[.. lo] == old (right[.. lo]);
422429
423430 resultPlacement := Right;
424431 }
425432 if resultPlacement. Right? && where == Left {
426- forall i | lo <= i < hi {
433+ for i := lo to hi
434+ modifies left
435+ invariant left[.. lo] == old (left[.. lo]) && right[.. lo] == old (right[.. lo])
436+ invariant left[hi.. ] == old (left[hi.. ]) && right[hi.. ] == old (right[hi.. ])
437+ invariant left[lo.. i] == right[lo.. i]
438+ {
427439 left[i] := right[i];
428440 }
429- assert left[lo.. hi] == mergedResult;
441+
442+ assert left[lo.. hi] == mergedResult by {
443+ assert mergedResult == right[lo.. hi];
444+ }
430445 assert right[.. ] == old @BEFORE_RETURN (right[..]);
431446 assert left[.. lo] == old (left[.. lo]);
432447
0 commit comments