Skip to content

Commit a481d6e

Browse files
authored
Fix error with external functions and sets. (#582)
* Fix error with external functions and sets. * Tidy model tests * Fix and add tests for external sets in `@bridge`.
1 parent 6dcee0b commit a481d6e

File tree

5 files changed

+91
-6
lines changed

5 files changed

+91
-6
lines changed

src/Bridges/singlebridgeoptimizer.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ macro bridge(modelname, bridge, ss, sst, vs, vst, sf, sft, vf, vft)
4343

4444
esc(quote
4545
$MOIU.@model $bridged_model_name $ss $sst $vs $vst $sf $sft $vf $vft
46-
const $modelname{T, OT<:MOI.ModelLike} = $MOIB.SingleBridgeOptimizer{$bridge{T}, $bridged_model_name{T}, OT}
46+
const $modelname{T, OT<:$MOI.ModelLike} = $MOIB.SingleBridgeOptimizer{$bridge{T}, $bridged_model_name{T}, OT}
4747
$MOIB.is_bridged(::$modelname, ::Type{<:$bridged_funs}, ::Type{<:$bridged_sets}) = true
48-
supports_bridging_constraint(::$modelname, ::Type{<:$bridged_funs}, ::Type{<:$bridged_sets}) = true
48+
$MOIB.supports_bridging_constraint(::$modelname, ::Type{<:$bridged_funs}, ::Type{<:$bridged_sets}) = true
4949
end)
5050
end

src/Utilities/model.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -465,8 +465,8 @@ end
465465

466466
# (MOI, :Zeros) -> :(MOI.Zeros)
467467
# (:Zeros) -> :(MOI.Zeros)
468-
_set(s::SymbolSet) = s.s
469-
_fun(s::SymbolFun) = s.s
468+
_set(s::SymbolSet) = esc(s.s)
469+
_fun(s::SymbolFun) = esc(s.s)
470470
function _typedset(s::SymbolSet)
471471
if s.typed
472472
:($(_set(s)){T})

test/Utilities/model.jl

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,37 @@
11
# TODO: It's hard to find where Model is defined!
22

3+
# We need to test this in a module at the top level because it can't be defined
4+
# in a testset. If it runs without error, then we're okay.
5+
module TestExternalModel
6+
using MathOptInterface
7+
struct NewSet <: MathOptInterface.AbstractScalarSet end
8+
struct NewFunction <: MathOptInterface.AbstractScalarFunction end
9+
Base.copy(::NewFunction) = NewFunction()
10+
Base.copy(::NewSet) = NewSet()
11+
MathOptInterface.Utilities.@model(ExternalModel,
12+
(MathOptInterface.ZeroOne, NewSet,),
13+
(),
14+
(),
15+
(),
16+
(NewFunction,),
17+
(),
18+
(),
19+
()
20+
)
21+
end
22+
23+
@testset "External @model" begin
24+
model = TestExternalModel.ExternalModel{Float64}()
25+
c = MOI.add_constraint(
26+
model, TestExternalModel.NewFunction(), TestExternalModel.NewSet())
27+
@test typeof(c) == MOI.ConstraintIndex{TestExternalModel.NewFunction,
28+
TestExternalModel.NewSet}
29+
c2 = MOI.add_constraint(
30+
model, TestExternalModel.NewFunction(), MOI.ZeroOne())
31+
@test typeof(c2) ==
32+
MOI.ConstraintIndex{TestExternalModel.NewFunction, MOI.ZeroOne}
33+
end
34+
335
@testset "Name test" begin
436
MOIT.nametest(Model{Float64}())
537
end

test/bridge.jl

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,3 +397,57 @@ end
397397
(MOI.VectorAffineFunction{Float64}, MOI.PositiveSemidefiniteConeTriangle, 0)))
398398
end
399399
end
400+
401+
# We need to test this in a module at the top level because it can't be defined
402+
# in a testset. If it runs without error, then we're okay.
403+
module TestExternalBridge
404+
using MathOptInterface
405+
406+
struct StrictlyGreaterThan <: MathOptInterface.AbstractScalarSet end
407+
struct StrictlyGreaterBridge{T} <: MathOptInterface.Bridges.AbstractBridge end
408+
409+
function StrictlyGreaterBridge(
410+
model,
411+
func::MathOptInterface.SingleVariable,
412+
set::StrictlyGreaterThan)
413+
return StrictlyGreaterBridge{Float64}()
414+
end
415+
416+
function MathOptInterface.supports_constraint(
417+
::Type{StrictlyGreaterBridge{T}},
418+
::Type{MathOptInterface.SingleVariable},
419+
::Type{StrictlyGreaterThan}) where {T}
420+
return true
421+
end
422+
423+
function MathOptInterface.Bridges.added_constraint_types(
424+
::Type{StrictlyGreaterBridge{T}},
425+
::Type{MathOptInterface.SingleVariable},
426+
::Type{StrictlyGreaterThan}) where {T}
427+
return [(
428+
MathOptInterface.SingleVariable,
429+
MathOptInterface.GreaterThan{T}
430+
)]
431+
end
432+
433+
MathOptInterface.Bridges.@bridge(StrictlyGreater, StrictlyGreaterBridge,
434+
(StrictlyGreaterThan, ),
435+
(),
436+
(),
437+
(),
438+
(MathOptInterface.SingleVariable, ),
439+
(),
440+
(),
441+
()
442+
)
443+
end
444+
445+
@testset "@bridge with external components" begin
446+
model = SimpleModel{Float64}();
447+
@test MOI.supports_constraint(model, MOI.SingleVariable, MOI.GreaterThan{Float64})
448+
@test !MOI.supports_constraint(model, MOI.SingleVariable, TestExternalBridge.StrictlyGreaterThan)
449+
450+
bridge = TestExternalBridge.StrictlyGreater{Float64}(model);
451+
@test MOI.supports_constraint(bridge, MOI.SingleVariable, MOI.GreaterThan{Float64})
452+
@test MOI.supports_constraint(bridge, MOI.SingleVariable, TestExternalBridge.StrictlyGreaterThan)
453+
end

test/hygiene.jl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ module Hygiene
33
using Compat, Compat.Test
44

55
import MathOptInterface
6-
# We do not define MOI and MOIU constants as the macros
7-
# should not rely on the fact that theses are defined in the outer scope
6+
const MOI = MathOptInterface
87

98
# Dict is used in the @model macro but setting Dict in the outer scope
109
# should not affect it

0 commit comments

Comments
 (0)