Grisette not normalising terms that I would expect it to #308
Replies: 2 comments
-
|
Hi @RobinWebbers, I am traveling and am very busy this week, but I will investigate sometime. The issue sounds to be related to how we utilize sbv as our SMT backend as the internal representation looks good. |
Beta Was this translation helpful? Give feedback.
-
|
Hi @RobinWebbers , I finally got some time to look at this. It wasn't very easy to investigate the problem without a reproducer for the constant folding problem. I tried to construct something but I cannot reproduce the problem. The obsolete definitions seem benign and would not hurt solver performance. It comes from the fact that Grisette doesn't simply such term, while the underlying sbv further simplifies it. Since sbv won't remove any value that has already been defined, it is shown in the final solver call. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi!
So I'm using Grisette to build a symbolic evaluator plugin for GHC Core. There was something that stumped me when looking at the generated code. Specifically, Grisette is usually very good at reducing any constant expression that may exist in a term, but in this instance it appears quite a few constants weren't folded. I was curious if you (@lsrcz) have any idea as to why this happened. I did not want to make an issue for this, since I'm not sure what is happening exactly and if it is actually a bug.
Code
This is the piece of code that I symbolically interpret. It is reasonableysmall and you can assume that
Signed 5is directly interpreted as the underlying SMT solver primitive. The goal for it is to show that it is valid: the expression is alwaysTrue(which holds, so no issue there!)Internal Representation
You can see what this translates to in the internal representation of my symbolic executor. A tag in Haskell can be 64 bits, hence the huge bvconcat. The remaining bit that actually determines the boolean is a bitcast of the Haskell expression you see up top. The first check is there just to ensure the tag is within bounds (otherwise, we would get Undefined Behaviour when pattern matching on this tag).
Constraints
So far so good, these are pretty much what I would expect them to be. (Of course, there is room for the equivalence check to be folded, but alas). Now, if I turn this into constraints for the SMT solver, something weird happens: the constraints that are generated only contain constants but still end up in the query:
Notice
s4, which is a constant but is not folded. If you follow the chain from there, you'll see that any (transitive) usage of this could have been folded. That is, the entire expression only contains constants. Another odd one here iss3, which is not even used at all (and is in fact the addition ofxandy; somehow Grisette reasoned about this ahead of time?).Minimal Example
I wasn't able to create a minimal example for the full thing. It appears the constants fold when I write them out manually. I was able to reconstruct the obsolete addition (like
s3) that appears in the output with the following expression.Do you have any idea why Grisette is not folding the constants? I'm curious what you have to say on the matter!
Beta Was this translation helpful? Give feedback.
All reactions