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

Egg invariant: unsatisfiable invariant of locally declared classes that depend on mutable local state #1545

Open
vkuncak opened this issue Jul 23, 2024 · 1 comment

Comments

@vkuncak
Copy link
Collaborator

vkuncak commented Jul 23, 2024

/* Curious case of Egg invariant. 

   When a class is defined inside a method, the context is captured inside an invariant.
   If this context is mutable and is changed before class declaration, the captured
   check is wrong and an attempt to construct class instance fails.

   The context should probably not be captured when there is no syntactic dependency.

   If there is a syntactic dependency that is mutable, probably we should just throw
   unless there is a clear way to handle such mutable context.
 */

import stainless.lang.*
import stainless.annotation.*
import StaticChecks.*

object EggInvariant {
  case class Mut(var x: Int)

  def test = {
    val m = Mut(2)
    m.x = 1
    assert(m.x == 1)

    final case class Egg(n: Int)

    Egg(3)
  }
}

The generated invariant is:

@invariant
@derived(test)
def inv(thiss: Egg): Boolean = {
  val m: Mut = Mut(2)
  @ghost (m.x == 1)
}
@mario-bucev
Copy link
Collaborator

One way to "fix" this is to run a check to ensure the path condition does not refer to mutable variables or mutable types.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants