I was looking at the example for vectorized constraints in the docs (Constraints · JuMP), which creates the constraint:

@constraint(model, con, A * x .== b)
2-element Vector{ConstraintRef{Model, MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64}, MathOptInterface.EqualTo{Float64}}, ScalarShape}}:
con : x[1] + 2 x[2] = 5.0
con : 3 x[1] + 4 x[2] = 6.0

I am curious as to why the constraint name does not get indexed (i.e., con[1], con[2]), as would be the case if indexing were used instead of the dot notation to create the constraint:

Thanks for the link. However, this may discourage users from using vectorized constraints if you can’t distinguish the name unless you set them in a separate line.

may discourage users from using vectorized constraints if you can’t distinguish the name unless you set them in a separate line.

A few things:

Changing the name at this point would be a breaking change, so we won’t be doing that

Calling set_name is pretty trivial, but there’s more than one way to do things, so if users would prefer to use the con[i=1:n] syntax instead of vectorized, that’s perfectly okay.

julia> @constraint(model, con, A * x .== b)
2-element Vector{ConstraintRef{Model, MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64}, MathOptInterface.EqualTo{Float64}}, ScalarShape}}:
con : x[1] + 2 x[2] = 5.0
con : 3 x[1] + 4 x[2] = 6.0
julia> for i in 1:length(con)
set_name(con[i], name(con[i]) * "[$i]")
end
julia> con
2-element Vector{ConstraintRef{Model, MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64}, MathOptInterface.EqualTo{Float64}}, ScalarShape}}:
con[1] : x[1] + 2 x[2] = 5.0
con[2] : 3 x[1] + 4 x[2] = 6.0

The answer isn’t as obvious as it seems. What would you do in this case?

julia> model = Model()
A JuMP Model
Feasibility problem with:
Variables: 0
Model mode: AUTOMATIC
CachingOptimizer state: NO_OPTIMIZER
Solver name: No optimizer attached.
julia> S = ["1", "2"]
2-element Vector{String}:
"1"
"2"
julia> @variable(model, x[S])
1-dimensional DenseAxisArray{VariableRef,1,...} with index sets:
Dimension 1, ["1", "2"]
And data, a 2-element Vector{VariableRef}:
x[1]
x[2]
julia> @constraint(model, con, x .== 0)
1-dimensional DenseAxisArray{ConstraintRef{Model, MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64}, MathOptInterface.EqualTo{Float64}}, ScalarShape},1,...} with index sets:
Dimension 1, ["1", "2"]
And data, a 2-element Vector{ConstraintRef{Model, MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64}, MathOptInterface.EqualTo{Float64}}, ScalarShape}}:
con : x[1] = 0.0
con : x[2] = 0.0

We probably shouldn’t name the constraints con[1] and con[2], but con["1"]?