Exit code has ALLOPT bit set when bad alloc is thrown
rkaminsk opened this issue · comments
This was first reported in potassco/guide#19, where the std::bad_alloc
was thrown in a propagator.
When there is a std::bad_alloc
exception when enumerating models with --opt-mode=optN
, then the OPTALL
bit is set in the exit code. To test this with clasp, I did the following experiment:
diff --git a/src/minimize_constraint.cpp b/src/minimize_constraint.cpp
index d4e3a56..6d8aa3c 100644
--- a/src/minimize_constraint.cpp
+++ b/src/minimize_constraint.cpp
@@ -391,6 +391,7 @@ void DefaultMinimize::reason(Solver& s, Literal p, LitVec& lits) {
x = shared_->lits[u.index()].first;
lits.push_back(x);
}
+ throw std::bad_alloc();
}
And then run with the following small program:
$ echo "#minimize{ X : p(X) }. 3 { p(1..5) }. 3 { p(3..7) }. 3 { p(5..10) }." \
| gringo \
| ./bin/clasp 0 --opt-mode=optN \
; echo $?
clasp version 3.3.3
Reading from stdin
Solving...
Answer: 1
p(6) p(7) p(9) p(3) p(1) p(2)
Optimization: 28
Answer: 2
p(6) p(7) p(8) p(3) p(1) p(2)
Optimization: 27
*** ERROR: (clasp): std::bad_alloc
SATISFIABLE
INTERRUPTED : 1
Models : 2+
Optimum : unknown
Optimization : 27
Calls : 1
Time : 0.001s (Solving: 0.00s 1st Model: 0.00s Unsat: 0.00s)
CPU Time : 0.001s
43
Because exit code 43
corresponds to 101011
, we have the bits INT
, SAT
, and ALLOPT
set. The ALLOPT
bit should not be set.
This is not a bug but simply a misinterpretation of clasp's exit codes. That is, clasp actually does not use the exit code encoding proposed in https://www.mat.unical.it/aspcomp2013/files/aspoutput.txt.
In particular, it has no concept of an ALLOPT bit. Instead, clasp uses a combination of the standard SAT competition codes together with some additional information regarding errors.
The codes are as follows:
enum ExitCode {
E_UNKNOWN = 0, /*!< Satisfiablity of problem not knwon; search not started. */
E_INTERRUPT = 1, /*!< Run was interrupted. */
E_SAT = 10, /*!< At least one model was found. */
E_EXHAUST = 20, /*!< Search-space was completely examined. */
E_MEMORY = 33, /*!< Run was interrupted by out of memory exception. */
E_ERROR = 65, /*!< Run was interrupted by internal error. */
E_NO_RUN = 128 /*!< Search not started because of syntax or command line error.*/
};
Hence, 43
is simply E_SAT + E_MEMORY - which is exactly what we we know about the program at the point of the exception.
Note that the meaning of 30 (i.e. E_SAT + E_EXHAUST) depends on the selected reasoning mode. E.g. for simple optimization it means optimum found. However, for optN
it means all optimal models have been enumerated.
Okay. To be honest, I find those exit codes a bit scary. Let's keep it like it is but never do something like this again. 😄
Thank you, that is a perfectly nice documentation for the guide. 👍