Skip to content

Unintuitive semantics for mixed non-hyper-predicates and hyper-predicates #996

@felixlinker

Description

@felixlinker

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    SIFdocumentationImprovements or additions to documentation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions