ethereum / act

Smart contract specification language

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Pretty Print Counterexamples

d-xo opened this issue · comments

commented

The counterexamples are currently not pretty printed in any way, and look very messy. For exmaple for this spec:


Invariant "(C.x < 9)" of "C":



---



---



---

Counter example found!

SMTModel {modelObjectives = [], modelBindings = Nothing, modelAssocs = [("C_j_x",7 :: Integer),("C_j_x_post",100 :: Integer),("C_j_CALLER",0 :: Integer),("C_j_CALLVALUE",0 :: Integer),("C_j_CALLDEPTH",0 :: Integer),("C_j_ORIGIN",0 :: Integer),("C_j_BLOCKHASH","" :: String),("C_j_BLOCKNUMBER",0 :: Integer),("C_j_DIFFICULTY",0 :: Integer),("C_j_CHAINID",0 :: Integer),("C_j_GASLIMIT",0 :: Integer),("C_j_COINBASE",0 :: Integer),("C_j_TIMESTAMP",0 :: Integer),("C_j_THIS",0 :: Integer),("C_j_NONCE",0 :: Integer)], modelUIFuns = []}

We should tidy this up, perhaps something like the following:

Invariant C.x < 9 of C:

  Counterexample:

    prestate:

      calldata:

        j()
      
      storage:

        x = 7

      environment:

        THIS      = 0
        NONCE     = 0
        ORIGIN    = 0
        CHAINID   = 0
        GASLIMIT  = 0
        COINBASE  = 0
        TIMESTAMP = 0
        CALLVALUE = 0
        CALLDEPTH = 0

    poststate:

      x = 100
commented

One thing I find misleading in this counterexample is the calldata part. If we actually run j(), the invariant x < 9 will not be violated, because you could never enter the if. The semantics of the counterexample is j() but with everything symbolic, so it is correct, I'm just not sure what the best way for reporting it is.

commented

hmmmm, isn't that represented by x being set to 7 in the pre block of the storage section?

commented

Not sure what you mean. To me x isn't really set to 7 in case x == 7, it's just a conditional update.

commented

But yea it's tricky. I was thinking about the connection between the act and the code, but if we're talking about only the act I'd say everything is fine.

commented

I mean that what I wanted to communicate with the counterexample is that if you call j() when the storage is in the state defined by the pre header in the storage section (x = 7), and the environment variables are assigned the values in the environment header (0 for everything), then the storage will transition to the state given by the post header (x = 100), and the invariant will be violated.

Looking at this again, the example is a bit weird since it's actually a false positive resulting from an insufficiently strict invariant, so maybe that's confusing matters, or perhaps I'm not understanding what you're getting at?

commented

Yes, that's exactly what I mean.
The counterexample is correct, but it is a bit weird because the counterexample's pre is unreachable considering the rest of the spec.