diff --git a/automata/automaton_G_and_F.jl b/automata/automaton_G_and_F.jl index b1e65c3df47bafab38f60d1ceef7dbddb6af1499..ba05cabdd66c062687176f6d69d57c1c12d32697 100644 --- a/automata/automaton_G_and_F.jl +++ b/automata/automaton_G_and_F.jl @@ -1,11 +1,7 @@ # Creation of the automaton types #@everywhere @eval abstract type EdgeAutomatonGandF <: Edge end -@everywhere struct EdgeAutomatonGandF <: Edge - transitions::TransitionSet - check_constraints::Function - update_state!::Function -end +@everywhere struct EdgeAutomatonGandF{T} <: Edge transitions::Union{Nothing,Vector{Symbol}} end @everywhere @eval $(MarkovProcesses.generate_code_lha_type_def(:AutomatonGandF, :EdgeAutomatonGandF)) function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float64, t1::Float64, t2::Float64, sym_obs_G::VariableModel, @@ -63,26 +59,23 @@ function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float id = MarkovProcesses.newid() #Symbol("Edge_$(lha_name)_$(basename_func)_$(from_loc)$(to_loc)_$(edge_number)") - function edge_name(from_loc::Location, to_loc::Location, edge_number::Int) - return Symbol("$(edge_type)_$(from_loc)$(to_loc)_$(edge_number)_$(model_name)_$(id)") - end - function check_constraints(from_loc::Location, to_loc::Location, edge_number::Int) - return Symbol("check_constraints_$(edge_type)_$(from_loc)$(to_loc)_$(edge_number)_$(model_name)_$(id)") - end - function update_state!(from_loc::Location, to_loc::Location, edge_number::Int) - return Symbol("update_state_$(edge_type)_$(from_loc)$(to_loc)_$(edge_number)_$(model_name)_$(id)!") + function generate_edge_type(from_loc::Location, to_loc::Location, edge_number::Int) + tag_type = Symbol("$(from_loc)$(to_loc)_$(edge_number)_$(model_name)_$(id)") + @eval type = EdgeAutomatonGandF{$(Meta.quot(tag_type))} + return @eval($type) end ## check_constraints & update_state! @everywhere @eval begin + #return quote istrue(val::Float64) = convert(Bool, val) ## Edges check constraint and update state functions # l0G loc # l0G => l1G - #struct $(edge_name(:l0G, :l1G, 1)) <: $(edge_type) transitions::TransitionSet end - $(check_constraints(:l0G, :l1G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true - $(update_state!(:l0G, :l1G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(generate_edge_type(:l0G, :l1G, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + $(check_constraints)(edge::$(generate_edge_type(:l0G, :l1G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true + $(update_state!)(edge::$(generate_edge_type(:l0G, :l1G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = 0; S_values[$(to_idx(:n))] = x[$(idx_obs_var_G)]; S_values[$(to_idx(:in))] = true; @@ -91,125 +84,125 @@ function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float # l1G loc # l1G => l3G - #struct $(edge_name(:l1G, :l3G, 1)) <: $(edge_type) transitions::TransitionSet end - $(check_constraints(:l1G, :l3G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(generate_edge_type(:l1G, :l3G, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + $(check_constraints)(edge::$(generate_edge_type(:l1G, :l3G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = S_time <= $t1 && S_values[$(to_idx(:n))] < $x1 || S_values[$(to_idx(:n))] > $x2 - $(update_state!(:l1G, :l3G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + $(update_state!)(edge::$(generate_edge_type(:l1G, :l3G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = min(abs($x1 - S_values[$(to_idx(:n))]), abs($x2 - S_values[$(to_idx(:n))])); S_values[$(to_idx(:in))] = false; :l3G) - #struct $(edge_name(:l1G, :l3G, 2)) <: $(edge_type) transitions::TransitionSet end - $(check_constraints(:l1G, :l3G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(generate_edge_type(:l1G, :l3G, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + $(check_constraints)(edge::$(generate_edge_type(:l1G, :l3G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_time <= $t1) && ($x1 <= S_values[$(to_idx(:n))] <= $x2) - $(update_state!(:l1G, :l3G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + $(update_state!)(edge::$(generate_edge_type(:l1G, :l3G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = 0; S_values[$(to_idx(:in))] = false; :l3G) - #struct $(edge_name(:l1G, :l3G, 3)) <: $(edge_type) transitions::TransitionSet end - $(check_constraints(:l1G, :l3G, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(generate_edge_type(:l1G, :l3G, 3)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + $(check_constraints)(edge::$(generate_edge_type(:l1G, :l3G, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = !istrue(S_values[$(to_idx(:in))]) && ($t1 <= S_time <= $t2) && ($x1 <= S_values[$(to_idx(:n))] <= $x2) - $(update_state!(:l1G, :l3G, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + $(update_state!)(edge::$(generate_edge_type(:l1G, :l3G, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] * (S_time - $t1); S_values[$(to_idx(:tprime))] = 0.0; :l3G) - #struct $(edge_name(:l1G, :l3G, 4)) <: $(edge_type) transitions::TransitionSet end - $(check_constraints(:l1G, :l3G, 4))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(generate_edge_type(:l1G, :l3G, 4)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + $(check_constraints)(edge::$(generate_edge_type(:l1G, :l3G, 4)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = istrue(S_values[$(to_idx(:in))]) && ($t1 <= S_time <= $t2) && ($x1 <= S_values[$(to_idx(:n))] <= $x2) - $(update_state!(:l1G, :l3G, 4))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + $(update_state!)(edge::$(generate_edge_type(:l1G, :l3G, 4)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:tprime))] = 0.0; :l3G) # l1G => l4G - #struct $(edge_name(:l1G, :l4G, 1)) <: $(edge_type) transitions::TransitionSet end - $(check_constraints(:l1G, :l4G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(generate_edge_type(:l1G, :l4G, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + $(check_constraints)(edge::$(generate_edge_type(:l1G, :l4G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = !istrue(S_values[$(to_idx(:in))]) && ($t1 <= S_time <= $t2) && (S_values[$(to_idx(:n))] < $x1 || S_values[$(to_idx(:n))] > $x2) - $(update_state!(:l1G, :l4G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + $(update_state!)(edge::$(generate_edge_type(:l1G, :l4G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] + S_values[$(to_idx(:d))] * (S_time - $t1); :l4G) - #struct $(edge_name(:l1G, :l4G, 2)) <: $(edge_type) transitions::TransitionSet end - $(check_constraints(:l1G, :l4G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(generate_edge_type(:l1G, :l4G, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + $(check_constraints)(edge::$(generate_edge_type(:l1G, :l4G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = istrue(S_values[$(to_idx(:in))]) && ($t1 <= S_time <= $t2) && (S_values[$(to_idx(:n))] < $x1 || S_values[$(to_idx(:n))] > $x2) - $(update_state!(:l1G, :l4G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + $(update_state!)(edge::$(generate_edge_type(:l1G, :l4G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (:l4G) # l1G => l2G #= - #struct $(edge_name(:l1G, :l2G, 3)) <: $(edge_type) transitions::TransitionSet end - $(check_constraints(:l1G, :l2G, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(generate_edge_type(:l1G, :l2G, 3)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + $(check_constraints)(edge::$(generate_edge_type(:l1G, :l2G, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = istrue(S_values[$(to_idx(:isabs))]) && S_time <= $t1 - $(update_state!(:l1G, :l2G, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + $(update_state!)(edge::$(generate_edge_type(:l1G, :l2G, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = ($t2 - $t1) * min(abs($x1 - S_values[$(to_idx(:n))]), abs($x2 - S_values[$(to_idx(:n))])); :l2G) - #struct $(edge_name(:l1G, :l2G, 4)) <: $(edge_type) transitions::TransitionSet end - $(check_constraints(:l1G, :l2G, 4))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(generate_edge_type(:l1G, :l2G, 4)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + $(check_constraints)(edge::$(generate_edge_type(:l1G, :l2G, 4)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = istrue(S_values[$(to_idx(:isabs))]) && ($t1 <= S_time <= $t2) - $(update_state!(:l1G, :l2G, 4))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + $(update_state!)(edge::$(generate_edge_type(:l1G, :l2G, 4)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] + ($t2 - S_time) * min(abs($x1 - S_values[$(to_idx(:n))]), abs($x2 - S_values[$(to_idx(:n))])); :l2G) - #struct $(edge_name(:l1G, :l2G, 1)) <: $(edge_type) transitions::TransitionSet end - $(check_constraints(:l1G, :l2G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(generate_edge_type(:l1G, :l2G, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + $(check_constraints)(edge::$(generate_edge_type(:l1G, :l2G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = istrue(S_values[$(to_idx(:in))]) && S_time >= $t2 - $(update_state!(:l1G, :l2G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + $(update_state!)(edge::$(generate_edge_type(:l1G, :l2G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (:l2G) - #struct $(edge_name(:l1G, :l2G, 2)) <: $(edge_type) transitions::TransitionSet end - $(check_constraints(:l1G, :l2G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(generate_edge_type(:l1G, :l2G, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + $(check_constraints)(edge::$(generate_edge_type(:l1G, :l2G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = !istrue(S_values[$(to_idx(:in))]) && S_time >= $t2 - $(update_state!(:l1G, :l2G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + $(update_state!)(edge::$(generate_edge_type(:l1G, :l2G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] * ($t2 - $t1); :l2G) =# # l3G loc # l3G => l1G - #struct $(edge_name(:l3G, :l1G, 1)) <: $(edge_type) transitions::TransitionSet end - $(check_constraints(:l3G, :l1G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true - $(update_state!(:l3G, :l1G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(generate_edge_type(:l3G, :l1G, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + $(check_constraints)(edge::$(generate_edge_type(:l3G, :l1G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true + $(update_state!)(edge::$(generate_edge_type(:l3G, :l1G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:n))] = x[$(idx_obs_var_G)]; S_values[$(to_idx(:isabs))] = $(m.isabsorbing)(p, x); :l1G) # l3G => l2G - #struct $(edge_name(:l3G, :l2G, 2)) <: $(edge_type) transitions::TransitionSet end - $(check_constraints(:l3G, :l2G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(generate_edge_type(:l3G, :l2G, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + $(check_constraints)(edge::$(generate_edge_type(:l3G, :l2G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = istrue(S_values[$(to_idx(:in))]) && (S_time >= $t2 || istrue(S_values[$(to_idx(:isabs))])) - $(update_state!(:l3G, :l2G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + $(update_state!)(edge::$(generate_edge_type(:l3G, :l2G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] * ($t2 - $t1); :l2G) - #struct $(edge_name(:l3G, :l2G, 1)) <: $(edge_type) transitions::TransitionSet end - $(check_constraints(:l3G, :l2G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(generate_edge_type(:l3G, :l2G, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + $(check_constraints)(edge::$(generate_edge_type(:l3G, :l2G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = !istrue(S_values[$(to_idx(:in))]) && (S_time >= $t2 || istrue(S_values[$(to_idx(:isabs))])) - $(update_state!(:l3G, :l2G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + $(update_state!)(edge::$(generate_edge_type(:l3G, :l2G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (:l2G) # l4G loc # l4G => l1G - #struct $(edge_name(:l4G, :l1G, 1)) <: $(edge_type) transitions::TransitionSet end - $(check_constraints(:l4G, :l1G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true - $(update_state!(:l4G, :l1G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(generate_edge_type(:l4G, :l1G, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + $(check_constraints)(edge::$(generate_edge_type(:l4G, :l1G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true + $(update_state!)(edge::$(generate_edge_type(:l4G, :l1G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] + S_values[$(to_idx(:tprime))] * min(abs($x1 - S_values[$(to_idx(:n))]), abs($x2 - S_values[$(to_idx(:n))])); S_values[$(to_idx(:tprime))] = 0.0; S_values[$(to_idx(:n))] = x[$(idx_obs_var_G)]; @@ -218,25 +211,25 @@ function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float :l1G) # l4G => l2G - #struct $(edge_name(:l4G, :l2G, 1)) <: $(edge_type) transitions::TransitionSet end - $(check_constraints(:l4G, :l2G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(generate_edge_type(:l4G, :l2G, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + $(check_constraints)(edge::$(generate_edge_type(:l4G, :l2G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (istrue(S_values[$(to_idx(:isabs))])) - $(update_state!(:l4G, :l2G, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + $(update_state!)(edge::$(generate_edge_type(:l4G, :l2G, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] + ($t2 - S_time) * min(abs($x1 - S_values[$(to_idx(:n))]), abs($x2 - S_values[$(to_idx(:n))])); :l2G) - #struct $(edge_name(:l4G, :l2G, 2)) <: $(edge_type) transitions::TransitionSet end - $(check_constraints(:l4G, :l2G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(generate_edge_type(:l4G, :l2G, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + $(check_constraints)(edge::$(generate_edge_type(:l4G, :l2G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_time >= $t2) - $(update_state!(:l4G, :l2G, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + $(update_state!)(edge::$(generate_edge_type(:l4G, :l2G, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] + S_values[$(to_idx(:tprime))] * min(abs($x1 - S_values[$(to_idx(:n))]), abs($x2 - S_values[$(to_idx(:n))])); :l2G) # Connection between the two automata: l2G => l1F - #struct $(edge_name(:l2G, :l1F, 1)) <: $(edge_type) transitions::TransitionSet end - $(check_constraints(:l2G, :l1F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true - $(update_state!(:l2G, :l1F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(generate_edge_type(:l2G, :l1F, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + $(check_constraints)(edge::$(generate_edge_type(:l2G, :l1F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true + $(update_state!)(edge::$(generate_edge_type(:l2G, :l1F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:n))] = x[$(idx_obs_var_F)]; S_values[$(to_idx(:dprime))] = Inf; S_values[$(to_idx(:isabs))] = $(m.isabsorbing)(p, x); @@ -244,77 +237,77 @@ function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float # l1F loc : we con#struct the edges of the form l1F => (..) # l1F => l2F - #struct $(edge_name(:l1F, :l2F, 1)) <: $(edge_type) transitions::TransitionSet end - $(check_constraints(:l1F, :l2F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(generate_edge_type(:l1F, :l2F, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + $(check_constraints)(edge::$(generate_edge_type(:l1F, :l2F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = S_time >= $t3 && S_values[$(to_idx(:dprime))] == 0 - $(update_state!(:l1F, :l2F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + $(update_state!)(edge::$(generate_edge_type(:l1F, :l2F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (#S_values[$(to_idx(:dprime))] = 0; :l2F) - #struct $(edge_name(:l1F, :l2F, 2)) <: $(edge_type) transitions::TransitionSet end - $(check_constraints(:l1F, :l2F, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(generate_edge_type(:l1F, :l2F, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + $(check_constraints)(edge::$(generate_edge_type(:l1F, :l2F, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_time >= $t4) && (S_values[$(to_idx(:n))] < $x3 || S_values[$(to_idx(:n))] > $x4) - $(update_state!(:l1F, :l2F, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + $(update_state!)(edge::$(generate_edge_type(:l1F, :l2F, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (#S_values[$(to_idx(:dprime))] = min(abs(S_values[$(to_idx(:n))] - $x3), abs(S_values[$(to_idx(:n))] - $x4)); S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] + S_values[$(to_idx(:dprime))]; :l2F) #= - #struct $(edge_name(:l1F, :l2F, 3)) <: $(edge_type) transitions::TransitionSet end - $(check_constraints(:l1F, :l2F, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(generate_edge_type(:l1F, :l2F, 3)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + $(check_constraints)(edge::$(generate_edge_type(:l1F, :l2F, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = istrue(S_values[$(to_idx(:isabs))]) && S_time <= $t4 - $(update_state!(:l1F, :l2F, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + $(update_state!)(edge::$(generate_edge_type(:l1F, :l2F, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] + S_values[$(to_idx(:dprime))]; :l2F) - #struct $(edge_name(:l1F, :l2F, 4)) <: $(edge_type) transitions::TransitionSet end - $(check_constraints(:l1F, :l2F, 4))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(generate_edge_type(:l1F, :l2F, 4)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + $(check_constraints)(edge::$(generate_edge_type(:l1F, :l2F, 4)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = S_time >= $t3 && S_values[$(to_idx(:dprime))] == 0 - $(update_state!(:l1F, :l2F, 4))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + $(update_state!)(edge::$(generate_edge_type(:l1F, :l2F, 4)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (:l2F) =# # l1F => l3F - #struct $(edge_name(:l1F, :l3F, 1)) <: $(edge_type) transitions::TransitionSet end - $(check_constraints(:l1F, :l3F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(generate_edge_type(:l1F, :l3F, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + $(check_constraints)(edge::$(generate_edge_type(:l1F, :l3F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_time <= $t3) && (S_values[$(to_idx(:n))] < $x3 || S_values[$(to_idx(:n))] > $x4) - $(update_state!(:l1F, :l3F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + $(update_state!)(edge::$(generate_edge_type(:l1F, :l3F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:dprime))] = min(sqrt((S_time - $t3)^2 + (S_values[$(to_idx(:n))] - $x4)^2), sqrt((S_time - $t3)^2 + (S_values[$(to_idx(:n))] - $x3)^2)); :l3F) - #struct $(edge_name(:l1F, :l3F, 2)) <: $(edge_type) transitions::TransitionSet end - $(check_constraints(:l1F, :l3F, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(generate_edge_type(:l1F, :l3F, 2)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + $(check_constraints)(edge::$(generate_edge_type(:l1F, :l3F, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = ($x3 <= S_values[$(to_idx(:n))] <= $x4) - $(update_state!(:l1F, :l3F, 2))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + $(update_state!)(edge::$(generate_edge_type(:l1F, :l3F, 2)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:dprime))] = 0; :l3F) - #struct $(edge_name(:l1F, :l3F, 3)) <: $(edge_type) transitions::TransitionSet end - $(check_constraints(:l1F, :l3F, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(generate_edge_type(:l1F, :l3F, 3)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + $(check_constraints)(edge::$(generate_edge_type(:l1F, :l3F, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_time >= $t3) && (S_values[$(to_idx(:n))] < $x3 || S_values[$(to_idx(:n))] > $x4) - $(update_state!(:l1F, :l3F, 3))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + $(update_state!)(edge::$(generate_edge_type(:l1F, :l3F, 3)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:dprime))] = min(S_values[$(to_idx(:dprime))], min(abs(S_values[$(to_idx(:n))] - $x3), abs(S_values[$(to_idx(:n))] - $x4))); :l3F) # l3F loc # l3F => l1F - #struct $(edge_name(:l3F, :l1F, 1)) <: $(edge_type) transitions::TransitionSet end - $(check_constraints(:l3F, :l1F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true - $(update_state!(:l3F, :l1F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(generate_edge_type(:l3F, :l1F, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + $(check_constraints)(edge::$(generate_edge_type(:l3F, :l1F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = true + $(update_state!)(edge::$(generate_edge_type(:l3F, :l1F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:n))] = x[$(idx_obs_var_F)]; S_values[$(to_idx(:isabs))] = $(m.isabsorbing)(p, x); :l1F) # l3F => l2F - #struct $(edge_name(:l3F, :l2F, 1)) <: $(edge_type) transitions::TransitionSet end - $(check_constraints(:l3F, :l2F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + #struct $(generate_edge_type(:l3F, :l2F, 1)) <: $(edge_type) transitions::Union{Nothing,Vector{Symbol}} end + $(check_constraints)(edge::$(generate_edge_type(:l3F, :l2F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_time >= $t4 || istrue(S_values[$(to_idx(:isabs))])) - $(update_state!(:l3F, :l2F, 1))(S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = + $(update_state!)(edge::$(generate_edge_type(:l3F, :l2F, 1)), S_time::Float64, S_values::Vector{Float64}, x::Vector{Int}, p::Vector{Float64}) = (S_values[$(to_idx(:d))] = S_values[$(to_idx(:d))] + S_values[$(to_idx(:dprime))]; :l2F) end @@ -327,113 +320,91 @@ function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float # l0G loc # l0G => l1G - edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l0G, :l1G, 1)), $(update_state!(:l0G, :l1G, 1))) + edge1 = $(generate_edge_type(:l0G, :l1G, 1))(nothing) map_edges[:l0G][:l1G] = [edge1] # l1G => l3G - edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l3G, 1)), $(update_state!(:l1G, :l3G, 1))) - edge2 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l3G, 2)), $(update_state!(:l1G, :l3G, 2))) - edge3 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l3G, 3)), $(update_state!(:l1G, :l3G, 3))) - edge4 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l3G, 4)), $(update_state!(:l1G, :l3G, 4))) + edge1 = $(generate_edge_type(:l1G, :l3G, 1))(nothing) + edge2 = $(generate_edge_type(:l1G, :l3G, 2))(nothing) + edge3 = $(generate_edge_type(:l1G, :l3G, 3))(nothing) + edge4 = $(generate_edge_type(:l1G, :l3G, 4))(nothing) map_edges[:l1G][:l3G] = [edge1, edge2, edge3, edge4] # l1G => l4G - edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l4G, 1)), $(update_state!(:l1G, :l4G, 1))) - edge2 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l4G, 2)), $(update_state!(:l1G, :l4G, 2))) + edge1 = $(generate_edge_type(:l1G, :l4G, 1))(nothing) + edge2 = $(generate_edge_type(:l1G, :l4G, 2))(nothing) map_edges[:l1G][:l4G] = [edge1, edge2] # l1G => l2G #= - edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l2G, 1)), $(update_state!(:l1G, :l2G, 1))) - edge2 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l2G, 2)), $(update_state!(:l1G, :l2G, 2))) - edge3 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l2G, 3)), $(update_state!(:l1G, :l2G, 3))) - edge4 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1G, :l2G, 4)), $(update_state!(:l1G, :l2G, 4))) + edge1 = $(generate_edge_type(:l1G, :l2G, 1))(nothing) + edge2 = $(generate_edge_type(:l1G, :l2G, 2))(nothing) + edge3 = $(generate_edge_type(:l1G, :l2G, 3))(nothing) + edge4 = $(generate_edge_type(:l1G, :l2G, 4))(nothing) map_edges[:l1G][:l2G] = [edge3, edge4, edge1, edge2] =# # l3G loc # l3G => l1G - edge1 = EdgeAutomatonGandF([:ALL], $(check_constraints(:l3G, :l1G, 1)), $(update_state!(:l3G, :l1G, 1))) + edge1 = $(generate_edge_type(:l3G, :l1G, 1))([:ALL]) map_edges[:l3G][:l1G] = [edge1] # l3G => l2G - edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l3G, :l2G, 1)), $(update_state!(:l3G, :l2G, 1))) - edge2 = EdgeAutomatonGandF(nothing, $(check_constraints(:l3G, :l2G, 2)), $(update_state!(:l3G, :l2G, 2))) + edge1 = $(generate_edge_type(:l3G, :l2G, 1))(nothing) + edge2 = $(generate_edge_type(:l3G, :l2G, 2))(nothing) map_edges[:l3G][:l2G] = [edge1, edge2] # l4 loc # l4G => l1G - edge1 = EdgeAutomatonGandF([:ALL], $(check_constraints(:l4G, :l1G, 1)), $(update_state!(:l4G, :l1G, 1))) + edge1 = $(generate_edge_type(:l4G, :l1G, 1))([:ALL]) map_edges[:l4G][:l1G] = [edge1] # l4G => l2G - edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l4G, :l2G, 1)), $(update_state!(:l4G, :l2G, 1))) - edge2 = EdgeAutomatonGandF(nothing, $(check_constraints(:l4G, :l2G, 2)), $(update_state!(:l4G, :l2G, 2))) + edge1 = $(generate_edge_type(:l4G, :l2G, 1))(nothing) + edge2 = $(generate_edge_type(:l4G, :l2G, 2))(nothing) map_edges[:l4G][:l2G] = [edge1,edge2] # l2G loc # l2G => l1F : Transition from autF to autG - edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l2G, :l1F, 1)), $(update_state!(:l2G, :l1F, 1))) + edge1 = $(generate_edge_type(:l2G, :l1F, 1))(nothing) map_edges[:l2G][:l1F] = [edge1] # l1F loc # l1F => l3F - edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1F, :l2F, 1)), $(update_state!(:l1F, :l2F, 1))) - edge2 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1F, :l2F, 2)), $(update_state!(:l1F, :l2F, 2))) + edge1 = $(generate_edge_type(:l1F, :l2F, 1))(nothing) + edge2 = $(generate_edge_type(:l1F, :l2F, 2))(nothing) map_edges[:l1F][:l2F] = [edge1, edge2] - #edge3 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1F, :l2F, 3)), $(update_state!(:l1F, :l2F, 3))) - #edge4 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1F, :l2F, 4)), $(update_state!(:l1F, :l2F, 4))) + #edge3 = $(generate_edge_type(:l1F, :l2F, 3))(nothing) + #edge4 = $(generate_edge_type(:l1F, :l2F, 4))(nothing) #map_edges[:l1F][:l2F] = [edge1, edge4, edge3, edge2] # l1F => l3F - edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1F, :l3F, 1)), $(update_state!(:l1F, :l3F, 1))) - edge2 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1F, :l3F, 2)), $(update_state!(:l1F, :l3F, 2))) - edge3 = EdgeAutomatonGandF(nothing, $(check_constraints(:l1F, :l3F, 3)), $(update_state!(:l1F, :l3F, 3))) + edge1 = $(generate_edge_type(:l1F, :l3F, 1))(nothing) + edge2 = $(generate_edge_type(:l1F, :l3F, 2))(nothing) + edge3 = $(generate_edge_type(:l1F, :l3F, 3))(nothing) map_edges[:l1F][:l3F] = [edge1, edge2, edge3] # l3F loc # l3F => l1F - edge1 = EdgeAutomatonGandF([:ALL], $(check_constraints(:l3F, :l1F, 1)), $(update_state!(:l3F, :l1F, 1))) + edge1 = $(generate_edge_type(:l3F, :l1F, 1))([:ALL]) map_edges[:l3F][:l1F] = [edge1] # l3F => l2F - edge1 = EdgeAutomatonGandF(nothing, $(check_constraints(:l3F, :l2F, 1)), $(update_state!(:l3F, :l2F, 1))) + edge1 = $(generate_edge_type(:l3F, :l2F, 1))(nothing) map_edges[:l3F][:l2F] = [edge1] end - ## Create data separately - map_edges_transitions = Dict{Symbol, Dict{Symbol,Vector{TransitionSet}}}() - map_edges_check_constraints = Dict{Symbol, Dict{Symbol,Vector{Function}}}() - map_edges_update_state = Dict{Symbol, Dict{Symbol,Vector{Function}}}() - for from_loc in keys(map_edges) - map_edges_transitions[from_loc] = Dict{Symbol,Vector{TransitionSet}}() - map_edges_check_constraints[from_loc] = Dict{Symbol,Vector{Function}}() - map_edges_update_state[from_loc] = Dict{Symbol,Vector{Function}}() - for to_loc in keys(map_edges[from_loc]) - map_edges_transitions[from_loc][to_loc] = TransitionSet[] - map_edges_check_constraints[from_loc][to_loc] = Function[] - map_edges_update_state[from_loc][to_loc] = Function[] - for edge in map_edges[from_loc][to_loc] - push!(map_edges_transitions[from_loc][to_loc], edge.transitions) - push!(map_edges_check_constraints[from_loc][to_loc], edge.check_constraints) - push!(map_edges_update_state[from_loc][to_loc], edge.update_state!) - end - end - end - ## Constants constants = Dict{Symbol,Float64}(:x1 => x1, :x2 => x2, :t1 => t1, :t2 => t2, :x3 => x3, :x4 => x4, :t3 => t3, :t4 => t4) - # Updating types and simulation method + # Updating types and simulation methods @everywhere @eval $(MarkovProcesses.generate_code_synchronized_model_type_def(model_name, lha_name)) - @everywhere @eval $(MarkovProcesses.new_generate_code_next_state(lha_name, edge_type)) + @everywhere @eval $(MarkovProcesses.generate_code_next_state(lha_name, edge_type, check_constraints, update_state!)) @everywhere @eval $(MarkovProcesses.generate_code_synchronized_simulation(model_name, lha_name, edge_type, m.f!, m.isabsorbing)) A = AutomatonGandF(m.transitions, locations, Λ_F, locations_init, locations_final, - map_var_automaton_idx, flow, map_edges, - map_edges_transitions, map_edges_check_constraints, map_edges_update_state, - constants, m.map_var_idx) + map_var_automaton_idx, flow, map_edges, constants, m.map_var_idx) return A end diff --git a/core/common.jl b/core/common.jl index c22a5837a5d29bee0bda72624af2abb8dd6a2f8b..4a501df49cbc18fc0bfc4bfc8eff803b0d11246e 100644 --- a/core/common.jl +++ b/core/common.jl @@ -11,7 +11,6 @@ abstract type Edge end const VariableModel = Symbol const ParameterModel = Symbol const Transition = Union{Symbol,Nothing} -const TransitionSet = Union{Vector{Symbol},Nothing} const Location = Symbol const VariableAutomaton = Symbol @@ -56,9 +55,6 @@ function generate_code_lha_type_def(lha_name::Symbol, edge_type::Symbol) map_var_automaton_idx::Dict{VariableAutomaton,Int} # nvar keys : str_var => idx in values flow::Dict{Location,Vector{Float64}} # output of length nvar map_edges::Dict{Location, Dict{Location,Vector{$(edge_type)}}} - map_edges_transitions::Dict{Location, Dict{Location,Vector{TransitionSet}}} - map_edges_check_constraints::Dict{Location, Dict{Location,Vector{Function}}} - map_edges_update_state::Dict{Location, Dict{Location,Vector{Function}}} constants::Dict{Symbol,Float64} map_var_model_idx::Dict{VariableModel,Int} # of dim d (of a model) end diff --git a/core/lha.jl b/core/lha.jl index 30fd1ec66047173409e082a96cc655aa51ec1a67..8f5fcc5f1d9514aae63417bee8a3c8e96071086c 100644 --- a/core/lha.jl +++ b/core/lha.jl @@ -90,234 +90,8 @@ function init_state(A::LHA, x0::Vector{Int}, t0::Float64) return S0 end -function generate_code_next_state_with_dicts_lha(lha_name::Symbol, edge_type::Symbol) - - return quote - # A push! method implementend by myself because of preallocation of edge_candidates - function _push_edge!(edge_id_candidates::Vector{Int}, target_loc_candidates::Vector{Symbol}, - edge_id::Int, target_loc::Symbol, nbr_candidates::Int) - if nbr_candidates < length(edge_id_candidates) - edge_id_candidates[nbr_candidates+1] = edge_id - target_loc_candidates[nbr_candidates+1] = target_loc - else - push!(edge_id_candidates, edge_id) - push!(target_loc_candidates, target_loc) - end - end - - function _find_edge_candidates!(edge_id_candidates::Vector{Int}, target_loc_candidates::Vector{Symbol}, - dict_transitions_from_current_loc::Dict{Location,Vector{TransitionSet}}, - dict_check_constraints_from_current_loc::Dict{Location,Vector{Function}}, - Λ::Dict{Location,Function}, - S_time::Float64, S_values::Vector{Float64}, - x::Vector{Int}, p::Vector{Float64}, - only_asynchronous::Bool) - nbr_candidates = 0 - for target_loc in keys(dict_transitions_from_current_loc) - if !Λ[target_loc](x) continue end - for i = eachindex(dict_transitions_from_current_loc[target_loc]) - check_constraints_edge = dict_check_constraints_from_current_loc[target_loc][i] - if check_constraints_edge(S_time, S_values, x, p) - transitions = dict_transitions_from_current_loc[target_loc][i] - if transitions == nothing - _push_edge!(edge_id_candidates, target_loc_candidates, i, target_loc, nbr_candidates) - nbr_candidates += 1 - return nbr_candidates - else - if !only_asynchronous - _push_edge!(edge_id_candidates, target_loc_candidates, i, target_loc, nbr_candidates) - nbr_candidates += 1 - end - end - end - end - end - return nbr_candidates - end - - function _get_edge_index(edge_id_candidates::Vector{Int}, target_loc_candidates::Vector{Symbol}, nbr_candidates::Int, - dict_transitions_from_current_loc::Dict{Location,Vector{TransitionSet}}, - detected_event::Bool, tr_nplus1::Transition) - ind_edge = 0 - bool_event = detected_event - for i = 1:nbr_candidates - target_loc = target_loc_candidates[i] - edge_id = edge_id_candidates[i] - transitions = dict_transitions_from_current_loc[target_loc][edge_id] - # Asynchronous edge detection: we fire it - if transitions == nothing - return (i, detected_event) - end - # Synchronous detection - if !detected_event && tr_nplus1 != nothing - if (transitions[1] == :ALL) || (tr_nplus1 in transitions) - ind_edge = i - bool_event = true - end - end - end - return (ind_edge, bool_event) - end - - function next_state!(A::$(lha_name), - ptr_loc_state::Vector{Symbol}, values_state::Vector{Float64}, ptr_time_state::Vector{Float64}, - xnplus1::Vector{Int}, tnplus1::Float64, tr_nplus1::Transition, - xn::Vector{Int}, p::Vector{Float64}, - edge_id_candidates::Vector{Int}, target_loc_candidates::Vector{Symbol}; verbose::Bool = false) - # En fait d'apres observation de Cosmos, après qu'on ait lu la transition on devrait stop. - detected_event::Bool = false - turns = 0 - Λ = getfield(A, :Λ) - flow = getfield(A, :flow) - map_edges = A.map_edges - map_edges_transitions = A.map_edges_transitions - map_edges_check_constraints = A.map_edges_check_constraints - map_edges_update_state = A.map_edges_update_state - if verbose - println("##### Begin next_state!") - @show xnplus1, tnplus1, tr_nplus1 - end - # First, we check the asynchronous transitions - while true - turns += 1 - if verbose @show turns end - #edge_candidates = empty!(edge_candidates) - dict_transitions_from_current_loc = map_edges_transitions[ptr_loc_state[1]] - dict_check_constraints_from_current_loc = map_edges_check_constraints[ptr_loc_state[1]] - # Save all edges that satisfies transition predicate (asynchronous ones) - nbr_candidates = _find_edge_candidates!(edge_id_candidates, target_loc_candidates, - dict_transitions_from_current_loc, dict_check_constraints_from_current_loc, - Λ, ptr_time_state[1], values_state, xn, p, true) - # Search the one we must chose, here the event is nothing because - # we're not processing yet the next event - ind_edge, detected_event = _get_edge_index(edge_id_candidates, target_loc_candidates, nbr_candidates, - dict_transitions_from_current_loc, - detected_event, nothing) - # Update the state with the chosen one (if it exists) - # Should be xn here - #first_round = false - if ind_edge > 0 - edge_target_loc = target_loc_candidates[ind_edge] - edge_id = edge_id_candidates[ind_edge] - firing_update_state! = map_edges_update_state[ptr_loc_state[1]][edge_target_loc][edge_id] - ptr_loc_state[1] = firing_update_state!(ptr_time_state[1], values_state, xn, p) - else - if verbose - println("No edge fired:") - @show ind_edge, detected_event, nbr_candidates - end - break - end - if verbose - println("Edge fired:") - @show edge_id_candidates, target_loc_candidates - @show ind_edge, detected_event, nbr_candidates - @show ptr_loc_state[1] - @show ptr_time_state[1] - @show values_state - if turns == 500 - @warn "We've reached 500 turns" - end - end - # For debug - #= - if turns > 100 - println("Number of turns in next_state! is suspicious") - @show first_round, detected_event - @show length(edge_candidates) - @show tnplus1, tr_nplus1, xnplus1 - @show edge_candidates - error("Unpredicted behavior automaton") - end - =# - end - if verbose - println("Time flies with the flow...") - end - # Now time flies according to the flow - for i in eachindex(values_state) - coeff_deriv = flow[ptr_loc_state[1]][i] - if coeff_deriv > 0 - values_state[i] += coeff_deriv*(tnplus1 - ptr_time_state[1]) - end - end - ptr_time_state[1] = tnplus1 - if verbose - @show ptr_loc_state[1] - @show ptr_time_state[1] - @show values_state - end - # Now firing an edge according to the event - while true - turns += 1 - if verbose @show turns end - edges_from_current_loc = map_edges[ptr_loc_state[1]] - dict_transitions_from_current_loc = map_edges_transitions[ptr_loc_state[1]] - dict_check_constraints_from_current_loc = map_edges_check_constraints[ptr_loc_state[1]] - # Save all edges that satisfies transition predicate (synchronous ones) - nbr_candidates = _find_edge_candidates!(edge_id_candidates, target_loc_candidates, - dict_transitions_from_current_loc, dict_check_constraints_from_current_loc, - Λ, ptr_time_state[1], values_state, xnplus1, p, false) - # Search the one we must chose - ind_edge, detected_event = _get_edge_index(edge_id_candidates, target_loc_candidates, nbr_candidates, - dict_transitions_from_current_loc, - detected_event, tr_nplus1) - # Update the state with the chosen one (if it exists) - if ind_edge > 0 - edge_target_loc = target_loc_candidates[ind_edge] - edge_id = edge_id_candidates[ind_edge] - firing_update_state! = map_edges_update_state[ptr_loc_state[1]][edge_target_loc][edge_id] - ptr_loc_state[1] = firing_update_state!(ptr_time_state[1], values_state, xnplus1, p) - end - if ind_edge == 0 || detected_event - if verbose - if detected_event - println("Synchronized with $(tr_nplus1)") - @show edge_id_candidates, target_loc_candidates - @show ind_edge, detected_event, nbr_candidates - @show detected_event - @show ptr_loc_state[1] - @show ptr_time_state[1] - @show values_state - else - println("No edge fired") - end - end - break - end - if verbose - @show edge_id_candidates, target_loc_candidates - @show ind_edge, detected_event, nbr_candidates - @show detected_event - @show ptr_loc_state[1] - @show ptr_time_state[1] - @show values_state - if turns == 500 - @warn "We've reached 500 turns" - end - end - # For debug - #= - if turns > 100 - println("Number of turns in next_state! is suspicious") - @show detected_event - @show length(edge_candidates) - @show tnplus1, tr_nplus1, xnplus1 - @show edge_candidates - error("Unpredicted behavior automaton") - end - =# - end - if verbose - println("##### End next_state!") - end - end - end -end - -############################################################################################################ - -function generate_code_next_state(lha_name::Symbol, edge_type::Symbol) +function generate_code_next_state(lha_name::Symbol, edge_type::Symbol, + check_constraints::Symbol, update_state!::Symbol) return quote # A push! method implementend by myself because of preallocation of edge_candidates @@ -339,8 +113,8 @@ function generate_code_next_state(lha_name::Symbol, edge_type::Symbol) for target_loc in keys(edges_from_current_loc) if !Λ[target_loc](x) continue end for edge in edges_from_current_loc[target_loc] - if edge.check_constraints(S_time, S_values, x, p) - if edge.transitions == nothing + if $(check_constraints)(edge, S_time, S_values, x, p) + if getfield(edge, :transitions) == nothing _push_edge!(edge_candidates, edge, nbr_candidates) nbr_candidates += 1 return nbr_candidates @@ -363,12 +137,13 @@ function generate_code_next_state(lha_name::Symbol, edge_type::Symbol) for i = 1:nbr_candidates edge = edge_candidates[i] # Asynchronous edge detection: we fire it - if edge.transitions == nothing + if getfield(edge, :transitions) == nothing return (i, detected_event) end # Synchronous detection if !detected_event && tr_nplus1 != nothing - if (edge.transitions[1] == :ALL) || (tr_nplus1 in edge.transitions) + if (getfield(edge, :transitions)[1] == :ALL) || + (tr_nplus1 in getfield(edge, :transitions)) ind_edge = i bool_event = true end @@ -409,7 +184,7 @@ function generate_code_next_state(lha_name::Symbol, edge_type::Symbol) #first_round = false if ind_edge > 0 firing_edge = edge_candidates[ind_edge] - ptr_loc_state[1] = firing_edge.update_state!(ptr_time_state[1], values_state, xn, p) + ptr_loc_state[1] = $(update_state!)(firing_edge, ptr_time_state[1], values_state, xn, p) else if verbose println("No edge fired") end break @@ -465,7 +240,7 @@ function generate_code_next_state(lha_name::Symbol, edge_type::Symbol) # Update the state with the chosen one (if it exists) if ind_edge > 0 firing_edge = edge_candidates[ind_edge] - ptr_loc_state[1] = firing_edge.update_state!(ptr_time_state[1], values_state, xnplus1, p) + ptr_loc_state[1] = $(update_state!)(firing_edge, ptr_time_state[1], values_state, xnplus1, p) end if ind_edge == 0 || detected_event if verbose diff --git a/core/model.jl b/core/model.jl index 9be33af0b5753618e4a1adb2b282781f6a979963..ef32b376a21b8addc241cab52d2ac0af2c7124f4 100644 --- a/core/model.jl +++ b/core/model.jl @@ -145,9 +145,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym time_bound = getfield(m, :time_bound) buffer_size = getfield(m, :buffer_size) estim_min_states = getfield(m, :estim_min_states) - #edge_candidates = Vector{$(edge_type)}(undef, 2) - edge_id_candidates = zeros(Int, 2) - target_loc_candidates = Vector{Symbol}(undef, 2) + edge_candidates = Vector{$(edge_type)}(undef, 2) # First alloc full_values = Vector{Vector{Int}}(undef, getfield(m, :dim_state)) for i = eachindex(full_values) full_values[i] = zeros(Int, estim_min_states) end @@ -166,7 +164,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym xn = copy(x0) tn = copy(t0) next_state!(A, ptr_loc_state, values_state, ptr_time_state, - x0, t0, nothing, x0, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose) + x0, t0, nothing, x0, p_sim, edge_candidates; verbose = verbose) isabsorbing::Bool = $(isabsorbing)(p_sim,xn) isacceptedLHA::Bool = isaccepted(ptr_loc_state[1], A) # Alloc of vectors where we stock n+1 values @@ -182,7 +180,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym end if isabsorbing && !isacceptedLHA next_state!(A, ptr_loc_state, values_state, ptr_time_state, - xn, time_bound, nothing, xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose) + xn, time_bound, nothing, xn, p_sim, edge_candidates; verbose = verbose) end setfield!(S, :loc, ptr_loc_state[1]) setfield!(S, :time, ptr_time_state[1]) @@ -197,7 +195,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym break end n += 1 - next_state!(A, ptr_loc_state, values_state, ptr_time_state, vec_x, l_t[1], l_tr[1], xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose) + next_state!(A, ptr_loc_state, values_state, ptr_time_state, vec_x, l_t[1], l_tr[1], xn, p_sim, edge_candidates; verbose = verbose) copyto!(xn, vec_x) tn = l_t[1] tr_n = l_tr[1] @@ -216,7 +214,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym end if isabsorbing && !isacceptedLHA next_state!(A, ptr_loc_state, values_state, ptr_time_state, - xn, time_bound, nothing, xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose) + xn, time_bound, nothing, xn, p_sim, edge_candidates; verbose = verbose) end setfield!(S, :loc, ptr_loc_state[1]) setfield!(S, :time, ptr_time_state[1]) @@ -241,7 +239,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym i -= 1 break end - next_state!(A, ptr_loc_state, values_state, ptr_time_state, vec_x, l_t[1], l_tr[1], xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose) + next_state!(A, ptr_loc_state, values_state, ptr_time_state, vec_x, l_t[1], l_tr[1], xn, p_sim, edge_candidates; verbose = verbose) copyto!(xn, vec_x) tn = l_t[1] tr_n = l_tr[1] @@ -267,7 +265,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym end if isabsorbing && !isacceptedLHA next_state!(A, ptr_loc_state, values_state, ptr_time_state, - xn, time_bound, nothing, xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose) + xn, time_bound, nothing, xn, p_sim, edge_candidates; verbose = verbose) end setfield!(S, :loc, ptr_loc_state[1]) setfield!(S, :time, ptr_time_state[1]) @@ -282,15 +280,13 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym ptr_loc_state = [S.loc] values_state = S.values ptr_time_state = [S.time] - #edge_candidates = Vector{$(edge_type)}(undef, 2) - edge_id_candidates = zeros(Int, 2) - target_loc_candidates = Vector{Symbol}(undef, 2) + edge_candidates = Vector{$(edge_type)}(undef, 2) # Values at time n n = 1 xn = copy(x0) tn = copy(t0) next_state!(A, ptr_loc_state, values_state, ptr_time_state, - x0, t0, nothing, x0, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose) + x0, t0, nothing, x0, p_sim, edge_candidates; verbose = verbose) isabsorbing::Bool = $(isabsorbing)(p_sim,xn) isacceptedLHA::Bool = isaccepted(ptr_loc_state[1], A) # Alloc of vectors where we stock n+1 values @@ -301,7 +297,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym if isabsorbing || isacceptedLHA if !isacceptedLHA next_state!(A, ptr_loc_state, values_state, ptr_time_state, - xn, time_bound, nothing, xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose) + xn, time_bound, nothing, xn, p_sim, edge_candidates; verbose = verbose) end setfield!(S, :loc, ptr_loc_state[1]) setfield!(S, :time, ptr_time_state[1]) @@ -318,7 +314,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym break end next_state!(A, ptr_loc_state, values_state, ptr_time_state, - vec_x, l_t[1], l_tr[1], xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose) + vec_x, l_t[1], l_tr[1], xn, p_sim, edge_candidates; verbose = verbose) copyto!(xn, vec_x) tn = l_t[1] tr_n = l_tr[1] @@ -327,7 +323,7 @@ function generate_code_synchronized_simulation(model_name::Symbol, lha_name::Sym end if isabsorbing && !isacceptedLHA next_state!(A, ptr_loc_state, values_state, ptr_time_state, - xn, time_bound, nothing, xn, p_sim, edge_id_candidates, target_loc_candidates; verbose = verbose) + xn, time_bound, nothing, xn, p_sim, edge_candidates; verbose = verbose) end setfield!(S, :loc, ptr_loc_state[1]) setfield!(S, :time, ptr_time_state[1])