In Gurobi 12:
If you have f(x) == 0, you must write it as z == f(x) and then write z == 0.
Basically, you must introduce auxiliary variables for all the general nonlinear
parts. (And no worries about additively separable or anything–they do that
under the hood).
In this implementation, we replace the entire LHS of the constraint with the
auxiliary variable rather than just the nonlinear part. Otherwise we would really
need to keep track of what nonlinear subexpressions we had already replaced and make
sure to use the same auxiliary variables, and from what we know, this is probably not
worth it.
We are not using Gurobi’s ‘.nl’ attribute at all for now–its usage seems like the
exception rather than the rule, so we will let Gurobi expand the expressions for now.