Skip to content
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

Add doc to sense_to_set #1843

Merged
merged 3 commits into from
Feb 11, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions docs/src/extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,17 @@ The [`@constraint`](@ref) macro always calls the same three functions:
Adding methods to these functions is the recommended way to extend the
[`@constraint`](@ref) macro.

### Adding `parse_constraint` methods

```@meta
# TODO(Benoît): Details how `parse_constraint` works and shows how
blegat marked this conversation as resolved.
Show resolved Hide resolved
# `sense_to_set` fit into the picture
```

```@docs
sense_to_set
```

### Adding `build_constraint` methods

There is typically two choices when creating a [`build_constraint`](@ref)
Expand Down
41 changes: 41 additions & 0 deletions src/macros.jl
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,47 @@ end

# two-argument build_constraint is used for one-sided constraints.
# Right-hand side is zero.

"""
sense_to_set(_error::Function, ::Val{sense_symbol})
Converts a sense symbol to a set `set` such that
`@constraint(model, func sense_symbol 0) is equivalent to
`@constraint(model, func in set)` for any `func::AbstractJuMPScalar`.
## Example
Once a custom set is defined you can directly create a JuMP constraint with it:
```jldoctest sense_to_set; setup = :(using JuMP)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Why is using JuMP needed for the doctest while MOIU doesn't need to be defined?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MOIU is exported by JuMP

julia> struct CustomSet{T} <: MOI.AbstractScalarSet
value::T
end
julia> model = Model();
julia> @variable(model, x)
x
julia> cref = @constraint(model, x in CustomSet(1.0))
x ∈ CustomSet{Float64}(1.0)
```
However, there might be an appropriate sign that could be used in order to
provide a more convenient syntax:
```jldoctest sense_to_set
julia> JuMP.sense_to_set(::Function, ::Val{:⊰}) = CustomSet(0.0)
julia> MOIU.shift_constant(set::CustomSet, value) = CustomSet(set.value + value)
julia> cref = @constraint(model, x ⊰ 1)
x ∈ CustomSet{Float64}(1.0)
```
Note that the whole function is first moved to the right-hand side, then the
sign is transformed into a set with zero constant and finally the constant is
moved to the set with `MOIU.shift_constant`.
"""
function sense_to_set end

sense_to_set(_error::Function, ::Union{Val{:(<=)}, Val{:(≤)}}) = MOI.LessThan(0.0)
sense_to_set(_error::Function, ::Union{Val{:(>=)}, Val{:(≥)}}) = MOI.GreaterThan(0.0)
sense_to_set(_error::Function, ::Val{:(==)}) = MOI.EqualTo(0.0)
Expand Down