Skip to content

Commit 9a1fcf3

Browse files
committed
add tests
1 parent 62393b2 commit 9a1fcf3

File tree

13 files changed

+176
-15
lines changed

13 files changed

+176
-15
lines changed

src/constraints.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ function disjunction(
379379
model::JuMP.Model,
380380
disjunct_indicators,
381381
nested_tag::DisjunctConstraint,
382-
name::String = "",
382+
name::String = ""
383383
) # TODO add kw argument to build exactly 1 constraint
384384
return _disjunction(error, model, disjunct_indicators, name, nested_tag)
385385
end

src/logic.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ function _eliminate_equivalence(lexpr::_LogicalExpr)
5757
elseif length(lexpr.args) == 2
5858
B = _eliminate_equivalence(lexpr.args[2])
5959
else
60-
error("The equivalence logic operator must have at least two arguments.")
60+
error("The equivalence logic operator must have at least two clauses.")
6161
end
6262
new_lexpr = _LogicalExpr(:&&, Any[
6363
_LogicalExpr(:(=>), Any[A, B]),
@@ -101,7 +101,7 @@ end
101101
function _move_negations_inward(lexpr::_LogicalExpr)
102102
if lexpr.head == :!
103103
if length(lexpr.args) != 1
104-
error("The negation operator can only have 1 clause.")
104+
error("The negation operator can only have one clause.")
105105
end
106106
new_lexpr = _negate(lexpr.args[1])
107107
else

test/constraints/bigm.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ function test_nonpositives_bigm()
202202
@test ref[1].set == MOI.Nonpositives(2)
203203
end
204204

205-
function test_greaterhan_bigm()
205+
function test_greaterthan_bigm()
206206
model = GDPModel()
207207
@variable(model, x)
208208
@variable(model, y, Logical)
@@ -231,7 +231,7 @@ function test_nonnegatives_bigm()
231231
@test ref[1].set == MOI.Nonnegatives(2)
232232
end
233233

234-
function test_greaterhan_bigm()
234+
function test_equalto_bigm()
235235
model = GDPModel()
236236
@variable(model, x)
237237
@variable(model, y, Logical)
@@ -247,7 +247,7 @@ function test_greaterhan_bigm()
247247
@test ref[2].set == MOI.LessThan(5.0 + 100)
248248
end
249249

250-
function test_greaterhan_bigm()
250+
function test_interval_bigm()
251251
model = GDPModel()
252252
@variable(model, x)
253253
@variable(model, y, Logical)
@@ -320,10 +320,10 @@ end
320320
test_calculate_tight_M()
321321
test_lessthan_bigm()
322322
test_nonpositives_bigm()
323-
test_greaterhan_bigm()
323+
test_greaterthan_bigm()
324324
test_nonnegatives_bigm()
325-
test_greaterhan_bigm()
326-
test_greaterhan_bigm()
325+
test_equalto_bigm()
326+
test_interval_bigm()
327327
test_zeros_bigm()
328328
test_nested_bigm()
329329
end

test/constraints/disjunct.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ function test_disjunct_add_fail()
77
@variable(model, w, Logical)
88
@variable(model, z, Bin)
99
@test_macro_throws UndefVarError @constraint(model, z == 1, DisjunctConstraint(w)) # binary variable
10+
@test_throws ErrorException build_constraint(error, 1z, MOI.EqualTo(1), DisjunctConstraint(w)) # binary variable
1011
end
1112

1213
function test_disjunct_add_success()

test/constraints/fallback.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
function test_reformulate_disjunct_constraint_fallback()
2+
model = GDPModel()
3+
@variable(model, x)
4+
c = build_constraint(error, 1x, MOI.LessThan(1))
5+
@test_throws ErrorException reformulate_disjunct_constraint(model, c, x, DummyReformulation())
6+
end
7+
8+
@testset "Fallbacks" begin
9+
test_reformulate_disjunct_constraint_fallback()
10+
end

test/constraints/hull.jl

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,18 @@ function test_vector_quadratic_hull_1sided(moiset)
341341
@test ref[1].set == moiset(2)
342342
end
343343
#less than, greater than, equalto
344+
function test_scalar_nonlinear_hull_1sided_error()
345+
model = GDPModel()
346+
@variable(model, 10 <= x <= 100)
347+
@variable(model, z, Logical)
348+
@constraint(model, con, log(x) <= 10, DisjunctConstraint(z))
349+
DP._reformulate_logical_variables(model)
350+
zbin = variable_by_name(model, "z")
351+
ϵ = 1e-3
352+
method = DP._Hull(Hull(ϵ, Dict(x => (0., 100.))), Set([x]))
353+
DP._disaggregate_variables(model, z, Set([x]), method)
354+
@test_throws ErrorException reformulate_disjunct_constraint(model, constraint_object(con), zbin, method)
355+
end
344356
function test_scalar_nonlinear_hull_1sided(moiset)
345357
model = GDPModel()
346358
@variable(model, 10 <= x <= 100)
@@ -371,6 +383,18 @@ function test_scalar_nonlinear_hull_1sided(moiset)
371383
@test DP._set_value(ref[1].set) == 0
372384
end
373385
#nonpositives, nonnegatives, zeros
386+
function test_vector_nonlinear_hull_1sided_error()
387+
model = GDPModel()
388+
@variable(model, 10 <= x <= 100)
389+
@variable(model, z, Logical)
390+
@constraint(model, con, [log(x),log(x)] <= [10,10], DisjunctConstraint(z))
391+
DP._reformulate_logical_variables(model)
392+
zbin = variable_by_name(model, "z")
393+
ϵ = 1e-3
394+
method = DP._Hull(Hull(ϵ, Dict(x => (0., 100.))), Set([x]))
395+
DP._disaggregate_variables(model, z, Set([x]), method)
396+
@test_throws ErrorException reformulate_disjunct_constraint(model, constraint_object(con), zbin, method)
397+
end
374398
function test_vector_nonlinear_hull_1sided(moiset)
375399
model = GDPModel()
376400
@variable(model, 10 <= x <= 100)
@@ -471,6 +495,18 @@ function test_scalar_quadratic_hull_2sided()
471495
@test DP._set_value(ref[i].set) == 0
472496
end
473497
end
498+
function test_scalar_nonlinear_hull_2sided_error()
499+
model = GDPModel()
500+
@variable(model, 10 <= x <= 100)
501+
@variable(model, z, Logical)
502+
@constraint(model, con, 0 <= log(x) <= 10, DisjunctConstraint(z))
503+
DP._reformulate_logical_variables(model)
504+
zbin = variable_by_name(model, "z")
505+
ϵ = 1e-3
506+
method = DP._Hull(Hull(ϵ, Dict(x => (0., 100.))), Set([x]))
507+
DP._disaggregate_variables(model, z, Set([x]), method)
508+
@test_throws ErrorException reformulate_disjunct_constraint(model, constraint_object(con), zbin, method)
509+
end
474510
function test_scalar_nonlinear_hull_2sided()
475511
model = GDPModel()
476512
@variable(model, 10 <= x <= 100)
@@ -525,14 +561,17 @@ end
525561
test_scalar_quadratic_hull_1sided(s)
526562
test_scalar_nonlinear_hull_1sided(s)
527563
end
564+
test_scalar_nonlinear_hull_1sided_error()
528565
for s in (MOI.Nonpositives, MOI.Nonnegatives, MOI.Zeros)
529566
test_vector_var_hull_1sided(s)
530567
test_vector_affine_hull_1sided(s)
531568
test_vector_quadratic_hull_1sided(s)
532569
test_vector_nonlinear_hull_1sided(s)
533570
end
571+
test_vector_nonlinear_hull_1sided_error()
534572
test_scalar_var_hull_2sided()
535573
test_scalar_affine_hull_2sided()
536574
test_scalar_quadratic_hull_2sided()
537575
test_scalar_nonlinear_hull_2sided()
576+
test_scalar_nonlinear_hull_2sided_error()
538577
end

test/constraints/indicator.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,16 @@ function test_indicator_vector_constraints()
2323
model = GDPModel()
2424
A = [1 0; 0 1]
2525
@variable(model, x)
26-
@variable(model, y[1:2], Logical)
26+
@variable(model, y[1:3], Logical)
2727
@constraint(model, A*[x,x] == [5,5], DisjunctConstraint(y[1]))
28-
@constraint(model, A*[x,x] == [10,10], DisjunctConstraint(y[2]))
28+
@constraint(model, A*[x,x] <= [0,0], DisjunctConstraint(y[2]))
29+
@constraint(model, A*[x,x] >= [10,10], DisjunctConstraint(y[3]))
2930
@disjunction(model, y)
3031
reformulate_model(model, Indicator())
3132

3233
ref_cons = DP._reformulation_constraints(model)
3334
ref_cons_obj = constraint_object.(ref_cons)
34-
@test length(ref_cons) == 4
35+
@test length(ref_cons) == 6
3536
@test all(is_valid.(model, ref_cons))
3637
@test all(isa.(ref_cons_obj, VectorConstraint))
3738
@test all([cobj.set isa MOI.Indicator for cobj in ref_cons_obj])

test/constraints/proposition.jl

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
1+
function test_op_fallback()
2+
@test_throws ErrorException iff(1,1)
3+
@test_throws ErrorException implies(1,1)
4+
@test_throws ErrorException 1 1
5+
@test_throws ErrorException 1 1
6+
end
7+
18
function test_proposition_add_fail()
29
m = GDPModel()
310
@variable(m, y[1:3], Logical)
11+
@test_throws ErrorException @constraint(m, y[1] in IsTrue())
412
@test_throws ErrorException @constraint(Model(), logical_or(y...) in IsTrue())
513
@test_throws ErrorException @constraint(m, logical_or(y...) == 2)
614
@test_throws ErrorException @constraint(m, logical_or(y...) <= 1)
@@ -262,6 +270,13 @@ function test_eliminate_equivalence()
262270
@test Set(new_ex.args[2].args) == Set{Any}(y)
263271
end
264272

273+
function test_eliminate_equivalence_error()
274+
model = GDPModel()
275+
@variable(model, y, Logical)
276+
ex = iff(y)
277+
@test_throws ErrorException DP._eliminate_equivalence(ex)
278+
end
279+
265280
function test_eliminate_equivalence_flat()
266281
model = GDPModel()
267282
@variable(model, y[1:3], Logical)
@@ -390,7 +405,7 @@ end
390405
function test_negate_and_error()
391406
model = GDPModel()
392407
@variable(model, y, Logical)
393-
@test_throws ErrorException DP._negate_or((y))
408+
@test_throws ErrorException DP._negate_and((y))
394409
end
395410

396411
function test_negate_negation()
@@ -419,6 +434,13 @@ function test_distribute_and_over_or()
419434
@test y[3] in new_ex.args[1].args || y[3] in new_ex.args[2].args
420435
end
421436

437+
function test_distribute_and_over_or_error()
438+
model = GDPModel()
439+
@variable(model, y[1:2], Logical)
440+
ex = (y[1] y[2])
441+
@test_throws ErrorException DP._distribute_and_over_or(ex)
442+
end
443+
422444
function test_distribute_and_over_or_nested()
423445
model = GDPModel()
424446
@variable(model, y[1:4], Logical)
@@ -486,7 +508,21 @@ function test_to_cnf()
486508
(!(y[1] in new_ex.args[6].args) && !(y[2] in new_ex.args[6].args) && y[3] in new_ex.args[6].args)
487509
end
488510

511+
function test_isa_literal_other()
512+
@test !DP._isa_literal(1)
513+
end
514+
515+
function test_reformulate_clause_error()
516+
model = GDPModel()
517+
@variable(model, y[1:2], Logical)
518+
ex = y[1] y[2]
519+
@test_throws ErrorException DP._reformulate_clause(model, ex)
520+
end
521+
489522
@testset "Logical Proposition Constraints" begin
523+
@testset "Logical Operators" begin
524+
test_op_fallback()
525+
end
490526
@testset "Add Proposition" begin
491527
test_proposition_add_fail()
492528
test_negation_add_success()
@@ -505,10 +541,13 @@ end
505541
test_equivalence_reformulation()
506542
test_intersection_reformulation()
507543
test_implication_reformulation()
544+
test_reformulate_clause_error()
508545
end
509546
@testset "Conjunctive Normal Form" begin
547+
test_isa_literal_other()
510548
test_lvar_cnf_functions()
511549
test_eliminate_equivalence()
550+
test_eliminate_equivalence_error()
512551
test_eliminate_equivalence_flat()
513552
test_eliminate_equivalence_nested()
514553
test_eliminate_implication()
@@ -525,6 +564,7 @@ end
525564
test_negate_negation()
526565
test_negate_negation_error()
527566
test_distribute_and_over_or()
567+
test_distribute_and_over_or_error()
528568
test_distribute_and_over_or_nested()
529569
test_to_cnf()
530570
end

test/disjunction.jl

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,17 @@ function test_disjunction_add_fail()
33
@variable(model, x)
44
@variable(model, y[1:2], Logical)
55
@constraint(model, x == 5, DisjunctConstraint(y[1]))
6-
6+
77
@test_macro_throws ErrorException @disjunction(model) #not enough arguments
88
@test_macro_throws UndefVarError @disjunction(model, y) #unassociated indicator
99
@test_macro_throws UndefVarError @disjunction(GDPModel(), y) #wrong model
1010
@test_macro_throws ErrorException @disjunction(Model(), y) #not a GDPModel
1111
@test_macro_throws UndefVarError @disjunction(model, [y[1], y[1]]) #duplicate indicator
12-
@test_macro_throws UndefVarError @disjunction(model, y[1]) #no disjunction expression
12+
@test_macro_throws UndefVarError @disjunction(model, y[1]) #unrecognized disjunction expression
13+
@test_throws ErrorException disjunction(model, y[1]) #unrecognized disjunction expression
14+
@test_throws ErrorException disjunction(model, [1]) #unrecognized disjunction expression
1315
@test_macro_throws UndefVarError @disjunction(model, y, "random_arg") #unrecognized extra argument
16+
@test_throws ErrorException DP._disjunction(error, model, y, "y", "random_arg") #unrecognized extra argument
1417
@test_macro_throws ErrorException @disjunction(model, "ABC") #unrecognized structure
1518
@test_macro_throws ErrorException @disjunction(model, begin y end) #@disjunctions (plural)
1619
@test_macro_throws UndefVarError @disjunction(model, x, y) #name x already exists
@@ -106,6 +109,16 @@ function test_disjunction_add_sparse_axis()
106109
@test Set(keys(disj.data)) == Set([(1,2),(1,3),(2,3)])
107110
end
108111

112+
function test_disjunctions_add_fail()
113+
model = GDPModel()
114+
@variable(model, x)
115+
@variable(model, y[1:2], Logical)
116+
@variable(model, z[1:2], Logical)
117+
@constraint(model, x <= 5, DisjunctConstraint(y[1]))
118+
@constraint(model, x >= 5, DisjunctConstraint(y[2]))
119+
@test_macro_throws ErrorException @disjunctions(model, y)
120+
end
121+
109122
function test_disjunctions_add_success()
110123
model = GDPModel()
111124
@variable(model, x)
@@ -203,6 +216,7 @@ end
203216
test_disjunction_add_array()
204217
test_disjunciton_add_dense_axis()
205218
test_disjunction_add_sparse_axis()
219+
test_disjunctions_add_fail()
206220
test_disjunctions_add_success()
207221
test_disjunction_function()
208222
test_disjunction_function_nested()

test/jump.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
function test_moi_set()
2+
for (jumpset, moisettype) in [(AtLeast(1), DP._MOIAtLeast),
3+
(AtMost(1), DP._MOIAtMost),
4+
(Exactly(1), DP._MOIExactly)]
5+
moiset = moi_set(jumpset, 10)
6+
@test moiset isa moisettype
7+
@test moiset.dimension == 10
8+
end
9+
end
10+
11+
@testset "JuMP" begin
12+
test_moi_set()
13+
end

0 commit comments

Comments
 (0)