Skip to content

Using rel(t,0) < rel(t,1) with implication in SIF mode causes an error. #994

@AkasakaJelos

Description

@AkasakaJelos

Consider the following example:

package exercises

// ##(--hyperMode extended --enableExperimentalHyperFeatures)

// @ requires rel(t,0) != rel(t,1)
func test_ghostIfandImplication(t uint64) {

    //@ assume rel(t,0) < rel(t,1)

    //Let's do logic table!

    //@ assert rel(t,0) < rel(t,1) ==> true     //T ==> T
    //@ refute rel(t,0) < rel(t,1) ==> false     //T ==> F
    //@ assert rel(t,0) > rel(t,1) ==> true     //F ==> T
    //@ assert rel(t,0) > rel(t,1) ==> false     //F ==> F
}

The program should verify, based on the logic truth table of implication. However, the truth is:

[info] Error at: </.../relissue12.go:15:2> Assert might fail.
[info] Assertion rel(t,0) > rel(t,1) ==> false might not hold.
[info] Gobra found 1 error.

If we dig into the SIF encoding, we have in the last assert:

 assert (p1 ==> p1 && p2 ==> t_V0_CN0 > t_V0_CN0_0) && (p2 ==> true) ==>
      (p1 ==> false) && (p2 ==> false)

If we set p1 to T and p2 to F, we end up with T ==> F (if we do with p2 == F, we get the same implication), which means we won't verify the stuff regardless of p2. According to Linard, the issue lies in the semantics of //@ assert rel(t,0) > rel(t,1) ==> false , which are completely unclear if we have only a single execution.

Changing it to:

//@ assert !(rel(t,0) > rel(t,1)) || false //F ==> F

will verify the statement, nevertheless.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions