Skip to content

Commit 3185a6f

Browse files
committed
Improve API
1 parent 4f716b0 commit 3185a6f

File tree

3 files changed

+419
-98
lines changed

3 files changed

+419
-98
lines changed

src/ModelAnalyzer.jl

Lines changed: 84 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ See [`summarize`](@ref), [`list_of_issues`](@ref), and
2525
function analyze end
2626

2727
"""
28-
summarize([io::IO,] AbstractData; verbose = true, max_issues = typemax(Int), kwargs...)
28+
summarize([io::IO,] AbstractData; name_source = nothing, verbose = true, max_issues = typemax(Int), kwargs...)
2929
3030
Print a summary of the analysis results contained in `AbstractData` to the
3131
specified IO stream. If no IO stream is provided, it defaults to `stdout`.
@@ -41,9 +41,11 @@ be a subtype of `AbstractIssue`). In the verbose case it will provide a text
4141
explaning the issue. In the non-verbose case it will provide just the issue
4242
name.
4343
44-
summarize([io::IO,] issue::AbstractIssue; verbose = true)
44+
summarize([io::IO,] issue::AbstractIssue; name_source = nothing, verbose = true)
4545
4646
This variant allows summarizing a single issue instance of type `AbstractIssue`.
47+
The model tha led to the issue can be provided to `name_source`, it will be used
48+
to generate the name of variables and constraints in the issue summary.
4749
"""
4850
function summarize end
4951

@@ -72,17 +74,23 @@ function summarize(io::IO, ::Type{T}; verbose = true) where {T<:AbstractIssue}
7274
end
7375
end
7476

75-
function summarize(io::IO, issue::AbstractIssue; verbose = true)
77+
function summarize(
78+
io::IO,
79+
issue::AbstractIssue;
80+
name_source = nothing,
81+
verbose = true,
82+
)
7683
if verbose
77-
return _verbose_summarize(io, issue)
84+
return _verbose_summarize(io, issue, name_source)
7885
else
79-
return _summarize(io, issue)
86+
return _summarize(io, issue, name_source)
8087
end
8188
end
8289

