Skip to content

Commit 35b46e2

Browse files
committed
Fix definition of canmodify. This patch does not pass tests due to
problems with canmodify in the bridge code.
1 parent 8822416 commit 35b46e2

13 files changed

+39
-46
lines changed

src/Bridges/bridgeoptimizer.jl

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -209,11 +209,13 @@ function MOI.addconstraint!(b::AbstractBridgeOptimizer, f::MOI.AbstractFunction,
209209
MOI.addconstraint!(b.model, f, s)
210210
end
211211
end
212-
function MOI.canmodify(b::AbstractBridgeOptimizer, ci::CI, change)
213-
if isbridged(b, typeof(ci))
214-
MOI.canmodify(b.bridged, ci, change) && MOI.canmodify(b, MOIB.bridge(b, ci), change)
212+
function MOI.canmodify(b::AbstractBridgeOptimizer, ::Type{C}, ::Type{Chg}) where {C<:CI,Chg<:MOI.AbstractFunctionModification}
213+
if isbridged(b, C)
214+
MOI.canmodify(b.bridged, C, Chg)
215+
# TODO(@blegat): how should the following be implemented?
216+
# && MOI.canmodify(b, MOIB.bridge(b, ci), Chg)
215217
else
216-
MOI.canmodify(b.model, ci, change)
218+
MOI.canmodify(b.model, C, Chg)
217219
end
218220
end
219221
function MOI.modify!(b::AbstractBridgeOptimizer, ci::CI, change)

src/Bridges/detbridge.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ end
141141
MOI.canget(model::MOI.ModelLike, a::MOI.ConstraintDual, ::Type{<:LogDetBridge}) = false
142142

143143
# Constraints
144-
MOI.canmodify(model::MOI.ModelLike, c::LogDetBridge, change) = false
144+
MOI.canmodify(model::MOI.ModelLike, ::Type{<:LogDetBridge}, change) = false
145145

146146
"""
147147
RootDetBridge{T}
@@ -207,4 +207,4 @@ end
207207
MOI.canget(model::MOI.ModelLike, ::MOI.ConstraintDual, ::Type{<:RootDetBridge}) = false
208208

209209
# Constraints
210-
MOI.canmodify(model::MOI.ModelLike, c::RootDetBridge, change) = false
210+
MOI.canmodify(model::MOI.ModelLike, ::Type{<:RootDetBridge}, ::Type{<:MOI.AbstractFunctionModification}) = false

src/Bridges/geomeanbridge.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,4 +138,4 @@ MOI.canget(model::MOI.ModelLike, a::MOI.ConstraintDual, ::Type{<:GeoMeanBridge})
138138
#end
139139

140140
# Constraints
141-
MOI.canmodify(model::MOI.ModelLike, c::GeoMeanBridge, change) = false
141+
MOI.canmodify(model::MOI.ModelLike, ::Type{<:GeoMeanBridge}, ::Type{<:MOI.AbstractFunctionModification}) = false

src/Bridges/intervalbridge.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ function MOI.get(model::MOI.ModelLike, a::MOI.ConstraintDual, c::SplitIntervalBr
5151
end
5252

5353
# Constraints
54-
MOI.canmodify(model::MOI.ModelLike, c::SplitIntervalBridge, change) = true
54+
MOI.canmodify(model::MOI.ModelLike, ::Type{<:SplitIntervalBridge}, ::Type{<:MOI.AbstractFunctionModification}) = true
5555
function MOI.modify!(model::MOI.ModelLike, c::SplitIntervalBridge, change::MOI.AbstractFunctionModification)
5656
MOI.modify!(model, c.lower, change)
5757
MOI.modify!(model, c.upper, change)

src/Bridges/rsocbridge.jl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,4 @@ function MOI.canget(model::MOI.ModelLike, a::MOI.ConstraintDual, ::Type{RSOCBrid
6565
end
6666
MOI.get(model::MOI.ModelLike, attr::MOI.ConstraintDual, c::RSOCBridge) = _get(model, attr, c)
6767

68-
# Constraints
69-
MOI.canmodify(model::MOI.ModelLike, c::RSOCBridge, change) = false
68+
MOI.canmodify(model::MOI.ModelLike, ::Type{<:RSOCBridge}, ::Type{<:MOI.AbstractFunctionModification}) = false

src/Bridges/soctopsdbridge.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ function MOI.delete!(instance::MOI.AbstractOptimizer, c::SOCtoPSDCBridge)
8686
MOI.delete!(instance, c.cr)
8787
end
8888

89-
MOI.canmodify(::MOI.AbstractOptimizer, ::SOCtoPSDCBridge, change) = false
89+
MOI.canmodify(::MOI.AbstractOptimizer, ::Type{<:SOCtoPSDCBridge}, ::Type{<:MOI.AbstractFunctionModification}) = false
9090

9191
"""
9292
The `RSOCtoPSDCBridge` transforms the second order cone constraint ``\\lVert x \\rVert \\le 2tu`` with ``u \\ge 0`` into the semidefinite cone constraints
@@ -151,4 +151,4 @@ function MOI.delete!(instance::MOI.AbstractOptimizer, c::RSOCtoPSDCBridge)
151151
MOI.delete!(instance, c.cr)
152152
end
153153

154-
MOI.canmodify(::MOI.AbstractOptimizer, ::RSOCtoPSDCBridge, change) = false
154+
MOI.canmodify(::MOI.AbstractOptimizer, ::Type{<:RSOCtoPSDCBridge}, change) = false

src/Test/contlinear.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ function linear1test(model::MOI.ModelLike, config::TestConfig)
172172
@test MOI.get(model, MOI.NumberOfConstraints{MOI.SingleVariable,MOI.GreaterThan{Float64}}()) == 3
173173

174174
if config.modify_lhs
175-
@test MOI.canmodify(model, c, MOI.ScalarCoefficientChange{Float64})
175+
@test MOI.canmodify(model, typeof(c), MOI.ScalarCoefficientChange{Float64})
176176
MOI.modify!(model, c, MOI.ScalarCoefficientChange{Float64}(z, 1.0))
177177
else
178178
@test MOI.candelete(model, c)
@@ -781,7 +781,7 @@ function linear5test(model::MOI.ModelLike, config::TestConfig)
781781
# solution: x = 2, y = 0, objv = 2
782782

783783
if config.modify_lhs
784-
@test MOI.canmodify(model, c1, MOI.ScalarCoefficientChange{Float64})
784+
@test MOI.canmodify(model, typeof(c1), MOI.ScalarCoefficientChange{Float64})
785785
MOI.modify!(model, c1, MOI.ScalarCoefficientChange(y, 3.0))
786786
else
787787
@test MOI.candelete(model, c1)
@@ -980,7 +980,7 @@ function linear7test(model::MOI.ModelLike, config::TestConfig)
980980
# y <= 0.0
981981

982982
if config.modify_lhs
983-
@test MOI.canmodify(model, c1, MOI.VectorConstantChange{Float64})
983+
@test MOI.canmodify(model, typeof(c1), MOI.VectorConstantChange{Float64})
984984
MOI.modify!(model, c1, MOI.VectorConstantChange([-100.0]))
985985
else
986986
@test MOI.candelete(model, c1)
@@ -1004,7 +1004,7 @@ function linear7test(model::MOI.ModelLike, config::TestConfig)
10041004
# y <= -100.0
10051005

10061006
if config.modify_lhs
1007-
@test MOI.canmodify(model, c2, MOI.VectorConstantChange{Float64})
1007+
@test MOI.canmodify(model, typeof(c2), MOI.VectorConstantChange{Float64})
10081008
MOI.modify!(model, c2, MOI.VectorConstantChange([100.0]))
10091009
else
10101010
@test MOI.candelete(model, c2)

src/Utilities/cachingoptimizer.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -227,19 +227,19 @@ function MOI.addconstraint!(m::CachingOptimizer, func::MOI.AbstractFunction, set
227227
return cindex
228228
end
229229

230-
function MOI.canmodify(m::CachingOptimizer, cindex::CI, change)
231-
MOI.canmodify(m.model_cache, cindex, change) || return false
230+
function MOI.canmodify(m::CachingOptimizer, ::Type{C}, change) where C <: CI
231+
MOI.canmodify(m.model_cache, C, change) || return false
232232
if m.state == AttachedOptimizer && m.mode == Manual
233-
MOI.canmodify(m.optimizer, m.model_to_optimizer_map[cindex], change) || return false
233+
MOI.canmodify(m.optimizer, C, change) || return false
234234
end
235235
return true
236236
end
237237

238238
function MOI.modify!(m::CachingOptimizer, cindex::CI, change)
239-
if m.mode == Automatic && m.state == AttachedOptimizer && !MOI.canmodify(m.optimizer, cindex, typeof(change))
239+
if m.mode == Automatic && m.state == AttachedOptimizer && !MOI.canmodify(m.optimizer, typeof(cindex), typeof(change))
240240
resetoptimizer!(m)
241241
end
242-
@assert MOI.canmodify(m, cindex, typeof(change))
242+
@assert MOI.canmodify(m, typeof(cindex), typeof(change))
243243
MOI.modify!(m.model_cache, cindex, change)
244244
if m.state == AttachedOptimizer
245245
MOI.modify!(m.optimizer, m.model_to_optimizer_map[cindex], mapvariables(m.model_to_optimizer_map,change))

src/Utilities/mockoptimizer.jl

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -202,10 +202,9 @@ function MOI.delete!(mock::MockOptimizer, idx::MOI.ConstraintIndex)
202202
MOI.delete!(mock.condual, idx)
203203
end
204204

205-
function MOI.canmodify(mock::MockOptimizer, c::CI, change)
206-
MOI.canmodify(mock.inner_model, xor_index(c), change)
205+
function MOI.canmodify(mock::MockOptimizer, ::Type{C}, change) where C <: CI
206+
MOI.canmodify(mock.inner_model, C, change)
207207
end
208-
209208
function MOI.modify!(mock::MockOptimizer, c::CI, change)
210209
MOI.modify!(mock.inner_model, xor_index(c), xor_variables(change))
211210
end

src/Utilities/model.jl

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -248,15 +248,11 @@ function MOI.delete!(model::AbstractModel, ci::CI)
248248
end
249249
end
250250

251-
MOI.canmodify(::AbstractModel, ::CI, ::Type{<:MOI.AbstractFunctionModification}) = true
251+
MOI.canmodify(::AbstractModel, ::Type{<:CI}, ::Type{<:MOI.AbstractFunctionModification}) = true
252252
function MOI.modify!(model::AbstractModel, ci::CI, change::MOI.AbstractFunctionModification)
253253
_modify!(model, ci, getconstrloc(model, ci), change)
254254
end
255255

256-
MOI.canmodify(::AbstractModel, ::CI, ::Type{<:MOI.AbstractFunction}) = true
257-
function MOI.modify!(model::AbstractModel, ci::CI, change::MOI.AbstractFunction)
258-
_modify!(model, ci, getconstrloc(model, ci), change)
259-
end
260256
MOI.canset(::AbstractModel, ::MOI.ConstraintFunction, ::Type{<:CI}) = true
261257
function MOI.set!(model::AbstractModel, ::MOI.ConstraintFunction, ci::CI, change::MOI.AbstractFunction)
262258
_modify!(model, ci, getconstrloc(model, ci), change)

src/Utilities/universalfallback.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ end
152152
MOI.supportsconstraint(uf::UniversalFallback, ::Type{F}, ::Type{S}) where {F<:MOI.AbstractFunction, S<:MOI.AbstractSet} = true
153153
MOI.canaddconstraint(uf::UniversalFallback, ::Type{F}, ::Type{S}) where {F<:MOI.AbstractFunction, S<:MOI.AbstractSet} = MOI.canaddconstraint(uf.model, F, S)
154154
MOI.addconstraint!(uf::UniversalFallback, f::MOI.AbstractFunction, s::MOI.AbstractSet) = MOI.addconstraint!(uf.model, f, s)
155-
MOI.canmodify(uf::UniversalFallback, ci::CI, change) = MOI.canmodify(uf.model, ci, change)
155+
MOI.canmodify(uf::UniversalFallback, ci::Type{<:CI}, change) = MOI.canmodify(uf.model, ci, change)
156156
MOI.modify!(uf::UniversalFallback, ci::CI, change) = MOI.modify!(uf.model, ci, change)
157157

158158
function MOI.canset(uf::UniversalFallback, ::MOI.ConstraintSet, ::Type{C}) where C <: CI

src/constraints.jl

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,24 +116,21 @@ function set!(model::ModelLike, ::ConstraintFunction, constraint_index, func)
116116
end
117117

118118
"""
119-
## Partial Modifications
119+
canmodify(model::ModelLike, ::Type{CI}, ::Type{M})::Bool where CI<:ConstraintIndex where M<:AbstractFunctionModification
120120
121-
canmodify(model::ModelLike, c::ConstraintIndex, ::Type{M})::Bool where M<:AbstractFunctionModification
122-
123-
Return a `Bool` indicating whether it is possible to apply a modification of type `M` to the function of constraint `c`.
121+
Return a `Bool` indicating whether it is possible to apply a modification of
122+
type `M` to the function of constraint of type `CI`.
124123
125124
### Examples
126125
127126
```julia
128-
canmodify(model, c, ScalarConstantChange{Float64})
127+
canmodify(model, MOI.ConstraintIndex{MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64}}, ScalarConstantChange{Float64})
129128
```
130129
"""
131130
function canmodify end
132-
canmodify(model::ModelLike, c::ConstraintIndex, change) = false
131+
canmodify(model::ModelLike, constraint_index, change) = false
133132

134133
"""
135-
## Partial Modifications
136-
137134
modify!(model::ModelLike, c::ConstraintIndex, change::AbstractFunctionModification)
138135
139136
Apply the modification specified by `change` to the function of constraint `c`.

test/bridge.jl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ MOIU.@model NoRSOCModel () (EqualTo, GreaterThan, LessThan, Interval) (Zeros, No
132132
# Dual is not yet implemented for RootDet and GeoMean bridges
133133
@test !MOI.canget(fullbridgedmock, MOI.ConstraintDual(), MOI.ConstraintIndex{MOI.VectorAffineFunction{Float64}, MOI.RootDetConeTriangle})
134134
ci = first(MOI.get(fullbridgedmock, MOI.ListOfConstraintIndices{MOI.VectorAffineFunction{Float64}, MOI.RootDetConeTriangle}()))
135-
@test !MOI.canmodify(fullbridgedmock, ci, MOI.VectorAffineFunction{Float64})
135+
@test !MOI.canmodify(fullbridgedmock, typeof(ci), MOI.VectorConstantChange{Float64})
136136
test_delete_bridge(fullbridgedmock, ci, 4, ((MOI.VectorAffineFunction{Float64}, MOI.RotatedSecondOrderCone, 0),
137137
(MOI.VectorAffineFunction{Float64}, MOI.GeometricMeanCone, 0),
138138
(MOI.VectorAffineFunction{Float64}, MOI.PositiveSemidefiniteConeTriangle, 0)))
@@ -165,7 +165,7 @@ end
165165
bridgedmock = MOIB.SplitInterval{Float64}(mock)
166166
MOIT.linear10test(bridgedmock, config)
167167
ci = first(MOI.get(bridgedmock, MOI.ListOfConstraintIndices{MOI.ScalarAffineFunction{Float64}, MOI.Interval{Float64}}()))
168-
@test MOI.canmodify(bridgedmock, ci, MOI.ScalarAffineFunction{Float64})
168+
@test MOI.canmodify(bridgedmock, typeof(ci), MOI.ScalarConstantChange{Float64})
169169
newf = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([1.0, -1.0], MOI.get(bridgedmock, MOI.ListOfVariableIndices())), 0.0)
170170
MOI.set!(bridgedmock, MOI.ConstraintFunction(), ci, newf)
171171
@test MOI.canget(bridgedmock, MOI.ConstraintFunction(), typeof(ci))
@@ -184,7 +184,7 @@ end
184184
(MOI.VectorAffineFunction{Float64}, MOI.SecondOrderCone) => [[3/2, 1/2, -1.0, -1.0]])
185185
MOIT.rotatedsoc1ftest(bridgedmock, config)
186186
ci = first(MOI.get(bridgedmock, MOI.ListOfConstraintIndices{MOI.VectorAffineFunction{Float64}, MOI.RotatedSecondOrderCone}()))
187-
@test !MOI.canmodify(bridgedmock, ci, MOI.VectorAffineFunction{Float64})
187+
@test !MOI.canmodify(bridgedmock, typeof(ci), MOI.VectorConstantChange{Float64})
188188
test_delete_bridge(bridgedmock, ci, 2, ((MOI.VectorAffineFunction{Float64}, MOI.SecondOrderCone, 0),))
189189
end
190190

@@ -196,7 +196,7 @@ end
196196
# Dual is not yet implemented for GeoMean bridge
197197
@test !MOI.canget(bridgedmock, MOI.ConstraintDual(), MOI.ConstraintIndex{MOI.VectorOfVariables, MOI.GeometricMeanCone})
198198
ci = first(MOI.get(bridgedmock, MOI.ListOfConstraintIndices{MOI.VectorAffineFunction{Float64}, MOI.GeometricMeanCone}()))
199-
@test !MOI.canmodify(bridgedmock, ci, MOI.VectorAffineFunction{Float64})
199+
@test !MOI.canmodify(bridgedmock, typeof(ci), MOI.VectorConstantChange{Float64})
200200
test_delete_bridge(bridgedmock, ci, 4, ((MOI.VectorAffineFunction{Float64}, MOI.RotatedSecondOrderCone, 0),
201201
(MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64}, 1)))
202202
end
@@ -209,7 +209,7 @@ end
209209
MOIT.soc1vtest(bridgedmock, config)
210210
MOIT.soc1ftest(bridgedmock, config)
211211
ci = first(MOI.get(bridgedmock, MOI.ListOfConstraintIndices{MOI.VectorAffineFunction{Float64}, MOI.SecondOrderCone}()))
212-
@test !MOI.canmodify(bridgedmock, ci, MOI.VectorAffineFunction{Float64})
212+
@test !MOI.canmodify(bridgedmock, typeof(ci), MOI.VectorConstantChange{Float64})
213213
test_delete_bridge(bridgedmock, ci, 3, ((MOI.VectorAffineFunction{Float64}, MOI.PositiveSemidefiniteConeTriangle, 0),))
214214
end
215215

@@ -223,7 +223,7 @@ end
223223
(MOI.VectorAffineFunction{Float64}, MOI.PositiveSemidefiniteConeTriangle) => [[2, -1/2, 2/8, -1/2, 2/8, 2/8]])
224224
MOIT.rotatedsoc1ftest(bridgedmock, config)
225225
ci = first(MOI.get(bridgedmock, MOI.ListOfConstraintIndices{MOI.VectorAffineFunction{Float64}, MOI.RotatedSecondOrderCone}()))
226-
@test !MOI.canmodify(bridgedmock, ci, MOI.VectorAffineFunction{Float64})
226+
@test !MOI.canmodify(bridgedmock, typeof(ci), MOI.VectorConstantChange{Float64})
227227
test_delete_bridge(bridgedmock, ci, 2, ((MOI.VectorAffineFunction{Float64}, MOI.PositiveSemidefiniteConeTriangle, 0),))
228228
end
229229

@@ -235,7 +235,7 @@ end
235235
# Dual is not yet implemented for LogDet bridge
236236
@test !MOI.canget(bridgedmock, MOI.ConstraintDual(), MOI.ConstraintIndex{MOI.VectorAffineFunction{Float64}, MOI.LogDetConeTriangle})
237237
ci = first(MOI.get(bridgedmock, MOI.ListOfConstraintIndices{MOI.VectorAffineFunction{Float64}, MOI.LogDetConeTriangle}()))
238-
@test !MOI.canmodify(bridgedmock, ci, MOI.VectorAffineFunction{Float64})
238+
@test !MOI.canmodify(bridgedmock, typeof(ci), MOI.VectorConstantChange{Float64})
239239
test_delete_bridge(bridgedmock, ci, 4, ((MOI.VectorAffineFunction{Float64}, MOI.ExponentialCone, 0), (MOI.VectorAffineFunction{Float64}, MOI.PositiveSemidefiniteConeTriangle, 0)))
240240
end
241241

@@ -247,7 +247,7 @@ end
247247
# Dual is not yet implemented for RootDet bridge
248248
@test !MOI.canget(bridgedmock, MOI.ConstraintDual(), MOI.ConstraintIndex{MOI.VectorAffineFunction{Float64}, MOI.RootDetConeTriangle})
249249
ci = first(MOI.get(bridgedmock, MOI.ListOfConstraintIndices{MOI.VectorAffineFunction{Float64}, MOI.RootDetConeTriangle}()))
250-
@test !MOI.canmodify(bridgedmock, ci, MOI.VectorAffineFunction{Float64})
250+
@test !MOI.canmodify(bridgedmock, typeof(ci), MOI.VectorConstantChange{Float64})
251251
test_delete_bridge(bridgedmock, ci, 4, ((MOI.VectorAffineFunction{Float64}, MOI.RotatedSecondOrderCone, 0),
252252
(MOI.VectorAffineFunction{Float64}, MOI.GeometricMeanCone, 0),
253253
(MOI.VectorAffineFunction{Float64}, MOI.PositiveSemidefiniteConeTriangle, 0)))

0 commit comments

Comments
 (0)