Skip to content

Commit 79d0c6e

Browse files
committed
[WIP] New conflict attributes
1 parent fa61f9c commit 79d0c6e

File tree

1 file changed

+76
-1
lines changed

1 file changed

+76
-1
lines changed

src/attributes.jl

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1844,6 +1844,16 @@ struct ConflictStatus <: AbstractModelAttribute end
18441844

18451845
attribute_value_type(::ConflictStatus) = ConflictStatusCode
18461846

1847+
"""
1848+
ConflictCount()
1849+
1850+
An [`AbstractModelAttribute`](@ref) for the number of conflicts found by the
1851+
solver in the most recent call to [`compute_conflict!`](@ref).
1852+
"""
1853+
struct ConflictCount <: AbstractModelAttribute end
1854+
1855+
attribute_value_type(::ConflictCount) = Int
1856+
18471857
"""
18481858
ListOfVariableAttributesSet()
18491859
@@ -2677,13 +2687,78 @@ end
26772687
26782688
A constraint attribute to query the [`ConflictParticipationStatusCode`](@ref)
26792689
indicating whether the constraint participates in the conflict.
2690+
2691+
## `conflict_index`
2692+
2693+
The optimizer may return multiple conflicts. See [`ConflictCount`](@ref)
2694+
for querying the number of conflicts found.
2695+
2696+
## Implementation
2697+
2698+
Optimizers should implement the following methods:
2699+
```julia
2700+
MOI.get(::Optimizer, ::MOI.ConstraintConflictStatus, ::MOI.ConstraintIndex)::T
2701+
```
2702+
They should not implement [`set`](@ref) or [`supports`](@ref).
26802703
"""
2681-
struct ConstraintConflictStatus <: AbstractConstraintAttribute end
2704+
struct ConstraintConflictStatus <: AbstractConstraintAttribute
2705+
conflict_index::Int
2706+
ConstraintConflictStatus(conflict_index = 1) = new(conflict_index)
2707+
end
26822708

26832709
function attribute_value_type(::ConstraintConflictStatus)
26842710
return ConflictParticipationStatusCode
26852711
end
26862712

2713+
"""
2714+
ListOfConstraintIndicesInConflict(conflict_index::Int = 1)
2715+
2716+
An [`AbstractModelAttribute`](@ref) for the `Vector{ConstraintIndex}` of all
2717+
constraints that participate in the conflict with index `conflict_index`.
2718+
2719+
The `conflict_index` is 1 by default, but it can be set to any value between
2720+
1 and the number of conflicts found by the solver, as indicated by
2721+
[`ConflictCount`](@ref).
2722+
2723+
## Implementation
2724+
Optimizers may implement the following methods:
2725+
```julia
2726+
MOI.get(
2727+
::Optimizer,
2728+
::MOI.ListOfConstraintIndicesInConflict,
2729+
)::Vector{MOI.ConstraintIndex}
2730+
```
2731+
A ineficient fallback is available for `get`.
2732+
They should not implement [`set`](@ref) or [`supports`](@ref).
2733+
"""
2734+
struct ListOfConstraintIndicesInConflict <: MOI.AbstractModelAttribute
2735+
conflict_index::Int
2736+
ListOfConstraintIndicesInConflict(conflict_index = 1) = new(conflict_index)
2737+
end
2738+
2739+
function attribute_value_type(::ListOfConstraintIndicesInConflict)
2740+
return Vector{ConstraintIndex}
2741+
end
2742+
2743+
function get(
2744+
model::ModelLike,
2745+
attr::ListOfConstraintIndicesInConflict,
2746+
)::Vector{ConstraintIndex}
2747+
result = Vector{ConstraintIndex}()
2748+
conflict_index = attr.conflict_index
2749+
constraint_types = get(model, ListOfConstraintTypesPresent())
2750+
for (F, S) in constraint_types
2751+
constraints = MOI.get(model, ListOfConstraintIndices{F,S}())
2752+
for con in constraints
2753+
status = get(model, ConstraintConflictStatus(conflict_index), con)
2754+
if status == NOT_IN_CONFLICT
2755+
push!(result, con)
2756+
end
2757+
end
2758+
end
2759+
return result
2760+
end
2761+
26872762
"""
26882763
UserDefinedFunction(name::Symbol, arity::Int) <: AbstractModelAttribute
26892764

0 commit comments

Comments
 (0)