@@ -37,7 +37,7 @@ function check_constraint!(m::Model, constr_j::ConstraintRef, constr_list::Vecto
37
37
end
38
38
function check_constraint! (m:: Model , constr:: ConstraintRef )
39
39
@assert all (is_valid (m, constr)) " $constr is not a valid constraint."
40
- new_constr = split_constraint (m, constr)
40
+ new_constr = split_constraint (constr)
41
41
if isnothing (new_constr)
42
42
new_constr = constr
43
43
else
@@ -53,7 +53,7 @@ function check_constraint!(m::Model, constr::AbstractArray{<:ConstraintRef})
53
53
idxs = get_indices (constr)
54
54
constr_dict = Dict (union (
55
55
[
56
- split_constraint (m, constr[idx... ]) |>
56
+ split_constraint (constr[idx... ]) |>
57
57
i -> isnothing (i) ?
58
58
(idx... ," " ) => constr[idx... ] :
59
59
[(idx... ," lb" ) => i[1 ], (idx... ," ub" ) => i[2 ]]
68
68
check_constraint! (m:: Model , constr:: Nothing ) = nothing
69
69
70
70
"""
71
- split_constraint(m::Model, constr::NonlinearConstraintRef )
71
+ split_constraint(constr::ConstraintRef )
72
72
73
- Split a nonlinear constraint that is an Interval or EqualTo constraint.
74
-
75
- split_constraint(m::Model, constr::ConstraintRef, constr_name::String = name(constr))
76
-
77
- Split a linear or quadratic constraint.
78
-
79
- split_constraint(m::Model, constr_obj::ScalarConstraint, lb_name::String, ub_name::String)
80
-
81
- Split a constraint that is a MOI.EqualTo or MOI.Interval.
82
-
83
- split_constraint(m::Model, func::Union{AffExpr,QuadExpr}, lb::Float64, ub::Float64, lb_name::String, ub_name::String)
84
-
85
- Create split constraint for linear or quadratic constraint.
86
-
87
- split_constraint(m::Model, constr::ConstraintRef, constr_func_expr::Expr, lb::Float64, ub::Float64)
88
-
89
- Split a nonlinear constraint.
73
+ Split a constraint that is an Interval or EqualTo constraint.
90
74
91
75
split_constraint(args...)
92
76
93
77
Return nothing for an empty disjunct.
94
78
"""
95
- function split_constraint (m:: Model , constr:: NonlinearConstraintRef )
96
- constr_expr = Meta. parse (string (constr))
97
- if is_equalto (constr) # replace == for lb <= expr <= ub and split
98
- lb, ub = 0 , 0 # rhs is always 0, but could get obtained from: constr_expr.args[3]
99
- constr_func_expr = copy (constr_expr. args[2 ])
100
- return split_constraint (m, constr_func_expr, lb, ub)
101
- elseif is_interval (constr) # split lb <= expr <= ub
102
- lb = constr_expr. args[1 ]
103
- ub = constr_expr. args[5 ]
104
- constr_func_expr = copy (constr_expr. args[3 ]) # get func part of constraint
105
- return split_constraint (m, constr_func_expr, lb, ub)
79
+ function split_constraint (constr:: ConstraintRef )
80
+ constr_set = constraint_set (constr)
81
+ if is_equalto (constr)
82
+ lb = ub = constr_set. value
83
+ return _split_constraint (constr. model, constr, lb, ub)
84
+ elseif is_interval (constr)
85
+ lb = constr_set. lower
86
+ ub = constr_set. upper
87
+ return _split_constraint (constr. model, constr, lb, ub)
106
88
else
107
89
return nothing
108
90
end
109
91
end
110
- function split_constraint (m:: Model , constr:: ConstraintRef , constr_name:: String = name (constr))
92
+ function _split_constraint (m:: Model , constr:: NonlinearConstraintRef , lb:: Float64 , ub:: Float64 )
93
+ nlp = nonlinear_model (m)
94
+ nlconstr = nlp[index (constr)]
95
+ # add lb constraint
96
+ nlp. last_constraint_index += 1
97
+ index1 = MOI. Nonlinear. ConstraintIndex (nlp. last_constraint_index)
98
+ nlp. constraints[index1] =
99
+ MOI. Nonlinear. Constraint (nlconstr. expression, MOI. LessThan (ub))
100
+ # add ub constraint
101
+ nlp. last_constraint_index += 1
102
+ index2 = MOI. Nonlinear. ConstraintIndex (nlp. last_constraint_index)
103
+ nlp. constraints[index2] =
104
+ MOI. Nonlinear. Constraint (nlconstr. expression, MOI. GreaterThan (lb))
105
+
106
+ return [
107
+ ConstraintRef (m, index1, constr. shape),
108
+ ConstraintRef (m, index2, constr. shape)
109
+ ]
110
+ end
111
+ function _split_constraint (m:: Model , constr:: ConstraintRef , lb:: Float64 , ub:: Float64 )
112
+ constr_name = name (constr)
111
113
if isempty (constr_name)
112
114
constr_name = " [$constr ]"
113
115
end
114
116
lb_name = name_split_constraint (constr_name, :lb )
115
117
ub_name = name_split_constraint (constr_name, :ub )
116
- constr_obj = constraint_object (constr)
117
- new_constraints = split_constraint (m, constr_obj, lb_name, ub_name)
118
-
119
- return new_constraints
120
- end
121
- function split_constraint (m:: Model , func:: Union{AffExpr,QuadExpr} , lb:: Float64 , ub:: Float64 , lb_name:: String , ub_name:: String )
118
+ func = constraint_object (constr). func
122
119
return [
123
120
@constraint (m, lb <= func, base_name = lb_name),
124
121
@constraint (m, func <= ub, base_name = ub_name)
125
122
]
126
123
end
127
- function split_constraint (m:: Model , constr_obj:: ScalarConstraint{T,<:MOI.EqualTo} , lb_name:: String , ub_name:: String ) where T
128
- split_constraint (m, constr_obj. func, constr_obj. set. value, constr_obj. set. value, lb_name, ub_name)
129
- end
130
- function split_constraint (m:: Model , constr_obj:: ScalarConstraint{T,<:MOI.Interval} , lb_name:: String , ub_name:: String ) where T
131
- split_constraint (m, constr_obj. func, constr_obj. set. lower, constr_obj. set. upper, lb_name, ub_name)
132
- end
133
- function split_constraint (m:: Model , constr_func_expr:: Expr , lb:: Real , ub:: Real )
134
- replace_JuMPvars! (constr_func_expr, m) # replace Expr with JuMP vars
135
- return [
136
- add_nonlinear_constraint (m, :($ lb <= $ constr_func_expr)),
137
- add_nonlinear_constraint (m, :($ constr_func_expr <= $ ub))
138
- ]
139
- end
140
124
split_constraint (args... ) = nothing
141
125
142
126
"""
0 commit comments