Closed lsrcz closed 4 months ago
This is a known issue, unfortunately. The "laziness" of execution can sometimes hide things from the symbolic engine. The "official" workaround is:
p = runSMTWith z3 {verbose = True} $ do
let f = uninterpret "f" :: SInteger -> SInteger
registerUISMTFunction f
query $ do
constrain $ \(Forall (b :: SInteger)) -> f b .== f b
checkSat
Note the call to registerUISMTFunction whose sole existence is to help with problems like this.
I'm not sure if there's much value in pursuing this to the bitter end; I come across this occasionally, and registerUISMTFunction
usually does the trick. If you do end up identifying a fix though, I'd love to hear.
Thank you, I'll try it out. A guaranteed workaround is sufficient for me. It might be useful to mention this in the documentation of uninterpreted functions.
Would it be a good idea to provide a function that combines the declaration and registration? Something like:
p = runSMTWith z3 {verbose = True} $ do
f :: SInteger -> SInteger <- getUninterpret "f"
query $ do
constrain $ \(Forall (b :: SInteger)) -> f b .== f b
checkSat
where
getUninterpret name = do
let f = uninterpret name
registerUISMTFunction f
return f
More/better documentation is always welcome! Please submit a PR.
Regarding getUninterpret
: I'm a little weary of the plethora of functions we already have. Do you think it'll make the user experience any better?
Sure, I added some documentation to the issue. Please review it.
For the additional API, I am also unsure about it, so I was asking :). Given that I only observed the issue when using quantifiers, it might be okay to stick with the current workaround.
yeah; I don't see much ROI in investigating this in any further depth. Feel free to close the ticket; though if you want to spend some cycles trying to see if we can improve the situation that's fine as well.
One more thing I noticed about this issue is that the registration function requires the MonadSymbolic
constraint, which is only available for Query
, but not for QueryT m
. Is this intentional, or there is a missing instance?
If the missing instance is intentional, then we cannot do this trick if we are declaring uninterpreted functions in a QueryT m
environment, and that's what I am doing.
It turns out that the registerUISMTFunction
function might also be overly-constrained though. The MonadSymbolic
constraint can be removed from that function as well as from smtFunName
, and the system still builds.
Do you think this is a good idea?
If it builds with smaller set of constraints, that'd be just fine. Please do a PR
@lsrcz Thinking about making a release sometime this weekend.. Can we close this ticket, or do you still want to fix up a few things here?
Hi @LeventErkok, I will close the ticket for now. Maybe come back to it in the future when I got some time to have a look..
There is likely a bug when using uninterpreted functions in a quantified formula. SBV does not declare them in the top-level.
The following code
gives
A current workaround I am using is to add a dummy constraint to declare the ufunc:
Note that the constraint must be declared before the constraint with forall, and the following code would crash