Consider the following algorithm where target = 13 and array = [5,10,15,20,25] where N = length of array
lo = 1
hi = N
while lo < hi:
mid = (lo+hi)//2
if target >= array[mid]:
lo = mid
else:
hi = mid
if array[lo] == target:
return lo
return False
I know that the above algorithm doesn't terminate for the above case where array = [5,10,15,20,25] and target = 13. And so, we can conclude that the algorithm doesn't always terminate.
But say if I had array = [5,10,15,20,25] and target = 1, then the algorithm would terminate.
So, using inputs to determine whether an algorithm always terminates or not is not good because it is not a foolproof way of determining whether an algorithm always terminates or not.
And so my question is, is there a way I can prove that the above algorithm always terminates without using any inputs/cases?
Thank you for any suggestions and insights. Appreciate the help.
Loop termination proofs can be carried by means of a variant function, that can be proven to decrease and to have a lower bound. In the given case, consider the quantity
hi - lo.After a single iteration, the new value is one of
hi - mid = hi - (hi + lo)//2 = (hi - lo)\\2mid - lo = (hi + lo)//2 - lo = (hi - lo)//2(We used the notation
//for the by-default quotient and\\for by-excess.)We see that the variant function always decreases, except when
hi - lo = 1andlo = midis chosen.In general, the variant function can be drawn from the rationale of the algorithm, in which you "do something to get closer to the solution". Here, you reduce the interval of uncertainty. Common problems are off-by-one situations, as is the case here.