Skip to content

Commit 3f7be94

Browse files
committed
Begin refactor from modifyconstraint(m, c, set) to
`set!(m, ConstraintSet(), c, set)`. This patch currently errors as it needs to be implemented for src/Utilities/model.jl, but I'm not sure where to start.
1 parent ef32b86 commit 3f7be94

File tree

11 files changed

+94
-63
lines changed

11 files changed

+94
-63
lines changed

perf/cachingoptimizer.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ MOIU.resetoptimizer!(caching_optimizer) # detach optimizer
1212
v = MOI.addvariables!(caching_optimizer, 2)
1313
cf = MOI.ScalarAffineFunction(v, [0.0, 0.0], 0.0)
1414
c = MOI.addconstraint!(caching_optimizer, cf, MOI.Interval(-Inf, 1.0))
15-
@btime MOI.modifyconstraint!($caching_optimizer, $c, $(MOI.Interval(0.0, 2.0)))
15+
@btime MOI.set!($caching_optimizer, $(MOI.ConstraintSet()), $c, $(MOI.Interval(0.0, 2.0)))
1616
MOIU.attachoptimizer!(caching_optimizer)
17-
@btime MOI.modifyconstraint!($caching_optimizer, $c, $(MOI.Interval(0.0, 2.0)))
18-
@btime MOI.modifyconstraint!($(caching_optimizer.model_cache), $c, $(MOI.Interval(0.0, 2.0)))
19-
@btime MOI.modifyconstraint!($(caching_optimizer.optimizer), $(caching_optimizer.model_to_optimizer_map[c]), $(MOI.Interval(0.0, 2.0)))
17+
@btime MOI.set!($caching_optimizer, $(MOI.ConstraintSet()), $c, $(MOI.Interval(0.0, 2.0)))
18+
@btime MOI.set!($(caching_optimizer.model_cache), $(MOI.ConstraintSet()), $c, $(MOI.Interval(0.0, 2.0)))
19+
@btime MOI.set!($(caching_optimizer.optimizer), $(MOI.ConstraintSet()), $(caching_optimizer.model_to_optimizer_map[c]), $(MOI.Interval(0.0, 2.0)))

