Add local and purgeable cuts in CPLEX

I am using CPLEX.jl and I add cuts in a callback with this syntax:

        con = @build_constraint(x <= 0)
        MOI.submit(myModel, MOI.UserCut(cb_data), con)

CPLEX library normally has several parameters when adding a cut that I would like to change (ex: the fact that the cut is purgeable or not, the fact that it is local to this branch or global to the whole tree).

To change these parameters, I would like to adapt the MOI.submit method. I tried to find its definition but the only one I found is the following one:

        function MOI.submit(
            model::Optimizer,
            cb::MOI.LazyConstraint{CallbackContext},
            f::MOI.ScalarAffineFunction{Float64},
            s::Union{
                MOI.LessThan{Float64},
                MOI.GreaterThan{Float64},
                MOI.EqualTo{Float64},
            },
        )

Unfortunately, this is not the method called when I use MOI.submit since the arguments types and number do not match. I tried to copy/paste it anyway just to be sure. I named the new method “mySubmit” but as expected, when I try to use it I get an error:

            ERROR: MethodError: no method matching mySubmit(::Model, ::MathOptInterface.LazyConstraint{CPLEX.CallbackContext}, ::ScalarConstraint{AffExpr, MathOptInterface.LessThan{Float64}})
            Closest candidates are:
              mySubmit(::CPLEX.Optimizer, ::MathOptInterface.LazyConstraint{CPLEX.CallbackContext}, ::MathOptInterface.ScalarAffineFunction{Float64}, ::Union{MathOptInterface.EqualTo{Float64}, MathOptInterface.GreaterThan{Float64}, MathOptInterface.LessThan{Float64}}) at /home/zach/Test/dummy_cb_ex.jl:79

Two of the arguments do not have the correct type:

  • the first one is “Model” instead of “CPLEX.Optimizer”;
  • the third one which defines the constraint.

Do you know where I can find the definition of the method called when I use MOI.submit? If it is the one I found, could you tell me why it does not work? I am a bit lost here…

Without answering your specific question, you can generally use the Julia macro @which before your function call to return this information:
https://docs.julialang.org/en/v1/stdlib/InteractiveUtils/#InteractiveUtils.@which

More specific to your question, each solver wrapper package (like CPLEX.jl) implements the MOI API. The MOI.submit for CPLEX here is the one you found?

For the discrepancy in the first argument, notice that the example in the CPLEX.jl README uses direct_model:

model = direct_model(CPLEX.Optimizer())

For the second:

the error tells you your argument is of the type above, but it might need to be

Thank you for your answers!
With @which I was able to find exactly the function called. In the end I had to adapt 10 functions to make it work, but it works!

Glad you got it working. You could also just use the solver-specific CPLEX callback and the C API directly. No need to modify a bunch of methods in MOI.