-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Unexpected unknown return when solving some instances #5938
Comments
I think your understanding is correct: the or-else handler depends on lower-level code that is spread around raise the right kinds of exceptions. This is overall brittle but errs on the side of producing unknown. The code in the nlsat solver is more of a hack in line of what the proposed patch suggests. It might be motivated based on that the nlsat code using libraries where tactic_exception has not been defined (algebraic numbers). It is safer to fix the places where an exception is treated as a default exception but is really recoverable. Non-recoverable exceptions should still throw. So for the relatively few samples that produce unknown it could be possible to figure out what is going on. Note that the utilities in math/lp all throw a default_exception. |
The cause of unknowns is definitely in some cases attributed to exceptions raised in the rewriter. By handling these the or-else tactic can recover. |
Oh, I see. When I removed all mk_qfnra_sat_solver in mk_qfnra_tactic, the unknown case number decrease from 40+ to 20+. But I didn't known why before. |
Yes, it seems more reasonable to catch default_exception. Instead, it may need large-scale checking and modifying on lower-level code to fix this. |
gives some information of the source of the exception. Then a debugger can be used to trace where/what exceptions are raised. It gives an idea of the source. |
Thanks a lot. I will try it. |
Hi, when I use z3 to solve some instances of different theories, I noticed that sometimes z3 will return some unexpected unknown.
The result is returned unknown when the time limit and memory limit don't exceed.
And the implementation of these theories in z3 are complete, such as QFNRA, QFLRA, etc.
Then I check the source code in z3, I find the or_else_tactical class work like this:
When the tactic which combined by or_else_tactical cannot solve the instance in time or in given configuration, tactic_exception should be thrown, and the goal will be passed to the next tactic to try to solve.
This is exactly what the authors implemented, e.g. nlsat_tactic:
Convert all z3 exceptions into tactic exceptions, and then the or_else_tactical will catch it and process.
Then we can use or_else_tactical with try_for_tactical to achieve a portfolio solver in z3.
But it will go wrong between the or_else_tactical and the solver tactic, e.g. qfnra_nlsat_tactic:
Before mk_nlsat_tactic, there are many preprocessing tactic which may not convert the z3_exception to tactic_exception.
If the time limit in try_for_tactical is not long enough to do these preprocessing(That's to say, the instance size is too large, maybe 300MB+), unexpected unknown will be returned.
When a large instance with 300MB+ cannot be preprocess in 5s, or_else_tactical will catch the z3_exception, and throw it.
Then z3 return unknown in 5s, maybe.
As far as I know, QFNRA isn't the only one that returns unexpected unknown.
A possible temporary hack as follow, but I don't know if this lead to bugs elsewhere in the program, such as cannot handle other z3_exception properly.
I don't know if I understand correctly, please criticize and correct me, thanks.
The text was updated successfully, but these errors were encountered: