Deleting variables in quadratic constraints in JuMP

It appears that when a variable is deleted in JuMP and it is part of a quadratic term, the entire term is dropped:

julia> using JuMP; m = Model(); @variable(m, x[1:2]);

julia> @constraint(m, c, 2 * x[1] * x[2] == 0)
c : 2 x[1]*x[2] == 0.0

julia> delete(m, x[1])

julia> c # entire quad term deleted including x[2] and its coef
c : 0 == 0.0

Would it make more sense to preserve x[2] and add it to the affine expression along with its coefficient as exemplified below?

julia> using JuMP; m = Model(); @variable(m, x[1:2]);

julia> quad = @expression(m, 2 * x[1] * x[2]) # example expression
2 x[1]*x[2]

julia> for p in keys(quad.terms) # illustration of current behavior
          if p.a == x[1] || p.b == x[2]
             delete!(quad.terms, p)
          end
       end

julia> quad
0

julia> quad = @expression(m, 2 * x[1] * x[2]) # example expression
2 x[1]*x[2]

julia> function new_delete(quad, var) # rough implementation of desired behavior
          for (p, coef) in quad.terms
             if p.a == var && p.b == var
                delete!(quad.terms, p)
             elseif p.a == var
                add_to_expression!(quad.aff, coef, p.b)
                delete!(quad.terms, p)
             elseif p.b == var
                add_to_expression!(quad.aff, coef, p.a)
                delete!(quad.terms, p)
             end
           end
       end
new_delete (generic function with 1 method)

julia> new_delete(quad, x[1])

julia> quad # x[2] if preserved with its coefficient
2 x[2]

The deletion can be thought as setting the value of the variable to zero. To be consistent with what you suggest, a linear term 2x should be transformed to a constant 2 when x is deleted which is inconsistent with what most solvers do.

4 Likes