Skip to content

Commit d662e85

Browse files
authored
Fix integration of compute_conflict through layers (jump-dev#1216)
* Fix integration of compute_conflict through layers * Add test for bridged error * Fix tests
1 parent e817d20 commit d662e85

File tree

4 files changed

+79
-2
lines changed

4 files changed

+79
-2
lines changed

src/Bridges/lazy_bridge_optimizer.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,3 +486,7 @@ end
486486
function bridging_cost(b::LazyBridgeOptimizer, args...)
487487
return bridging_cost(b.graph, node(b, args...))
488488
end
489+
490+
function MOI.compute_conflict!(model::LazyBridgeOptimizer)
491+
return MOI.compute_conflict!(model.model)
492+
end

src/Utilities/cachingoptimizer.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,3 +1009,7 @@ function MOI.submit(
10091009
end
10101010

10111011
# TODO: get and set methods to look up/set name strings
1012+
1013+
function MOI.compute_conflict!(model::CachingOptimizer)
1014+
return MOI.compute_conflict!(model.optimizer)
1015+
end

src/Utilities/mockoptimizer.jl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,8 @@ function MOI.optimize!(mock::MockOptimizer)
133133
mock.hasdual = true
134134
return mock.optimize!(mock)
135135
end
136-
function MOI.compute_conflict!(::MockOptimizer) end
136+
137+
MOI.compute_conflict!(::MockOptimizer) = nothing
137138

138139
function throw_mock_unsupported_names(attr)
139140
return throw(MOI.UnsupportedAttribute(
@@ -305,13 +306,15 @@ function MOI.set(
305306
)
306307
return _safe_set_result(mock.con_basis, attr, idx, value)
307308
end
309+
308310
function MOI.set(
309311
mock::MockOptimizer,
310312
::MOI.ConstraintConflictStatus,
311313
idx::MOI.ConstraintIndex,
312314
value,
313315
)
314-
return mock.constraint_conflict_status[idx] = value
316+
mock.constraint_conflict_status[idx] = value
317+
return
315318
end
316319

317320
MOI.get(mock::MockOptimizer, ::MOI.RawSolver) = mock
@@ -529,6 +532,7 @@ function MOI.get(
529532
MOI.throw_if_not_valid(mock, idx)
530533
return _safe_get_result(mock.con_basis, attr, idx, "basis status")
531534
end
535+
532536
function MOI.get(
533537
mock::MockOptimizer,
534538
::MOI.ConstraintConflictStatus,

test/attributes.jl

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,68 @@
3030
ones(2))
3131
end
3232
end
33+
34+
@testset "test_integration_compute_conflict" begin
35+
optimizer = MOI.Utilities.MockOptimizer(MOI.Utilities.Model{Float64}())
36+
model = MOI.Utilities.CachingOptimizer(
37+
MOI.Utilities.Model{Float64}(),
38+
MOI.Bridges.full_bridge_optimizer(optimizer, Float64),
39+
)
40+
x = MOI.add_variable(model)
41+
c1 = MOI.add_constraint(model, MOI.SingleVariable(x), MOI.LessThan(0.0))
42+
c2 = MOI.add_constraint(model, MOI.SingleVariable(x), MOI.GreaterThan(1.0))
43+
MOI.optimize!(model)
44+
@test MOI.get(optimizer, MOI.ConflictStatus()) == MOI.COMPUTE_CONFLICT_NOT_CALLED
45+
MOI.set(optimizer, MOI.ConflictStatus(), MOI.CONFLICT_FOUND)
46+
MOI.set(
47+
optimizer,
48+
MOI.ConstraintConflictStatus(),
49+
MOI.get(
50+
optimizer,
51+
MOI.ListOfConstraintIndices{MOI.SingleVariable,MOI.LessThan{Float64}}(),
52+
)[1],
53+
MOI.NOT_IN_CONFLICT,
54+
)
55+
MOI.set(
56+
optimizer,
57+
MOI.ConstraintConflictStatus(),
58+
MOI.get(
59+
optimizer,
60+
MOI.ListOfConstraintIndices{MOI.SingleVariable,MOI.GreaterThan{Float64}}(),
61+
)[1],
62+
MOI.IN_CONFLICT,
63+
)
64+
MOI.compute_conflict!(model)
65+
@test MOI.get(model, MOI.ConflictStatus()) == MOI.CONFLICT_FOUND
66+
@test MOI.get(model, MOI.ConstraintConflictStatus(), c1) == MOI.NOT_IN_CONFLICT
67+
@test MOI.get(model, MOI.ConstraintConflictStatus(), c2) == MOI.IN_CONFLICT
68+
end
69+
70+
MOI.Utilities.@model(
71+
OnlyScalarConstraints,
72+
(),
73+
(MOI.GreaterThan, MOI.LessThan),
74+
(),
75+
(),
76+
(),
77+
(MOI.ScalarAffineFunction,),
78+
(),
79+
()
80+
)
81+
82+
@testset "test_integration_compute_conflict" begin
83+
optimizer = MOI.Utilities.MockOptimizer(OnlyScalarConstraints{Float64}())
84+
model = MOI.Bridges.full_bridge_optimizer(optimizer, Float64)
85+
x = MOI.add_variable(model)
86+
c = MOI.add_constraint(
87+
model,
88+
MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(1.0, x)], 0.0),
89+
MOI.Interval(0.0, 1.0),
90+
)
91+
MOI.optimize!(model)
92+
@test MOI.get(optimizer, MOI.ConflictStatus()) == MOI.COMPUTE_CONFLICT_NOT_CALLED
93+
MOI.set(optimizer, MOI.ConflictStatus(), MOI.CONFLICT_FOUND)
94+
MOI.compute_conflict!(model)
95+
@test MOI.get(model, MOI.ConflictStatus()) == MOI.CONFLICT_FOUND
96+
@test_throws ArgumentError MOI.get(model, MOI.ConstraintConflictStatus(), c)
97+
end

0 commit comments

Comments
 (0)