-
-
Notifications
You must be signed in to change notification settings - Fork 398
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[breaking] refactor the parse_constraint methods #2736
Conversation
Codecov Report
@@ Coverage Diff @@
## master #2736 +/- ##
==========================================
+ Coverage 93.90% 94.10% +0.19%
==========================================
Files 44 43 -1
Lines 5561 5512 -49
==========================================
- Hits 5222 5187 -35
+ Misses 339 325 -14
Continue to review full report at Codecov.
|
@dourouc05 Here's an example of the julia> using JuMP
julia> const MutableArithmetics = JuMP._MA;
julia> function JuMP.parse_constraint_call(
_error::Function,
is_vectorized::Bool,
::Val{:binpacking},
args...,
)
@assert !is_vectorized
new_args = MutableArithmetics.rewrite.(args)
parse_code = quote end
new_lhs = Expr(:vect)
for (lhs, code) in new_args
push!(parse_code.args, code)
push!(new_lhs.args, lhs)
end
N = length(args)
x = gensym()
push!(parse_code.args, Expr(:(=), x, new_lhs))
build_code = :(build_constraint($(_error), $new_lhs, MOI.Zeros($N)))
return parse_code, build_code
end
julia> model = Model(); @variable(model, x[1:4]);
julia> @constraint(model, binpacking(x[1], x[2], x[3], x[4]))
[x[1], x[2], x[3], x[4]] ∈ MathOptInterface.Zeros(4) |
It looks nicer than the current solution! I think that the only type of syntax that cannot be implemented is array indexing, which is tricky anyway. Is there any standard error message for constraints that do not support vectorisation? (To have a uniform message instead of a raw |
You could implement the vectorized version. I just didn't here for simplicity. Array indexing is very tricky because it isn't syntactically unique. Instead it depends on the data. You're best to have @constraint(model, x == element(y, z)) or something similar |
That's for that specific example. What about other constraints where vectorisation does not make sense at all? I'm thinking about |
Then just throw an informative error. I don't think we need a specific one for now. |
@blegat can you take a look at this? |
Co-authored-by: Benoît Legat <[email protected]>
Background
We previously had
parse_constraint_expr
parse_constraint_head
parse_one_operator_constraint
parse_ternary_constraint
with a mix of interceptions and reorganizations.
I've simplified this to:
parse_constraint
entry point from the macro. This is not for extending.parse_constraint_head
, which is for interceptingExpr(head, ...)
expressions.parse_constraint_call
, which is for interceptingExpr(:call, op, ...)
expressions.These are now better documented, and the documentation has examples of extending via
parse_constraint_
.Deprecations
sense_to_set
is nowoperator_to_set
parse_one_operator_constraint
is nowparse_constriant_call
parse_constraint_expr
is nowparse_constraint
Breaking changes
parse_ternary_constraint
is removedTODOs
Closes #2236