8390
function summarize(
8491
io::IO,
8592
issues::Vector{T};
93+
name_source = nothing,
8694
verbose = true,
8795
max_issues = typemax(Int),
8896
) where {T<:AbstractIssue}
@@ -92,7 +100,7 @@ function summarize(
92100
print(io, "\n\n## List of issues\n\n")
93101
for issue in first(issues, max_issues)
94102
print(io, " * ")
95-
summarize(io, issue, verbose = verbose)
103+
summarize(io, issue, verbose = verbose, name_source = name_source)
96104
print(io, "\n")
97105
end
98106
return
@@ -102,9 +110,79 @@ function summarize(data::AbstractData; kwargs...)
102110
return summarize(stdout, data; kwargs...)
103111
end
104112

113+
"""
114+
value(issue::AbstractIssue)
115+
116+
Return the value associated to a particular issue. The value is a number
117+
with a different meaning depending on the type of issue. For example, for
118+
some numerical issues, it can be the coefficient value.
119+
"""
120+
function value(issue::AbstractIssue, ::Nothing)
121+
return value(issue)
122+
end
123+
function value(issue::AbstractIssue, ::MOI.ModelLike)
124+
return value(issue)
125+
end
126+
127+
"""
128+
variable(issue::AbstractIssue)
129+
130+
Return the variable associated to a particular issue.
131+
"""
132+
function variable(issue::AbstractIssue, ::Nothing)
133+
return variable(issue)
134+
end
135+
function variable(issue::AbstractIssue, ::MOI.ModelLike)
136+
return variable(issue)
137+
end
138+
139+
"""
140+
variables(issue::AbstractIssue)
141+
142+
Return the variables associated to a particular issue.
143+
"""
144+
function variables(issue::AbstractIssue, ::Nothing)
145+
return variables(issue)
146+
end
147+
function variables(issue::AbstractIssue, ::MOI.ModelLike)
148+
return variables(issue)
149+
end
150+
151+
"""
152+
constraint(issue::AbstractIssue)
153+
154+
Return the constraint associated to a particular issue.
155+
"""
156+
function constraint(issue::AbstractIssue, ::Nothing)
157+
return constraint(issue)
158+
end
159+
function constraint(issue::AbstractIssue, ::MOI.ModelLike)
160+
return constraint(issue)
161+
end
162+
105163
function _verbose_summarize end
106164
function _summarize end
107165

166+
function _name(ref::MOI.VariableIndex, model::MOI.ModelLike)
167+
name = MOI.get(model, MOI.VariableName(), ref)
168+
if !isempty(name)
169+
return name
170+
end
171+
return "$ref"
172+
end
173+
174+
function _name(ref::MOI.ConstraintIndex, model::MOI.ModelLike)
175+
name = MOI.get(model, MOI.ConstraintName(), ref)
176+
if !isempty(name)
177+
return name
178+
end
179+
return "$ref"
180+
end
181+
182+
function _name(ref, ::Nothing)
183+
return "$ref"
184+
end
185+
108186
include("numerical.jl")
109187
include("feasibility.jl")
110188
include("infeasibility.jl")

src/jump.jl

Lines changed: 66 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,79 @@
11
using JuMP
22

3-
# struct JuMPData{T<:AbstractData} <: AbstractData
3+
# struct JuMPData{T<:AbstractData} <: ModelAnalyzer.AbstractData
44
# data::T
5+
# model::JuMP.Model
56
# end
67

7-
struct JuMPIssue{T<:AbstractIssue} <: AbstractIssue
8-
issue::T
9-
end
8+
# struct JuMPIssue{T<:AbstractIssue} <: ModelAnalyzer.AbstractIssue
9+
# issue::T
10+
# model::JuMP.Model
11+
# end
1012

11-
function analyze(
13+
function ModelAnalyzer.analyze(
1214
analyzer::T,
1315
model::JuMP.Model;
1416
kwargs...,
15-
) where {T<:AbstractAnalyzer}
17+
) where {T<:ModelAnalyzer.AbstractAnalyzer}
1618
moi_model = JuMP.backend(model)
17-
# Perform the analysis
18-
result = analyze(analyzer, moi_model; kwargs...)
19-
# return JuMPData(result)
19+
result = ModelAnalyzer.analyze(analyzer, moi_model; kwargs...)
20+
# return JuMPData(result, model)
2021
return result
2122
end
2223

23-
# function _name(ref)
24-
# name = JuMP.name(ref)
25-
# if !isempty(name)
26-
# return name
27-
# end
28-
# return "$(ref.index)"
29-
# end
24+
function ModelAnalyzer._name(ref::MOI.VariableIndex, model::JuMP.Model)
25+
jump_ref = JuMP.VariableRef(model, ref)
26+
name = JuMP.name(jump_ref)
27+
if !isempty(name)
28+
return name
29+
end
30+
return "$jump_ref"
31+
end
32+
33+
function ModelAnalyzer._name(ref::MOI.ConstraintIndex, model::JuMP.Model)
34+
jump_ref = JuMP.constraint_ref_with_index(model, ref)
35+
name = JuMP.name(jump_ref)
36+
if !isempty(name)
37+
return name
38+
end
39+
return "$jump_ref"
40+
end
41+
42+
"""
43+
variable(issue::ModelAnalyzer.AbstractIssue, model::JuMP.Model)
44+
45+
Return the **JuMP** variable reference associated to a particular issue.
46+
"""
47+
function ModelAnalyzer.variable(
48+
issue::ModelAnalyzer.AbstractIssue,
49+
model::JuMP.Model,
50+
)
51+
ref = ModelAnalyzer.variable(issue)
52+
return JuMP.VariableRef(model, ref)
53+
end
54+
55+
"""
56+
variables(issue::ModelAnalyzer.AbstractIssue, model::JuMP.Model)
57+
58+
Return the **JuMP** variable references associated to a particular issue.
59+
"""
60+
function ModelAnalyzer.variables(
61+
issue::ModelAnalyzer.AbstractIssue,
62+
model::JuMP.Model,
63+
)
64+
refs = ModelAnalyzer.variables(issue)
65+
return JuMP.VariableRef.(model, refs)
66+
end
67+
68+
"""
69+
constraint(issue::ModelAnalyzer.AbstractIssue, model::JuMP.Model)
70+
71+
Return the **JuMP** constraint reference associated to a particular issue.
72+
"""
73+
function ModelAnalyzer.constraint(
74+
issue::ModelAnalyzer.AbstractIssue,
75+
model::JuMP.Model,
76+
)
77+
ref = ModelAnalyzer.constraint(issue)
78+
return JuMP.constraint_ref_with_index(model, ref)
79+
end

0 commit comments

Comments
 (0)