src/Bridges/intervalbridge.jl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ function MOI.modifyconstraint!(model::MOI.ModelLike, c::SplitIntervalBridge, cha
5656
MOI.modifyconstraint!(model, c.lower, change)
5757
MOI.modifyconstraint!(model, c.upper, change)
5858
end
59-
function MOI.modifyconstraint!(model::MOI.ModelLike, c::SplitIntervalBridge, change::MOI.Interval)
60-
MOI.modifyconstraint!(model, c.lower, MOI.GreaterThan(change.lower))
61-
MOI.modifyconstraint!(model, c.upper, MOI.LessThan(change.upper))
59+
60+
MOI.canset(model::MOI.ModelLike, ::MOI.ConstraintSet, c::SplitIntervalBridge, ::Type{MOI.Interval}) = true
61+
function MOI.set!(model::MOI.ModelLike, ::MOI.ConstraintSet, c::SplitIntervalBridge, change::MOI.Interval)
62+
MOI.set!(model, MOI.ConstraintSet(), c.lower, MOI.GreaterThan(change.lower))
63+
MOI.set!(model, MOI.ConstraintSet(), c.upper, MOI.LessThan(change.upper))
6264
end

src/MathOptInterface.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,8 @@ function copy! end
150150
include("indextypes.jl")
151151
include("functions.jl")
152152
include("sets.jl")
153-
include("constraints.jl")
154153
include("attributes.jl")
154+
include("constraints.jl")
155155
include("objectives.jl")
156156
include("variables.jl")
157157
include("nlp.jl")

src/Test/contlinear.jl

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -229,8 +229,8 @@ function linear1test(model::MOI.ModelLike, config::TestConfig)
229229
# s.t. x + y + z <= 1
230230
# x >= -1
231231
# y,z >= 0
232-
@test MOI.canmodifyconstraint(model, vc1, MOI.GreaterThan{Float64})
233-
MOI.modifyconstraint!(model, vc1, MOI.GreaterThan(-1.0))
232+
@test MOI.canset(model, MOI.ConstraintSet(), vc1, MOI.GreaterThan{Float64})
233+
MOI.set!(model, MOI.ConstraintSet(), vc1, MOI.GreaterThan(-1.0))
234234

235235
if config.solve
236236
MOI.optimize!(model)
@@ -255,8 +255,8 @@ function linear1test(model::MOI.ModelLike, config::TestConfig)
255255
# max x + 2z
256256
# s.t. x + y + z <= 1
257257
# x, y >= 0, z = 0 (vc3)
258-
@test MOI.canmodifyconstraint(model, vc1, MOI.GreaterThan{Float64})
259-
MOI.modifyconstraint!(model, vc1, MOI.GreaterThan(0.0))
258+
@test MOI.canset(model, MOI.ConstraintSet(), vc1, MOI.GreaterThan{Float64})
259+
MOI.set!(model, MOI.ConstraintSet(), vc1, MOI.GreaterThan(0.0))
260260

261261
@test MOI.candelete(model, vc3)
262262
MOI.delete!(model, vc3)
@@ -666,8 +666,8 @@ function linear4test(model::MOI.ModelLike, config::TestConfig)
666666
# Min x - y
667667
# s.t. 100.0 <= x
668668
# y <= 0.0
669-
@test MOI.canmodifyconstraint(model, c1, MOI.GreaterThan{Float64})
670-
MOI.modifyconstraint!(model, c1, MOI.GreaterThan(100.0))
669+
@test MOI.canset(model, MOI.ConstraintSet(), c1, MOI.GreaterThan{Float64})
670+
MOI.set!(model, MOI.ConstraintSet(), c1, MOI.GreaterThan(100.0))
671671
if config.solve
672672
MOI.optimize!(model)
673673
@test MOI.get(model, MOI.TerminationStatus()) == MOI.Success
@@ -681,8 +681,8 @@ function linear4test(model::MOI.ModelLike, config::TestConfig)
681681
# Min x - y
682682
# s.t. 100.0 <= x
683683
# y <= -100.0
684-
@test MOI.canmodifyconstraint(model, c2, MOI.LessThan{Float64})
685-
MOI.modifyconstraint!(model, c2, MOI.LessThan(-100.0))
684+
@test MOI.canset(model, MOI.ConstraintSet(), c2, MOI.LessThan{Float64})
685+
MOI.set!(model, MOI.ConstraintSet(), c2, MOI.LessThan(-100.0))
686686
if config.solve
687687
MOI.optimize!(model)
688688
@test MOI.get(model, MOI.TerminationStatus()) == MOI.Success
@@ -778,8 +778,8 @@ function linear5test(model::MOI.ModelLike, config::TestConfig)
778778
# 1 x + 2 y <= 4
779779
# x >= 0, y >= 0
780780
#
781-
# solution: x = 2, y = 0, objv = 2
782-
781+
# solution: x = 2, y = 0, objv = 2
782+
783783
if config.modify_lhs
784784
@test MOI.canmodifyconstraint(model, c1, MOI.ScalarCoefficientChange{Float64})
785785
MOI.modifyconstraint!(model, c1, MOI.ScalarCoefficientChange(y, 3.0))
@@ -790,7 +790,7 @@ function linear5test(model::MOI.ModelLike, config::TestConfig)
790790
@test MOI.canaddconstraint(model, typeof(cf1), MOI.LessThan{Float64})
791791
c1 = MOI.addconstraint!(model, cf1, MOI.LessThan(4.0))
792792
end
793-
793+
794794
if config.solve
795795
MOI.optimize!(model)
796796

@@ -905,8 +905,8 @@ function linear6test(model::MOI.ModelLike, config::TestConfig)
905905
# Min x - y
906906
# s.t. 100.0 <= x
907907
# y <= 0.0
908-
@test MOI.canmodifyconstraint(model, c1, MOI.GreaterThan{Float64})
909-
MOI.modifyconstraint!(model, c1, MOI.GreaterThan(100.0))
908+
@test MOI.canset(model, MOI.ConstraintSet(), c1, MOI.GreaterThan{Float64})
909+
MOI.set!(model, MOI.ConstraintSet(), c1, MOI.GreaterThan(100.0))
910910
if config.solve
911911
MOI.optimize!(model)
912912
@test MOI.get(model, MOI.TerminationStatus()) == MOI.Success
@@ -920,8 +920,8 @@ function linear6test(model::MOI.ModelLike, config::TestConfig)
920920
# Min x - y
921921
# s.t. 100.0 <= x
922922
# y <= -100.0
923-
@test MOI.canmodifyconstraint(model, c2, MOI.LessThan{Float64})
924-
MOI.modifyconstraint!(model, c2, MOI.LessThan(-100.0))
923+
@test MOI.canset(model, MOI.ConstraintSet(), c2, MOI.LessThan{Float64})
924+
MOI.set!(model, MOI.ConstraintSet(), c2, MOI.LessThan(-100.0))
925925
if config.solve
926926
MOI.optimize!(model)
927927
@test MOI.get(model, MOI.TerminationStatus()) == MOI.Success
@@ -984,11 +984,11 @@ function linear7test(model::MOI.ModelLike, config::TestConfig)
984984
MOI.modifyconstraint!(model, c1, MOI.VectorConstantChange([-100.0]))
985985
else
986986
@test MOI.candelete(model, c1)
987-
MOI.delete!(model, c1)
987+
MOI.delete!(model, c1)
988988
@test MOI.canaddconstraint(model, MOI.VectorAffineFunction{Float64}, MOI.Nonnegatives)
989-
c1 = MOI.addconstraint!(model, MOI.VectorAffineFunction([MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(1.0, x))], [-100.0]), MOI.Nonnegatives(1))
989+
c1 = MOI.addconstraint!(model, MOI.VectorAffineFunction([MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(1.0, x))], [-100.0]), MOI.Nonnegatives(1))
990990
end
991-
991+
992992
if config.solve
993993
MOI.optimize!(model)
994994
@test MOI.get(model, MOI.TerminationStatus()) == MOI.Success
@@ -1012,7 +1012,7 @@ function linear7test(model::MOI.ModelLike, config::TestConfig)
10121012
@test MOI.canaddconstraint(model, MOI.VectorAffineFunction{Float64}, MOI.Nonpositives)
10131013
c2 = MOI.addconstraint!(model, MOI.VectorAffineFunction([MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(1.0, y))], [100.0]), MOI.Nonpositives(1))
10141014
end
1015-
1015+
10161016
if config.solve
10171017
MOI.optimize!(model)
10181018
@test MOI.get(model, MOI.TerminationStatus()) == MOI.Success
@@ -1330,8 +1330,8 @@ function linear10test(model::MOI.ModelLike, config::TestConfig)
13301330
end
13311331
end
13321332

