@@ -2,33 +2,36 @@ abstract type StructOfConstraints <: MOI.ModelLike end
2
2
3
3
function _throw_if_cannot_delete (model:: StructOfConstraints , vis, fast_in_vis)
4
4
broadcastcall (model) do constrs
5
- return _throw_if_cannot_delete (constrs, vis, fast_in_vis)
5
+ if constrs != = nothing
6
+ _throw_if_cannot_delete (constrs, vis, fast_in_vis)
7
+ end
8
+ return
6
9
end
10
+ return
7
11
end
8
12
function _deleted_constraints (
9
13
callback:: Function ,
10
14
model:: StructOfConstraints ,
11
15
vi,
12
16
)
13
17
broadcastcall (model) do constrs
14
- return _deleted_constraints (callback, constrs, vi)
18
+ if constrs != = nothing
19
+ _deleted_constraints (callback, constrs, vi)
20
+ end
21
+ return
15
22
end
23
+ return
16
24
end
17
25
18
26
function MOI. add_constraint (
19
27
model:: StructOfConstraints ,
20
- func:: MOI.AbstractFunction ,
21
- set:: MOI.AbstractSet ,
22
- )
23
- if MOI. supports_constraint (model, typeof (func), typeof (set))
24
- return MOI. add_constraint (
25
- constraints (model, typeof (func), typeof (set)),
26
- func,
27
- set,
28
- )
29
- else
30
- throw (MOI. UnsupportedConstraint {typeof(func),typeof(set)} ())
28
+ func:: F ,
29
+ set:: S ,
30
+ ) where {F<: MOI.AbstractFunction ,S<: MOI.AbstractSet }
31
+ if ! MOI. supports_constraint (model, F, S)
32
+ throw (MOI. UnsupportedConstraint {F,S} ())
31
33
end
34
+ return MOI. add_constraint (constraints (model, F, S), func, set)
32
35
end
33
36
34
37
function constraints (
@@ -49,26 +52,27 @@ function MOI.get(
49
52
end
50
53
51
54
function MOI. delete (model:: StructOfConstraints , ci:: MOI.ConstraintIndex )
52
- return MOI. delete (constraints (model, ci), ci)
55
+ MOI. delete (constraints (model, ci), ci)
56
+ return
53
57
end
54
58
55
59
function MOI. is_valid (
56
60
model:: StructOfConstraints ,
57
61
ci:: MOI.ConstraintIndex{F,S} ,
58
62
) where {F,S}
59
- if MOI. supports_constraint (model, F, S)
60
- return MOI. is_valid (constraints (model, ci), ci)
61
- else
63
+ if ! MOI. supports_constraint (model, F, S)
62
64
return false
63
65
end
66
+ return MOI. is_valid (constraints (model, ci), ci)
64
67
end
65
68
66
69
function MOI. modify (
67
70
model:: StructOfConstraints ,
68
71
ci:: MOI.ConstraintIndex ,
69
72
change:: MOI.AbstractFunctionModification ,
70
73
)
71
- return MOI. modify (constraints (model, ci), ci, change)
74
+ MOI. modify (constraints (model, ci), ci, change)
75
+ return
72
76
end
73
77
74
78
function MOI. set (
@@ -77,45 +81,55 @@ function MOI.set(
77
81
ci:: MOI.ConstraintIndex ,
78
82
func_or_set,
79
83
)
80
- return MOI. set (constraints (model, ci), attr, ci, func_or_set)
84
+ MOI. set (constraints (model, ci), attr, ci, func_or_set)
85
+ return
81
86
end
82
87
83
88
function MOI. get (
84
89
model:: StructOfConstraints ,
85
- loc:: MOI.ListOfConstraintTypesPresent ,
86
- ) where {T}
87
- return broadcastvcat (model) do v
88
- return MOI. get (v, loc)
90
+ attr:: MOI.ListOfConstraintTypesPresent ,
91
+ )
92
+ return broadcastvcat (model) do constrs
93
+ if constrs === nothing
94
+ return Tuple{DataType,DataType}[]
95
+ end
96
+ return MOI. get (constrs, attr)
89
97
end
90
98
end
91
99
92
100
function MOI. get (
93
101
model:: StructOfConstraints ,
94
- noc :: MOI.NumberOfConstraints{F,S} ,
102
+ attr :: MOI.NumberOfConstraints{F,S} ,
95
103
) where {F,S}
96
- if MOI. supports_constraint (model, F, S)
97
- return MOI. get (constraints (model, F, S), noc)
98
- else
104
+ if ! MOI. supports_constraint (model, F, S)
99
105
return 0
100
106
end
107
+ return MOI. get (constraints (model, F, S), attr)
101
108
end
102
109
103
110
function MOI. get (
104
111
model:: StructOfConstraints ,
105
- loc :: MOI.ListOfConstraintIndices{F,S} ,
112
+ attr :: MOI.ListOfConstraintIndices{F,S} ,
106
113
) where {F,S}
107
- if MOI. supports_constraint (model, F, S)
108
- return MOI. get (constraints (model, F, S), loc)
109
- else
114
+ if ! MOI. supports_constraint (model, F, S)
110
115
return MOI. ConstraintIndex{F,S}[]
111
116
end
117
+ return MOI. get (constraints (model, F, S), attr)
112
118
end
113
119
114
120
function MOI. is_empty (model:: StructOfConstraints )
115
- return mapreduce_constraints (MOI. is_empty, & , model, true )
121
+ return mapreduce_constraints (& , model, true ) do constrs
122
+ return constrs === nothing || MOI. is_empty (constrs)
123
+ end
116
124
end
117
125
function MOI. empty! (model:: StructOfConstraints )
118
- return broadcastcall (MOI. empty!, model)
126
+ broadcastcall (model) do constrs
127
+ if constrs != = nothing
128
+ MOI. empty! (constrs)
129
+ end
130
+ return
131
+ end
132
+ return
119
133
end
120
134
121
135
# Can be used to access constraints of a model
@@ -178,33 +192,13 @@ end
178
192
179
193
# (MOI, :Zeros) -> :(MOI.Zeros)
180
194
# (:Zeros) -> :(MOI.Zeros)
181
- _set (s:: SymbolSet ) = esc (s. s)
182
- _fun (s:: SymbolFun ) = esc (s. s)
183
- function _typedset (s:: SymbolSet )
184
- if s. typed
185
- T = esc (:T )
186
- :($ (_set (s)){$ T})
187
- else
188
- _set (s)
189
- end
190
- end
191
- function _typedfun (s:: SymbolFun )
192
- if s. typed
193
- T = esc (:T )
194
- :($ (_fun (s)){$ T})
195
- else
196
- _fun (s)
197
- end
198
- end
195
+ _typedset (s:: SymbolSet ) = s. typed ? Expr (:curly , esc (s. s), esc (:T )) : esc (s. s)
196
+ _typedfun (s:: SymbolFun ) = s. typed ? Expr (:curly , esc (s. s), esc (:T )) : esc (s. s)
199
197
200
198
# Base.lowercase is moved to Unicode.lowercase in Julia v0.7
201
199
using Unicode
202
200
203
201
_field (s:: SymbolFS ) = Symbol (replace (lowercase (string (s. s)), " ." => " _" ))
204
-
205
- _getC (s:: SymbolSet ) = :(VectorOfConstraints{F,$ (_typedset (s))})
206
- _getC (s:: SymbolFun ) = _typedfun (s)
207
-
208
202
_callfield (f, s:: SymbolFS ) = :($ f (model.$ (_field (s))))
209
203
_broadcastfield (b, s:: SymbolFS ) = :($ b (f, model.$ (_field (s))))
210
204
_mapreduce_field (s:: SymbolFS ) = :(cur = op (cur, f (model.$ (_field (s)))))
@@ -223,62 +217,61 @@ If `types` is vector of `SymbolFun` (resp. `SymbolSet`) then the constraints
223
217
of that function (resp. set) type are stored in the corresponding field.
224
218
"""
225
219
function struct_of_constraint_code (struct_name, types, field_types = nothing )
226
- esc_struct_name = struct_name
227
220
T = esc (:T )
228
- typed_struct = :($ (esc_struct_name ){$ T})
221
+ typed_struct = :($ (struct_name ){$ T})
229
222
type_parametrized = field_types === nothing
230
223
if type_parametrized
231
224
field_types = [Symbol (" C$i " ) for i in eachindex (types)]
232
225
append! (typed_struct. args, field_types)
233
226
end
227
+ struct_def = :(mutable struct $ typed_struct <: StructOfConstraints end )
234
228
235
- struct_def = :(struct $ typed_struct <: StructOfConstraints end )
236
-
237
- for (t, field_type) in zip (types, field_types)
238
- field = _field (t)
239
- push! (struct_def. args[3 ]. args, :($ field:: $field_type ))
240
- end
241
229
code = quote
242
- function $MOIU. broadcastcall (f:: Function , model:: $esc_struct_name )
243
- return $ (Expr (:block , _callfield .(Ref (:f ), types)... ))
230
+ function $MOIU. broadcastcall (f:: Function , model:: $struct_name )
231
+ $ (Expr (:block , _callfield .(Ref (:f ), types)... ))
232
+ return
244
233
end
245
- function $MOIU. broadcastvcat (f:: Function , model:: $esc_struct_name )
234
+
235
+ function $MOIU. broadcastvcat (f:: Function , model:: $struct_name )
246
236
return vcat ($ (_callfield .(Ref (:f ), types)... ))
247
237
end
238
+
248
239
function $MOIU. mapreduce_constraints (
249
240
f:: Function ,
250
241
op:: Function ,
251
- model:: $esc_struct_name ,
242
+ model:: $struct_name ,
252
243
cur,
253
244
)
254
245
return $ (Expr (:block , _mapreduce_field .(types)... ))
255
246
end
256
247
end
257
248
258
- for t in types
259
- if t isa SymbolFun
260
- fun = _fun (t)
261
- set = :(MOI. AbstractSet)
262
- else
263
- fun = :(MOI. AbstractFunction)
264
- set = _set (t)
265
- end
249
+ for (t, field_type) in zip (types, field_types)
266
250
field = _field (t)
267
- code = quote
268
- $ code
251
+ push! (struct_def. args[3 ]. args, :($ field:: Union{Nothing,$field_type} ))
252
+ fun = t isa SymbolFun ? esc (t. s) : :(MOI. AbstractFunction)
253
+ set = t isa SymbolFun ? :(MOI. AbstractSet) : esc (t. s)
254
+ constraints_code = :(
269
255
function $MOIU. constraints (
270
- model:: $esc_struct_name ,
256
+ model:: $typed_struct ,
271
257
:: Type{<:$fun} ,
272
258
:: Type{<:$set} ,
273
- )
259
+ ) where {$ T}
260
+ if model.$ field === nothing
261
+ model.$ field = $ (field_type)()
262
+ end
274
263
return model.$ field
275
264
end
265
+ )
266
+ if type_parametrized
267
+ append! (constraints_code. args[1 ]. args, field_types)
276
268
end
269
+ push! (code. args, constraints_code)
277
270
end
278
271
supports_code = if eltype (types) <: SymbolFun
279
272
quote
280
273
function $MOI. supports_constraint (
281
- model:: $esc_struct_name {$T} ,
274
+ model:: $struct_name {$T} ,
282
275
:: Type{F} ,
283
276
:: Type{S} ,
284
277
) where {
@@ -293,7 +286,7 @@ function struct_of_constraint_code(struct_name, types, field_types = nothing)
293
286
@assert eltype (types) <: SymbolSet
294
287
quote
295
288
function $MOI. supports_constraint (
296
- model:: $esc_struct_name {$T} ,
289
+ model:: $struct_name {$T} ,
297
290
:: Type{F} ,
298
291
:: Type{S} ,
299
292
) where {
@@ -307,7 +300,8 @@ function struct_of_constraint_code(struct_name, types, field_types = nothing)
307
300
end
308
301
expr = Expr (:block , struct_def, supports_code, code)
309
302
if ! isempty (field_types)
310
- constructors = [:($ field_type ()) for field_type in field_types]
303
+ constructors = [:(nothing ) for field_type in field_types]
304
+ # constructors = [:($field_type()) for field_type in field_types]
311
305
# If there is no field type, the default constructor is sufficient and
312
306
# adding this constructor will make a `StackOverflow`.
313
307
constructor_code = :(function $typed_struct () where {$ T}
0 commit comments