Given the following algorithm for linear-search (referring to index 1 as the index of the first element in an array of elements):
found_idx = nil
for i = 1 to A.length
if A[i] == value
found_idx = i
return found_idx
end-if
end-for
found_idx
I was wondering if this loop-invariant is correct: " At the start of each iteration of the for-loop, found_idx is the index in the array ending at i-1 at which value exists if that value exists"
Here is my proposed informal explanation of this loop-invariant according to the format in CLRS:
i
, A[i]
is checked and then i
is incremented, meaning that all elements up to i-1
have been checked prior to each new iteration.i > A.length
, meaning that all elements up to and including A.length
have been checked.My main point of concern is that it feels incorrect to refer to the index ending at i-1
because the loop starts with i
at 1, which is the first element of the array. In other words, it feels fallacious to refer to a subarray of an array, wherein the subarray ends at an index less than the starting index of the array for which the subarray is supposed to be a subarray in the first place. This seems to imply that the loop invariant given above is actually false before the very first iteration of the loop.
Thoughts?
Since the loop terminates early, its invariant is as follows:
found_idx = nil && ∀k<i : A[k] ≠ value
The part after &&
means "All of A
's elements at indexes below i
are not equal to value
".
found_idx
at nil
, or terminates the loop earlyi
reaches A.length
Loop's post-condition is found_idx = nil && ∀k<A.length : A[k] ≠ value
, which simply means that value
is not among A
's elements. It also means that you can eliminate found_idx
by rewriting your loop as follows:
for i = 1 to A.length
if A[i] == value
return i
end-if
end-for
return nil