Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
odow committed Oct 30, 2024
1 parent 6d5f51e commit 8a11eba
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 30 deletions.
44 changes: 30 additions & 14 deletions src/Utilities/copy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@ function _copy_constraints(
index_map,
cis_src::Vector{MOI.ConstraintIndex{F,S}},
) where {F,S}
if !MOI.supports_constraint(dest, F, S)
throw(MOI.UnsupportedConstraint{F,S}())

Check warning on line 193 in src/Utilities/copy.jl

View check run for this annotation

Codecov / codecov/patch

src/Utilities/copy.jl#L193

Added line #L193 was not covered by tests
end
return _copy_constraints(dest, src, index_map, index_map[F, S], cis_src)
end

Expand Down Expand Up @@ -383,19 +386,6 @@ function default_copy_to(dest::MOI.ModelLike, src::MOI.ModelLike)
error("Model $(typeof(dest)) does not support copy_to.")
end
MOI.empty!(dest)
for (F, S) in MOI.get(src, MOI.ListOfConstraintTypesPresent())
if F == MOI.VariableIndex
if !MOI.supports_add_constrained_variable(dest, S)
throw(MOI.UnsupportedConstraint{F,S}())
end
elseif F == MOI.VectorOfVariables
if !MOI.supports_add_constrained_variables(dest, S)
throw(MOI.UnsupportedConstraint{F,S}())
end
elseif !MOI.supports_constraint(dest, F, S)
throw(MOI.UnsupportedConstraint{F,S}())
end
end
index_map, vis_src, constraints_not_added =
_copy_variables_with_set(dest, src)
# Copy variable attributes
Expand Down Expand Up @@ -424,13 +414,21 @@ struct _CopyVariablesWithSetCache
end

