From c67c2eda8971ceb8afacb382a6362c7071c4a7d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Sat, 26 Jun 2021 10:54:30 -0400 Subject: [PATCH 1/3] Throw error when adding constraint to MatrixOfConstraints --- src/Utilities/matrix_of_constraints.jl | 20 ++++++++++++++++++++ test/Utilities/matrix_of_constraints.jl | 16 ++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/Utilities/matrix_of_constraints.jl b/src/Utilities/matrix_of_constraints.jl index 60d9f25970..d6d5a57566 100644 --- a/src/Utilities/matrix_of_constraints.jl +++ b/src/Utilities/matrix_of_constraints.jl @@ -316,6 +316,18 @@ function _add_set(sets, i, func::MOI.AbstractVectorFunction) return add_set(sets, i, MOI.output_dimension(func)) end +const _MODIF_NOT_ALLOWED = """ +MatrixOfConstraints does not allow modifications to be made to the model once +`MOI.Utilities.final_touch` has been called. This is called at the end of +`MOI.copy_to` and in `MOI.Utilities.attach_optimizer` (which is called by +`MOI.optimize!` in a `MOI.Utilities.CachingOptimizer`). In order to be able to +apply modifications to this model, you should add a layer +`MOI.Utilities.CachingOptimizer(MOI.Utilities.Model{Float64}(), model)` +where `model` is the current model. This will automatically empty `model` when +modifications are done after `MOI.Utilities.final_touch` is called and copy the +model again in `MOI.Utilities.attach_optimizer`. +""" + function _add_constraint( model::MatrixOfConstraints, i::Int, @@ -343,6 +355,9 @@ function MOI.add_constraint( if i === nothing || F != _affine_function_type(T, S) throw(MOI.UnsupportedConstraint{F,S}()) end + if model.final_touch + throw(MOI.AddConstraintNotAllowed{F,S}(_MODIF_NOT_ALLOWED)) + end return _add_constraint(model, i, IdentityMap(), func, set) end @@ -434,6 +449,11 @@ end function final_touch(model::MatrixOfConstraints, index_map) if model.final_touch + # If `default_copy_to` calls `final_touch`, then `index_map` is not + # `nothing` and `final_touch` should be `false`. + # When `CachingOptimizer` calls this, `index_map` is `nothing` + # and `final_touch` might be `true`. + # So we are always in a case where `index_map` is `nothing`. @assert index_map === nothing return end diff --git a/test/Utilities/matrix_of_constraints.jl b/test/Utilities/matrix_of_constraints.jl index ba8058edac..7807b9a33d 100644 --- a/test/Utilities/matrix_of_constraints.jl +++ b/test/Utilities/matrix_of_constraints.jl @@ -510,6 +510,22 @@ function test_copy() return test_copy(MOIU.OneBasedIndexing) end +function test_modif() + model = + matrix_instance(Int, MOIU.Box{Int}, OrdLP{Int}, MOIU.OneBasedIndexing) + x = MOI.add_variable(model) + fx = MOI.SingleVariable(x) + func = 2fx + set = MOI.EqualTo(1) + c = MOI.add_constraint(model, func, set) + MOIU.final_touch(model, nothing) + @test_throws MOI.DeleteNotAllowed(c) MOI.delete(model, c) + err = MOI.AddConstraintNotAllowed{typeof(func),typeof(set)}( + MOIU._MODIF_NOT_ALLOWED, + ) + @test_throws err MOI.add_constraint(model, func, set) +end + end TestMatrixOfConstraints.runtests() From efd8fe88e81b4d21eb3126f549191441716f67f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Tue, 29 Jun 2021 10:02:52 -0400 Subject: [PATCH 2/3] No abbreviation --- src/Utilities/matrix_of_constraints.jl | 4 ++-- test/Utilities/matrix_of_constraints.jl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Utilities/matrix_of_constraints.jl b/src/Utilities/matrix_of_constraints.jl index d6d5a57566..1c1fa629c4 100644 --- a/src/Utilities/matrix_of_constraints.jl +++ b/src/Utilities/matrix_of_constraints.jl @@ -316,7 +316,7 @@ function _add_set(sets, i, func::MOI.AbstractVectorFunction) return add_set(sets, i, MOI.output_dimension(func)) end -const _MODIF_NOT_ALLOWED = """ +const _MATRIXOFCONSTRAINTS_MODIFY_NOT_ALLOWED_ERROR_MESSAGE = """ MatrixOfConstraints does not allow modifications to be made to the model once `MOI.Utilities.final_touch` has been called. This is called at the end of `MOI.copy_to` and in `MOI.Utilities.attach_optimizer` (which is called by @@ -356,7 +356,7 @@ function MOI.add_constraint( throw(MOI.UnsupportedConstraint{F,S}()) end if model.final_touch - throw(MOI.AddConstraintNotAllowed{F,S}(_MODIF_NOT_ALLOWED)) + throw(MOI.AddConstraintNotAllowed{F,S}(_MATRIXOFCONSTRAINTS_MODIFY_NOT_ALLOWED_ERROR_MESSAGE)) end return _add_constraint(model, i, IdentityMap(), func, set) end diff --git a/test/Utilities/matrix_of_constraints.jl b/test/Utilities/matrix_of_constraints.jl index 7807b9a33d..74f71a2fdf 100644 --- a/test/Utilities/matrix_of_constraints.jl +++ b/test/Utilities/matrix_of_constraints.jl @@ -521,7 +521,7 @@ function test_modif() MOIU.final_touch(model, nothing) @test_throws MOI.DeleteNotAllowed(c) MOI.delete(model, c) err = MOI.AddConstraintNotAllowed{typeof(func),typeof(set)}( - MOIU._MODIF_NOT_ALLOWED, + MOIU._MATRIXOFCONSTRAINTS_MODIFY_NOT_ALLOWED_ERROR_MESSAGE, ) @test_throws err MOI.add_constraint(model, func, set) end From dccdbe4deb0f6c69bf430df5e8861a8be6efb43a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Tue, 29 Jun 2021 10:18:24 -0400 Subject: [PATCH 3/3] Fix format --- src/Utilities/matrix_of_constraints.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Utilities/matrix_of_constraints.jl b/src/Utilities/matrix_of_constraints.jl index 1c1fa629c4..13e9883c07 100644 --- a/src/Utilities/matrix_of_constraints.jl +++ b/src/Utilities/matrix_of_constraints.jl @@ -356,7 +356,11 @@ function MOI.add_constraint( throw(MOI.UnsupportedConstraint{F,S}()) end if model.final_touch - throw(MOI.AddConstraintNotAllowed{F,S}(_MATRIXOFCONSTRAINTS_MODIFY_NOT_ALLOWED_ERROR_MESSAGE)) + throw( + MOI.AddConstraintNotAllowed{F,S}( + _MATRIXOFCONSTRAINTS_MODIFY_NOT_ALLOWED_ERROR_MESSAGE, + ), + ) end return _add_constraint(model, i, IdentityMap(), func, set) end