Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect desugaring of ternary operator with impure operands #777

Closed
jcp19 opened this issue Jul 2, 2024 · 2 comments · Fixed by #778
Closed

Incorrect desugaring of ternary operator with impure operands #777

jcp19 opened this issue Jul 2, 2024 · 2 comments · Fixed by #778
Assignees

Comments

@jcp19
Copy link
Contributor

jcp19 commented Jul 2, 2024

Reported by Conradin Laux.

In the file below, function h2 verifies just fine, but function h does not, even though it computes the same value as h2 using a ternary expression.

ghost
requires i >= 0
decreases i
func h(i int) (res int) {
    return i == 0 ? 0 : h(i - 1)
}

ghost
requires i >= 0
decreases i
func h2(i int) (res int) {
    if i == 0 {
        return 0
    } else {
        return h2(i - 1)
    }
}

Looking at the viper encoding, we find that the ternary expression in function h is encoded as

      var N2: Int
      // first, h is called
      N2 := h_41fccf1_F(i_V0_CN0 - 1)
      // only then do we desugar the ternary expression
      res_V0_CN1 := (i_V0_CN0 == 0 ? 0 : N2)

Clearly, this is wrong. I think that the most appropriate solution here is to always require that a ternary expression is pure. As such, the example above would be rejected because we would call a non-pure function in a ternary operation. This does not limit expressiveness, because we could always use a ghost if instead.

@ArquintL
Copy link
Member

ArquintL commented Jul 2, 2024

Alternatively, we could encode an impure ternary operator as an if statement. While convenient to overcome Go‘s shortage of a ternary operator, this encoding might be more surprising than just rejecting such ternary operators

@jcp19
Copy link
Contributor Author

jcp19 commented Jul 2, 2024

Alternatively, we could encode an impure ternary operator as an if statement. While convenient to overcome Go‘s shortage of a ternary operator, this encoding might be more surprising than just rejecting such ternary operators

Yeah, I think that would be too surprising, and I don't see a good reason for doing that transformation because a ghost if is always acceptable in the contexts where a non-pure conditional expression was accepted before this PR.

@jcp19 jcp19 closed this as completed in #778 Jul 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants