0

I'm programming in Eiffel for a school Lab, and one of the tasks is to find a bug in a given algorithm. The algorithm returns the first repeated character.

The algorithm works as follows:

word: STRING
first_repeated_character: CHARACTER
local
    i: INTEGER
    ch: CHARACTER
    stop: BOOLEAN
do
    from 
        i := 1
        Result := '%U'
    until
        i > word.count or stop
    loop
        ch := word[i]
        if ch = word[i + 1] then
            Result := ch
            stop := true
        end
        i := i + 1
    end
end

I spent the last couple of hours trying to find the bug in this, but it always passes all tests.

Any help would be much appreciated. Thanks.

M. Averbach
  • 121
  • 10

2 Answers2

0

I think the bug is that the code forgets to check if i + 1 is a valid index for word.

What about this code?

first_repeated_character (word: STRING): CHARACTER
    -- First repeated character in `word'.
    -- If none, returns the null character '%U'.
  local
    i, n: INTEGER
    ch: CHARACTER
  do
    from 
        i := 1
        n := word.count
    until
        Result /= '%U' or i > n
    loop
        ch := word [i]
        if i + 1 <= n and then ch = word [i + 1] then
            Result := ch
        end
        i := i + 1
    end
  end
Alexander Kogtenkov
  • 5,770
  • 1
  • 27
  • 35
Jocelyn
  • 693
  • 5
  • 8
  • Thank you very much. I tried testing with the null character before, and that failed. Now it works. Thanks again! – M. Averbach Jan 07 '16 at 21:38
  • Note that Eiffel has a great techno "Design By Contract", and when you have a feature call, you should read the "precondition" of that feature. This will often give you a clue of potential issues, and then what the "caller" should check before calling the feature. In addition, as Alexander suggested, make sure the assertions (contracts) are enabled for STRING. This way, at execution time, you will see the violated assertions, and find issue very early. – Jocelyn Jan 11 '16 at 08:34
0

Whilst trying to find a bug by searching for tests is a legitimate approach (and Eiffel Studio includes AutoTest, which does this systematically for you), it's a brute-force approach.

Here is a more intelligent algorithm which will find the bug in this case:

Examine every feature call in the routine under consideration. List all its preconditions (plus class invariants). Consider if there are any conditions for this routine that will fail to meet any of these preconditions or invariants. If you find such a set of conditions, then you have probably found a bug (if the preconditions are overly strict, then the routine might work anyway - but in that case you have found another bug). You can then write a test case for these particular conditions to demonstrate the bug (and validate your reasoning).

Using this algorithm, you will locate the bug in this case (just like Jocelyn did).