Skip to content

Commit 67dc926

Browse files
authored
[FileFormats.NL] make ResultCount more permissive in when it returns 1 (#2130)
1 parent 60cbf9f commit 67dc926

File tree

2 files changed

+21
-5
lines changed

2 files changed

+21
-5
lines changed

src/FileFormats/NL/sol.jl

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ function SolFileResults(
6363
end
6464

6565
function MOI.get(sol::SolFileResults, ::MOI.ResultCount)
66-
return MOI.get(sol, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT ? 1 : 0
66+
return isempty(sol.variable_primal) ? 0 : 1
6767
end
6868

6969
function MOI.get(sol::SolFileResults, ::MOI.RawStatusString)
@@ -206,6 +206,15 @@ For the primal status, assume a solution is present. Other code is responsible
206206
for returning `MOI.NO_SOLUTION` if no primal solution is present.
207207
"""
208208
function _interpret_status(solve_result_num::Int, raw_status_string::String)
209+
message = lowercase(raw_status_string)
210+
# Handle some status strings that are, in most cases, solver-specific.
211+
if occursin("time limit, feasible solution", message)
212+
return MOI.TIME_LIMIT, MOI.FEASIBLE_POINT
213+
end
214+
# No handle the solve status codes. These are solver-specific, although they
215+
# should be grouped into XYZ codes, where the first digit is a generic
216+
# group (optimal, infeasible, limit, etc), and the YZ are solver-specific
217+
# codes with more meaning.
209218
if 0 <= solve_result_num < 100
210219
# Solved, and nothing went wrong. Even though we say `LOCALLY_SOLVED`,
211220
# some solvers like SHOT use this status to represent problems that are
@@ -224,10 +233,7 @@ function _interpret_status(solve_result_num::Int, raw_status_string::String)
224233
elseif 500 <= solve_result_num < 600
225234
return MOI.OTHER_ERROR, MOI.UNKNOWN_RESULT_STATUS
226235
end
227-
# If we didn't get a valid solve_result_num, try to get the status from the
228-
# solve_message string. Some solvers (e.g. SCIP) don't ever print the
229-
# suffixes so we need this.
230-
message = lowercase(raw_status_string)
236+
# If all else fails, attempt to infer the status from `raw_status_string`.
231237
if occursin("optimal", message)
232238
return MOI.LOCALLY_SOLVED, MOI.FEASIBLE_POINT
233239
elseif occursin("infeasible", message)

test/FileFormats/NL/sol.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,8 @@ function test_statuses()
279279
(MOI.DUAL_INFEASIBLE, MOI.UNKNOWN_RESULT_STATUS),
280280
(400, "norm limit exceeded") =>
281281
(MOI.OTHER_LIMIT, MOI.UNKNOWN_RESULT_STATUS),
282+
(403, "Solver 10.0.1: time limit, feasible solution\n") =>
283+
(MOI.TIME_LIMIT, MOI.FEASIBLE_POINT),
282284
(500, "Solver error.") =>
283285
(MOI.OTHER_ERROR, MOI.UNKNOWN_RESULT_STATUS),
284286
(-1, "Optimal Solution Found") =>
@@ -307,6 +309,14 @@ function test_sol_empty()
307309
return
308310
end
309311

312+
function test_result_count()
313+
results = NL.SolFileResults("raw", MOI.OTHER_LIMIT)
314+
@test MOI.get(results, MOI.ResultCount()) == 0
315+
results.variable_primal[MOI.VariableIndex(1)] = 0.0
316+
@test MOI.get(results, MOI.ResultCount()) == 1
317+
return
318+
end
319+
310320
end
311321

312322
TestNonlinearSolFiles.runtests()

0 commit comments

Comments
 (0)