1333-
@test MOI.canmodifyconstraint(model, c, MOI.Interval{Float64})
1334-
MOI.modifyconstraint!(model, c, MOI.Interval(2.0, 12.0))
1333+
@test MOI.canset(model, MOI.ConstraintSet(), c, MOI.Interval{Float64})
1334+
MOI.set!(model, MOI.ConstraintSet(), c, MOI.Interval(2.0, 12.0))
13351335

13361336
if config.query
13371337
@test MOI.canget(model, MOI.ConstraintSet(), typeof(c))

src/Utilities/cachingoptimizer.jl

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -247,14 +247,21 @@ function MOI.modifyconstraint!(m::CachingOptimizer, cindex::CI, change)
247247
return
248248
end
249249

250-
function MOI.modifyconstraint!(m::CachingOptimizer, cindex::CI{F,S}, set::S) where {F<:MOI.AbstractFunction, S<:MOI.AbstractSet}
251-
if m.mode == Automatic && m.state == AttachedOptimizer && !MOI.canmodifyconstraint(m.optimizer, cindex, S)
250+
function MOI.canset(m::CachingOptimizer, ::MOI.ConstraintSet, cindex::CI, ::Type{S}) where S <: MOI.AbstractSet
251+
MOI.canset(m.model_cache, MOI.ConstraintSet(), cindex, S) || return false
252+
if m.state == AttachedOptimizer && m.mode == Manual
253+
MOI.canset(m.optimizer, MOI.ConstraintSet(), m.model_to_optimizer_map[cindex], S) || return false
254+
end
255+
return true
256+
end
257+
function MOI.set!(m::CachingOptimizer, ::MOI.ConstraintSet, cindex::CI{F,S}, set::S) where {F<:MOI.AbstractFunction, S<:MOI.AbstractSet}
258+
if m.mode == Automatic && m.state == AttachedOptimizer && !MOI.canset(m.optimizer, MOI.ConstraintSet(), cindex, S)
252259
resetoptimizer!(m)
253260
end
254-
@assert MOI.canmodifyconstraint(m, cindex, S)
255-
MOI.modifyconstraint!(m.model_cache, cindex, set)
261+
@assert MOI.canset(m, MOI.ConstraintSet(), cindex, S)
262+
MOI.set!(m.model_cache, MOI.ConstraintSet(), cindex, set)
256263
if m.state == AttachedOptimizer
257-
MOI.modifyconstraint!(m.optimizer, m.model_to_optimizer_map[cindex], set)
264+
MOI.set!(m.optimizer, MOI.ConstraintSet(), m.model_to_optimizer_map[cindex], set)
258265
end
259266
return
260267
end

