Unexpected error using PriorityQueue

Hey there

I’m getting “LoadError: TypeError: in typeassert, expected Type, got a value of type EventType” in the following code. I understand the error, but I do not understand why it occurs. Why does it expect a Type and not EventType? I believe I specified the correct type in the signature of register_s_arrival() and when I pass it to register_s_arrival() from simulate(), but that clearly doesn’t work.

Also: won’t there be a key-problem if more than one V_ARRIVED_S*-event is enqueued? If so, do you have any good suggestions to avoid it?

I’m using Julia version 1.7.1 and I run it from my terminal. The following code should enable you to recreate the error:

using Random, Distributions, DataStructures

@enum EventType begin
    V_ARRIVED_S1
    V_ARRIVED_S2 
end

struct Environment
    hours_to_run::Float64
    arrival_D_st1::Exponential
    arrival_D_st2::Exponential
    travel_time_st1st2_D::Exponential
    travel_time_st2st1_D::Exponential
    
    Environment() = new(420.0, 
    Exponential(10),
    Exponential(10),
    Exponential(10),
    Exponential(10))
end

mutable struct State
    vehicles::Vector{Int64}
    State(v::Vector{Int64}) = new(v)
end

function register_s_arrival(station::Int64, s::State, env::Environment, q::PriorityQueue{EventType, Float64}, curr_t::Float64)
    if s.vehicles[station] >= 1
        s.vehicles[station] -= 1
        if station == 1
            ttime =  curr_t + rand(env.travel_time_st1st2_D)
            enqueue!(q, EventType::V_ARRIVED_S2, ttime)
        else
            ttime =  curr_t + rand(env.travel_time_st2st1_D)
            enqueue!(q, EventType::V_ARRIVED_S1, ttime)
        end

        return 0
    else
        return 1
    end
end

function simulate(env::Environment, carsSt1::Int64, carsSt2::Int64)
    t = 0
    state = State([carsSt1, carsSt2])
    events = PriorityQueue{EventType, Float64}()
    dt1 = rand(env.arrival_D_st1)
    dt2 = rand(env.arrival_D_st2)

    while t <= env.hours_to_run
        if dt1 < dt2
            t = dt1
            dt1 = rand(env.arrival_D_st1)
            res = register_s_arrival(1, state, env, events, t)
        else
            t = dt2
            dt2 = t + rand(env.arrival_D_st2)
            res = register_s_arrival(2, state, env, events, t)
        end
    end
end

simulate(Environment(), 2, 2)

The stacktrace yields:

Stacktrace:
 [1] register_s_arrival(station::Int64, s::State, env::Environment, q::PriorityQueue{EventType, Float64, Base.Order.ForwardOrdering}, curr_t::Float64)
   @ Main mwe.jl:35
 [2] simulate(env::Environment, carsSt1::Int64, carsSt2::Int64)
   @ Main mwe.jl:59
 [3] top-level scope
   @ Main mwe.jl:64
in expression starting at mwe.jl:64

Please do not hesitate to ping for more information if I’ve left anything out or suggest formatting improvements, this is my first question on any programming forum.
I would appreciate any help, thank you in advance :grinning:

I think it’s just a small syntax error in your enqueue! lines. Just use:

enqueue!(q, V_ARRIVED_S2, ttime)

e.g.:

julia> @enum EventType begin
           V_ARRIVED_S1
           V_ARRIVED_S2
       end

julia> using DataStructures

julia> events = PriorityQueue{EventType, Float64}()
PriorityQueue{EventType, Float64, Base.Order.ForwardOrdering}()

julia> enqueue!(events, V_ARRIVED_S2, 1.0)
PriorityQueue{EventType, Float64, Base.Order.ForwardOrdering} with 1 entry:
  V_ARRIVED_S2 => 1.0

julia> enqueue!(events, EventType::V_ARRIVED_S2, 1.0)
ERROR: TypeError: in typeassert, expected Type, got a value of type EventType
Stacktrace:
 [1] top-level scope
   @ REPL[6]:1
3 Likes

As @oheil said, the mentioned error comes from :: which is a typeassert, and in the order you put them, you are checking if the EventType is of the type V_ARRIVED_S1 (which is not a type but a value and this trigger an exception because it is nonsense). It seems to me that you confused C++ (or another language) syntax with Julia syntax. Julia does not use :: for namespaces, but . (the same as for fields of a structure).

3 Likes