From 79d0c6e358a87dac2abc1b6be67cd5b53d849b77 Mon Sep 17 00:00:00 2001 From: joaquimg Date: Wed, 11 Jun 2025 11:43:43 -0300 Subject: [PATCH 1/2] [WIP] New conflict attributes --- src/attributes.jl | 77 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/src/attributes.jl b/src/attributes.jl index 6bc6ec2845..8238eb4639 100644 --- a/src/attributes.jl +++ b/src/attributes.jl @@ -1844,6 +1844,16 @@ struct ConflictStatus <: AbstractModelAttribute end attribute_value_type(::ConflictStatus) = ConflictStatusCode +""" + ConflictCount() + +An [`AbstractModelAttribute`](@ref) for the number of conflicts found by the +solver in the most recent call to [`compute_conflict!`](@ref). +""" +struct ConflictCount <: AbstractModelAttribute end + +attribute_value_type(::ConflictCount) = Int + """ ListOfVariableAttributesSet() @@ -2677,13 +2687,78 @@ end A constraint attribute to query the [`ConflictParticipationStatusCode`](@ref) indicating whether the constraint participates in the conflict. + +## `conflict_index` + +The optimizer may return multiple conflicts. See [`ConflictCount`](@ref) +for querying the number of conflicts found. + +## Implementation + +Optimizers should implement the following methods: +```julia +MOI.get(::Optimizer, ::MOI.ConstraintConflictStatus, ::MOI.ConstraintIndex)::T +``` +They should not implement [`set`](@ref) or [`supports`](@ref). """ -struct ConstraintConflictStatus <: AbstractConstraintAttribute end +struct ConstraintConflictStatus <: AbstractConstraintAttribute + conflict_index::Int + ConstraintConflictStatus(conflict_index = 1) = new(conflict_index) +end function attribute_value_type(::ConstraintConflictStatus) return ConflictParticipationStatusCode end +""" + ListOfConstraintIndicesInConflict(conflict_index::Int = 1) + +An [`AbstractModelAttribute`](@ref) for the `Vector{ConstraintIndex}` of all +constraints that participate in the conflict with index `conflict_index`. + +The `conflict_index` is 1 by default, but it can be set to any value between +1 and the number of conflicts found by the solver, as indicated by +[`ConflictCount`](@ref). + +## Implementation +Optimizers may implement the following methods: +```julia +MOI.get( + ::Optimizer, + ::MOI.ListOfConstraintIndicesInConflict, +)::Vector{MOI.ConstraintIndex} +``` +A ineficient fallback is available for `get`. +They should not implement [`set`](@ref) or [`supports`](@ref). +""" +struct ListOfConstraintIndicesInConflict <: MOI.AbstractModelAttribute + conflict_index::Int + ListOfConstraintIndicesInConflict(conflict_index = 1) = new(conflict_index) +end + +function attribute_value_type(::ListOfConstraintIndicesInConflict) + return Vector{ConstraintIndex} +end + +function get( + model::ModelLike, + attr::ListOfConstraintIndicesInConflict, +)::Vector{ConstraintIndex} + result = Vector{ConstraintIndex}() + conflict_index = attr.conflict_index + constraint_types = get(model, ListOfConstraintTypesPresent()) + for (F, S) in constraint_types + constraints = MOI.get(model, ListOfConstraintIndices{F,S}()) + for con in constraints + status = get(model, ConstraintConflictStatus(conflict_index), con) + if status == NOT_IN_CONFLICT + push!(result, con) + end + end + end + return result +end + """ UserDefinedFunction(name::Symbol, arity::Int) <: AbstractModelAttribute From 7896c49dbfd1ab8973e15ea027f3e8744bf55acf Mon Sep 17 00:00:00 2001 From: joaquimg Date: Wed, 16 Jul 2025 09:40:39 -0300 Subject: [PATCH 2/2] remove list of --- src/attributes.jl | 49 ----------------------------------------------- 1 file changed, 49 deletions(-) diff --git a/src/attributes.jl b/src/attributes.jl index 8238eb4639..d3beefe5a1 100644 --- a/src/attributes.jl +++ b/src/attributes.jl @@ -2710,55 +2710,6 @@ function attribute_value_type(::ConstraintConflictStatus) return ConflictParticipationStatusCode end -""" - ListOfConstraintIndicesInConflict(conflict_index::Int = 1) - -An [`AbstractModelAttribute`](@ref) for the `Vector{ConstraintIndex}` of all -constraints that participate in the conflict with index `conflict_index`. - -The `conflict_index` is 1 by default, but it can be set to any value between -1 and the number of conflicts found by the solver, as indicated by -[`ConflictCount`](@ref). - -## Implementation -Optimizers may implement the following methods: -```julia -MOI.get( - ::Optimizer, - ::MOI.ListOfConstraintIndicesInConflict, -)::Vector{MOI.ConstraintIndex} -``` -A ineficient fallback is available for `get`. -They should not implement [`set`](@ref) or [`supports`](@ref). -""" -struct ListOfConstraintIndicesInConflict <: MOI.AbstractModelAttribute - conflict_index::Int - ListOfConstraintIndicesInConflict(conflict_index = 1) = new(conflict_index) -end - -function attribute_value_type(::ListOfConstraintIndicesInConflict) - return Vector{ConstraintIndex} -end - -function get( - model::ModelLike, - attr::ListOfConstraintIndicesInConflict, -)::Vector{ConstraintIndex} - result = Vector{ConstraintIndex}() - conflict_index = attr.conflict_index - constraint_types = get(model, ListOfConstraintTypesPresent()) - for (F, S) in constraint_types - constraints = MOI.get(model, ListOfConstraintIndices{F,S}()) - for con in constraints - status = get(model, ConstraintConflictStatus(conflict_index), con) - if status == NOT_IN_CONFLICT - push!(result, con) - end - end - end - return result -end - """ UserDefinedFunction(name::Symbol, arity::Int) <: AbstractModelAttribute