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

Universal constraint fallback #415

Merged
merged 15 commits into from
Jul 22, 2018
Merged

Universal constraint fallback #415

merged 15 commits into from
Jul 22, 2018

Conversation

blegat
Copy link
Member

@blegat blegat commented Jun 30, 2018

Closes #397
Closes jump-dev/JuMP.jl#1152

@blegat blegat changed the title [WIP] Universal constraint fallback Universal constraint fallback Jul 8, 2018
@blegat
Copy link
Member Author

blegat commented Jul 8, 2018

Ready for review :)

@codecov-io
Copy link

codecov-io commented Jul 8, 2018

Codecov Report

Merging #415 into master will increase coverage by 0.22%.
The diff coverage is 98.69%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #415      +/-   ##
==========================================
+ Coverage   95.55%   95.78%   +0.22%     
==========================================
  Files          40       40              
  Lines        5088     5315     +227     
==========================================
+ Hits         4862     5091     +229     
+ Misses        226      224       -2
Impacted Files Coverage Δ
src/Test/modellike.jl 100% <100%> (ø) ⬆️
src/Utilities/model.jl 98.76% <96.55%> (+0.02%) ⬆️
src/Utilities/universalfallback.jl 99.43% <99.1%> (+0.61%) ⬆️
src/Utilities/functions.jl 99.35% <0%> (+1.44%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 851125c...bf61745. Read the comment docs.

removevariable(f::MOI.AbstractFunction, s::MOI.AbstractSet, vi::MOI.VariableIndex)

Return a tuple `(g, t)` representing the constraint `f`-in-`s` with the
variable of index `vi` removed.
Copy link
Member

Choose a reason for hiding this comment

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

Unclear what it means to remove a variable from a constraint. Could you clarify?

@@ -137,16 +142,48 @@ end
MOI.canget(model::AbstractModel, ::MOI.Name) = true
MOI.get(model::AbstractModel, ::MOI.Name) = model.name

"""
newname(model::MOI.ModelLike, IdxT::Type{<:MOI.Index}, idx::MOI.Index, name::String)
Copy link
Member

Choose a reason for hiding this comment

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

Nit: IdxT could be IndexType. Another question for the style guide is whether we prefer idx or index.

Copy link
Member Author

Choose a reason for hiding this comment

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

Indeed, it would be nice to have a convention for that

end

"""
setname(idxnames::Dict{<:MOI.Index, String}, namesidx::Dict{String, <:MOI.Index}, idx::MOI.Index, name::String, idxtype::Symbol)
Copy link
Member

Choose a reason for hiding this comment

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

Naming suggestion: index_to_name and name_to_index

setname(idxnames::Dict{<:MOI.Index, String}, namesidx::Dict{String, <:MOI.Index}, idx::MOI.Index, name::String, idxtype::Symbol)

Sets the name of the index `idx` to the name `name` in the maps `idxnames` and `namesidx`.
If the name is already taken by an index different from `idx` then an error is thrown usin g `idxtype` to create a custom error message.
Copy link
Member

Choose a reason for hiding this comment

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

Typo: "usin g" -> "using"

end
function _removevar!(constrs::Vector, vi::VI)
for i in eachindex(constrs)
constrs[i] = _removevar(constrs[i]..., vi)
ci, f, s = constrs[i]
constrs[i] = (ci, removevariable(f, s, vi)...)
end
[]
Copy link
Member

Choose a reason for hiding this comment

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

Nit: since you're touching this function, please add a return statement.

"""
newname(model::MOI.ModelLike, IndexType::Type{<:MOI.Index}, idx::MOI.Index, name::String)

Return a `Bool` indicating whether `name` is not already used by an index of
Copy link
Member

Choose a reason for hiding this comment

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

The negative is confusing in this description. Maybe say "Returns a Bool indicating whether name is available to be used by an index of type IndexType (i.e., it's not already used)."

@@ -137,16 +145,48 @@ end
MOI.canget(model::AbstractModel, ::MOI.Name) = true
MOI.get(model::AbstractModel, ::MOI.Name) = model.name

"""
newname(model::MOI.ModelLike, IndexType::Type{<:MOI.Index}, idx::MOI.Index, name::String)
Copy link
Member

Choose a reason for hiding this comment

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

check_can_assign_name maybe? It's a bit confusing why this method should throw an error. What about returning 1 of 3 possible statuses: NameUnassigned, NameAssignedAndMatches, and NameMismatch?

Copy link
Member Author

Choose a reason for hiding this comment

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

If it does not throw an error, there won't be much code to share between the three places where this is used since we will have to branch on these three statuses. If we make typos in these branches we will introduce bugs and inconsistencies between the three places

setname(index_to_names::Dict{<:MOI.Index, String}, names_to_index::Dict{String, <:MOI.Index}, idx::MOI.Index, name::String, idxtype::Symbol)

Sets the name of the index `idx` to the name `name` in the maps `index_to_names` and `names_to_index`.
If the name is already taken by an index different from `idx` then an error is thrown using `idxtype` to create a custom error message.
Copy link
Member

Choose a reason for hiding this comment

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

I'm looking at the code and don't see where the error is thrown.

critical constraints and attributes while still supporting other attributes
with a small performance penalty. Note that `model` is unaware of constraints
and attributes stored by `UniversalFallback` so this is not appropriate if
`model` is an optimizer (for this reason, `optimize!` have not been
Copy link
Member

Choose a reason for hiding this comment

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

Nit: optimize! has not been implemented

@@ -76,6 +127,29 @@ function MOI.get(uf::UniversalFallback, attr::Union{MOI.AbstractVariableAttribut
end
end

function MOI.get(uf::UniversalFallback, attr::MOI.NumberOfConstraints{F, S}) where {F, S}
if MOI.supportsconstraint(uf.model, F, S)
MOI.get(uf.model, attr)
Copy link
Member

Choose a reason for hiding this comment

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

Nit: use return statements in these functions

end
function MOI.get(uf::UniversalFallback, ::Type{CI}, name::String)
if MOI.canget(uf.model, CI, name)
MOI.get(uf.model, CI, name)
Copy link
Member

Choose a reason for hiding this comment

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

Nit: return statements

MOI.canset(uf.model, attr, C)
function MOI.canaddconstraint(uf::UniversalFallback, ::Type{F}, ::Type{S}) where {F<:MOI.AbstractFunction, S<:MOI.AbstractSet}
if MOI.supportsconstraint(uf.model, F, S)
MOI.canaddconstraint(uf.model, F, S)
Copy link
Member

Choose a reason for hiding this comment

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

Return statements

@@ -64,8 +65,12 @@ end

struct UnknownOptimizerAttribute <: MOI.AbstractOptimizerAttribute end

# A few constraint types are supported to test both the fallback and the
Copy link
Member

Choose a reason for hiding this comment

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

Nit: "A few" -> "Few"

Copy link
Member

Choose a reason for hiding this comment

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

To my Kiwi English, it seems weird to say "Few" here. To me, "A few" reads as "we've only implemented a couple of constraint types to test the functionality" whereas "Few" has a negative connotation and means "Not enough constraint types are supported".

SO suggests the following example:

  • I have few friends.
  • I have a few friends.

Copy link
Member

Choose a reason for hiding this comment

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

I suggested "few" because I understood that the comment was trying to say that the model supports fewer constraint types than usual so that it can test the fallback.

Copy link
Member Author

Choose a reason for hiding this comment

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

I meant "A few" in opposition of none otherwise only the fallback is tested

@blegat blegat merged commit 7862c11 into master Jul 22, 2018
@blegat blegat deleted the bl/ufcon branch August 28, 2018 14:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants