Skip to content

Commit 833e6c1

Browse files
committed
Add query tools
1 parent f0d70fa commit 833e6c1

File tree

4 files changed

+112
-0
lines changed

4 files changed

+112
-0
lines changed

ext/ModelAnalyzerJuMPExt/ModelAnalyzerJuMPExt.jl

+13
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,17 @@ function ModelAnalyzer.constraint(
7979
return JuMP.constraint_ref_with_index(model, ref)
8080
end
8181

82+
"""
83+
constraintss(issue::ModelAnalyzer.AbstractIssue, model::JuMP.GenericModel)
84+
85+
Return the **JuMP** constraints reference associated to a particular issue.
86+
"""
87+
function ModelAnalyzer.constraints(
88+
issue::ModelAnalyzer.AbstractIssue,
89+
model::JuMP.GenericModel,
90+
)
91+
ref = ModelAnalyzer.constraints(issue)
92+
return JuMP.constraint_ref_with_index.(model, ref)
93+
end
94+
8295
end # module ModelAnalyzerJuMPExt

src/ModelAnalyzer.jl

+39
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,19 @@ function value(issue::AbstractIssue, ::MOI.ModelLike)
151151
return value(issue)
152152
end
153153

154+
"""
155+
values(issue::AbstractIssue)
156+
157+
Return the values associated to a particular issue.
158+
"""
159+
function values(issue::AbstractIssue, ::Nothing)
160+
return values(issue)
161+
end
162+
163+
function values(issue::AbstractIssue, ::MOI.ModelLike)
164+
return values(issue)
165+
end
166+
154167
"""
155168
variable(issue::AbstractIssue)
156169
@@ -190,6 +203,32 @@ function constraint(issue::AbstractIssue, ::MOI.ModelLike)
190203
return constraint(issue)
191204
end
192205

206+
"""
207+
constraints(issue::AbstractIssue)
208+
209+
Return the constraints associated to a particular issue.
210+
"""
211+
function constraints(issue::AbstractIssue, ::Nothing)
212+
return constraints(issue)
213+
end
214+
215+
function constraints(issue::AbstractIssue, ::MOI.ModelLike)
216+
return constraints(issue)
217+
end
218+
219+
"""
220+
set(issue::AbstractIssue)
221+
222+
Return the set associated to a particular issue.
223+
"""
224+
function set(issue::AbstractIssue, ::Nothing)
225+
return set(issue)
226+
end
227+
228+
function set(issue::AbstractIssue, ::MOI.ModelLike)
229+
return set(issue)
230+
end
231+
193232
function _verbose_summarize end
194233

195234
function _summarize end

src/infeasibility.jl

+18
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ struct InfeasibleBounds{T} <: AbstractInfeasibilitylIssue
5555
ub::T
5656
end
5757

58+
ModelAnalyzer.variable(issue::InfeasibleBounds) = issue.variable
59+
60+
ModelAnalyzer.values(issue::InfeasibleBounds) = [issue.lb, issue.ub]
61+
5862
"""
5963
InfeasibleIntegrality{T} <: AbstractInfeasibilitylIssue
6064
@@ -77,6 +81,12 @@ struct InfeasibleIntegrality{T} <: AbstractInfeasibilitylIssue
7781
set::Union{MOI.Integer,MOI.ZeroOne}#, MOI.Semicontinuous{T}, MOI.Semiinteger{T}}
7882
end
7983

84+
ModelAnalyzer.variable(issue::InfeasibleIntegrality) = issue.variable
85+
86+
ModelAnalyzer.values(issue::InfeasibleIntegrality) = [issue.lb, issue.ub]
87+
88+
ModelAnalyzer.set(issue::InfeasibleIntegrality) = issue.set
89+
8090
"""
8191
InfeasibleConstraintRange{T} <: AbstractInfeasibilitylIssue
8292
@@ -101,6 +111,12 @@ struct InfeasibleConstraintRange{T} <: AbstractInfeasibilitylIssue
101111
set::Union{MOI.EqualTo{T},MOI.LessThan{T},MOI.GreaterThan{T}}
102112
end
103113

114+
ModelAnalyzer.constraint(issue::InfeasibleConstraintRange) = issue.constraint
115+
116+
ModelAnalyzer.values(issue::InfeasibleConstraintRange) = [issue.lb, issue.ub]
117+
118+
ModelAnalyzer.set(issue::InfeasibleConstraintRange) = issue.set
119+
104120
"""
105121
IrreducibleInfeasibleSubset <: AbstractInfeasibilitylIssue
106122
@@ -121,6 +137,8 @@ struct IrreducibleInfeasibleSubset <: AbstractInfeasibilitylIssue
121137
constraint::Vector{<:MOI.ConstraintIndex}
122138
end
123139

140+
ModelAnalyzer.constraints(issue::IrreducibleInfeasibleSubset) = issue.constraint
141+
124142
"""
125143
Data <: ModelAnalyzer.AbstractData
126144

test/infeasibility.jl

+42
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ function test_bounds()
3737
2.0,
3838
1.0,
3939
)
40+
@test ModelAnalyzer.variable(ret[], model) == y
41+
@test ModelAnalyzer.values(ret[]) == [2.0, 1.0]
4042
#
4143
buf = IOBuffer()
4244
ModelAnalyzer.summarize(
@@ -82,6 +84,9 @@ function test_integrality()
8284
2.9,
8385
MOI.Integer(),
8486
)
87+
@test ModelAnalyzer.variable(ret[], model) == y
88+
@test ModelAnalyzer.values(ret[]) == [2.2, 2.9]
89+
@test ModelAnalyzer.set(ret[]) == MOI.Integer()
8590
#
8691
buf = IOBuffer()
8792
ModelAnalyzer.summarize(
@@ -129,6 +134,9 @@ function test_binary()
129134
0.8,
130135
MOI.ZeroOne(),
131136
)
137+
@test ModelAnalyzer.variable(ret[], model) == x
138+
@test ModelAnalyzer.values(ret[]) == [0.5, 0.8]
139+
@test ModelAnalyzer.set(ret[]) == MOI.ZeroOne()
132140
return
133141
end
134142

@@ -150,6 +158,9 @@ function test_range()
150158
22.0,
151159
MOI.LessThan{Float64}(1.0),
152160
)
161+
@test ModelAnalyzer.constraint(ret[], model) == c
162+
@test ModelAnalyzer.values(ret[]) == [11.0, 22.0]
163+
@test ModelAnalyzer.set(ret[]) == MOI.LessThan{Float64}(1.0)
153164
#
154165
buf = IOBuffer()
155166
ModelAnalyzer.summarize(
@@ -198,6 +209,9 @@ function test_range_neg()
198209
22.0,
199210
MOI.LessThan{Float64}(1.0),
200211
)
212+
@test ModelAnalyzer.constraint(ret[], model) == c
213+
@test ModelAnalyzer.values(ret[]) == [11.0, 22.0]
214+
@test ModelAnalyzer.set(ret[]) == MOI.LessThan{Float64}(1.0)
201215
return
202216
end
203217

@@ -219,6 +233,9 @@ function test_range_equalto()
219233
3.0,
220234
MOI.EqualTo{Float64}(1.0),
221235
)
236+
@test ModelAnalyzer.constraint(ret[], model) == c
237+
@test ModelAnalyzer.values(ret[]) == [3.0, 3.0]
238+
@test ModelAnalyzer.set(ret[]) == MOI.EqualTo{Float64}(1.0)
222239
return
223240
end
224241

@@ -240,6 +257,9 @@ function test_range_equalto_2()
240257
7.0,
241258
MOI.EqualTo{Float64}(1.0),
242259
)
260+
@test ModelAnalyzer.constraint(ret[], model) == c
261+
@test ModelAnalyzer.values(ret[]) == [7.0, 7.0]
262+
@test ModelAnalyzer.set(ret[]) == MOI.EqualTo{Float64}(1.0)
243263
return
244264
end
245265

@@ -261,6 +281,9 @@ function test_range_greaterthan()
261281
22.0,
262282
MOI.GreaterThan{Float64}(100.0),
263283
)
284+
@test ModelAnalyzer.constraint(ret[], model) == c
285+
@test ModelAnalyzer.values(ret[]) == [11.0, 22.0]
286+
@test ModelAnalyzer.set(ret[]) == MOI.GreaterThan{Float64}(100.0)
264287
return
265288
end
266289

@@ -282,6 +305,9 @@ function test_range_equalto_3()
282305
22.0,
283306
MOI.EqualTo{Float64}(100.0),
284307
)
308+
@test ModelAnalyzer.constraint(ret[], model) == c
309+
@test ModelAnalyzer.values(ret[]) == [11.0, 22.0]
310+
@test ModelAnalyzer.set(ret[]) == MOI.EqualTo{Float64}(100.0)
285311
return
286312
end
287313

@@ -326,6 +352,9 @@ function test_iis()
326352
@test length(ret[].constraint) == 2
327353
@test Set([ret[].constraint[1], ret[].constraint[2]]) ==
328354
Set(JuMP.index.([c2, c1]))
355+
iis = ModelAnalyzer.constraints(ret[], model)
356+
@test length(iis) == 2
357+
@test Set(iis) == Set([c2, c1])
329358
#
330359
buf = IOBuffer()
331360
ModelAnalyzer.summarize(
@@ -388,6 +417,10 @@ function test_iis_multiple()
388417
@test JuMP.index(c2) in Set([ret[].constraint[1], ret[].constraint[2]])
389418
@test Set([ret[].constraint[1], ret[].constraint[2]])
390419
Set(JuMP.index.([c3, c2, c1]))
420+
iis = ModelAnalyzer.constraints(ret[], model)
421+
@test length(iis) == 2
422+
@test Set(iis) Set([c3, c2, c1])
423+
@test c2 in iis
391424
return
392425
end
393426

@@ -415,6 +448,9 @@ function test_iis_interval_right()
415448
@test length(ret[].constraint) == 2
416449
@test Set([ret[].constraint[1], ret[].constraint[2]]) ==
417450
Set(JuMP.index.([c2, c1]))
451+
iis = ModelAnalyzer.constraints(ret[], model)
452+
@test length(iis) == 2
453+
@test Set(iis) == Set([c2, c1])
418454
return
419455
end
420456

@@ -442,6 +478,9 @@ function test_iis_interval_left()
442478
@test length(ret[].constraint) == 2
443479
@test Set([ret[].constraint[1], ret[].constraint[2]]) ==
444480
Set(JuMP.index.([c2, c1]))
481+
iis = ModelAnalyzer.constraints(ret[], model)
482+
@test length(iis) == 2
483+
@test Set(iis) == Set([c2, c1])
445484
return
446485
end
447486

@@ -472,6 +511,9 @@ function test_iis_spare()
472511
@test length(ret[].constraint) == 2
473512
@test Set([ret[].constraint[1], ret[].constraint[2]]) ==
474513
Set(JuMP.index.([c2, c1]))
514+
iis = ModelAnalyzer.constraints(ret[], model)
515+
@test length(iis) == 2
516+
@test Set(iis) == Set([c2, c1])
475517
return
476518
end
477519

0 commit comments

Comments
 (0)