Maximum Subarray Problem
Below is the solution built during the lecture. You have to adapt it into a variant where *empty segments are not allowed*.
To do that, you have to
- add a precondition (with requires) to state that the array is
not empty;
- update the specification (the two ensures);
- update the code;
- update the loop invariants.
use int.Int use array.Array use array.ArraySum (* lo cl hi i +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ a | | | | | | | | | | | | | | | | | | | | | |?|?|?|?|?|?|?|?|?|?| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |<----- maxsum ------>| |<----- curmax ---->| *) let maximum_subarray (a: array int) : (s: int) ensures { forall l h. 0 <= l <= h <= length a -> sum a l h <= s } ensures { exists l h. 0 <= l <= h <= length a /\ sum a l h = s } = (* the maximum in a[0..i[ is a[lo..hi[ *) let ref maxsum = 0 in let ghost ref lo = 0 in let ghost ref hi = 0 in (* the maximum ending on i is a[cl..i[ *) let ref curmax = 0 in let ghost ref cl = 0 in for i = 0 to length a - 1 do invariant { forall l. 0 <= l <= i -> sum a l i <= curmax } invariant { 0 <= cl <= i /\ sum a cl i = curmax } invariant { forall l h. 0 <= l <= h <= i -> sum a l h <= maxsum } invariant { 0 <= lo <= hi <= i /\ sum a lo hi = maxsum } curmax <- curmax + a[i]; if curmax < 0 then ( curmax <- 0; cl <- i+1 ); if curmax > maxsum then ( maxsum <- curmax; lo <- cl; hi <- i+1 ) done; return maxsum
Generated by why3doc 1.8.2+git