0

I'm trying to proof the following LinearSearch using the Hoare-Logic, but I get a contradiction proofing (1) => (2). I belive that my invariant should be different.

Currently I'm using {s ≥ 0 & s < i → f[s] ≠ value} as invariant. That means all elements from 0 to i-1 have already been compared with the searched value, therefor all elements from f[0] to f[i-1] are unequal to the searched value.

I started applying the rules from the bottom of the algorithm to the top.

The contradiction arises when I try to proof the (1) implicieses (2). Because it applies in (1) that {f[i] = value} and for all s < i it applies that f[s] ≠ value. That is correct so far.

But in (2) it applies for all s <i+1 that f[s] ≠ value and consequently f[i] ≠ value.

The caontradiction is: to proof that

(1) → (2)

I have to proof that

f[i] = value → f[i] ≠ value

and that is not true.

Thats why I think I need to change my invariant. But I don't no how?

public boolean LinearSearch (int value, int[] f) {
//Precondition = {f.length() > 0}

int i = 0;

boolean found = false;

//{s ≥ 0 & s < i → f[s] ≠ value}
while (i < f.length()-1 || !found) {
//{(s ≥ 0 & s < i → f[s] ≠ value) & (i < f.length()-1 || found = false)}

    if (value == f[i]) {
(1) //{(s ≥ 0 & s < i → f[s] ≠ value) & (i < f.length()-1 || found = false) & (value = f[i])} 

(2) //{(s ≥ 0 & s < i+1 → f[s] ≠ value)}
    ↕
    //{(s ≥ 0 & s < i+1 → f[s] ≠ value) & true = true}
    found = true;

    //{(s ≥ 0 & s < i+1 → f[s] ≠ value) & found = found} 
    }

    //{(s ≥ 0 & s < i+1 → f[s] ≠ value) & found = found} 
    ↕
    //{s ≥ 0 & s < i+1 → f[s] ≠ value}
    i = i + 1;

//{s ≥ 0 & s < i → f[s] ≠ value}
}//end while
//{(s ≥ 0 & s < i → f[s] ≠ value) & !(i < f.length()-1 || found = false)}
↓
//Postcondition = {i = f.length()-1 | f[i] = value}
return found;
}//end LinearSearch
aioobe
  • 413,195
  • 112
  • 811
  • 826
Schrello
  • 27
  • 5
  • Your invariant is correct if you return early from the loop, but not if you use a boolean flag instead. The correct invariant for this version of linear search should be something like `((s >= 0 and s < i) implies f[s] != value) or (found and f[i-1] == value)`. – kaya3 Dec 22 '20 at 06:42

1 Answers1

0

Thank you @aioobe for your answer.

I tried

{s ≥ 0 & s < i-1 → f[s] ≠ value} 

and got the following proof. I think it works. If you see mistakes please tell me. Maybe it helps anyone else who needs to use the Hoare-Logic.

public boolean LinearSearch (int value, int[] f) {
//Precondition = {f.length() > 0}
↓
//{true & true}
↕
//{true & false = false}
↕
//{false → f[s] ≠ value & false = false}
↕
//{s ≥ 0 & s < 0-1 → f[s] ≠ value & false = false}
int i = 0;
//{s ≥ 0 & s < i-1 → f[s] ≠ value & false = false}
boolean found = false;
//{s ≥ 0 & s < i-1 → f[s] ≠ value & found = found}
↕
//{s ≥ 0 & s < i-1 → f[s] ≠ value}
while (i < f.length() & !found) {
//{(s ≥ 0 & s < i-1 → f[s] ≠ value) & (i < f.length() & found = false)}

    if (value == f[i]) {
    //{(s ≥ 0 & s < i-1 → f[s] ≠ value) & (i < f.length() & found = false) & (value = f[i])} 
        ↓
        //{(s ≥ 0 & s < i → f[s] ≠ value)}
        ↕
        //{(s ≥ 0 & s < i-1+1 → f[s] ≠ value) & true = true}
        found = true;

        //{(s ≥ 0 & s < i-1+1 → f[s] ≠ value) & found = found} 
        }

    //{(s ≥ 0 & s < i-1+1 → f[s] ≠ value) & found = found} 
    ↕
    //{s ≥ 0 & s < i-1+1 → f[s] ≠ value}
    i = i + 1;

    //{s ≥ 0 & s < i-1 → f[s] ≠ value}
    }//end while
//{(s ≥ 0 & s < i-1 → f[s] ≠ value) & !(i < f.length() & found = false)}
↓
//Postcondition = {i = f.length() | found = true}
return found;
}//end LinearSearch
Schrello
  • 27
  • 5