Skip to content

Commit 45042ff

Browse files
authored
[Bridges] fix ConstraintConflictStatus in added_constrained_variable_types (#2871)
1 parent ec8434e commit 45042ff

File tree

2 files changed

+73
-19
lines changed

2 files changed

+73
-19
lines changed

src/Bridges/bridge_optimizer.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1749,6 +1749,9 @@ function MOI.set(
17491749
return throw(MOI.SettingVariableIndexNotAllowed())
17501750
end
17511751

1752+
_f_type(::Type{S}) where {S<:MOI.AbstractScalarSet} = MOI.VariableIndex
1753+
_f_type(::Type{S}) where {S<:MOI.AbstractVectorSet} = MOI.VectorOfVariables
1754+
17521755
function MOI.get(
17531756
model::MOI.ModelLike,
17541757
attr::MOI.ConstraintConflictStatus,
@@ -1765,6 +1768,17 @@ function MOI.get(
17651768
end
17661769
end
17671770
end
1771+
for (S,) in MOI.Bridges.added_constrained_variable_types(typeof(bridge))
1772+
F = _f_type(S)
1773+
for ci in MOI.get(bridge, MOI.ListOfConstraintIndices{F,S}())
1774+
status = MOI.get(model, attr, ci)
1775+
if status == MOI.IN_CONFLICT
1776+
return status
1777+
elseif status == MOI.MAYBE_IN_CONFLICT
1778+
ret = status
1779+
end
1780+
end
1781+
end
17681782
return ret
17691783
end
17701784

test/Bridges/lazy_bridge_optimizer.jl

Lines changed: 59 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2300,31 +2300,71 @@ MOI.Utilities.@model(
23002300
()
23012301
)
23022302

2303+
function _test_conflicts(model, inner, c)
2304+
ci = MOI.ConstraintIndex[]
2305+
for (F, S) in MOI.get(inner, MOI.ListOfConstraintTypesPresent())
2306+
append!(ci, MOI.get(inner, MOI.ListOfConstraintIndices{F,S}()))
2307+
end
2308+
list = (MOI.NOT_IN_CONFLICT, MOI.IN_CONFLICT, MOI.MAYBE_IN_CONFLICT)
2309+
for a in Iterators.product(ntuple(i -> list, length(ci))...)
2310+
MOI.set(inner, MOI.ConflictCount(), 1)
2311+
MOI.set.(inner, MOI.ConstraintConflictStatus(), ci, a)
2312+
MOI.compute_conflict!(model)
2313+
status = MOI.get(model, MOI.ConstraintConflictStatus(), c)
2314+
@test status == reduce(_cmp, a)
2315+
end
2316+
return
2317+
end
2318+
2319+
function _cmp(
2320+
a::MOI.ConflictParticipationStatusCode,
2321+
b::MOI.ConflictParticipationStatusCode,
2322+
)
2323+
if a == MOI.IN_CONFLICT || b == MOI.IN_CONFLICT
2324+
return MOI.IN_CONFLICT
2325+
elseif a == MOI.MAYBE_IN_CONFLICT || b == MOI.MAYBE_IN_CONFLICT
2326+
return MOI.MAYBE_IN_CONFLICT
2327+
else
2328+
return MOI.NOT_IN_CONFLICT
2329+
end
2330+
end
2331+
23032332
function test_issue_2838()
23042333
inner = MOI.Utilities.MockOptimizer(Model2838{Float64}())
23052334
model = MOI.Bridges.full_bridge_optimizer(inner, Float64)
23062335
x = MOI.add_variables(model, 2)
23072336
f = MOI.Utilities.operate(vcat, Float64, (1.0 * x)...)
23082337
c = MOI.add_constraint(model, f, MOI.Nonnegatives(2))
2309-
F, S = MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}
2310-
ci = MOI.get(inner, MOI.ListOfConstraintIndices{F,S}())
2311-
function cmp(a, b)
2312-
if a == MOI.IN_CONFLICT || b == MOI.IN_CONFLICT
2313-
return MOI.IN_CONFLICT
2314-
elseif a == MOI.MAYBE_IN_CONFLICT || b == MOI.MAYBE_IN_CONFLICT
2315-
return MOI.MAYBE_IN_CONFLICT
2316-
else
2317-
return MOI.NOT_IN_CONFLICT
2318-
end
2319-
end
2320-
list = (MOI.NOT_IN_CONFLICT, MOI.IN_CONFLICT, MOI.MAYBE_IN_CONFLICT)
2321-
for a in list, b in list
2322-
MOI.set(inner, MOI.ConflictCount(), 1)
2323-
MOI.set(inner, MOI.ConstraintConflictStatus(), ci[1], a)
2324-
MOI.set(inner, MOI.ConstraintConflictStatus(), ci[2], b)
2325-
MOI.compute_conflict!(model)
2326-
@test MOI.get(model, MOI.ConstraintConflictStatus(), c) == cmp(a, b)
2327-
end
2338+
_test_conflicts(model, inner, c)
2339+
return
2340+
end
2341+
2342+
function test_issue_2870_scalar_slack()
2343+
inner = MOI.Utilities.MockOptimizer(MOI.Utilities.Model{Float64}())
2344+
model = MOI.Bridges.Constraint.ScalarSlack{Float64}(inner)
2345+
x = MOI.add_variable(model)
2346+
c = MOI.add_constraint(model, 2.0 * x, MOI.Interval(1.0, -1.0))
2347+
_test_conflicts(model, inner, c)
2348+
return
2349+
end
2350+
2351+
function test_issue_2870_geomean_to_power()
2352+
inner = MOI.Utilities.MockOptimizer(MOI.Utilities.Model{Float64}())
2353+
model = MOI.Bridges.Constraint.GeoMeanToPower{Float64}(inner)
2354+
x = MOI.add_variables(model, 4)
2355+
f = MOI.VectorOfVariables(x)
2356+
c = MOI.add_constraint(model, f, MOI.GeometricMeanCone(4))
2357+
_test_conflicts(model, inner, c)
2358+
return
2359+
end
2360+
2361+
function test_issue_2870_relative_entropy()
2362+
inner = MOI.Utilities.MockOptimizer(MOI.Utilities.Model{Float64}())
2363+
model = MOI.Bridges.Constraint.RelativeEntropy{Float64}(inner)
2364+
x = MOI.add_variables(model, 5)
2365+
f = MOI.VectorOfVariables(x)
2366+
c = MOI.add_constraint(model, f, MOI.RelativeEntropyCone(5))
2367+
_test_conflicts(model, inner, c)
23282368
return
23292369
end
23302370

0 commit comments

Comments
 (0)