src/Utilities/mockoptimizer.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,9 @@ function MOI.modifyconstraint!(mock::MockOptimizer, c::CI, change)
210210
MOI.modifyconstraint!(mock.inner_model, xor_index(c), xor_variables(change))
211211
end
212212

213-
function MOI.modifyconstraint!(mock::MockOptimizer, c::CI{F,S}, set::S) where {F<:MOI.AbstractFunction, S<:MOI.AbstractSet}
214-
MOI.modifyconstraint!(mock.inner_model, xor_index(c), set)
213+
MOI.canset(mock::MockOptimizer, ::MOI.ConstraintSet, c::CI{F,S}, set::Type{S}) where {F<:MOI.AbstractFunction, S<:MOI.AbstractSet} = true
214+
function MOI.set!(mock::MockOptimizer, ::MOI.ConstraintSet, c::CI{F,S}, set::S) where {F<:MOI.AbstractFunction, S<:MOI.AbstractSet}
215+
MOI.set!(mock.inner_model, ConstraintSet(), xor_index(c), set)
215216
end
216217

217218
function MOI.canmodifyobjective(mock::MockOptimizer, change)

src/Utilities/model.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ MOIU.broadcastcall(constrs -> _addcon(solver, constrs), model)
326326
```
327327
"""
328328
function broadcastcall end
329+
329330
"""
330331
broadcastvcat(f::Function, model::AbstractModel)
331332
@@ -339,6 +340,7 @@ _getfun(ci, f, s) = f
339340
_getfun(cindices::Tuple) = _getfun(cindices...)
340341
_getfuns(constrs::Vector) = _getfun.(constrs)
341342
MOIU.broadcastvcat(_getfuns, model)
343+
```
342344
"""
343345
function broadcastvcat end
344346

src/Utilities/universalfallback.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,14 @@ MOI.addconstraint!(uf::UniversalFallback, f::MOI.AbstractFunction, s::MOI.Abstra
155155
MOI.canmodifyconstraint(uf::UniversalFallback, ci::CI, change) = MOI.canmodifyconstraint(uf.model, ci, change)
156156
MOI.modifyconstraint!(uf::UniversalFallback, ci::CI, change) = MOI.modifyconstraint!(uf.model, ci, change)
157157

158+
function MOI.canset(uf::UniversalFallback, cs::MOI.ConstraintSet, ci::CI, ::Type{S}) where S <: MOI.AbstractSet
159+
MOI.canset(uf.model, ci, S)
160+
end
161+
function MOI.set!(uf::UniversalFallback, cs::MOI.ConstraintSet, ci::CI, set::AbstractSet)
162+
MOI.set!(uf.model, ci, set)
163+
end
164+
165+
158166
# Objective
159167
MOI.canmodifyobjective(uf::UniversalFallback, ::Type{M}) where M<:MOI.AbstractFunctionModification = MOI.canmodifyobjective(uf.model, M)
160168
MOI.modifyobjective!(uf::UniversalFallback, change::MOI.AbstractFunctionModification) = MOI.modifyobjective!(uf.model, change)

src/attributes.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -491,8 +491,8 @@ If `N` is omitted, it is 1 by default.
491491
492492
Given a constraint `function-in-set`, the `ConstraintPrimal` is the value of the
493493
function evaluated at the primal solution of the variables. For example, given
494-
the constraint `ScalarAffineFunction([x,y], [1, 2], 3)`-in-`Interval(0, 20)` and
495-
a primal solution of `(x,y) = (4,5)`, the `ConstraintPrimal` solution of the
494+
the constraint `ScalarAffineFunction([x,y], [1, 2], 3)`-in-`Interval(0, 20)` and
495+
a primal solution of `(x,y) = (4,5)`, the `ConstraintPrimal` solution of the
496496
constraint is `1 * 4 + 2 * 5 + 3 = 17`.
497497
"""
498498
struct ConstraintPrimal <: AbstractConstraintAttribute

src/constraints.jl

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,44 @@ function addconstraints! end
4343
# default fallback
4444
addconstraints!(model::ModelLike, funcs, sets) = addconstraint!.(model, funcs, sets)
4545

46+
4647
"""
47-
## Modify Function
48+
canset(model::ModelLike, ::ConstraintSet, c::ConstraintIndex{F,S}, ::Type{S})::Bool
4849
49-
canmodifyconstraint(model::ModelLike, c::ConstraintIndex{F,S}, ::Type{F})::Bool
50+
Return a `Bool` indicating whether the set in constraint `c` can be replaced by
51+
another set of the same type `S` as the original set.
52+
"""
53+
canset(model::ModelLike, ::ConstraintSet, c::ConstraintIndex, ::Type{S}) where S = false
5054

