Skip to content

Commit a7f7064

Browse files
committed
rename to exclusive
1 parent e5f686f commit a7f7064

File tree

10 files changed

+51
-48
lines changed

10 files changed

+51
-48
lines changed

src/constraints.jl

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,10 @@ function JuMP.delete(model::Model, cref::DisjunctionRef)
117117
delete!(gdp_data(model).constraint_to_indicator, cref)
118118
end
119119
delete!(_disjunctions(model), index(cref))
120-
exactly1_dict = gdp_data(model).exactly1_constraints
121-
if haskey(exactly1_dict, cref)
122-
JuMP.delete(model, exactly1_dict[cref])
123-
delete!(exactly1_dict, cref)
120+
exclusive_dict = gdp_data(model).exclusive_constraints
121+
if haskey(exclusive_dict, cref)
122+
JuMP.delete(model, exclusive_dict[cref])
123+
delete!(exclusive_dict, cref)
124124
end
125125
_set_ready_to_optimize(model, false)
126126
return
@@ -316,7 +316,7 @@ function _disjunction(
316316
model::Model, # TODO: generalize to AbstractModel
317317
structure::AbstractVector, #generalize for containers
318318
name::String;
319-
exactly1::Bool = true,
319+
exclusive::Bool = true,
320320
extra_kwargs...
321321
)
322322
# check for unneeded keywords
@@ -326,12 +326,12 @@ function _disjunction(
326326
# create the disjunction
327327
dref = _create_disjunction(_error, model, structure, name, false)
328328
# add the exactly one constraint if desired
329-
if exactly1
329+
if exclusive
330330
lvars = JuMP.constraint_object(dref).indicators
331331
func = Union{Number, LogicalVariableRef}[1, lvars...]
332332
set = _MOIExactly(length(lvars) + 1)
333333
cref = JuMP.add_constraint(model, JuMP.VectorConstraint(func, set))
334-
gdp_data(model).exactly1_constraints[dref] = cref
334+
gdp_data(model).exclusive_constraints[dref] = cref
335335
end
336336
return dref
337337
end
@@ -354,7 +354,7 @@ function _disjunction(
354354
structure,
355355
name::String,
356356
tag::Disjunct;
357-
exactly1::Bool = true,
357+
exclusive::Bool = true,
358358
extra_kwargs...
359359
)
360360
# check for unneeded keywords
@@ -366,12 +366,12 @@ function _disjunction(
366366
obj = constraint_object(dref)
367367
_add_indicator_var(_DisjunctConstraint(obj, tag.indicator), dref, model)
368368
# add the exactly one constraint if desired
369-
if exactly1
369+
if exclusive
370370
lvars = JuMP.constraint_object(dref).indicators
371371
func = LogicalVariableRef[tag.indicator, lvars...]
372372
set = _MOIExactly(length(lvars) + 1)
373373
cref = JuMP.add_constraint(model, JuMP.VectorConstraint(func, set))
374-
gdp_data(model).exactly1_constraints[dref] = cref
374+
gdp_data(model).exclusive_constraints[dref] = cref
375375
end
376376
return dref
377377
end
@@ -396,15 +396,17 @@ end
396396
disjunct_indicators::Vector{LogicalVariableRef},
397397
[nested_tag::Disjunct],
398398
[name::String = ""];
399-
[exactly1::Bool = true]
399+
[exclusive::Bool = true]
400400
)
401401
402402
Create a disjunction comprised of disjuncts with indicator variables `disjunct_indicators`
403403
and add it to `model`. For nested disjunctions, the `nested_tag` is required to indicate
404-
which disjunct it will be part of in the parent disjunction. By default, `exactly1` adds
404+
which disjunct it will be part of in the parent disjunction. By default, `exclusive` adds
405405
a constraint of the form `@constraint(model, disjunct_indicators in Exactly(1))` making
406406
the disjuncts exclusive to one another; this is required for certain reformulations like
407-
[`Hull`](@ref). To conveniently generate many disjunctions at once, see [`@disjunction`](@ref)
407+
[`Hull`](@ref). For nested disjunctions, `exclusive` creates a constraint of the form
408+
`@constraint(model, disjunct_indicators in Exactly(nested_tag.indicator))`.
409+
To conveniently generate many disjunctions at once, see [`@disjunction`](@ref)
408410
and [`@disjunctions`](@ref).
409411
"""
410412
function disjunction(

src/datatypes.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ mutable struct GDPData
391391
disjunctions::_MOIUC.CleverDict{DisjunctionIndex, ConstraintData{Disjunction}}
392392

393393
# Exactly one constraint mappings
394-
exactly1_constraints::Dict{DisjunctionRef, LogicalConstraintRef}
394+
exclusive_constraints::Dict{DisjunctionRef, LogicalConstraintRef}
395395

396396
# Indicator variable mappings
397397
indicator_to_binary::Dict{LogicalVariableRef, VariableRef}

src/hull.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ end
149149
################################################################################
150150
# HULL REFORMULATION
151151
################################################################################
152-
requires_exactly1(::Hull) = true
152+
requires_exclusive(::Hull) = true
153153

154154
function _reformulate_disjunctions(model::Model, method::Hull)
155155
_query_variable_bounds(model, method)

src/macros.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,8 @@ The recognized keyword arguments in `kw_args` are the following:
155155
the constraint names are set to `base_name[...]` for each index `...`
156156
of the axes `axes`.
157157
- `container`: Specify the container type.
158-
- `exactly1`: Specify a `Bool` whether an exactly one constraint for the indicator
159-
variables should be added.
158+
- `exclusive`: Specify a `Bool` whether an constraint should be added to make
159+
the disjuncts strictly exlcusive of one another.
160160
161161
To create disjunctions without macros, see [`disjunction`](@ref).
162162
"""

src/reformulate.jl

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,22 +47,23 @@ end
4747
# DISJUNCTIONS
4848
################################################################################
4949
"""
50-
requires_exactly1(method::AbstractReformulationMethod)
50+
requires_exclusive(method::AbstractReformulationMethod)
5151
52-
Return a `Bool` whether `method` requires an exactly one constraint for each
53-
disjunction. For new reformulation method types, this should be extended to
54-
in case such a constraint is required (defaults to `false` otherwise).
52+
Return a `Bool` whether `method` requires an the disjuncts to be exactly exclusive
53+
for each disjunction (i.e., it requires an exactly one constraint). For new
54+
reformulation method types, this should be extended to in case such a constraint
55+
is required (defaults to `false` otherwise).
5556
"""
56-
requires_exactly1(::AbstractReformulationMethod) = false
57+
requires_exclusive(::AbstractReformulationMethod) = false
5758

5859
# disjunctions
5960
function _reformulate_all_disjunctions(model::Model, method::AbstractReformulationMethod)
6061
for (idx, disj) in _disjunctions(model)
6162
disj.constraint.nested && continue #only reformulate top level disjunctions
6263
dref = DisjunctionRef(model, idx)
63-
if requires_exactly1(method) && !haskey(gdp_data(model).exactly1_constraints, dref)
64-
error("Reformulation method `$method` requires exactly one constraints for " *
65-
"disjunctions, but `exactly1 = false` for disjunction `$dref`.")
64+
if requires_exclusive(method) && !haskey(gdp_data(model).exclusive_constraints, dref)
65+
error("Reformulation method `$method` requires exclusive disjuncts for " *
66+
"disjunctions, but `exclusive = false` for disjunction `$dref`.")
6667
end
6768
ref_cons = reformulate_disjunction(model, disj.constraint, method)
6869
for (i, ref_con) in enumerate(ref_cons)

test/constraints/bigm.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,10 +288,10 @@ function test_nested_bigm()
288288
@variable(model, z[1:2], Logical)
289289
@constraint(model, x <= 5, Disjunct(y[1]))
290290
@constraint(model, x >= 5, Disjunct(y[2]))
291-
@disjunction(model, inner, y, Disjunct(z[1]), exactly1 = false)
291+
@disjunction(model, inner, y, Disjunct(z[1]), exclusive = false)
292292
@constraint(model, x <= 10, Disjunct(z[1]))
293293
@constraint(model, x >= 10, Disjunct(z[2]))
294-
@disjunction(model, outer, z, exactly1 = false)
294+
@disjunction(model, outer, z, exclusive = false)
295295

296296
reformulate_model(model, BigM())
297297
bvrefs = DP._indicator_to_binary(model)

test/constraints/disjunction.jl

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ function test_disjunction_add_success()
5151
disj = DisjunctionRef(model, DisjunctionIndex(1))
5252
disj2 = DisjunctionRef(model, DisjunctionIndex(2))
5353
@test @disjunction(model, y) == disj
54-
@test @disjunction(model, disj2, y, exactly1 = false) == disj2
54+
@test @disjunction(model, disj2, y, exclusive = false) == disj2
5555
@test owner_model(disj) == model
5656
@test is_valid(model, disj)
5757
@test index(disj) == DisjunctionIndex(1)
@@ -62,8 +62,8 @@ function test_disjunction_add_success()
6262
@test DP._disjunctions(model)[index(disj)] == DP._constraint_data(disj)
6363
@test !constraint_object(disj).nested
6464
@test constraint_object(disj).indicators == y
65-
@test haskey(gdp_data(model).exactly1_constraints, disj)
66-
@test !haskey(gdp_data(model).exactly1_constraints, disj2)
65+
@test haskey(gdp_data(model).exclusive_constraints, disj)
66+
@test !haskey(gdp_data(model).exclusive_constraints, disj2)
6767
@test disj == copy(disj)
6868
end
6969

@@ -89,7 +89,7 @@ function test_disjunction_add_nested()
8989
@test !constraint_object(outer).nested
9090
@test haskey(DP._indicator_to_constraints(model), z[1])
9191
@test inner in DP._indicator_to_constraints(model)[z[1]]
92-
@test haskey(gdp_data(model).exactly1_constraints, inner)
92+
@test haskey(gdp_data(model).exclusive_constraints, inner)
9393
end
9494

9595
function test_disjunction_add_array()
@@ -189,15 +189,15 @@ function test_disjunction_delete()
189189
@test delete(model, disj) isa Nothing
190190
@test !haskey(gdp_data(model).disjunctions, index(disj))
191191
@test !DP._ready_to_optimize(model)
192-
@test !haskey(gdp_data(model).exactly1_constraints, disj)
192+
@test !haskey(gdp_data(model).exclusive_constraints, disj)
193193

194194
model = GDPModel()
195195
@variable(model, x)
196196
@variable(model, y[1:2], Logical)
197197
@variable(model, z[1:2], Logical)
198198
@constraint(model, x <= 5, Disjunct(y[1]))
199199
@constraint(model, x >= 5, Disjunct(y[2]))
200-
@disjunction(model, inner, y, Disjunct(z[1]), exactly1 = false)
200+
@disjunction(model, inner, y, Disjunct(z[1]), exclusive = false)
201201

202202
@test delete(model, inner) isa Nothing
203203
@test !haskey(gdp_data(model).disjunctions, index(inner))
@@ -219,7 +219,7 @@ function test_disjunction_function()
219219
set_name(disj, "new_name")
220220
@test name(disj) == "new_name"
221221
@test haskey(DP._disjunctions(model), index(disj))
222-
@test haskey(gdp_data(model).exactly1_constraints, disj)
222+
@test haskey(gdp_data(model).exclusive_constraints, disj)
223223
end
224224

225225
function test_disjunction_function_nested()
@@ -233,7 +233,7 @@ function test_disjunction_function_nested()
233233
@constraint(model, x >= 10, Disjunct(z[2]))
234234
disj1 = DisjunctionRef(model, DisjunctionIndex(1))
235235
disj2 = DisjunctionRef(model, DisjunctionIndex(2))
236-
@test disjunction(model, y, Disjunct(z[1]), "inner", exactly1 = false) == disj1
236+
@test disjunction(model, y, Disjunct(z[1]), "inner", exclusive = false) == disj1
237237
@test disjunction(model, z, "outer") == disj2
238238

239239
@test is_valid(model, disj1)
@@ -244,7 +244,7 @@ function test_disjunction_function_nested()
244244
@test !constraint_object(disj2).nested
245245
@test haskey(DP._indicator_to_constraints(model), z[1])
246246
@test disj1 in DP._indicator_to_constraints(model)[z[1]]
247-
@test !haskey(gdp_data(model).exactly1_constraints, disj1)
247+
@test !haskey(gdp_data(model).exclusive_constraints, disj1)
248248
end
249249

250250
@testset "Disjunction" begin

test/constraints/fallback.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ function test_reformulate_disjunct_constraint_fallback()
55
@test_throws ErrorException reformulate_disjunct_constraint(model, c, x, DummyReformulation())
66
end
77

8-
function test_exactly1_fallback()
9-
@test requires_exactly1(BigM()) == false
8+
function test_exclusive_fallback()
9+
@test requires_exclusive(BigM()) == false
1010
end
1111

1212
@testset "Fallbacks" begin
1313
test_reformulate_disjunct_constraint_fallback()
14-
test_exactly1_fallback()
14+
test_exclusive_fallback()
1515
end

test/constraints/hull.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -636,14 +636,14 @@ function test_scalar_nonlinear_hull_2sided()
636636
end
637637
end
638638

639-
function test_exactly1_error()
639+
function test_exclusive_error()
640640
model = GDPModel()
641641
@variable(model, 10 <= x <= 100)
642642
@variable(model, z[1:2], Logical)
643643
@constraint(model, 1 <= x <= 5, Disjunct(z[1]))
644644
@constraint(model, 3 <= x <= 5, Disjunct(z[2]))
645-
disjunction(model, z, exactly1 = false)
646-
@test requires_exactly1(Hull())
645+
disjunction(model, z, exclusive = false)
646+
@test requires_exclusive(Hull())
647647
@test_throws ErrorException reformulate_model(model, Hull())
648648
end
649649

@@ -686,5 +686,5 @@ end
686686
test_scalar_quadratic_hull_2sided()
687687
test_scalar_nonlinear_hull_2sided()
688688
test_scalar_nonlinear_hull_2sided_error()
689-
test_exactly1_error()
689+
test_exclusive_error()
690690
end

test/constraints/indicator.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ function test_indicator_array()
4444
@variable(model, y[1:2], Logical)
4545
@constraint(model, [1:3, 1:2], x <= 6, Disjunct(y[1]))
4646
@constraint(model, [1:3, 1:2], x >= 6, Disjunct(y[2]))
47-
@disjunction(model, y, exactly1 = false)
47+
@disjunction(model, y, exclusive = false)
4848
reformulate_model(model, Indicator())
4949

5050
ref_cons = DP._reformulation_constraints(model)
@@ -61,7 +61,7 @@ function test_indicator_dense_axis()
6161
@variable(model, y[1:2], Logical)
6262
@constraint(model, [["a","b","c"],[1,2]], x <= 7, Disjunct(y[1]))
6363
@constraint(model, [["a","b","c"],[1,2]], x >= 7, Disjunct(y[2]))
64-
@disjunction(model, y, exactly1 = false)
64+
@disjunction(model, y, exclusive = false)
6565
reformulate_model(model, Indicator())
6666

6767
ref_cons = DP._reformulation_constraints(model)
@@ -78,7 +78,7 @@ function test_indicator_sparse_axis()
7878
@variable(model, y[1:2], Logical)
7979
@constraint(model, [i = 1:3, j = 1:3; j > i], x <= 7, Disjunct(y[1]))
8080
@constraint(model, [i = 1:3, j = 1:3; j > i], x >= 7, Disjunct(y[2]))
81-
@disjunction(model, y, exactly1 = false)
81+
@disjunction(model, y, exclusive = false)
8282
reformulate_model(model, Indicator())
8383

8484
ref_cons = DP._reformulation_constraints(model)
@@ -96,10 +96,10 @@ function test_indicator_nested()
9696
@variable(model, z[1:2], Logical)
9797
@constraint(model, x <= 5, Disjunct(y[1]))
9898
@constraint(model, x >= 5, Disjunct(y[2]))
99-
@disjunction(model, y, Disjunct(z[1]), exactly1 = false)
99+
@disjunction(model, y, Disjunct(z[1]), exclusive = false)
100100
@constraint(model, x <= 10, Disjunct(z[1]))
101101
@constraint(model, x >= 10, Disjunct(z[2]))
102-
@disjunction(model, z, exactly1 = false)
102+
@disjunction(model, z, exclusive = false)
103103
reformulate_model(model, Indicator())
104104

105105
ref_cons = DP._reformulation_constraints(model)

0 commit comments

Comments
 (0)