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
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