function _build_copy_variables_with_set_cache(
dest::MOI.ModelLike,
src::MOI.ModelLike,
cache::_CopyVariablesWithSetCache,
::Type{S},
) where {S<:MOI.AbstractScalarSet}
F = MOI.VariableIndex
supports =
MOI.supports_add_constrained_variable(dest, S) ||
MOI.supports_constraint(dest, F, S)
indices = MOI.ConstraintIndex{F,S}[]
for ci in MOI.get(src, MOI.ListOfConstraintIndices{F,S}())
# Check this inside the loop so there exists at least one constraint
if !supports
throw(MOI.UnsupportedConstraint{F,S}())
end
x = MOI.get(src, MOI.ConstraintFunction(), ci)
if x in cache.variables_with_domain
# `x` is already assigned to a domain. Add this constraint via
Expand Down Expand Up @@ -479,13 +477,21 @@ function _is_variable_cone(
end

function _build_copy_variables_with_set_cache(
dest::MOI.ModelLike,
src::MOI.ModelLike,
cache::_CopyVariablesWithSetCache,
::Type{S},
) where {S<:MOI.AbstractVectorSet}
F = MOI.VectorOfVariables
supports =

Check warning on line 486 in src/Utilities/copy.jl

View check run for this annotation

Codecov / codecov/patch

src/Utilities/copy.jl#L486

Added line #L486 was not covered by tests
MOI.supports_add_constrained_variables(dest, S) ||
MOI.supports_constraint(dest, F, S)
indices = MOI.ConstraintIndex{F,S}[]
for ci in MOI.get(src, MOI.ListOfConstraintIndices{F,S}())
# Check this inside the loop so there exists at least one constraint
if !supports
throw(MOI.UnsupportedConstraint{F,S}())

Check warning on line 493 in src/Utilities/copy.jl

View check run for this annotation

Codecov / codecov/patch

src/Utilities/copy.jl#L492-L493

Added lines #L492 - L493 were not covered by tests
end
f = MOI.get(src, MOI.ConstraintFunction(), ci)
if _is_variable_cone(cache, f)
for fi in f.variables
Expand Down Expand Up @@ -544,7 +550,7 @@ function _copy_variables_with_set(dest, src)
cache.variable_to_column[v] = i
end
for S in sorted_variable_sets_by_cost(dest, src)
_build_copy_variables_with_set_cache(src, cache, S)
_build_copy_variables_with_set_cache(dest, src, cache, S)
end
column(x::MOI.VariableIndex) = cache.variable_to_column[x]
start_column(x) = column(first(x[1]))
Expand Down Expand Up @@ -715,9 +721,14 @@ function _try_constrain_variables_on_creation(
index_map::IndexMap,
::Type{S},
) where {S<:MOI.AbstractVectorSet}
supports = MOI.supports_add_constrained_variables(dest, S)

Check warning on line 724 in src/Utilities/copy.jl

View check run for this annotation

Codecov / codecov/patch

src/Utilities/copy.jl#L724

Added line #L724 was not covered by tests
not_added = MOI.ConstraintIndex{MOI.VectorOfVariables,S}[]
for ci_src in
MOI.get(src, MOI.ListOfConstraintIndices{MOI.VectorOfVariables,S}())
# Check this inside the loop so there exists at least one constraint
if !supports
throw(MOI.UnsupportedConstraint{MOI.VectorOfVariables,S}())

Check warning on line 730 in src/Utilities/copy.jl

View check run for this annotation

Codecov / codecov/patch

src/Utilities/copy.jl#L729-L730

Added lines #L729 - L730 were not covered by tests
end
f_src = MOI.get(src, MOI.ConstraintFunction(), ci_src)
if !allunique(f_src.variables)
# Can't add it because there are duplicate variables
Expand All @@ -743,9 +754,14 @@ function _try_constrain_variables_on_creation(
index_map::IndexMap,
::Type{S},
) where {S<:MOI.AbstractScalarSet}
supports = MOI.supports_add_constrained_variable(dest, S)

Check warning on line 757 in src/Utilities/copy.jl

View check run for this annotation

Codecov / codecov/patch

src/Utilities/copy.jl#L757

Added line #L757 was not covered by tests
not_added = MOI.ConstraintIndex{MOI.VariableIndex,S}[]
for ci_src in
MOI.get(src, MOI.ListOfConstraintIndices{MOI.VariableIndex,S}())
# Check this inside the loop so there exists at least one constraint
if !supports
throw(MOI.UnsupportedConstraint{MOI.VariableIndex,S}())

Check warning on line 763 in src/Utilities/copy.jl

View check run for this annotation

Codecov / codecov/patch

src/Utilities/copy.jl#L762-L763

Added lines #L762 - L763 were not covered by tests
end
f_src = MOI.get(src, MOI.ConstraintFunction(), ci_src)
if haskey(index_map, f_src)
# Can't add it because it contains a variable previously added
Expand Down
50 changes: 34 additions & 16 deletions test/Utilities/copy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -176,12 +176,8 @@ MOI.empty!(model::ConstrainedVariablesModel) = empty!(model.added_constrained)

MOI.supports_incremental_interface(::ConstrainedVariablesModel) = true

function MOI.copy_to(
dest::ConstrainedVariablesModel,
src::MOI.ModelLike;
kwargs...,
)
return MOIU.default_copy_to(dest, src; kwargs...)
function MOI.copy_to(dest::ConstrainedVariablesModel, src::MOI.ModelLike)
return MOIU.default_copy_to(dest, src)
end

function MOI.add_variables(model::ConstrainedVariablesModel, n)
Expand All @@ -192,6 +188,13 @@ function MOI.add_variables(model::ConstrainedVariablesModel, n)
return MOI.VariableIndex.(m .+ (1:n))
end

function MOI.supports_add_constrained_variables(
::ConstrainedVariablesModel,
::Type{<:MOI.AbstractVectorSet},
)
return true
end

function MOI.add_constrained_variables(
model::ConstrainedVariablesModel,
set::MOI.AbstractVectorSet,
Expand All @@ -204,6 +207,14 @@ function MOI.add_constrained_variables(
return MOI.VariableIndex.(m .+ (1:MOI.dimension(set))), ci
end

function MOI.supports_constraint(
::ConstrainedVariablesModel,
::Type{MOI.VectorOfVariables},
::Type{<:MOI.AbstractVectorSet},
)
return true
end

function MOI.add_constraint(
::ConstrainedVariablesModel,
func::MOI.VectorOfVariables,
Expand Down Expand Up @@ -261,6 +272,14 @@ function MOI.add_variable(model::AbstractConstrainedVariablesModel)
return MOI.add_variable(model.inner)
end

function MOI.supports_constraint(
::AbstractConstrainedVariablesModel,
::Type{<:MOI.AbstractFunction},
::Type{<:MOI.AbstractSet},
)
return true
end

function MOI.add_constraint(
model::AbstractConstrainedVariablesModel,
f::MOI.AbstractFunction,
Expand All @@ -273,10 +292,9 @@ end

function MOI.copy_to(
dest::AbstractConstrainedVariablesModel,
src::MOI.ModelLike;
kwargs...,
src::MOI.ModelLike,
)
return MOIU.default_copy_to(dest, src; kwargs...)
return MOIU.default_copy_to(dest, src)
end

MOI.supports_incremental_interface(::AbstractConstrainedVariablesModel) = true
Expand Down Expand Up @@ -321,7 +339,7 @@ function MOI.supports_constraint(
::Type{MOI.VectorOfVariables},
::Type{MOI.Nonnegatives},
)
return false
return true
end

function MOI.supports_add_constrained_variables(
Expand Down Expand Up @@ -1003,32 +1021,32 @@ function test_copy_to_sorted_sets()
return
end

function test_add_constraint_not_allowed_scalar_variable()
function test_default_copy_to_unsupported_scalar_variable()
F, S = MOI.VariableIndex, MOI.GreaterThan{Float64}
model = MOI.Utilities.Model{Float64}()
x, _ = MOI.add_constrained_variable(model, MOI.GreaterThan(1.0))
dest = MOI.FileFormats.CBF.Model()
@test_throws(MOI.AddConstraintNotAllowed{F,S}, MOI.copy_to(dest, model))
@test_throws(MOI.UnsupportedConstraint{F,S}, MOI.copy_to(dest, model))
return
end

function test_add_constraint_not_allowed_vector_variables()
function test_default_copy_to_unsupported_vector_variables()
F, S = MOI.VectorOfVariables, MOI.AllDifferent
model = MOI.Utilities.Model{Float64}()
x, _ = MOI.add_constrained_variables(model, MOI.AllDifferent(3))
dest = MOI.FileFormats.CBF.Model()
@test_throws(MOI.AddConstraintNotAllowed{F,S}, MOI.copy_to(dest, model))
@test_throws(MOI.UnsupportedConstraint{F,S}, MOI.copy_to(dest, model))
return
end

function test_add_constraint_not_allowed_scalar_function()
function test_default_copy_to_unsupported_scalar_function()
F, S = MOI.ScalarNonlinearFunction, MOI.EqualTo{Float64}
model = MOI.Utilities.Model{Float64}()
x = MOI.add_variable(model)
f = MOI.ScalarNonlinearFunction(:log, Any[x])
MOI.add_constraint(model, f, MOI.EqualTo(0.0))
dest = MOI.FileFormats.CBF.Model()
@test_throws(MOI.AddConstraintNotAllowed{F,S}, MOI.copy_to(dest, model))
@test_throws(MOI.UnsupportedConstraint{F,S}, MOI.copy_to(dest, model))
return
end

Expand Down

0 comments on commit 8a11eba

Please sign in to comment.