Skip to content

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

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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions