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

InexactError: trunc(Int64, -Inf) in _variable_info #67

Closed
LebedevRI opened this issue May 25, 2024 · 4 comments · Fixed by #68
Closed

InexactError: trunc(Int64, -Inf) in _variable_info #67

LebedevRI opened this issue May 25, 2024 · 4 comments · Fixed by #68

Comments

@LebedevRI
Copy link

This is julia 1.10.3 + up-to-date packages.

(@v1.10) pkg> st
Status `~/.julia/environments/v1.10/Project.toml`
  [861a8166] Combinatorics v1.0.2
  [86223c79] Graphs v1.11.0
  [87dc4568] HiGHS v1.9.0
  [7073ff75] IJulia v1.24.2
  [b6b21f68] Ipopt v1.6.2
  [4076af6c] JuMP v1.22.1
  [a7f392d2] MiniZinc v0.3.8

This does not happen with HiGHS. I suspect the reproducer can be trimmed significantly.

using Combinatorics
using JuMP
import HiGHS
import MiniZinc

function main()
    NUM_OUTPUT_CONTACTS = 3
    NUM_OUTPUT_CONTACT_NAMES = ["Common", "A", "B"]
    NUM_DEVICE_CONTACTS = 2
    NUM_DEVICE_CONTACT_NAMES = ["-", "+"]
    NUM_INPUT_DEVICES = 3
    
    NUM_SWITCHES = 3
    NUM_SWITCH_CONTACTS = 1+11 # first contact is "self"

    CONTACT_NAMES = Vector{String}() # Name of i'th each contact
    CONTACT_LOOKUP = Dict{String,Dict}() # Index of the given contact, deep
    begin
        GROUP = "Sense"
        CONTACT_LOOKUP[GROUP] = Dict{String,Int}()
        for i in 1:NUM_OUTPUT_CONTACTS
            NAME = GROUP * " " * NUM_OUTPUT_CONTACT_NAMES[i]
            push!(CONTACT_NAMES, NAME)
            CONTACT_LOOKUP[GROUP][NUM_OUTPUT_CONTACT_NAMES[i]] = length(CONTACT_NAMES)
        end
    end
    begin
        GROUP = "Device"
        CONTACT_LOOKUP[GROUP] = Dict{Int,Dict{String,Int}}()
        for i in 1:NUM_INPUT_DEVICES
            CONTACT_LOOKUP[GROUP][i] = Dict{String,Int}()
            for j in 1:NUM_DEVICE_CONTACTS
                NAME = GROUP * " " * string(i) * " pole " * NUM_DEVICE_CONTACT_NAMES[j]
                push!(CONTACT_NAMES, NAME)
                CONTACT_LOOKUP[GROUP][i][NUM_DEVICE_CONTACT_NAMES[j]] = length(CONTACT_NAMES)
            end
        end
    end
    begin
        GROUP = "Switch"
        CONTACT_LOOKUP[GROUP] = Dict{Int,Dict{Int,Int}}()
        for i in 1:NUM_SWITCHES
            CONTACT_LOOKUP[GROUP][i] = Dict{Int,Int}()
            for j in 1:NUM_SWITCH_CONTACTS
                NAME = GROUP * " " * string(i) * " contact " * string(j) * (j == 1 ? " (self)" : "")
                push!(CONTACT_NAMES, NAME)
                CONTACT_LOOKUP[GROUP][i][j] = length(CONTACT_NAMES)
            end
        end
    end
    NUM_CONTACTS_TOTAL = length(CONTACT_NAMES)

    CONTACT_INDEXES = Dict{String,Int}() # Index of the given contact
    for i in 1:NUM_CONTACTS_TOTAL
        CONTACT_INDEXES[CONTACT_NAMES[i]] = i
    end
    
    INTERESTING_STATES = Set()
    for a in 1:NUM_INPUT_DEVICES
        for b in 1:NUM_INPUT_DEVICES
            for (pole,otherpole) in permutations(NUM_DEVICE_CONTACT_NAMES)
                STATE = Set()
                for d in zip((a,b),("A", "B"))
                    push!(STATE, ("Device " * string(d[1]) * " pole " * pole, "Sense " * first(NUM_OUTPUT_CONTACT_NAMES)))
                    push!(STATE, ("Device " * string(d[1]) * " pole " * otherpole, "Sense " * d[2]))
                    if a == b
                        break
                    end
                end
                push!(INTERESTING_STATES, STATE)
            end
        end        
    end  
    NUM_KEYFRAMES = length(INTERESTING_STATES)

    #model = Model(HiGHS.Optimizer);
    model = Model(() -> MiniZinc.Optimizer{Float64}("highs"))

    @variable(model, HardWires[1:NUM_CONTACTS_TOTAL, 1:NUM_CONTACTS_TOTAL], Bin)
    @constraints(model, begin
        # Hard-wiring graph is symmetrical
        [i=1:NUM_CONTACTS_TOTAL, j=1:NUM_CONTACTS_TOTAL], (HardWires[i,j] == HardWires[j,i])
        # Connections should never be hard-wired to themselves (they are themselves)
        [i=1:NUM_CONTACTS_TOTAL], HardWires[i,i] == 0
    end);
    
    @variable(model, 1 <= SwitchPosition[1:NUM_KEYFRAMES, 1:NUM_SWITCHES] <= NUM_SWITCH_CONTACTS, Int)

    @variable(model, Reachability[1:NUM_KEYFRAMES, 1:NUM_CONTACTS_TOTAL, 1:NUM_CONTACTS_TOTAL], Bin)

    @constraints(model, begin
        # Graph is symmetrical
        #[k=1:NUM_KEYFRAMES, i=1:NUM_CONTACTS_TOTAL, j=1:NUM_CONTACTS_TOTAL], (Reachability[k,i,j] == Reachability[k,j,i] := true)
        [k=1:NUM_KEYFRAMES, i=1:NUM_CONTACTS_TOTAL, j=1:NUM_CONTACTS_TOTAL], HardWires[i,j] --> {Reachability[k,i,j] == true}
    end);
    
    print(model)
    optimize!(model)
    @show convert.(Bool, value.(HardWires))
end

main()
InexactError: trunc(Int64, -Inf)

Stacktrace:
  [1] trunc
    @ ./float.jl:905 [inlined]
  [2] ceil
    @ ./float.jl:384 [inlined]
  [3] _variable_info(model::MathOptInterface.Utilities.GenericModel{Float64, MathOptInterface.Utilities.ObjectiveContainer{Float64}, MathOptInterface.Utilities.VariablesContainer{Float64}, MiniZinc.ModelFunctionConstraints{Float64}}, x::MathOptInterface.VariableIndex)
    @ MiniZinc ~/.julia/packages/MiniZinc/S9TPM/src/write.jl:38
  [4] (::MiniZinc.var"#3#4"{MathOptInterface.Utilities.GenericModel{Float64, MathOptInterface.Utilities.ObjectiveContainer{Float64}, MathOptInterface.Utilities.VariablesContainer{Float64}, MiniZinc.ModelFunctionConstraints{Float64}}})(x::MathOptInterface.VariableIndex)
    @ MiniZinc ./none:0
  [5] iterate
    @ ./generator.jl:47 [inlined]
  [6] _all(f::Base.var"#384#386", itr::Base.Generator{Vector{MathOptInterface.VariableIndex}, MiniZinc.var"#3#4"{MathOptInterface.Utilities.GenericModel{Float64, MathOptInterface.Utilities.ObjectiveContainer{Float64}, MathOptInterface.Utilities.VariablesContainer{Float64}, MiniZinc.ModelFunctionConstraints{Float64}}}}, ::Colon)
    @ Base ./reduce.jl:1297
  [7] all
    @ ./reduce.jl:1283 [inlined]
  [8] Dict(kv::Base.Generator{Vector{MathOptInterface.VariableIndex}, MiniZinc.var"#3#4"{MathOptInterface.Utilities.GenericModel{Float64, MathOptInterface.Utilities.ObjectiveContainer{Float64}, MathOptInterface.Utilities.VariablesContainer{Float64}, MiniZinc.ModelFunctionConstraints{Float64}}}})
    @ Base ./dict.jl:111
  [9] _write_variables(io::IOStream, model::MathOptInterface.Utilities.GenericModel{Float64, MathOptInterface.Utilities.ObjectiveContainer{Float64}, MathOptInterface.Utilities.VariablesContainer{Float64}, MiniZinc.ModelFunctionConstraints{Float64}})
    @ MiniZinc ~/.julia/packages/MiniZinc/S9TPM/src/write.jl:45
 [10] write(io::IOStream, model::MathOptInterface.Utilities.GenericModel{Float64, MathOptInterface.Utilities.ObjectiveContainer{Float64}, MathOptInterface.Utilities.VariablesContainer{Float64}, MiniZinc.ModelFunctionConstraints{Float64}})
    @ MiniZinc ~/.julia/packages/MiniZinc/S9TPM/src/write.jl:512
 [11] #20
    @ ~/.julia/packages/MiniZinc/S9TPM/src/optimize.jl:75 [inlined]
 [12] open(::MiniZinc.var"#20#22"{MiniZinc.Optimizer{Float64}}, ::String, ::Vararg{String}; kwargs::@Kwargs{})
    @ Base ./io.jl:396
 [13] open(::Function, ::String, ::String)
    @ Base ./io.jl:393
 [14] _run_minizinc(dest::MiniZinc.Optimizer{Float64})
    @ MiniZinc ~/.julia/packages/MiniZinc/S9TPM/src/optimize.jl:74
 [15] optimize!(dest::MiniZinc.Optimizer{Float64}, src::MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}})
    @ MiniZinc ~/.julia/packages/MiniZinc/S9TPM/src/optimize.jl:210
 [16] optimize!(m::MathOptInterface.Utilities.CachingOptimizer{MiniZinc.Optimizer{Float64}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}})
    @ MathOptInterface.Utilities ~/.julia/packages/MathOptInterface/2CULs/src/Utilities/cachingoptimizer.jl:316
 [17] optimize!
    @ ~/.julia/packages/MathOptInterface/2CULs/src/Bridges/bridge_optimizer.jl:380 [inlined]
 [18] optimize!
    @ ~/.julia/packages/MathOptInterface/2CULs/src/MathOptInterface.jl:85 [inlined]
 [19] optimize!(m::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{MiniZinc.Optimizer{Float64}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}})
    @ MathOptInterface.Utilities ~/.julia/packages/MathOptInterface/2CULs/src/Utilities/cachingoptimizer.jl:316
 [20] optimize!(model::Model; ignore_optimize_hook::Bool, _differentiation_backend::MathOptInterface.Nonlinear.SparseReverseMode, kwargs::@Kwargs{})
    @ JuMP ~/.julia/packages/JuMP/Gwn88/src/optimizer_interface.jl:457
 [21] optimize!
    @ ~/.julia/packages/JuMP/Gwn88/src/optimizer_interface.jl:409 [inlined]
 [22] main()
    @ Main ./In[67]:98
 [23] top-level scope
    @ In[67]:102
@odow
Copy link
Member

odow commented May 25, 2024

Here's a simpler reproducible example.

julia> using JuMP

julia> import HiGHS

julia> import MiniZinc

julia> model = Model(() -> MiniZinc.Optimizer{Float64}("highs"))
A JuMP Model
Feasibility problem with:
Variables: 0
Model mode: AUTOMATIC
CachingOptimizer state: EMPTY_OPTIMIZER
Solver name: MiniZinc

julia> @variable(model, x, Bin)
x

julia> optimize!(model)
ERROR: InexactError: trunc(Int64, -Inf)
Stacktrace:
  [1] trunc
    @ ./float.jl:905 [inlined]
  [2] ceil
    @ ./float.jl:384 [inlined]
  [3] _variable_info(model::MathOptInterface.Utilities.GenericModel{…}, x::MathOptInterface.VariableIndex)
    @ MiniZinc ~/.julia/packages/MiniZinc/S9TPM/src/write.jl:38
  [4] (::MiniZinc.var"#3#4"{MathOptInterface.Utilities.GenericModel{}})(x::MathOptInterface.VariableIndex)
    @ MiniZinc ./none:0
  [5] iterate
    @ ./generator.jl:47 [inlined]

I'll push a fix.

@LebedevRI
Copy link
Author

@odow thank you for taking a look!

@odow
Copy link
Member

odow commented May 25, 2024

See #68

@odow odow closed this as completed in #68 May 25, 2024
@LebedevRI
Copy link
Author

@odow thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

2 participants