Skip to content

Commit 2460400

Browse files
committed
clean up @disjunction
1 parent ed22679 commit 2460400

File tree

1 file changed

+17
-40
lines changed

1 file changed

+17
-40
lines changed

src/macros.jl

Lines changed: 17 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,43 +4,27 @@
44
Add disjunction macro.
55
"""
66
macro disjunction(m, args...)
7-
#get disjunction (pos_args) and keyword arguments
8-
pos_args, kw_args, _ = Containers._extract_kw_args(args)
9-
@assert length(pos_args) > 1 "At least 2 disjuncts must be included. If there is an empty disjunct, use `nothing`."
7+
#get disjunction (args) and keyword arguments
8+
disjuncts, kwargs, _ = Containers._extract_kw_args(args)
109

11-
#get kw_args and set defaults if missing
12-
reformulation = filter(i -> i.args[1] == :reformulation, kw_args)
13-
if !isempty(reformulation)
14-
reformulation = reformulation[1].args[2]
15-
reformulation_kind = eval(reformulation)
16-
@assert reformulation_kind in [:big_m, :hull] "Invalid reformulation method passed to keyword argument `:reformulation`. Valid options are :big_m (Big-M Reformulation) and :hull (Hull Reformulation)."
17-
if reformulation_kind == :big_m
18-
M = filter(i -> i.args[1] == :M, kw_args)
19-
param = !isempty(M) ? M[1].args[2] : :(missing)
20-
elseif reformulation_kind == :hull
21-
ϵ = filter(i -> i.args[1] == , kw_args)
22-
param = !isempty(ϵ) ? ϵ[1].args[2] : :(1e-6)
23-
else
24-
end
25-
else
26-
throw(UndefKeywordError(:reformulation))
27-
end
28-
name = filter(i -> i.args[1] == :name, kw_args)
29-
if !isempty(name)
30-
name = name[1].args[2]
31-
disj_name = Symbol("disj_",eval(name))
32-
else
33-
name = :(Symbol("disj",gensym()))
34-
disj_name = eval(name)
35-
end
10+
#get kwargs and set defaults if missing
11+
reformulation_kwarg = filter(i -> i.args[1] == :reformulation, kwargs)
12+
reformulation = isempty(reformulation_kwarg) ? throw(UndefKeywordError(:reformulation)) : reformulation_kwarg[1].args[2]
13+
M_kwarg = filter(i -> i.args[1] == :M, kwargs)
14+
M = isempty(M_kwarg) ? :missing : M_kwarg[1].args[2]
15+
ϵ_kwarg = filter(i -> i.args[1] == , kwargs)
16+
ϵ = isempty(ϵ_kwarg) ? :(1e-6) : ϵ_kwarg[1].args[2]
17+
name_kwarg = filter(i -> i.args[1] == :name, kwargs)
18+
name = isempty(name_kwarg) ? Symbol("disj_",gensym()) : name_kwarg[1].args[2]
19+
disj_name = isempty(name_kwarg) ? name : Symbol("disj_",eval(name))
3620

3721
#create constraints for each disjunction
38-
disj_names = [Symbol("$(disj_name)[$i]") for i in eachindex(pos_args)]
22+
disj_names = [Symbol("$(disj_name)[$i]") for i in eachindex(disjuncts)]
3923
disjunction = []
40-
for (d,dname) in zip(pos_args,disj_names)
24+
for (d,dname) in zip(disjuncts,disj_names)
4125
if Meta.isexpr(d, :tuple)
4226
for (j,di) in enumerate(d.args)
43-
i = findfirst(x -> x == d, pos_args)
27+
i = findfirst(x -> x == d, disjuncts)
4428
dname_j = Symbol("$(disj_name)[$i,$j]")
4529
d.args[j] = add_disjunction_constraint(m, di, dname_j)
4630
end
@@ -49,17 +33,10 @@ macro disjunction(m, args...)
4933
push!(disjunction, add_disjunction_constraint(m, d, dname))
5034
end
5135
end
52-
53-
# #XOR constraint name
54-
# xor_con = Symbol("XOR($disj_name)")
5536

5637
#build disjunction
5738
code = quote
58-
if !in($name, keys(object_dictionary($m)))
59-
$m[$name] = @variable($m, [eachindex($disjunction)], Bin, base_name = string($name))
60-
end
61-
# @constraint($m, $xor_con, sum($m[$name]) == 1)
62-
DisjunctiveProgramming.reformulate_disjunction($m, $(disjunction...); bin_var = $name, reformulation = $reformulation, param = $param)
39+
DisjunctiveProgramming.add_disjunction!($m, $(disjunction...); reformulation = $reformulation, M = $M, ϵ = $ϵ, name = $name)
6340
end
6441

6542
return esc(code)
@@ -110,7 +87,7 @@ function add_disjunction!(m::Model,disj...;reformulation::Symbol,M=missing,ϵ=1e
11087
@assert reformulation in [:big_m, :hull] "Invalid reformulation method passed to keyword argument `:reformulation`. Valid options are :big_m (Big-M Reformulation) and :hull (Hull Reformulation)."
11188
@assert length(disj) > 1 "At least 2 disjuncts must be included. If there is an empty disjunct, use `nothing`."
11289

113-
#get kw_args and set defaults if missing
90+
#get kwargs and set defaults if missing
11491
param = reformulation == :big_m ? M : ϵ
11592
bin_var = ismissing(name) ? Symbol("disj",gensym()) : name
11693

0 commit comments

Comments
 (0)