Hi everyone,
I just tried proving some property using gobra's hypermode, and I'm pretty sure I found a soundness bug. The following code verifies successfully when using gobra at version bc3c90375d672dbc796edb7011b70bc9098eeb21.
// @ requires acc(arr)
// @ ensures !contains && low(t) ==> low(contains)
func Includes(t int, arr []int) (contains bool) {
contains = false
// @ invariant acc(arr)
// @ invariant 0 <= idx && idx <= len(arr)
// @ invariant !contains && low(t) ==> low(contains)
for idx := 0; idx < len(arr); idx++ {
if arr[idx] == t {
contains = true
}
}
return contains
}
Intuitively, the post-condition specifies that: if two executions are called with the same element t, and t is not included in one array, then t is not included in either array. Clearly, that's not the case.
For example, the following two calls satisfy the left-hand side of the implication, but not the right-hand side:
Includes(0, []int{1}) // == false
Includes(0, []int{0}) // == true
I hope I didn't make a mistake in parsing the post-condition! Let me know, if I did.
Hi everyone,
I just tried proving some property using gobra's hypermode, and I'm pretty sure I found a soundness bug. The following code verifies successfully when using gobra at version
bc3c90375d672dbc796edb7011b70bc9098eeb21.Intuitively, the post-condition specifies that: if two executions are called with the same element
t, andtis not included in one array, thentis not included in either array. Clearly, that's not the case.For example, the following two calls satisfy the left-hand side of the implication, but not the right-hand side:
Includes(0, []int{1}) // == falseIncludes(0, []int{0}) // == trueI hope I didn't make a mistake in parsing the post-condition! Let me know, if I did.