From 40d93001c4465b491679f0af7d9a72e554f87e29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Thu, 19 Sep 2019 11:29:43 +0200 Subject: [PATCH 1/2] Fix == for sets with mutable fields --- src/sets.jl | 14 ++++++++++++++ test/sets.jl | 31 +++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/src/sets.jl b/src/sets.jl index 6e8575a283..e97a2316cc 100644 --- a/src/sets.jl +++ b/src/sets.jl @@ -148,6 +148,10 @@ struct EqualTo{T <: Number} <: AbstractScalarSet value::T end +function Base.:(==)(set1::S, set2::S) where S <: Union{GreaterThan, LessThan, EqualTo} + return constant(set1) == constant(set2) +end + """ Interval{T <: Real}(lower::T,upper::T) @@ -279,6 +283,10 @@ dual_set(s::DualPowerCone{T}) where T <: Real = PowerCone{T}(s.exponent) dimension(s::Union{ExponentialCone, DualExponentialCone, PowerCone, DualPowerCone}) = 3 +function Base.:(==)(set1::S, set2::S) where S <: Union{PowerCone, DualPowerCone} + return set1.exponent == set2.exponent +end + """ abstract type AbstractSymmetricMatrixSetTriangle <: AbstractVectorSet end @@ -573,6 +581,10 @@ struct Semiinteger{T <: Real} <: AbstractScalarSet upper::T end +function Base.:(==)(set1::S, set2::S) where S <: Union{Interval, Semicontinuous, Semiinteger} + return set1.lower == set2.lower && set1.upper == set2.upper +end + """ SOS1{T <: Real}(weights::Vector{T}) @@ -655,6 +667,8 @@ function Base.copy(set::IndicatorSet{A,S}) where {A,S} return IndicatorSet{A}(copy(set.set)) end +Base.:(==)(set1::IndicatorSet{A, S}, set2::IndicatorSet{A, S}) where {A, S} = set1.set == set2.set + # isbits types, nothing to copy function Base.copy(set::Union{Reals, Zeros, Nonnegatives, Nonpositives, GreaterThan, LessThan, EqualTo, Interval, diff --git a/test/sets.jl b/test/sets.jl index 6e7a2613bd..8d3aafa710 100644 --- a/test/sets.jl +++ b/test/sets.jl @@ -18,6 +18,37 @@ end Base.copy(mlt::MutLessThan) = MutLessThan(Base.copy(mlt.upper)) @testset "Sets" begin + @testset "==" begin + # By default, `==` redirects to `===`, it works for bits type + # but not for `BigInt`s. We define functions creating different + # instances so that `a() !== a()`. + a() = big(1) + b() = big(2) + @test a() !== a() + @test b() !== b() + for S in [MOI.LessThan, MOI.GreaterThan, MOI.EqualTo, MOI.PowerCone, MOI.DualPowerCone] + @test S(a()) == S(a()) + @test S(a()) != S(b()) + @test S(b()) == S(b()) + @test S(b()) == S(b()) + @test S(b()) == S(b()) + end + for S in [MOI.Interval, MOI.Semicontinuous, MOI.Semiinteger] + @test S(a(), b()) == S(a(), b()) + @test S(a(), b()) != S(b(), a()) + @test S(a(), b()) != S(b(), b()) + @test S(a(), b()) != S(a(), a()) + @test S(a(), a()) != S(b(), b()) + @test S(a(), a()) == S(a(), a()) + end + S = MOI.IndicatorSet + A() = MOI.LessThan(a()) + B() = MOI.LessThan(b()) + @test S{MOI.ACTIVATE_ON_ZERO}(A()) == S{MOI.ACTIVATE_ON_ZERO}(A()) + @test S{MOI.ACTIVATE_ON_ZERO}(A()) != S{MOI.ACTIVATE_ON_ONE}(A()) + @test S{MOI.ACTIVATE_ON_ZERO}(A()) != S{MOI.ACTIVATE_ON_ZERO}(B()) + @test S{MOI.ACTIVATE_ON_ONE}(A()) != S{MOI.ACTIVATE_ON_ONE}(B()) + end @testset "Copy" begin @testset "for $S" for S in [MOI.SOS1, MOI.SOS2] s = S([1.0]) From 4d9d25005ff909a746f8f772ca3015bd5766f62f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Thu, 19 Sep 2019 11:42:24 +0200 Subject: [PATCH 2/2] Remove redundant test --- test/sets.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/sets.jl b/test/sets.jl index 8d3aafa710..8d1e11678f 100644 --- a/test/sets.jl +++ b/test/sets.jl @@ -30,8 +30,7 @@ Base.copy(mlt::MutLessThan) = MutLessThan(Base.copy(mlt.upper)) @test S(a()) == S(a()) @test S(a()) != S(b()) @test S(b()) == S(b()) - @test S(b()) == S(b()) - @test S(b()) == S(b()) + @test S(b()) != S(a()) end for S in [MOI.Interval, MOI.Semicontinuous, MOI.Semiinteger] @test S(a(), b()) == S(a(), b())