51-
Return a `Bool` indicating whether the function in constraint `c` can be replaced by another function of the same type `F` as the original function.
55+
"""
56+
set!(model::ModelLike, ::ConstraintSet, c::ConstraintIndex{F,S}, set::S)
57+
58+
Change the set of constraint `c` to the new set `set` which should be of the
59+
same type as the original set.
60+
61+
### Examples
62+
63+
If `c` is a `ConstraintIndex{F,Interval}`
64+
65+
```julia
66+
set!(model, ConstraintSet(), c, Interval(0, 5))
67+
set!(model, ConstraintSet(), c, NonPositives) # Error
68+
```
69+
"""
70+
function set!(model::ModelLike, cs::ConstraintSet, c::ConstraintIndex{F,S1}, s::S2) where F where S1 where S2
71+
if S1 != S2 # throw helpful error
72+
error("Cannot modify sets of different types. Use `transformconstraint!` instead.")
73+
else # throw original error suggesting that it is not implemented
74+
throw(MethodError(set!, (model, cs, c, s)))
75+
end
76+
end
5277

53-
## Modify Set
78+
"""
79+
## Modify Function
5480
55-
canmodifyconstraint(model::ModelLike, c::ConstraintIndex{F,S}, ::Type{S})::Bool
81+
canmodifyconstraint(model::ModelLike, c::ConstraintIndex{F,S}, ::Type{F})::Bool
5682
57-
Return a `Bool` indicating whether the set in constraint `c` can be replaced by another set of the same type `S` as the original set.
83+
Return a `Bool` indicating whether the function in constraint `c` can be replaced by another function of the same type `F` as the original function.
5884
5985
## Partial Modifications
6086
@@ -87,21 +113,6 @@ modifyconstraint!(model, c, ScalarAffineFunction([v1,v2],[1.0,2.0],5.0))
87113
modifyconstraint!(model, c, SingleVariable(v1)) # Error
88114
```
89115
90-
## Modify Set
91-
92-
modifyconstraint!(model::ModelLike, c::ConstraintIndex{F,S}, set::S)
93-
94-
Change the set of constraint `c` to the new set `set` which should be of the same type as the original set.
95-
96-
### Examples
97-
98-
If `c` is a `ConstraintIndex{F,Interval}`
99-
100-
```julia
101-
modifyconstraint!(model, c, Interval(0, 5))
102-
modifyconstraint!(model, c, NonPositives) # Error
103-
```
104-
105116
## Partial Modifications
106117
107118
modifyconstraint!(model::ModelLike, c::ConstraintIndex, change::AbstractFunctionModification)

test/cachingoptimizer.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,16 @@
6262
@test MOI.canaddconstraint(m.optimizer, MOI.SingleVariable, MOI.LessThan{Float64})
6363
@test MOI.canaddconstraint(m, MOI.SingleVariable, MOI.LessThan{Float64})
6464
lb = MOI.addconstraint!(m, MOI.SingleVariable(v), MOI.LessThan(10.0))
65-
@test MOI.canmodifyconstraint(m, lb, MOI.LessThan{Float64})
66-
MOI.modifyconstraint!(m, lb, MOI.LessThan(11.0))
65+
@test MOI.canset(m, MOI.ConstraintSet(), lb, MOI.LessThan{Float64})
66+
MOI.set!(m, MOI.ConstraintSet(), lb, MOI.LessThan(11.0))
6767
@test MOI.get(m, MOI.ConstraintSet(), lb) == MOI.LessThan(11.0)
6868
@test MOI.get(m, MOI.ConstraintFunction(), lb) == MOI.SingleVariable(v)
6969

7070
MOIU.dropoptimizer!(m)
7171
@test MOIU.state(m) == MOIU.NoOptimizer
7272

73-
@test MOI.canmodifyconstraint(m, lb, MOI.LessThan{Float64})
74-
MOI.modifyconstraint!(m, lb, MOI.LessThan(12.0))
73+
@test MOI.canset(m, MOI.ConstraintSet(), lb, MOI.LessThan{Float64})
74+
MOI.set!(m, MOI.ConstraintSet(), lb, MOI.LessThan(12.0))
7575
@test MOI.get(m, MOI.ConstraintSet(), lb) == MOI.LessThan(12.0)
7676

7777
@test MOI.candelete(m, x[2])

0 commit comments

Comments
 (0)