diff --git a/automata/automaton_F.jl b/automata/automaton_F.jl index b18b37ee29a677286be48d99faf34f2242a72646..016c38357e4a9b7c178500d8161ca5f5003f5a46 100644 --- a/automata/automaton_F.jl +++ b/automata/automaton_F.jl @@ -1,76 +1,4 @@ -@everywhere istrue(val::Float64) = convert(Bool, val) - -# Invariant predicates functions -@everywhere true_inv_predicate(x::Vector{Int}) = true - -# Check constraints and update state functions - -# l0 loc : we construct the edges of the form l0 => (..) -# "cc" as check_constraints and "us" as update_state -# l0 => l1 -@everywhere cc_aut_F_l0l1_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = true -# us_aut_F_l0l1_1! inside create_automaton_F - -# l1 loc -# l1 => l2 -@everywhere cc_aut_F_l1l2_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -getfield(S, :time) >= constants[:t1] && -(constants[:x1] <= S[:n] <= constants[:x2]) -@everywhere us_aut_F_l1l2_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l2; - S[:d] = 0) - -@everywhere cc_aut_F_l1l2_4(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -getfield(S, :time) >= constants[:t1] && -S[:d] == 0 -@everywhere us_aut_F_l1l2_4!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l2) - -@everywhere cc_aut_F_l1l2_2(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(getfield(S, :time) >= constants[:t2]) && -(S[:n] < constants[:x1] || S[:n] > constants[:x2]) -@everywhere us_aut_F_l1l2_2!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l2; - S[:d] = min(abs(S[:n] - constants[:x1]), abs(S[:n] - constants[:x2]))) - -@everywhere cc_aut_F_l1l2_3(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -istrue(S[:isabs]) && getfield(S, :time) <= constants[:t2] -@everywhere us_aut_F_l1l2_3!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l2) - -# l1 => l3 -@everywhere cc_aut_F_l1l3_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(constants[:x1] <= S[:n] <= constants[:x2]) -@everywhere us_aut_F_l1l3_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l3; - S[:d] = 0;) - -@everywhere cc_aut_F_l1l3_2(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S[:n] < constants[:x1] || S[:n] > constants[:x2]) && -(getfield(S, :time) <= constants[:t1]) -@everywhere us_aut_F_l1l3_2!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l3; - S[:d] = min(sqrt((getfield(S, :time) - constants[:t1])^2 + (S[:n] - constants[:x2])^2), - sqrt((getfield(S, :time) - constants[:t1])^2 + (S[:n] - constants[:x1])^2))) - -@everywhere cc_aut_F_l1l3_3(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S[:n] < constants[:x1] || S[:n] > constants[:x2]) && -(constants[:t1] <= getfield(S, :time) <= constants[:t2]) -@everywhere us_aut_F_l1l3_3!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l3; - S[:d] = min(S[:d], min(abs(S[:n] - constants[:x1]), abs(S[:n] - constants[:x2])))) - -# l3 loc -# l3 => l1 -@everywhere cc_aut_F_l3l1_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = true - -# l3 => l2 -@everywhere cc_aut_F_l3l2_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(getfield(S, :time) >= constants[:t2]) -@everywhere us_aut_F_l3l2_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l2) - function create_automaton_F(m::ContinuousTimeModel, x1::Float64, x2::Float64, t1::Float64, t2::Float64, sym_obs::VariableModel) # Requirements for the automaton @assert sym_obs in m.g "$(sym_obs) is not observed." @@ -81,6 +9,7 @@ function create_automaton_F(m::ContinuousTimeModel, x1::Float64, x2::Float64, t1 locations = [:l0, :l1, :l2, :l3] ## Invariant predicates + @everywhere true_inv_predicate(x::Vector{Int}) = true Λ_F = Dict(:l0 => getfield(Main, :true_inv_predicate), :l1 => getfield(Main, :true_inv_predicate), :l2 => getfield(Main, :true_inv_predicate), :l3 => getfield(Main, :true_inv_predicate)) @@ -106,53 +35,124 @@ function create_automaton_F(m::ContinuousTimeModel, x1::Float64, x2::Float64, t1 map_edges[loc] = Dict{Location, Vector{Edge}}() end - sym_isabs_func = Symbol(m.isabsorbing) idx_obs_var = getfield(m, :map_var_idx)[sym_obs] - nbr_rand = rand(1:1000) + idx_var_n = map_var_automaton_idx[:n] + idx_var_d = map_var_automaton_idx[:d] + idx_var_isabs = map_var_automaton_idx[:isabs] + + nbr_rand = rand(1:100000) basename_func = "$(replace(m.name, ' '=>'_'))_$(nbr_rand)" basename_func = replace(basename_func, '-'=>'_') + sym_isabs_func = Symbol(m.isabsorbing) + func_name(type_func::Symbol, from_loc::Location, to_loc::Location, edge_number::Int) = + Symbol("$(type_func)_aut_F_$(basename_func)_$(from_loc)$(to_loc)_$(edge_number)$(type_func == :us ? "!" : "")") + meta_elementary_functions = quote + @everywhere istrue(val::Float64) = convert(Bool, val) + + ## Check constraints and update state functions + # l0 loc : we construct the edges of the form l0 => (..) + # "cc" as check_constraints and "us" as update_state + # l0 => l1 + @everywhere $(func_name(:cc, :l0, :l1, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = true + @everywhere $(func_name(:us, :l0, :l1, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (S.loc = :l1; + getfield(S, :values)[$(idx_var_n)] = x[$(idx_obs_var)]; + setindex!(getfield(S, :values), Inf, $(idx_var_d)); + setindex!(getfield(S, :values), getfield(Main, $(Meta.quot(sym_isabs_func)))(p, x), $(idx_var_isabs))) + + # l1 loc + # l1 => l2 + @everywhere $(func_name(:cc, :l1, :l2, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + getfield(S, :time) >= $t1 && + ($x1 <= getfield(S, :values)[$(idx_var_n)] <= $x2) + @everywhere $(func_name(:us, :l1, :l2, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (S.loc = :l2; + setindex!(getfield(S, :values), 0, $(idx_var_d))) + + @everywhere $(func_name(:cc, :l1, :l2, 4))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + getfield(S, :time) >= $t1 && + getfield(S, :values)[$(idx_var_d)] == 0 + @everywhere $(func_name(:us, :l1, :l2, 4))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (S.loc = :l2) + + @everywhere $(func_name(:cc, :l1, :l2, 2))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (getfield(S, :time) >= $t2) && + (getfield(S, :values)[$(idx_var_n)] < $x1 || getfield(S, :values)[$(idx_var_n)] > $x2) + @everywhere $(func_name(:us, :l1, :l2, 2))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (S.loc = :l2; + setindex!(getfield(S, :values), min(abs(getfield(S, :values)[$(idx_var_n)] - $x1), abs(getfield(S, :values)[$(idx_var_n)] - $x2)), $(idx_var_d))) + + @everywhere $(func_name(:cc, :l1, :l2, 3))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + istrue(getfield(S, :values)[$(idx_var_isabs)]) && getfield(S, :time) <= $t2 + @everywhere $(func_name(:us, :l1, :l2, 3))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (S.loc = :l2) + + # l1 => l3 + @everywhere $(func_name(:cc, :l1, :l3, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + ($x1 <= getfield(S, :values)[$(idx_var_n)] <= $x2) + @everywhere $(func_name(:us, :l1, :l3, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (S.loc = :l3; + setindex!(getfield(S, :values), 0, $(idx_var_d))) + + @everywhere $(func_name(:cc, :l1, :l3, 2))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (getfield(S, :values)[$(idx_var_n)] < $x1 || getfield(S, :values)[$(idx_var_n)] > $x2) && + (getfield(S, :time) <= $t1) + @everywhere $(func_name(:us, :l1, :l3, 2))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (S.loc = :l3; + setindex!(getfield(S, :values), min(sqrt((getfield(S, :time) - $t1)^2 + (getfield(S, :values)[$(idx_var_n)] - $x2)^2), + sqrt((getfield(S, :time) - $t1)^2 + (getfield(S, :values)[$(idx_var_n)] - $x1)^2)), $(idx_var_d))) + + @everywhere $(func_name(:cc, :l1, :l3, 3))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (getfield(S, :values)[$(idx_var_n)] < $x1 || getfield(S, :values)[$(idx_var_n)] > $x2) && + ($t1 <= getfield(S, :time) <= $t2) + @everywhere $(func_name(:us, :l1, :l3, 3))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (S.loc = :l3; + val_min = min(getfield(S, :values)[$(idx_var_d)], + min(abs(getfield(S, :values)[$(idx_var_n)] - $x1), abs(getfield(S, :values)[$(idx_var_n)] - $x2))); + setindex!(getfield(S, :values), val_min, $(idx_var_d))) + + # l3 loc + # l3 => l1 + @everywhere $(func_name(:cc, :l3, :l1, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = true + @everywhere $(func_name(:us, :l3, :l1, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (S.loc = :l1; + getfield(S, :values)[$(idx_var_n)] = x[$(idx_obs_var)]; + setindex!(getfield(S, :values), getfield(Main, $(Meta.quot(sym_isabs_func)))(p, x), $(idx_var_isabs))) + + # l3 => l2 + @everywhere $(func_name(:cc, :l3, :l2, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (getfield(S, :time) >= $t2) + @everywhere $(func_name(:us, :l3, :l2, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (S.loc = :l2) + end + eval(meta_elementary_functions) # l0 loc # l0 => l1 - sym_func_us_l0l1_1 = Symbol("us_aut_F_$(basename_func)_l0l1_1!") - str_us_l0l1_1 = " - @everywhere $(sym_func_us_l0l1_1)(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = \n - (S.loc = :l1; \n - S[:n] = x[$(idx_obs_var)];\n - S[:d] = Inf; \n - S[:isabs] = getfield(Main, $(Meta.quot(sym_isabs_func)))(p, x))" - eval(Meta.parse(str_us_l0l1_1)) - edge1 = Edge([nothing], getfield(Main, :cc_aut_F_l0l1_1), getfield(Main, sym_func_us_l0l1_1)) + edge1 = Edge([nothing], getfield(Main, func_name(:cc, :l0, :l1, 1)), getfield(Main, func_name(:us, :l0, :l1, 1))) map_edges[:l0][:l1] = [edge1] # l1 loc # l1 => l2 - edge1 = Edge([nothing], getfield(Main, :cc_aut_F_l1l2_1), getfield(Main, :us_aut_F_l1l2_1!)) - edge2 = Edge([nothing], getfield(Main, :cc_aut_F_l1l2_2), getfield(Main, :us_aut_F_l1l2_2!)) - edge3 = Edge([nothing], getfield(Main, :cc_aut_F_l1l2_3), getfield(Main, :us_aut_F_l1l2_3!)) - edge4 = Edge([nothing], getfield(Main, :cc_aut_F_l1l2_4), getfield(Main, :us_aut_F_l1l2_4!)) + edge1 = Edge([nothing], getfield(Main, func_name(:cc, :l1, :l2, 1)), getfield(Main, func_name(:us, :l1, :l2, 1))) + edge2 = Edge([nothing], getfield(Main, func_name(:cc, :l1, :l2, 2)), getfield(Main, func_name(:us, :l1, :l2, 2))) + edge3 = Edge([nothing], getfield(Main, func_name(:cc, :l1, :l2, 3)), getfield(Main, func_name(:us, :l1, :l2, 3))) + edge4 = Edge([nothing], getfield(Main, func_name(:cc, :l1, :l2, 4)), getfield(Main, func_name(:us, :l1, :l2, 4))) map_edges[:l1][:l2] = [edge1, edge2, edge3, edge4] # l1 => l3 - edge1 = Edge([nothing], getfield(Main, :cc_aut_F_l1l3_1), getfield(Main, :us_aut_F_l1l3_1!)) - edge2 = Edge([nothing], getfield(Main, :cc_aut_F_l1l3_2), getfield(Main, :us_aut_F_l1l3_2!)) - edge3 = Edge([nothing], getfield(Main, :cc_aut_F_l1l3_3), getfield(Main, :us_aut_F_l1l3_3!)) + edge1 = Edge([nothing], getfield(Main, func_name(:cc, :l1, :l3, 1)), getfield(Main, func_name(:us, :l1, :l3, 1))) + edge2 = Edge([nothing], getfield(Main, func_name(:cc, :l1, :l3, 2)), getfield(Main, func_name(:us, :l1, :l3, 2))) + edge3 = Edge([nothing], getfield(Main, func_name(:cc, :l1, :l3, 3)), getfield(Main, func_name(:us, :l1, :l3, 3))) map_edges[:l1][:l3] = [edge1, edge2, edge3] # l3 loc # l3 => l1 - sym_func_us_l3l1_1 = Symbol("us_aut_F_$(basename_func)_l0l1_1!") - str_us_l3l1_1 = - "@everywhere $(sym_func_us_l3l1_1)(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = \n - (S.loc = :l1;\n - S[:n] = x[$(idx_obs_var)];\n - S[:isabs] = getfield(Main, $(Meta.quot(sym_isabs_func)))(p, x))" - eval(Meta.parse(str_us_l3l1_1)) - edge1 = Edge([:ALL], getfield(Main, :cc_aut_F_l3l1_1), getfield(Main, sym_func_us_l3l1_1)) + edge1 = Edge([:ALL], getfield(Main, func_name(:cc, :l3, :l1, 1)), getfield(Main, func_name(:us, :l3, :l1, 1))) map_edges[:l3][:l1] = [edge1] # l3 => l2 - edge1 = Edge([nothing], getfield(Main, :cc_aut_F_l3l2_1), getfield(Main, :us_aut_F_l3l2_1!)) + edge1 = Edge([nothing], getfield(Main, func_name(:cc, :l3, :l2, 1)), getfield(Main, func_name(:us, :l3, :l2, 1))) map_edges[:l3][:l2] = [edge1] ## Constants diff --git a/automata/automaton_G.jl b/automata/automaton_G.jl index b07a4796d412caa34dcec7ca3c00cdfc1c350425..01efc47b7fd9f2164ee4e23674ce638b15911c5e 100644 --- a/automata/automaton_G.jl +++ b/automata/automaton_G.jl @@ -1,121 +1,4 @@ -@everywhere istrue(val::Float64) = convert(Bool, val) - -# Invariant predicate functions -@everywhere true_inv_predicate(x::Vector{Int}) = true - -# l0 loc -# l0 => l1 -@everywhere cc_aut_G_l0l1_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = true - -# l1 => l3 -@everywhere cc_aut_G_l1l3_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -getfield(S, :time) <= constants[:t1] && -S[:n] < constants[:x1] || S[:n] > constants[:x2] -@everywhere us_aut_G_l1l3_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l3; - S[:d] = min(abs(constants[:x1] - S[:n]), abs(constants[:x2] - S[:n])); - S[:in] = false) - -@everywhere cc_aut_G_l1l3_2(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(getfield(S, :time) <= constants[:t1]) && -(constants[:x1] <= S[:n] <= constants[:x2]) -@everywhere us_aut_G_l1l3_2!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l3; - S[:d] = 0; - S[:in] = false) - -@everywhere cc_aut_G_l1l3_3(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -!istrue(S[:in]) && -(constants[:t1] <= getfield(S, :time) <= constants[:t2]) && -(constants[:x1] <= S[:n] <= constants[:x2]) -@everywhere us_aut_G_l1l3_3!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l3; - S[:d] = S[:d] * (getfield(S, :time) - constants[:t1]); - S[:tprime] = 0.0) - -@everywhere cc_aut_G_l1l3_4(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -istrue(S[:in]) && -(constants[:t1] <= getfield(S, :time) <= constants[:t2]) && -(constants[:x1] <= S[:n] <= constants[:x2]) -@everywhere us_aut_G_l1l3_4!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l3; - S[:tprime] = 0.0) - -# l1 => l4 -@everywhere cc_aut_G_l1l4_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -!istrue(S[:in]) && -(constants[:t1] <= getfield(S, :time) <= constants[:t2]) && -(S[:n] < constants[:x1] || S[:n] > constants[:x2]) -@everywhere us_aut_G_l1l4_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l4; - S[:d] += S[:d] * (getfield(S, :time) - constants[:t1])) - -@everywhere cc_aut_G_l1l4_2(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -istrue(S[:in]) && -(constants[:t1] <= getfield(S, :time) <= constants[:t2]) && -(S[:n] < constants[:x1] || S[:n] > constants[:x2]) -@everywhere us_aut_G_l1l4_2!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l4) - - -# l1 => l2 -@everywhere cc_aut_G_l1l2_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -istrue(S[:in]) && -getfield(S, :time) >= constants[:t2] -@everywhere us_aut_G_l1l2_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l2) - -@everywhere cc_aut_G_l1l2_2(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -!istrue(S[:in]) && -getfield(S, :time) >= constants[:t2] -@everywhere us_aut_G_l1l2_2!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l2; - S[:d] = S[:d] * (constants[:t2] - constants[:t1])) - -@everywhere cc_aut_G_l1l2_3(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -istrue(S[:isabs]) && -getfield(S, :time) <= constants[:t1] -@everywhere us_aut_G_l1l2_3!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l2; - S[:d] = (constants[:t2] - constants[:t1]) * -min(abs(constants[:x1] - S[:n]), abs(constants[:x2] - S[:n]))) - -@everywhere cc_aut_G_l1l2_4(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -istrue(S[:isabs]) && -(constants[:t1] <= getfield(S, :time) <= constants[:t2]) -@everywhere us_aut_G_l1l2_4!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l2; - S[:d] += (constants[:t2] - getfield(S, :time)) * -min(abs(constants[:x1] - S[:n]), abs(constants[:x2] - S[:n]))) - -# l3 => l1 -@everywhere cc_aut_G_l3l1_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = true - -# l4 => l1 -@everywhere cc_aut_G_l4l1_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = true - -# l2 => l1 -@everywhere cc_aut_G_l3l2_2(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -istrue(S[:in]) && -getfield(S, :time) >= constants[:t2] -@everywhere us_aut_G_l3l2_2!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l2; - S[:d] = S[:d] * (constants[:t2] - constants[:t1])) - -@everywhere cc_aut_G_l3l2_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -!istrue(S[:in]) && -getfield(S, :time) >= constants[:t2] -@everywhere us_aut_G_l3l2_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l2) - -# l4 => l2 -@everywhere cc_aut_G_l4l2_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(getfield(S, :time) >= constants[:t2]) -@everywhere us_aut_G_l4l2_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l2; - S[:d] += S[:tprime] * min(abs(constants[:x1] - S[:n]), abs(constants[:x2] - S[:n])); - S[:tprime] = 0.0) function create_automaton_G(m::ContinuousTimeModel, x1::Float64, x2::Float64, t1::Float64, t2::Float64, sym_obs::VariableModel) # Requirements for the automaton @@ -127,6 +10,7 @@ function create_automaton_G(m::ContinuousTimeModel, x1::Float64, x2::Float64, t1 locations = [:l0, :l1, :l2, :l3, :l4] # Invariant predicates + @everywhere true_inv_predicate(x::Vector{Int}) = true Λ_F = Dict(:l0 => getfield(Main, :true_inv_predicate), :l1 => getfield(Main, :true_inv_predicate), :l2 => getfield(Main, :true_inv_predicate), :l3 => getfield(Main, :true_inv_predicate), :l4 => getfield(Main, :true_inv_predicate)) @@ -152,80 +36,193 @@ function create_automaton_G(m::ContinuousTimeModel, x1::Float64, x2::Float64, t1 map_edges[loc] = Dict{Location, Vector{Edge}}() end - sym_isabs_func = Symbol(m.isabsorbing) idx_obs_var = getfield(m, :map_var_idx)[sym_obs] - nbr_rand = rand(1:1000) + idx_var_n = map_var_automaton_idx[:n] + idx_var_d = map_var_automaton_idx[:d] + idx_var_isabs = map_var_automaton_idx[:isabs] + idx_var_in = map_var_automaton_idx[:in] + idx_var_tprime = map_var_automaton_idx[:tprime] + + nbr_rand = rand(1:100000) basename_func = "$(replace(m.name, ' '=>'_'))_$(nbr_rand)" basename_func = replace(basename_func, '-'=>'_') + sym_isabs_func = Symbol(m.isabsorbing) + func_name(type_func::Symbol, from_loc::Location, to_loc::Location, edge_number::Int) = + Symbol("$(type_func)_aut_G_$(basename_func)_$(from_loc)$(to_loc)_$(edge_number)$(type_func == :us ? "!" : "")") + meta_elementary_functions = quote + @everywhere istrue(val::Float64) = convert(Bool, val) + # l0 loc + # l0 => l1 + @everywhere $(func_name(:cc, :l0, :l1, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = true + @everywhere $(func_name(:us, :l0, :l1, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l1")); + setindex!(getfield(S, :values), 0, $(idx_var_d)); + setindex!(getfield(S, :values), x[$(idx_obs_var)], $(idx_var_n)); + setindex!(getfield(S, :values), true, $(idx_var_in)); + setindex!(getfield(S, :values), getfield(Main, $(Meta.quot(sym_isabs_func)))(p, x), $(idx_var_isabs))) + + # l1 => l3 + @everywhere $(func_name(:cc, :l1, :l3, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + getfield(S, :time) <= $t1 && + getfield(S, :values)[$(idx_var_n)] < $x1 || getfield(S, :values)[$(idx_var_n)] > $x2 + @everywhere $(func_name(:us, :l1, :l3, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l3")); + setindex!(getfield(S, :values), min(abs($x1 - getfield(S, :values)[$(idx_var_n)]), abs($x2 - getfield(S, :values)[$(idx_var_n)])), $(idx_var_d)); + setindex!(getfield(S, :values), false, $(idx_var_in))) + + @everywhere $(func_name(:cc, :l1, :l3, 2))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (getfield(S, :time) <= $t1) && + ($x1 <= getfield(S, :values)[$(idx_var_n)] <= $x2) + @everywhere $(func_name(:us, :l1, :l3, 2))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l3")); + setindex!(getfield(S, :values), 0, $(idx_var_d)); + setindex!(getfield(S, :values), false, $(idx_var_in))) + + @everywhere $(func_name(:cc, :l1, :l3, 3))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + !istrue(getfield(S, :values)[$(idx_var_in)]) && + ($t1 <= getfield(S, :time) <= $t2) && + ($x1 <= getfield(S, :values)[$(idx_var_n)] <= $x2) + @everywhere $(func_name(:us, :l1, :l3, 3))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l3")); + setindex!(getfield(S, :values), getfield(S, :values)[$(idx_var_d)] * (getfield(S, :time) - $t1), $(idx_var_d)); + setindex!(getfield(S, :values), 0.0, $(idx_var_tprime))) + + @everywhere $(func_name(:cc, :l1, :l3, 4))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + istrue(getfield(S, :values)[$(idx_var_in)]) && + ($t1 <= getfield(S, :time) <= $t2) && + ($x1 <= getfield(S, :values)[$(idx_var_n)] <= $x2) + @everywhere $(func_name(:us, :l1, :l3, 4))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l3")); + setindex!(getfield(S, :values), 0.0, $(idx_var_tprime))) + + # l1 => l4 + @everywhere $(func_name(:cc, :l1, :l4, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + !istrue(getfield(S, :values)[$(idx_var_in)]) && + ($t1 <= getfield(S, :time) <= $t2) && + (getfield(S, :values)[$(idx_var_n)] < $x1 || getfield(S, :values)[$(idx_var_n)] > $x2) + @everywhere $(func_name(:us, :l1, :l4, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l4")); + setindex!(getfield(S, :values), getfield(S, :values)[$(idx_var_d)] + getfield(S, :values)[$(idx_var_d)] * (getfield(S, :time) - $t1), $(idx_var_d))) + + @everywhere $(func_name(:cc, :l1, :l4, 2))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + istrue(getfield(S, :values)[$(idx_var_in)]) && + ($t1 <= getfield(S, :time) <= $t2) && + (getfield(S, :values)[$(idx_var_n)] < $x1 || getfield(S, :values)[$(idx_var_n)] > $x2) + @everywhere $(func_name(:us, :l1, :l4, 2))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l4"))) + + + # l1 => l2 + @everywhere $(func_name(:cc, :l1, :l2, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + istrue(getfield(S, :values)[$(idx_var_in)]) && + getfield(S, :time) >= $t2 + @everywhere $(func_name(:us, :l1, :l2, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l2"))) + + @everywhere $(func_name(:cc, :l1, :l2, 2))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + !istrue(getfield(S, :values)[$(idx_var_in)]) && + getfield(S, :time) >= $t2 + @everywhere $(func_name(:us, :l1, :l2, 2))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l2")); + setindex!(getfield(S, :values), getfield(S, :values)[$(idx_var_d)] * ($t2 - $t1), $(idx_var_d))) + + @everywhere $(func_name(:cc, :l1, :l2, 3))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + istrue(getfield(S, :values)[$(idx_var_isabs)]) && + getfield(S, :time) <= $t1 + @everywhere $(func_name(:us, :l1, :l2, 3))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l2")); + setindex!(getfield(S, :values), ($t2 - $t1) * min(abs($x1 - getfield(S, :values)[$(idx_var_n)]), abs($x2 - getfield(S, :values)[$(idx_var_n)])), $(idx_var_d))) + + @everywhere $(func_name(:cc, :l1, :l2, 4))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + istrue(getfield(S, :values)[$(idx_var_isabs)]) && + ($t1 <= getfield(S, :time) <= $t2) + @everywhere $(func_name(:us, :l1, :l2, 4))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l2")); + setindex!(getfield(S, :values), getfield(S, :values)[$(idx_var_d)] + ($t2 - getfield(S, :time)) * min(abs($x1 - getfield(S, :values)[$(idx_var_n)]), abs($x2 - getfield(S, :values)[$(idx_var_n)])), $(idx_var_d))) + + # l3 => l1 + @everywhere $(func_name(:cc, :l3, :l1, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = true + @everywhere $(func_name(:us, :l3, :l1, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l1")); + setindex!(getfield(S, :values), x[$(idx_obs_var)], $(idx_var_n)); + setindex!(getfield(S, :values), getfield(Main, $(Meta.quot(sym_isabs_func)))(p, x), $(idx_var_isabs))) + + # l4 => l1 + @everywhere $(func_name(:cc, :l4, :l1, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = true + @everywhere $(func_name(:us, :l4, :l1, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l1")); + setindex!(getfield(S, :values), getfield(S, :values)[$(idx_var_d)] + getfield(S, :values)[$(idx_var_tprime)] * min(abs($x1 - getfield(S, :values)[$(idx_var_n)]), abs($x2 - getfield(S, :values)[$(idx_var_n)])), $(idx_var_d)); + setindex!(getfield(S, :values), 0.0, $(idx_var_tprime)); + setindex!(getfield(S, :values), x[$(idx_obs_var)], $(idx_var_n)); + setindex!(getfield(S, :values), true, $(idx_var_in)); + setindex!(getfield(S, :values), getfield(Main, $(Meta.quot(sym_isabs_func)))(p, x), $(idx_var_isabs))) + + # l2 => l1 + @everywhere $(func_name(:cc, :l3, :l2, 2))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + istrue(getfield(S, :values)[$(idx_var_in)]) && + getfield(S, :time) >= $t2 + @everywhere $(func_name(:us, :l3, :l2, 2))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l2")); + setindex!(getfield(S, :values), getfield(S, :values)[$(idx_var_d)] * ($t2 - $t1), $(idx_var_d))) + + @everywhere $(func_name(:cc, :l3, :l2, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + !istrue(getfield(S, :values)[$(idx_var_in)]) && + getfield(S, :time) >= $t2 + @everywhere $(func_name(:us, :l3, :l2, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l2"))) + + # l4 => l2 + @everywhere $(func_name(:cc, :l4, :l2, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (getfield(S, :time) >= $t2) + @everywhere $(func_name(:us, :l4, :l2, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l2")); + setindex!(getfield(S, :values), getfield(S, :values)[$(idx_var_d)] + getfield(S, :values)[$(idx_var_tprime)] * min(abs($x1 - getfield(S, :values)[$(idx_var_n)]), abs($x2 - getfield(S, :values)[$(idx_var_n)])), $(idx_var_d)); + setindex!(getfield(S, :values), 0.0, $(idx_var_tprime))) + end + eval(meta_elementary_functions) # l0 loc # l0 => l1 - sym_func_us_l0l1_1 = Symbol("us_aut_G_$(basename_func)_l0l1_1!") - str_us_l0l1_1 = " - @everywhere $(sym_func_us_l0l1_1)(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = \n - (S.loc = :l1; \n - S[:d] = 0; \n - S[:n] = x[$(idx_obs_var)]; \n - S[:in] = true; \n - S[:isabs] = getfield(Main, $(Meta.quot(sym_isabs_func)))(p, x))" - eval(Meta.parse(str_us_l0l1_1)) - edge1 = Edge([nothing], getfield(Main, :cc_aut_G_l0l1_1), getfield(Main, sym_func_us_l0l1_1)) + edge1 = Edge([nothing], getfield(Main, func_name(:cc, :l0, :l1, 1)), getfield(Main, func_name(:us, :l0, :l1, 1))) map_edges[:l0][:l1] = [edge1] # l1 loc # l1 => l3 - edge1 = Edge([nothing], getfield(Main, :cc_aut_G_l1l3_1), getfield(Main, :us_aut_G_l1l3_1!)) - edge2 = Edge([nothing], getfield(Main, :cc_aut_G_l1l3_2), getfield(Main, :us_aut_G_l1l3_2!)) - edge3 = Edge([nothing], getfield(Main, :cc_aut_G_l1l3_3), getfield(Main, :us_aut_G_l1l3_3!)) - edge4 = Edge([nothing], getfield(Main, :cc_aut_G_l1l3_4), getfield(Main, :us_aut_G_l1l3_4!)) + edge1 = Edge([nothing], getfield(Main, func_name(:cc, :l1, :l3, 1)), getfield(Main, func_name(:us, :l1, :l3, 1))) + edge2 = Edge([nothing], getfield(Main, func_name(:cc, :l1, :l3, 2)), getfield(Main, func_name(:us, :l1, :l3, 2))) + edge3 = Edge([nothing], getfield(Main, func_name(:cc, :l1, :l3, 3)), getfield(Main, func_name(:us, :l1, :l3, 3))) + edge4 = Edge([nothing], getfield(Main, func_name(:cc, :l1, :l3, 4)), getfield(Main, func_name(:us, :l1, :l3, 4))) map_edges[:l1][:l3] = [edge1, edge2, edge3, edge4] # l1 => l4 - edge1 = Edge([nothing], getfield(Main, :cc_aut_G_l1l4_1), getfield(Main, :us_aut_G_l1l4_1!)) - edge2 = Edge([nothing], getfield(Main, :cc_aut_G_l1l4_2), getfield(Main, :us_aut_G_l1l4_2!)) + edge1 = Edge([nothing], getfield(Main, func_name(:cc, :l1, :l4, 1)), getfield(Main, func_name(:us, :l1, :l4, 1))) + edge2 = Edge([nothing], getfield(Main, func_name(:cc, :l1, :l4, 2)), getfield(Main, func_name(:us, :l1, :l4, 2))) map_edges[:l1][:l4] = [edge1, edge2] # l1 => l2 - edge1 = Edge([nothing], getfield(Main, :cc_aut_G_l1l2_1), getfield(Main, :us_aut_G_l1l2_1!)) - edge2 = Edge([nothing], getfield(Main, :cc_aut_G_l1l2_2), getfield(Main, :us_aut_G_l1l2_2!)) - edge3 = Edge([nothing], getfield(Main, :cc_aut_G_l1l2_3), getfield(Main, :us_aut_G_l1l2_3!)) - edge4 = Edge([nothing], getfield(Main, :cc_aut_G_l1l2_4), getfield(Main, :us_aut_G_l1l2_4!)) + edge1 = Edge([nothing], getfield(Main, func_name(:cc, :l1, :l2, 1)), getfield(Main, func_name(:us, :l1, :l2, 1))) + edge2 = Edge([nothing], getfield(Main, func_name(:cc, :l1, :l2, 2)), getfield(Main, func_name(:us, :l1, :l2, 2))) + edge3 = Edge([nothing], getfield(Main, func_name(:cc, :l1, :l2, 3)), getfield(Main, func_name(:us, :l1, :l2, 3))) + edge4 = Edge([nothing], getfield(Main, func_name(:cc, :l1, :l2, 4)), getfield(Main, func_name(:us, :l1, :l2, 4))) map_edges[:l1][:l2] = [edge1, edge2, edge3, edge4] # l3 loc # l3 => l1 - sym_func_us_l3l1_1 = Symbol("us_aut_G_$(basename_func)_l3l1_1!") - str_us_l3l1_1 = " - @everywhere $(sym_func_us_l3l1_1)(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = - (S.loc = :l1; - S[:n] = x[$(idx_obs_var)]; - S[:isabs] = getfield(Main, $(Meta.quot(sym_isabs_func)))(p, x))" - eval(Meta.parse(str_us_l3l1_1)) - edge1 = Edge([:ALL], getfield(Main, :cc_aut_G_l3l1_1), getfield(Main, sym_func_us_l3l1_1)) + edge1 = Edge([:ALL], getfield(Main, func_name(:cc, :l3, :l1, 1)), getfield(Main, func_name(:us, :l3, :l1, 1))) map_edges[:l3][:l1] = [edge1] # l3 => l2 - edge1 = Edge([nothing], getfield(Main, :cc_aut_G_l3l2_1), getfield(Main, :us_aut_G_l3l2_1!)) - edge2 = Edge([nothing], getfield(Main, :cc_aut_G_l3l2_2), getfield(Main, :us_aut_G_l3l2_2!)) + edge1 = Edge([nothing], getfield(Main, func_name(:cc, :l3, :l2, 1)), getfield(Main, func_name(:us, :l3, :l2, 1))) + edge2 = Edge([nothing], getfield(Main, func_name(:cc, :l3, :l2, 2)), getfield(Main, func_name(:us, :l3, :l2, 2))) map_edges[:l3][:l2] = [edge1, edge2] # l4 loc # l4 => l1 - sym_func_us_l4l1_1 = Symbol("us_aut_G_$(basename_func)_l4l1_1!") - str_us_l4l1_1 = " - @everywhere $(sym_func_us_l4l1_1)(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = \n - (S.loc = :l1; \n - S[:d] += S[:tprime] * min(abs(constants[:x1] - S[:n]), abs(constants[:x2] - S[:n])); \n - S[:tprime] = 0.0; \n - S[:n] = x[$(idx_obs_var)]; \n - S[:in] = true; \n - S[:isabs] = getfield(Main, $(Meta.quot(sym_isabs_func)))(p, x))" - eval(Meta.parse(str_us_l4l1_1)) - edge1 = Edge([:ALL], getfield(Main, :cc_aut_G_l4l1_1), getfield(Main, sym_func_us_l4l1_1)) + edge1 = Edge([:ALL], getfield(Main, func_name(:cc, :l4, :l1, 1)), getfield(Main, func_name(:us, :l4, :l1, 1))) map_edges[:l4][:l1] = [edge1] # l4 => l2 - edge1 = Edge([nothing], getfield(Main, :cc_aut_G_l4l2_1), getfield(Main, :us_aut_G_l4l2_1!)) + edge1 = Edge([nothing], getfield(Main, func_name(:cc, :l4, :l2, 1)), getfield(Main, func_name(:us, :l4, :l2, 1))) map_edges[:l4][:l2] = [edge1] ## Constants diff --git a/automata/automaton_G_and_F.jl b/automata/automaton_G_and_F.jl index bd42caf86f795844d685c220aec5f46367fe5259..1bfd93ef3dc5a2bfa7ffa57f3c7f8b9f7fbe51dc 100644 --- a/automata/automaton_G_and_F.jl +++ b/automata/automaton_G_and_F.jl @@ -1,191 +1,4 @@ -@everywhere istrue(val::Float64) = convert(Bool, val) - -## Invariant predicate functions - -@everywhere true_inv_predicate(x::Vector{Int}) = true - -## Edges check constraint and update state functions - -# l0G loc -# l0G => l1G -@everywhere cc_aut_G_l0Gl1G_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = true - -# l1G loc -# l1G => l3G -@everywhere cc_aut_G_l1Gl3G_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -getfield(S, :time) <= constants[:t1] && -S[:n] < constants[:x1] || S[:n] > constants[:x2] -@everywhere us_aut_G_l1Gl3G_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l3G; - S[:d] = min(abs(constants[:x1] - S[:n]), abs(constants[:x2] - S[:n])); - S[:in] = false) - -@everywhere cc_aut_G_l1Gl3G_2(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(getfield(S, :time) <= constants[:t1]) && -(constants[:x1] <= S[:n] <= constants[:x2]) -@everywhere us_aut_G_l1Gl3G_2!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l3G; - S[:d] = 0; - S[:in] = false) - -@everywhere cc_aut_G_l1Gl3G_3(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -!istrue(S[:in]) && -(constants[:t1] <= getfield(S, :time) <= constants[:t2]) && -(constants[:x1] <= S[:n] <= constants[:x2]) -@everywhere us_aut_G_l1Gl3G_3!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l3G; - S[:d] = S[:d] * (getfield(S, :time) - constants[:t1]); - S[:tprime] = 0.0) - -@everywhere cc_aut_G_l1Gl3G_4(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -istrue(S[:in]) && -(constants[:t1] <= getfield(S, :time) <= constants[:t2]) && -(constants[:x1] <= S[:n] <= constants[:x2]) -@everywhere us_aut_G_l1Gl3G_4!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l3G; - S[:tprime] = 0.0) - -# l1G => l4G -@everywhere cc_aut_G_l1Gl4G_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -!istrue(S[:in]) && -(constants[:t1] <= getfield(S, :time) <= constants[:t2]) && -(S[:n] < constants[:x1] || S[:n] > constants[:x2]) -@everywhere us_aut_G_l1Gl4G_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l4G; - S[:d] += S[:d] * (getfield(S, :time) - constants[:t1])) - -@everywhere cc_aut_G_l1Gl4G_2(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -istrue(S[:in]) && -(constants[:t1] <= getfield(S, :time) <= constants[:t2]) && -(S[:n] < constants[:x1] || S[:n] > constants[:x2]) -@everywhere us_aut_G_l1Gl4G_2!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l4G) - -# l1G => l2G -@everywhere cc_aut_G_l1Gl2G_3(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -istrue(S[:isabs]) && -getfield(S, :time) <= constants[:t1] -@everywhere us_aut_G_l1Gl2G_3!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l2G; - S[:d] = (constants[:t2] - constants[:t1]) * - min(abs(constants[:x1] - S[:n]), abs(constants[:x2] - S[:n]))) - -@everywhere cc_aut_G_l1Gl2G_4(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -istrue(S[:isabs]) && -(constants[:t1] <= getfield(S, :time) <= constants[:t2]) -@everywhere us_aut_G_l1Gl2G_4!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l2G; - S[:d] += (constants[:t2] - getfield(S, :time)) * - min(abs(constants[:x1] - S[:n]), abs(constants[:x2] - S[:n]))) - -@everywhere cc_aut_G_l1Gl2G_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -istrue(S[:in]) && -getfield(S, :time) >= constants[:t2] -@everywhere us_aut_G_l1Gl2G_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l2G) - -@everywhere cc_aut_G_l1Gl2G_2(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -!istrue(S[:in]) && -getfield(S, :time) >= constants[:t2] -@everywhere us_aut_G_l1Gl2G_2!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l2G; - S[:d] = S[:d] * (constants[:t2] - constants[:t1])) - -# l3G loc -# l3G => l1G -@everywhere cc_aut_G_l3Gl1G_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = true - -# l3G => l2G -@everywhere cc_aut_G_l3Gl2G_2(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -istrue(S[:in]) && -getfield(S, :time) >= constants[:t2] -@everywhere us_aut_G_l3Gl2G_2!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l2G; - S[:d] = S[:d] * (constants[:t2] - constants[:t1])) - -@everywhere cc_aut_G_l3Gl2G_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -!istrue(S[:in]) && -getfield(S, :time) >= constants[:t2] -@everywhere us_aut_G_l3Gl2G_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l2G) - -# l4G loc -# l4G => l1G -@everywhere cc_aut_G_l4Gl1G_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = true - -# l4G => l2G -@everywhere cc_aut_G_l4Gl2G_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(getfield(S, :time) >= constants[:t2]) -@everywhere us_aut_G_l4Gl2G_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l2G; - S[:d] += S[:tprime] * min(abs(constants[:x1] - S[:n]), abs(constants[:x2] - S[:n])); - S[:tprime] = 0.0) - -# Connection between the two automata: l2G => l1F -@everywhere cc_aut_F_l2Gl1F_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = true - -# l1F loc : we construct the edges of the form l1F => (..) -# l1F => l2F -@everywhere cc_aut_F_l1Fl2F_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -getfield(S, :time) >= constants[:t3] && -(constants[:x3] <= S[:n] <= constants[:x4]) -@everywhere us_aut_F_l1Fl2F_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l2F; - S[:dprime] = 0) - -@everywhere cc_aut_F_l1Fl2F_4(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -getfield(S, :time) >= constants[:t3] && -S[:dprime] == 0 -@everywhere us_aut_F_l1Fl2F_4!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l2F) - -@everywhere cc_aut_F_l1Fl2F_2(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(getfield(S, :time) >= constants[:t4]) && -(S[:n] < constants[:x3] || S[:n] > constants[:x4]) -@everywhere us_aut_F_l1Fl2F_2!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l2F; - S[:dprime] = min(abs(S[:n] - constants[:x3]), abs(S[:n] - constants[:x4])); - S[:d] += S[:dprime]) - -@everywhere cc_aut_F_l1Fl2F_3(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -istrue(S[:isabs]) && getfield(S, :time) <= constants[:t4] -@everywhere us_aut_F_l1Fl2F_3!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l2F; - S[:d] += S[:dprime]) - -# l1F => l3F -@everywhere cc_aut_F_l1Fl3F_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(constants[:x3] <= S[:n] <= constants[:x4]) -@everywhere us_aut_F_l1Fl3F_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l3F; - S[:dprime] = 0;) - -@everywhere cc_aut_F_l1Fl3F_2(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S[:n] < constants[:x3] || S[:n] > constants[:x4]) && -(getfield(S, :time) <= constants[:t3]) -@everywhere us_aut_F_l1Fl3F_2!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l3F; - S[:dprime] = min(sqrt((getfield(S, :time) - constants[:t3])^2 + (S[:n] - constants[:x4])^2), - sqrt((getfield(S, :time) - constants[:t3])^2 + (S[:n] - constants[:x3])^2))) - -@everywhere cc_aut_F_l1Fl3F_3(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S[:n] < constants[:x3] || S[:n] > constants[:x4]) && -(constants[:t3] <= getfield(S, :time) <= constants[:t4]) -@everywhere us_aut_F_l1Fl3F_3!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l3F; - S[:dprime] = min(S[:dprime], min(abs(S[:n] - constants[:x3]), abs(S[:n] - constants[:x4])))) - -# l3F loc -# l3F => l1F -@everywhere cc_aut_F_l3Fl1F_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = true - -# l3F => l2F -@everywhere cc_aut_F_l3Fl2F_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(getfield(S, :time) >= constants[:t4]) -@everywhere us_aut_F_l3Fl2F_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l2F) - function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float64, t1::Float64, t2::Float64, sym_obs_G::VariableModel, x3::Float64, x4::Float64, t3::Float64, t4::Float64, sym_obs_F::VariableModel) # Requirements for the automaton @@ -195,12 +8,13 @@ function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float @assert (x3 <= x4) "x3 > x3 impossible for G and F automaton." @assert (t3 <= t4) "t3 > t4 impossible for G and F automaton." @assert (t2 <= t3) "t3 > t2 impossible for G and F automaton." - + # Locations locations = [:l0G, :l1G, :l2G, :l3G, :l4G, :l1F, :l2F, :l3F] # Invariant predicates + @everywhere true_inv_predicate(x::Vector{Int}) = true Λ_F = Dict(:l0G => getfield(Main, :true_inv_predicate), :l1G => getfield(Main, :true_inv_predicate), :l2G => getfield(Main, :true_inv_predicate), :l3G => getfield(Main, :true_inv_predicate), :l4G => getfield(Main, :true_inv_predicate), @@ -232,123 +46,299 @@ function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float map_edges[loc] = Dict{Location, Vector{Edge}}() end - sym_isabs_func = Symbol(m.isabsorbing) idx_obs_var_F = getfield(m, :map_var_idx)[sym_obs_F] idx_obs_var_G = getfield(m, :map_var_idx)[sym_obs_G] + idx_var_n = map_var_automaton_idx[:n] + idx_var_d = map_var_automaton_idx[:d] + idx_var_dprime = map_var_automaton_idx[:dprime] + idx_var_isabs = map_var_automaton_idx[:isabs] + idx_var_in = map_var_automaton_idx[:in] + idx_var_tprime = map_var_automaton_idx[:tprime] + nbr_rand = rand(1:1000) basename_func = "$(replace(m.name, ' '=>'_'))_$(nbr_rand)" basename_func = replace(basename_func, '-'=>'_') - + sym_isabs_func = Symbol(m.isabsorbing) + func_name(type_func::Symbol, from_loc::Location, to_loc::Location, edge_number::Int) = + Symbol("$(type_func)_aut_F_$(basename_func)_$(from_loc)$(to_loc)_$(edge_number)$(type_func == :us ? "!" : "")") + meta_elementary_functions = quote + @everywhere istrue(val::Float64) = convert(Bool, val) + ## Edges check constraint and update state functions + + # l0G loc + # l0G => l1G + @everywhere $(func_name(:cc, :l0G, :l1G, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = true + @everywhere $(func_name(:us, :l0G, :l1G, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l1G")); + setindex!(getfield(S, :values), 0, $(idx_var_d)); + setindex!(getfield(S, :values), x[$(idx_obs_var_G)], $(idx_var_n)); + setindex!(getfield(S, :values), true, $(idx_var_in)); + setindex!(getfield(S, :values), getfield(Main, $(Meta.quot(sym_isabs_func)))(p, x), $(idx_var_isabs))) + + # l1G loc + # l1G => l3G + @everywhere $(func_name(:cc, :l1G, :l3G, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + getfield(S, :time) <= $t1 && + getfield(S, :values)[$(idx_var_n)] < $x1 || getfield(S, :values)[$(idx_var_n)] > $x2 + @everywhere $(func_name(:us, :l1G, :l3G, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l3G")); + setindex!(getfield(S, :values), min(abs($x1 - getfield(S, :values)[$(idx_var_n)]), abs($x2 - getfield(S, :values)[$(idx_var_n)])), $(idx_var_d)); + setindex!(getfield(S, :values), false, $(idx_var_in))) + + @everywhere $(func_name(:cc, :l1G, :l3G, 2))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (getfield(S, :time) <= $t1) && + ($x1 <= getfield(S, :values)[$(idx_var_n)] <= $x2) + @everywhere $(func_name(:us, :l1G, :l3G, 2))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l3G")); + setindex!(getfield(S, :values), 0, $(idx_var_d)); + setindex!(getfield(S, :values), false, $(idx_var_in))) + + @everywhere $(func_name(:cc, :l1G, :l3G, 3))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + !istrue(getfield(S, :values)[$(idx_var_in)]) && + ($t1 <= getfield(S, :time) <= $t2) && + ($x1 <= getfield(S, :values)[$(idx_var_n)] <= $x2) + @everywhere $(func_name(:us, :l1G, :l3G, 3))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l3G")); + setindex!(getfield(S, :values), getfield(S, :values)[$(idx_var_d)] * (getfield(S, :time) - $t1), $(idx_var_d)); + setindex!(getfield(S, :values), 0.0, $(idx_var_tprime))) + + @everywhere $(func_name(:cc, :l1G, :l3G, 4))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + istrue(getfield(S, :values)[$(idx_var_in)]) && + ($t1 <= getfield(S, :time) <= $t2) && + ($x1 <= getfield(S, :values)[$(idx_var_n)] <= $x2) + @everywhere $(func_name(:us, :l1G, :l3G, 4))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l3G")); + setindex!(getfield(S, :values), 0.0, $(idx_var_tprime))) + + # l1G => l4G + @everywhere $(func_name(:cc, :l1G, :l4G, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + !istrue(getfield(S, :values)[$(idx_var_in)]) && + ($t1 <= getfield(S, :time) <= $t2) && + (getfield(S, :values)[$(idx_var_n)] < $x1 || getfield(S, :values)[$(idx_var_n)] > $x2) + @everywhere $(func_name(:us, :l1G, :l4G, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l4G")); + setindex!(getfield(S, :values), getfield(S, :values)[$(idx_var_d)] + getfield(S, :values)[$(idx_var_d)] * (getfield(S, :time) - $t1), $(idx_var_d))) + + @everywhere $(func_name(:cc, :l1G, :l4G, 2))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + istrue(getfield(S, :values)[$(idx_var_in)]) && + ($t1 <= getfield(S, :time) <= $t2) && + (getfield(S, :values)[$(idx_var_n)] < $x1 || getfield(S, :values)[$(idx_var_n)] > $x2) + @everywhere $(func_name(:us, :l1G, :l4G, 2))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l4G"))) + + # l1G => l2G + @everywhere $(func_name(:cc, :l1G, :l2G, 3))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + istrue(getfield(S, :values)[$(idx_var_isabs)]) && + getfield(S, :time) <= $t1 + @everywhere $(func_name(:us, :l1G, :l2G, 3))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l2G")); + setindex!(getfield(S, :values), ($t2 - $t1) * min(abs($x1 - getfield(S, :values)[$(idx_var_n)]), abs($x2 - getfield(S, :values)[$(idx_var_n)])), $(idx_var_d))) + + @everywhere $(func_name(:cc, :l1G, :l2G, 4))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + istrue(getfield(S, :values)[$(idx_var_isabs)]) && + ($t1 <= getfield(S, :time) <= $t2) + @everywhere $(func_name(:us, :l1G, :l2G, 4))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l2G")); + setindex!(getfield(S, :values), getfield(S, :values)[$(idx_var_d)] + ($t2 - getfield(S, :time)) * min(abs($x1 - getfield(S, :values)[$(idx_var_n)]), abs($x2 - getfield(S, :values)[$(idx_var_n)])), $(idx_var_d))) + + @everywhere $(func_name(:cc, :l1G, :l2G, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + istrue(getfield(S, :values)[$(idx_var_in)]) && + getfield(S, :time) >= $t2 + @everywhere $(func_name(:us, :l1G, :l2G, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l2G"))) + + @everywhere $(func_name(:cc, :l1G, :l2G, 2))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + !istrue(getfield(S, :values)[$(idx_var_in)]) && + getfield(S, :time) >= $t2 + @everywhere $(func_name(:us, :l1G, :l2G, 2))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l2G")); + setindex!(getfield(S, :values), getfield(S, :values)[$(idx_var_d)] * ($t2 - $t1), $(idx_var_d))) + + # l3G loc + # l3G => l1G + @everywhere $(func_name(:cc, :l3G, :l1G, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = true + @everywhere $(func_name(:us, :l3G, :l1G, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l1G")); + setindex!(getfield(S, :values), x[$(idx_obs_var_G)], $(idx_var_n)); + setindex!(getfield(S, :values), getfield(Main, $(Meta.quot(sym_isabs_func)))(p, x), $(idx_var_isabs))) + + # l3G => l2G + @everywhere $(func_name(:cc, :l3G, :l2G, 2))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + istrue(getfield(S, :values)[$(idx_var_in)]) && + getfield(S, :time) >= $t2 + @everywhere $(func_name(:us, :l3G, :l2G, 2))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l2G")); + setindex!(getfield(S, :values), getfield(S, :values)[$(idx_var_d)] * ($t2 - $t1), $(idx_var_d))) + + @everywhere $(func_name(:cc, :l3G, :l2G, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + !istrue(getfield(S, :values)[$(idx_var_in)]) && + getfield(S, :time) >= $t2 + @everywhere $(func_name(:us, :l3G, :l2G, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l2G"))) + + # l4G loc + # l4G => l1G + @everywhere $(func_name(:cc, :l4G, :l1G, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = true + @everywhere $(func_name(:us, :l4G, :l1G, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l1G")); + setindex!(getfield(S, :values), getfield(S, :values)[$(idx_var_d)] + getfield(S, :values)[$(idx_var_tprime)] * min(abs($x1 - getfield(S, :values)[$(idx_var_n)]), abs($x2 - getfield(S, :values)[$(idx_var_n)])), $(idx_var_d)); + setindex!(getfield(S, :values), 0.0, $(idx_var_tprime)); + setindex!(getfield(S, :values), x[$(idx_obs_var_G)], $(idx_var_n)); + setindex!(getfield(S, :values), true, $(idx_var_in)); + setindex!(getfield(S, :values), getfield(Main, $(Meta.quot(sym_isabs_func)))(p, x), $(idx_var_isabs))) + + # l4G => l2G + @everywhere $(func_name(:cc, :l4G, :l2G, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (getfield(S, :time) >= $t2) + @everywhere $(func_name(:us, :l4G, :l2G, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l2G")); + setindex!(getfield(S, :values), getfield(S, :values)[$(idx_var_d)] + getfield(S, :values)[$(idx_var_tprime)] * min(abs($x1 - getfield(S, :values)[$(idx_var_n)]), abs($x2 - getfield(S, :values)[$(idx_var_n)])), $(idx_var_d)); + setindex!(getfield(S, :values), 0.0, $(idx_var_tprime))) + + # Connection between the two automata: l2G => l1F + @everywhere $(func_name(:cc, :l2G, :l1F, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = true + @everywhere $(func_name(:us, :l2G, :l1F, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l1F")); + setindex!(getfield(S, :values), x[$(idx_obs_var_F)], $(idx_var_n)); + setindex!(getfield(S, :values), Inf, $(idx_var_dprime)); + setindex!(getfield(S, :values), getfield(Main, $(Meta.quot(sym_isabs_func)))(p, x), $(idx_var_isabs))) + + # l1F loc : we construct the edges of the form l1F => (..) + # l1F => l2F + @everywhere $(func_name(:cc, :l1F, :l2F, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + getfield(S, :time) >= $t3 && + ($x3 <= getfield(S, :values)[$(idx_var_n)] <= $x4) + @everywhere $(func_name(:us, :l1F, :l2F, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l2F")); + setindex!(getfield(S, :values), 0, $(idx_var_dprime))) + + @everywhere $(func_name(:cc, :l1F, :l2F, 4))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + getfield(S, :time) >= $t3 && + getfield(S, :values)[$(idx_var_dprime)] == 0 + @everywhere $(func_name(:us, :l1F, :l2F, 4))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l2F"))) + + @everywhere $(func_name(:cc, :l1F, :l2F, 2))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (getfield(S, :time) >= $t4) && + (getfield(S, :values)[$(idx_var_n)] < $x3 || getfield(S, :values)[$(idx_var_n)] > $x4) + @everywhere $(func_name(:us, :l1F, :l2F, 2))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l2F")); + setindex!(getfield(S, :values), min(abs(getfield(S, :values)[$(idx_var_n)] - $x3), abs(getfield(S, :values)[$(idx_var_n)] - $x4)), $(idx_var_dprime)); + setindex!(getfield(S, :values), getfield(S, :values)[$(idx_var_d)] + getfield(S, :values)[$(idx_var_dprime)], $(idx_var_d))) + + @everywhere $(func_name(:cc, :l1F, :l2F, 3))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + istrue(getfield(S, :values)[$(idx_var_isabs)]) && getfield(S, :time) <= $t4 + @everywhere $(func_name(:us, :l1F, :l2F, 3))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l2F")); + setindex!(getfield(S, :values), getfield(S, :values)[$(idx_var_d)] + getfield(S, :values)[$(idx_var_dprime)], $(idx_var_d))) + + # l1F => l3F + @everywhere $(func_name(:cc, :l1F, :l3F, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + ($x3 <= getfield(S, :values)[$(idx_var_n)] <= $x4) + @everywhere $(func_name(:us, :l1F, :l3F, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l3F")); + setindex!(getfield(S, :values), 0, $(idx_var_dprime));) + + @everywhere $(func_name(:cc, :l1F, :l3F, 2))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (getfield(S, :values)[$(idx_var_n)] < $x3 || getfield(S, :values)[$(idx_var_n)] > $x4) && + (getfield(S, :time) <= $t3) + @everywhere $(func_name(:us, :l1F, :l3F, 2))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l3F")); + setindex!(getfield(S, :values), min(sqrt((getfield(S, :time) - $t3)^2 + (getfield(S, :values)[$(idx_var_n)] - $x4)^2), + sqrt((getfield(S, :time) - $t3)^2 + (getfield(S, :values)[$(idx_var_n)] - $x3)^2)), $(idx_var_dprime))) + + @everywhere $(func_name(:cc, :l1F, :l3F, 3))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (getfield(S, :values)[$(idx_var_n)] < $x3 || getfield(S, :values)[$(idx_var_n)] > $x4) && + ($t3 <= getfield(S, :time) <= $t4) + @everywhere $(func_name(:us, :l1F, :l3F, 3))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l3F")); + setindex!(getfield(S, :values), min(getfield(S, :values)[$(idx_var_dprime)], min(abs(getfield(S, :values)[$(idx_var_n)] - $x3), abs(getfield(S, :values)[$(idx_var_n)] - $x4))), $(idx_var_dprime))) + + # l3F loc + # l3F => l1F + @everywhere $(func_name(:cc, :l3F, :l1F, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = true + @everywhere $(func_name(:us, :l3F, :l1F, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l1F")); + setindex!(getfield(S, :values), x[$(idx_obs_var_F)], $(idx_var_n)); + setindex!(getfield(S, :values), getfield(Main, $(Meta.quot(sym_isabs_func)))(p, x), $(idx_var_isabs))) + + # l3F => l2F + @everywhere $(func_name(:cc, :l3F, :l2F, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (getfield(S, :time) >= $t4) + @everywhere $(func_name(:us, :l3F, :l2F, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l2F"))) + end + eval(meta_elementary_functions) + # l0G loc # l0G => l1G - sym_func_us_l0Gl1G_1 = Symbol("us_aut_G_$(basename_func)_l0Gl1G_1!") - str_us_l0Gl1G_1 = " - @everywhere $(sym_func_us_l0Gl1G_1)(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = \n - (S.loc = :l1G; \n - S[:d] = 0; \n - S[:n] = x[$(idx_obs_var_G)]; \n - S[:in] = true; \n - S[:isabs] = getfield(Main, $(Meta.quot(sym_isabs_func)))(p, x))" - eval(Meta.parse(str_us_l0Gl1G_1)) - edge1 = Edge([nothing], getfield(Main, :cc_aut_G_l0Gl1G_1), getfield(Main, sym_func_us_l0Gl1G_1)) + edge1 = Edge([nothing], getfield(Main, func_name(:cc, :l0G, :l1G, 1)), getfield(Main, func_name(:us, :l0G, :l1G, 1))) map_edges[:l0G][:l1G] = [edge1] # l1G => l3G - edge1 = Edge([nothing], getfield(Main, :cc_aut_G_l1Gl3G_1), getfield(Main, :us_aut_G_l1Gl3G_1!)) - edge2 = Edge([nothing], getfield(Main, :cc_aut_G_l1Gl3G_2), getfield(Main, :us_aut_G_l1Gl3G_2!)) - edge3 = Edge([nothing], getfield(Main, :cc_aut_G_l1Gl3G_3), getfield(Main, :us_aut_G_l1Gl3G_3!)) - edge4 = Edge([nothing], getfield(Main, :cc_aut_G_l1Gl3G_4), getfield(Main, :us_aut_G_l1Gl3G_4!)) + edge1 = Edge([nothing], getfield(Main, func_name(:cc, :l1G, :l3G, 1)), getfield(Main, func_name(:us, :l1G, :l3G, 1))) + edge2 = Edge([nothing], getfield(Main, func_name(:cc, :l1G, :l3G, 2)), getfield(Main, func_name(:us, :l1G, :l3G, 2))) + edge3 = Edge([nothing], getfield(Main, func_name(:cc, :l1G, :l3G, 3)), getfield(Main, func_name(:us, :l1G, :l3G, 3))) + edge4 = Edge([nothing], getfield(Main, func_name(:cc, :l1G, :l3G, 4)), getfield(Main, func_name(:us, :l1G, :l3G, 4))) map_edges[:l1G][:l3G] = [edge1, edge2, edge3, edge4] - + # l1G => l4G - edge1 = Edge([nothing], getfield(Main, :cc_aut_G_l1Gl4G_1), getfield(Main, :us_aut_G_l1Gl4G_1!)) - edge2 = Edge([nothing], getfield(Main, :cc_aut_G_l1Gl4G_2), getfield(Main, :us_aut_G_l1Gl4G_2!)) + edge1 = Edge([nothing], getfield(Main, func_name(:cc, :l1G, :l4G, 1)), getfield(Main, func_name(:us, :l1G, :l4G, 1))) + edge2 = Edge([nothing], getfield(Main, func_name(:cc, :l1G, :l4G, 2)), getfield(Main, func_name(:us, :l1G, :l4G, 2))) map_edges[:l1G][:l4G] = [edge1, edge2] - + # l1G => l2G - edge1 = Edge([nothing], getfield(Main, :cc_aut_G_l1Gl2G_1), getfield(Main, :us_aut_G_l1Gl2G_1!)) - edge2 = Edge([nothing], getfield(Main, :cc_aut_G_l1Gl2G_2), getfield(Main, :us_aut_G_l1Gl2G_2!)) - edge3 = Edge([nothing], getfield(Main, :cc_aut_G_l1Gl2G_3), getfield(Main, :us_aut_G_l1Gl2G_3!)) - edge4 = Edge([nothing], getfield(Main, :cc_aut_G_l1Gl2G_4), getfield(Main, :us_aut_G_l1Gl2G_4!)) + edge1 = Edge([nothing], getfield(Main, func_name(:cc, :l1G, :l2G, 1)), getfield(Main, func_name(:us, :l1G, :l2G, 1))) + edge2 = Edge([nothing], getfield(Main, func_name(:cc, :l1G, :l2G, 2)), getfield(Main, func_name(:us, :l1G, :l2G, 2))) + edge3 = Edge([nothing], getfield(Main, func_name(:cc, :l1G, :l2G, 3)), getfield(Main, func_name(:us, :l1G, :l2G, 3))) + edge4 = Edge([nothing], getfield(Main, func_name(:cc, :l1G, :l2G, 4)), getfield(Main, func_name(:us, :l1G, :l2G, 4))) map_edges[:l1G][:l2G] = [edge3, edge4, edge1, edge2] # l3G loc # l3G => l1G - sym_func_us_l3Gl1G_1 = Symbol("us_aut_G_$(basename_func)_l3Gl1G_1!") - str_us_l3Gl1G_1 = " - @everywhere $(sym_func_us_l3Gl1G_1)(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = \n - (S.loc = :l1G; \n - S[:n] = x[$(idx_obs_var_G)]; \n - S[:isabs] = getfield(Main, $(Meta.quot(sym_isabs_func)))(p, x))" - eval(Meta.parse(str_us_l3Gl1G_1)) - edge1 = Edge([:ALL], getfield(Main, :cc_aut_G_l3Gl1G_1), getfield(Main, sym_func_us_l3Gl1G_1)) + edge1 = Edge([:ALL], getfield(Main, func_name(:cc, :l3G, :l1G, 1)), getfield(Main, func_name(:us, :l3G, :l1G, 1))) map_edges[:l3G][:l1G] = [edge1] - + # l3G => l2G - edge1 = Edge([nothing], getfield(Main, :cc_aut_G_l3Gl2G_1), getfield(Main, :us_aut_G_l3Gl2G_1!)) - edge2 = Edge([nothing], getfield(Main, :cc_aut_G_l3Gl2G_2), getfield(Main, :us_aut_G_l3Gl2G_2!)) + edge1 = Edge([nothing], getfield(Main, func_name(:cc, :l3G, :l2G, 1)), getfield(Main, func_name(:us, :l3G, :l2G, 1))) + edge2 = Edge([nothing], getfield(Main, func_name(:cc, :l3G, :l2G, 2)), getfield(Main, func_name(:us, :l3G, :l2G, 2))) map_edges[:l3G][:l2G] = [edge1, edge2] # l4 loc # l4G => l1G - sym_func_us_l4Gl1G_1 = Symbol("us_aut_G_$(basename_func)_l4Gl1G_1!") - str_us_l4Gl1G_1 = " - @everywhere $(sym_func_us_l4Gl1G_1)(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = \n - (S.loc = :l1G; \n - S[:d] += S[:tprime] * min(abs(constants[:x1] - S[:n]), abs(constants[:x2] - S[:n])); \n - S[:tprime] = 0.0; \n - S[:n] = x[$(idx_obs_var_G)]; \n - S[:in] = true; \n - S[:isabs] = getfield(Main, $(Meta.quot(sym_isabs_func)))(p, x))" - eval(Meta.parse(str_us_l4Gl1G_1)) - edge1 = Edge([:ALL], getfield(Main, :cc_aut_G_l4Gl1G_1), getfield(Main, sym_func_us_l4Gl1G_1)) + edge1 = Edge([:ALL], getfield(Main, func_name(:cc, :l4G, :l1G, 1)), getfield(Main, func_name(:us, :l4G, :l1G, 1))) map_edges[:l4G][:l1G] = [edge1] # l4G => l2G - edge1 = Edge([nothing], getfield(Main, :cc_aut_G_l4Gl2G_1), getfield(Main, :us_aut_G_l4Gl2G_1!)) + edge1 = Edge([nothing], getfield(Main, func_name(:cc, :l4G, :l2G, 1)), getfield(Main, func_name(:us, :l4G, :l2G, 1))) map_edges[:l4G][:l2G] = [edge1] # l2G loc # l2G => l1F : Transition from autF to autG - sym_func_us_l2Gl1F_1 = Symbol("us_aut_G_$(basename_func)_l2Gl1F_1!") - str_us_l2Gl1F_1 = " - @everywhere $(sym_func_us_l2Gl1F_1)(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = \n - (S.loc = :l1F; \n - S[:n] = x[$(idx_obs_var_F)];\n - S[:dprime] = Inf; \n - S[:isabs] = getfield(Main, $(Meta.quot(sym_isabs_func)))(p, x))" - eval(Meta.parse(str_us_l2Gl1F_1)) - edge1 = Edge([nothing], getfield(Main, :cc_aut_F_l2Gl1F_1), getfield(Main, sym_func_us_l2Gl1F_1)) + edge1 = Edge([nothing], getfield(Main, func_name(:cc, :l2G, :l1F, 1)), getfield(Main, func_name(:us, :l2G, :l1F, 1))) map_edges[:l2G][:l1F] = [edge1] # l1F loc # l1F => l3F - edge1 = Edge([nothing], getfield(Main, :cc_aut_F_l1Fl2F_1), getfield(Main, :us_aut_F_l1Fl2F_1!)) - edge2 = Edge([nothing], getfield(Main, :cc_aut_F_l1Fl2F_2), getfield(Main, :us_aut_F_l1Fl2F_2!)) - edge3 = Edge([nothing], getfield(Main, :cc_aut_F_l1Fl2F_3), getfield(Main, :us_aut_F_l1Fl2F_3!)) - edge4 = Edge([nothing], getfield(Main, :cc_aut_F_l1Fl2F_4), getfield(Main, :us_aut_F_l1Fl2F_4!)) + edge1 = Edge([nothing], getfield(Main, func_name(:cc, :l1F, :l2F, 1)), getfield(Main, func_name(:us, :l1F, :l2F, 1))) + edge2 = Edge([nothing], getfield(Main, func_name(:cc, :l1F, :l2F, 2)), getfield(Main, func_name(:us, :l1F, :l2F, 2))) + edge3 = Edge([nothing], getfield(Main, func_name(:cc, :l1F, :l2F, 3)), getfield(Main, func_name(:us, :l1F, :l2F, 3))) + edge4 = Edge([nothing], getfield(Main, func_name(:cc, :l1F, :l2F, 4)), getfield(Main, func_name(:us, :l1F, :l2F, 4))) map_edges[:l1F][:l2F] = [edge1, edge4, edge3, edge2] # l1F => l3F - edge1 = Edge([nothing], getfield(Main, :cc_aut_F_l1Fl3F_1), getfield(Main, :us_aut_F_l1Fl3F_1!)) - edge2 = Edge([nothing], getfield(Main, :cc_aut_F_l1Fl3F_2), getfield(Main, :us_aut_F_l1Fl3F_2!)) - edge3 = Edge([nothing], getfield(Main, :cc_aut_F_l1Fl3F_3), getfield(Main, :us_aut_F_l1Fl3F_3!)) + edge1 = Edge([nothing], getfield(Main, func_name(:cc, :l1F, :l3F, 1)), getfield(Main, func_name(:us, :l1F, :l3F, 1))) + edge2 = Edge([nothing], getfield(Main, func_name(:cc, :l1F, :l3F, 2)), getfield(Main, func_name(:us, :l1F, :l3F, 2))) + edge3 = Edge([nothing], getfield(Main, func_name(:cc, :l1F, :l3F, 3)), getfield(Main, func_name(:us, :l1F, :l3F, 3))) map_edges[:l1F][:l3F] = [edge1, edge2, edge3] # l3F loc # l3F => l1F - sym_func_us_l3Fl1F_1 = Symbol("us_aut_G_$(basename_func)_l3Fl1F_1!") - str_us_l3Fl1F_1 = " - @everywhere $(sym_func_us_l3Fl1F_1)(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = \n - (S.loc = :l1F;\n - S[:n] = x[$(idx_obs_var_F)];\n - S[:isabs] = getfield(Main, $(Meta.quot(sym_isabs_func)))(p, x))" - eval(Meta.parse(str_us_l3Fl1F_1)) - edge1 = Edge([:ALL], getfield(Main, :cc_aut_F_l3Fl1F_1), getfield(Main, sym_func_us_l3Fl1F_1)) + edge1 = Edge([:ALL], getfield(Main, func_name(:cc, :l3F, :l1F, 1)), getfield(Main, func_name(:us, :l3F, :l1F, 1))) map_edges[:l3F][:l1F] = [edge1] # l3F => l2F - edge1 = Edge([nothing], getfield(Main, :cc_aut_F_l3Fl2F_1), getfield(Main, :us_aut_F_l3Fl2F_1!)) + edge1 = Edge([nothing], getfield(Main, func_name(:cc, :l3F, :l2F, 1)), getfield(Main, func_name(:us, :l3F, :l2F, 1))) map_edges[:l3F][:l2F] = [edge1] ## Constants diff --git a/automata/euclidean_distance_automaton.jl b/automata/euclidean_distance_automaton.jl index 7b64a18ed5d749ec2ba65d8fe92a146c2569797b..5fc21aebdab2a6615c16ee4280b2b6175eb7a8ef 100644 --- a/automata/euclidean_distance_automaton.jl +++ b/automata/euclidean_distance_automaton.jl @@ -1,25 +1,4 @@ -# l0 loc -# l0 => l1 -@everywhere cc_eucl_dist_aut_l0l1_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = true - -# l1 loc -# l1 => l1 -@everywhere cc_eucl_dist_aut_l1l1_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -S[:t] >= constants[Symbol("tml_$(S[:idx])")] -@everywhere us_eucl_dist_aut_l1l1_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S[:d] += (S[:n] - constants[Symbol("y_$(S[:idx])")])^2; - S[:idx] += 1.0) - -# l1 => l2 -@everywhere cc_eucl_dist_aut_l1l2_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -S[:idx] >= constants[:nbr_obs] + 1 -@everywhere us_eucl_dist_aut_l1l2_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l2; - S[:d] = sqrt(S[:d])) - -@everywhere cc_eucl_dist_aut_l1l1_2(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = true - function create_euclidean_distance_automaton(m::ContinuousTimeModel, timeline::AbstractVector{Float64}, observations::AbstractVector{Float64}, sym_obs::VariableModel) # Requirements for the automaton @assert sym_obs in m.g "$(sym_obs) is not observed." @@ -40,16 +19,7 @@ function create_euclidean_distance_automaton(m::ContinuousTimeModel, timeline::A map_var_automaton_idx = Dict{VariableAutomaton,Int}(:t => 1, :n => 2, :d => 3, :idx => 4) - nbr_first_vars = 4 - for i = 1:nbr_observations - map_var_automaton_idx[Symbol("tml_$(convert(Float64, i))")] = nbr_first_vars + i - end - for i = 1:nbr_observations - map_var_automaton_idx[Symbol("y_$(convert(Float64, i))")] = nbr_first_vars + nbr_observations + i - end - - vector_flow = zeros(nbr_first_vars + 2*nbr_observations) - vector_flow[1] = 1.0 + vector_flow = [1.0, 0.0, 0.0, 0.0] flow = Dict{Location,Vector{Float64}}(:l0 => vector_flow, :l1 => vector_flow, :l2 => vector_flow) @@ -61,36 +31,78 @@ function create_euclidean_distance_automaton(m::ContinuousTimeModel, timeline::A end idx_obs_var = getfield(m, :map_var_idx)[sym_obs] + idx_var_t = map_var_automaton_idx[:t] + idx_var_n = map_var_automaton_idx[:n] + idx_var_d = map_var_automaton_idx[:d] + idx_var_idx = map_var_automaton_idx[:idx] + nbr_rand = rand(1:1000) basename_func = "$(replace(m.name, ' '=>'_'))_$(nbr_rand)" basename_func = replace(basename_func, '-'=>'_') - + func_name(type_func::Symbol, from_loc::Location, to_loc::Location, edge_number::Int) = + Symbol("$(type_func)_eucl_dist_aut_$(basename_func)_$(from_loc)$(to_loc)_$(edge_number)$(type_func == :us ? "!" : "")") + meta_elementary_functions = quote + # l0 loc + # l0 => l1 + @everywhere $(func_name(:cc, :l0, :l1, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = true + @everywhere $(func_name(:us, :l0, :l1, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l1")); + setindex!(getfield(S, :values), x[$(idx_obs_var)], $(idx_var_n)); + setindex!(getfield(S, :values), 0.0, $(idx_var_d)); + setindex!(getfield(S, :values), 1.0, $(idx_var_idx))) + + # l1 loc + # l1 => l1 + # Defined below + @everywhere $(func_name(:cc, :l1, :l1, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + getfield(S, :values)[$(idx_var_t)] >= $(timeline)[convert(Int, getfield(S, :values)[$(idx_var_idx)])] + @everywhere $(func_name(:us, :l1, :l1, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setindex!(getfield(S, :values), getfield(S, :values)[$(idx_var_d)] + + (getfield(S, :values)[$(idx_var_n)] - $(observations)[convert(Int, getfield(S, :values)[$(idx_var_idx)])])^2, + $(idx_var_d)); + setindex!(getfield(S, :values), getfield(S, :values)[$(idx_var_idx)] + 1.0, $(idx_var_idx))) + + @everywhere $(func_name(:cc, :l1, :l1, 2))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = true + @everywhere $(func_name(:us, :l1, :l1, 2))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setindex!(getfield(S, :values), x[$(idx_obs_var)], $(idx_var_n))) + + # l1 => l2 + @everywhere $(func_name(:cc, :l1, :l2, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + getfield(S, :values)[$(idx_var_idx)] >= ($nbr_observations + 1) + @everywhere $(func_name(:us, :l1, :l2, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l2")); + setindex!(getfield(S, :values), sqrt(getfield(S, :values)[$(idx_var_d)]), $(idx_var_d))) + end + eval(meta_elementary_functions) + # l0 loc # l0 => l1 - sym_func_us_l0l1_1 = Symbol("us_eucl_dist_$(basename_func)_l0l1_1!") - str_us_l0l1_1 = " - @everywhere $(sym_func_us_l0l1_1)(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = \n - (S.loc = :l1; \n - S[:n] = x[$(idx_obs_var)];\n - S[:d] = 0.0;\n - S[:idx] = 1.0)" - eval(Meta.parse(str_us_l0l1_1)) - edge1 = Edge([nothing], getfield(Main, :cc_eucl_dist_aut_l0l1_1), getfield(Main, sym_func_us_l0l1_1)) + edge1 = Edge([nothing], getfield(Main, func_name(:cc, :l0, :l1, 1)), getfield(Main, func_name(:us, :l0, :l1, 1))) map_edges[:l0][:l1] = [edge1] # l1 loc # l1 => l1 - sym_func_us_l1l2_2 = Symbol("us_eucl_dist_$(basename_func)_l1l2_2!") - str_us_l1l2_2 = " - @everywhere $(sym_func_us_l1l2_2)(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) =\n - (S[:n] = x[$(idx_obs_var)])" - eval(Meta.parse(str_us_l1l2_2)) - edge1 = Edge([nothing], getfield(Main, :cc_eucl_dist_aut_l1l1_1), getfield(Main, :us_eucl_dist_aut_l1l1_1!)) - edge2 = Edge([:ALL], getfield(Main, :cc_eucl_dist_aut_l1l1_2), getfield(Main, sym_func_us_l1l2_2)) + #= + edge1 = Edge([:ALL], getfield(Main, func_name(:cc, :l1, :l1, 1)), getfield(Main, func_name(:us, :l1, :l2, 1))) + map_edges[:l1][:l1] = [edge1] + for i = 1:nbr_observations + meta_edge_i = quote + @everywhere $(func_name(:cc, :l1, :l1, 1+i))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + S[:t] >= $(timeline[i]) + @everywhere $(func_name(:us, :l1, :l1, 1+i))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setindex!(getfield(S, :values), S[:d] + (S[:n] - $(observations[i]))^2, $(idx_var_d)); + setindex!(getfield(S, :values), S[:idx] + 1.0, $(idx_var_idx))) + end + eval(meta_edge_i) + push!(map_edges[:l1][:l1], Edge([nothing], getfield(Main, func_name(:cc, :l1, :l1, 1+i)), getfield(Main, func_name(:us, :l1, :l1, 1+i)))) + end + =# + edge1 = Edge([nothing], getfield(Main, func_name(:cc, :l1, :l1, 1)), getfield(Main, func_name(:us, :l1, :l1, 1))) + edge2 = Edge([:ALL], getfield(Main, func_name(:cc, :l1, :l1, 2)), getfield(Main, func_name(:us, :l1, :l1, 2))) map_edges[:l1][:l1] = [edge1, edge2] # l1 => l2 - edge1 = Edge([nothing], getfield(Main, :cc_eucl_dist_aut_l1l2_1), getfield(Main, :us_eucl_dist_aut_l1l2_1!)) + edge1 = Edge([nothing], getfield(Main, func_name(:cc, :l1, :l2, 1)), getfield(Main, func_name(:us, :l1, :l2, 1))) map_edges[:l1][:l2] = [edge1] ## Constants diff --git a/automata/period_automaton.jl b/automata/period_automaton.jl index 653efe7eba9282b34a2a3355dee6275ce86fcdf3..19581c705d3ce71a319872883e577efe9338efb4 100644 --- a/automata/period_automaton.jl +++ b/automata/period_automaton.jl @@ -1,139 +1,4 @@ -## Edge functions - -# l0 loc -# * l0 => l0 -@everywhere cc_aut_per_l0l0_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -true -@everywhere us_aut_per_l0l0_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(nothing) - -# * l0 => l0prime -@everywhere cc_aut_per_l0l0prime_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -S[:t] >= constants[:initT] -@everywhere us_aut_per_l0l0prime_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :l0prime) - -# * l0 => low -@everywhere cc_aut_per_l0low_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -S[:t] >= constants[:initT] -@everywhere us_aut_per_l0low_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :low; - S[:t] = 0.0; - S[:top] = 0.0; - S[:n] = -1) - -# l0prime -# * l0prime => l0prime -@everywhere cc_aut_per_l0primel0prime_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -true -@everywhere us_aut_per_l0primel0prime_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(nothing) - -# * l0prime => low -@everywhere cc_aut_per_l0primelow_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -true -@everywhere us_aut_per_l0primelow_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :low; - S[:t] = 0.0; - S[:top] = 0.0; - S[:n] = -1) - -# low -# * low => low -@everywhere cc_aut_per_lowlow_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -S[:n] < constants[:N] -@everywhere us_aut_per_lowlow_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(nothing) - -# * low => mid -@everywhere cc_aut_per_lowmid_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -S[:n] < constants[:N] -@everywhere us_aut_per_lowmid_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :mid) - -# * low => final -@everywhere cc_aut_per_lowfinal_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -S[:n] == constants[:N] -@everywhere us_aut_per_lowfinal_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :final) - -# mid -# * mid => mid -@everywhere cc_aut_per_midmid_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -S[:n] < constants[:N] -@everywhere us_aut_per_midmid_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(nothing) - -# * mid => low -@everywhere cc_aut_per_midlow_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -S[:n] < constants[:N] && -S[:top] == 0.0 -@everywhere us_aut_per_midlow_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :low) - -@everywhere cc_aut_per_midlow_2(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -S[:n] == -1.0 && -S[:top] == 1.0 -@everywhere us_aut_per_midlow_2!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :low; - S[:n] += 1; - S[:t] = 0.0; - S[:top] = 0.0) - -@everywhere cc_aut_per_midlow_3(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(0 <= S[:n] <= 1) && -S[:top] == 1.0 -@everywhere us_aut_per_midlow_3!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :low; - S[:n] += 1; - S[:top] = 0.0; - S[:mean_tp] = (S[:mean_tp] * (S[:n]-1) + S[:tp]) / S[:n]; - S[:tp] = 0.0) - -@everywhere cc_aut_per_midlow_4(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(2 <= S[:n] < constants[:N]) && -S[:top] == 1.0 -@everywhere us_aut_per_midlow_4!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :low; - S[:n] += 1; - S[:top] = 0.0; - S[:mean_tp] = (S[:mean_tp] * (S[:n]-1) + S[:tp]) / S[:n]; - S[:var_tp] = (S[:var_tp] * (S[:n]-1) + (S[:mean_tp]-S[:tp])^2) / S[:n]; - S[:tp] = 0.0) - -# * mid => high -@everywhere cc_aut_per_midhigh_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -S[:n] < constants[:N] -@everywhere us_aut_per_midhigh_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :high; - S[:top] = 1.0) - -# * mid => final -@everywhere cc_aut_per_midfinal_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -S[:n] == constants[:N] -@everywhere us_aut_per_midfinal_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :final) - -# high -# * high => high -@everywhere cc_aut_per_highhigh_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -S[:n] < constants[:N] -@everywhere us_aut_per_highhigh_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(nothing) - -# * high => mid -@everywhere cc_aut_per_highmid_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -S[:n] < constants[:N] -@everywhere us_aut_per_highmid_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :mid) - -# * high => final -@everywhere cc_aut_per_highfinal_1(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -S[:n] == constants[:N] -@everywhere us_aut_per_highfinal_1!(S::StateLHA, constants::Dict{Symbol,Float64}, x::Vector{Int}, p::Vector{Float64}) = -(S.loc = :final) - function create_period_automaton(m::ContinuousTimeModel, L::Float64, H::Float64, N::Int, sym_obs::VariableModel; initT::Float64 = 0.0) # Requirements for the automaton @@ -159,13 +24,6 @@ function create_period_automaton(m::ContinuousTimeModel, L::Float64, H::Float64, @everywhere not_low_predicate(x::Vector{Int}) = !low_predicate(x) @everywhere mid_predicate(x::Vector{Int}) = $L < x[$(Meta.quot(idx_sym_obs))] < $H @everywhere high_predicate(x::Vector{Int}) = x[$(Meta.quot(idx_sym_obs))] >= $H - #= - eval(Meta.parse("@everywhere true_predicate(x::Vector{Int}) = true")) - eval(Meta.parse("@everywhere low_predicate(x::Vector{Int}) = x[$(Meta.quot(idx_sym_obs))] <= $L")) - eval(Meta.parse("@everywhere not_low_predicate(x::Vector{Int}) = !low_predicate(x)")) - eval(Meta.parse("@everywhere mid_predicate(x::Vector{Int}) = L < x[$(Meta.quot(idx_sym_obs))] < $H")) - eval(Meta.parse("@everywhere high_predicate(x::Vector{Int}) = x[$(Meta.quot(idx_sym_obs))] >= $H")) - =# Λ_F = Dict(:l0 => getfield(Main, :true_predicate), :l0prime => getfield(Main, :not_low_predicate), :low => getfield(Main, :low_predicate), :mid => getfield(Main, :mid_predicate), @@ -184,70 +42,219 @@ function create_period_automaton(m::ContinuousTimeModel, L::Float64, H::Float64, :low => [1.0,0.0,0.0,1.0,0.0,0.0], :mid => [1.0,0.0,0.0,1.0,0.0,0.0], :high => [1.0,0.0,0.0,1.0,0.0,0.0], - :final => [1.0,0.0,0.0,0.0,0.0,0.0]) - + :final => [1.0,0.0,0.0,0.0,0.0,0.0]) ## Edges map_edges = Dict{Location, Dict{Location, Vector{Edge}}}() for loc in locations map_edges[loc] = Dict{Location, Vector{Edge}}() end + + idx_obs_var = getfield(m, :map_var_idx)[sym_obs] + idx_var_t = map_var_automaton_idx[:t] + idx_var_tp = map_var_automaton_idx[:tp] + idx_var_mean_tp = map_var_automaton_idx[:mean_tp] + idx_var_var_tp = map_var_automaton_idx[:var_tp] + idx_var_n = map_var_automaton_idx[:n] + idx_var_top = map_var_automaton_idx[:top] + + nbr_rand = rand(1:100000) + basename_func = "$(replace(m.name, ' '=>'_'))_$(nbr_rand)" + basename_func = replace(basename_func, '-'=>'_') + func_name(type_func::Symbol, from_loc::Location, to_loc::Location, edge_number::Int) = + Symbol("$(type_func)_aut_per_$(basename_func)_$(from_loc)$(to_loc)_$(edge_number)$(type_func == :us ? "!" : "")") + meta_elementary_functions = quote + ## Edge functions + + # l0 loc + # * l0 => l0 + @everywhere $(func_name(:cc, :l0, :l0, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + true + @everywhere $(func_name(:us, :l0, :l0, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (nothing) + + # * l0 => l0prime + @everywhere $(func_name(:cc, :l0, :l0prime, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + S[:t] >= $initT + @everywhere $(func_name(:us, :l0, :l0prime, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("l0prime"))) + + # * l0 => low + @everywhere $(func_name(:cc, :l0, :low, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + S[:t] >= $initT + @everywhere $(func_name(:us, :l0, :low, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("low")); + setindex!(getfield(S, :values), 0.0, $(idx_var_t)); + setindex!(getfield(S, :values), 0.0, $(idx_var_top)); + setindex!(getfield(S, :values), -1, $(idx_var_n))) + + # l0prime + # * l0prime => l0prime + @everywhere $(func_name(:cc, :l0prime, :l0prime, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + true + @everywhere $(func_name(:us, :l0prime, :l0prime, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (nothing) + + # * l0prime => low + @everywhere $(func_name(:cc, :l0prime, :low, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + true + @everywhere $(func_name(:us, :l0prime, :low, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("low")); + setindex!(getfield(S, :values), 0.0, $(idx_var_t)); + setindex!(getfield(S, :values), 0.0, $(idx_var_top)); + setindex!(getfield(S, :values), -1, $(idx_var_n))) + + # low + # * low => low + @everywhere $(func_name(:cc, :low, :low, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + S[:n] < $N + @everywhere $(func_name(:us, :low, :low, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (nothing) + + # * low => mid + @everywhere $(func_name(:cc, :low, :mid, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + S[:n] < $N + @everywhere $(func_name(:us, :low, :mid, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("mid"))) + + # * low => final + @everywhere $(func_name(:cc, :low, :final, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + S[:n] == $N + @everywhere $(func_name(:us, :low, :final, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("final"))) + + # mid + # * mid => mid + @everywhere $(func_name(:cc, :mid, :mid, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + S[:n] < $N + @everywhere $(func_name(:us, :mid, :mid, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (nothing) + + # * mid => low + @everywhere $(func_name(:cc, :mid, :low, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + S[:n] < $N && + S[:top] == 0.0 + @everywhere $(func_name(:us, :mid, :low, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("low"))) + + @everywhere $(func_name(:cc, :mid, :low, 2))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + S[:n] == -1.0 && + S[:top] == 1.0 + @everywhere $(func_name(:us, :mid, :low, 2))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("low")); + setindex!(getfield(S, :values), S[:n] + 1, $(idx_var_n)); + setindex!(getfield(S, :values), 0.0, $(idx_var_t)); + setindex!(getfield(S, :values), 0.0, $(idx_var_top))) + + @everywhere $(func_name(:cc, :mid, :low, 3))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (0 <= S[:n] <= 1) && + S[:top] == 1.0 + @everywhere $(func_name(:us, :mid, :low, 3))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("low")); + setindex!(getfield(S, :values), S[:n] + 1, $(idx_var_n)); + setindex!(getfield(S, :values), 0.0, $(idx_var_top)); + setindex!(getfield(S, :values), (S[:mean_tp] * (S[:n]-1) + S[:tp]) / S[:n], $(idx_var_mean_tp)); + setindex!(getfield(S, :values), 0.0, $(idx_var_tp))) + + @everywhere $(func_name(:cc, :mid, :low, 4))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (2 <= S[:n] < $N) && + S[:top] == 1.0 + @everywhere $(func_name(:us, :mid, :low, 4))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("low")); + setindex!(getfield(S, :values), S[:n] + 1, $(idx_var_n)); + setindex!(getfield(S, :values), 0.0, $(idx_var_top)); + setindex!(getfield(S, :values), (S[:mean_tp] * (S[:n]-1) + S[:tp]) / S[:n], $(idx_var_mean_tp)); + setindex!(getfield(S, :values), (S[:var_tp] * (S[:n]-1) + (S[:mean_tp]-S[:tp])^2) / S[:n], $(idx_var_var_tp))) + + # * mid => high + @everywhere $(func_name(:cc, :mid, :high, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + S[:n] < $N + @everywhere $(func_name(:us, :mid, :high, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("high")); + setindex!(getfield(S, :values), 1.0, $(idx_var_top))) + + # * mid => final + @everywhere $(func_name(:cc, :mid, :final, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + S[:n] == $N + @everywhere $(func_name(:us, :mid, :final, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("final"))) + + # high + # * high => high + @everywhere $(func_name(:cc, :high, :high, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + S[:n] < $N + @everywhere $(func_name(:us, :high, :high, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (nothing) + + # * high => mid + @everywhere $(func_name(:cc, :high, :mid, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + S[:n] < $N + @everywhere $(func_name(:us, :high, :mid, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("mid"))) + + # * high => final + @everywhere $(func_name(:cc, :high, :final, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + S[:n] == $N + @everywhere $(func_name(:us, :high, :final, 1))(S::StateLHA, x::Vector{Int}, p::Vector{Float64}) = + (setfield!(S, :loc, Symbol("final"))) + end + eval(meta_elementary_functions) # l0 loc # * l0 => l0 - edge_1 = Edge([:ALL], getfield(Main, :cc_aut_per_l0l0_1), getfield(Main, :us_aut_per_l0l0_1!)) + edge_1 = Edge([:ALL], getfield(Main, func_name(:cc, :l0, :l0, 1)), getfield(Main, func_name(:us, :l0, :l0, 1))) map_edges[:l0][:l0] = [edge_1] # * l0 => l0prime - edge_1 = Edge([nothing], getfield(Main, :cc_aut_per_l0l0prime_1), getfield(Main, :us_aut_per_l0l0prime_1!)) + edge_1 = Edge([nothing], getfield(Main, func_name(:cc, :l0, :l0prime, 1)), getfield(Main, func_name(:us, :l0, :l0prime, 1))) map_edges[:l0][:l0prime] = [edge_1] # * l0 => low - edge_1 = Edge([nothing], getfield(Main, :cc_aut_per_l0low_1), getfield(Main, :us_aut_per_l0low_1!)) + edge_1 = Edge([nothing], getfield(Main, func_name(:cc, :l0, :low, 1)), getfield(Main, func_name(:us, :l0, :low, 1))) map_edges[:l0][:low] = [edge_1] # l0prime # * l0prime => l0prime - edge_1 = Edge([:ALL], getfield(Main, :cc_aut_per_l0primel0prime_1), getfield(Main, :us_aut_per_l0primel0prime_1!)) + edge_1 = Edge([:ALL], getfield(Main, func_name(:cc, :l0prime, :l0prime, 1)), getfield(Main, func_name(:us, :l0prime, :l0prime, 1))) map_edges[:l0prime][:l0prime] = [edge_1] # * l0prime => low - edge_1 = Edge([nothing], getfield(Main, :cc_aut_per_l0primelow_1), getfield(Main, :us_aut_per_l0primelow_1!)) + edge_1 = Edge([nothing], getfield(Main, func_name(:cc, :l0prime, :low, 1)), getfield(Main, func_name(:us, :l0prime, :low, 1))) map_edges[:l0prime][:low] = [edge_1] # low # * low => low - edge_1 = Edge([:ALL], getfield(Main, :cc_aut_per_lowlow_1), getfield(Main, :us_aut_per_lowlow_1!)) + edge_1 = Edge([:ALL], getfield(Main, func_name(:cc, :low, :low, 1)), getfield(Main, func_name(:us, :low, :low, 1))) map_edges[:low][:low] = [edge_1] # * low => mid - edge_1 = Edge([:ALL], getfield(Main, :cc_aut_per_lowmid_1), getfield(Main, :us_aut_per_lowmid_1!)) + edge_1 = Edge([:ALL], getfield(Main, func_name(:cc, :low, :mid, 1)), getfield(Main, func_name(:us, :low, :mid, 1))) map_edges[:low][:mid] = [edge_1] # * low => final - edge_1 = Edge([nothing], getfield(Main, :cc_aut_per_lowfinal_1), getfield(Main, :us_aut_per_lowfinal_1!)) + edge_1 = Edge([nothing], getfield(Main, func_name(:cc, :low, :final, 1)), getfield(Main, func_name(:us, :low, :final, 1))) map_edges[:low][:final] = [edge_1] # mid # * mid => mid - edge_1 = Edge([:ALL], getfield(Main, :cc_aut_per_midmid_1), getfield(Main, :us_aut_per_midmid_1!)) + edge_1 = Edge([:ALL], getfield(Main, func_name(:cc, :mid, :mid, 1)), getfield(Main, func_name(:us, :mid, :mid, 1))) map_edges[:mid][:mid] = [edge_1] # * mid => low - edge_1 = Edge([:ALL], getfield(Main, :cc_aut_per_midlow_1), getfield(Main, :us_aut_per_midlow_1!)) - edge_2 = Edge([:ALL], getfield(Main, :cc_aut_per_midlow_2), getfield(Main, :us_aut_per_midlow_2!)) - edge_3 = Edge([:ALL], getfield(Main, :cc_aut_per_midlow_3), getfield(Main, :us_aut_per_midlow_3!)) - edge_4 = Edge([:ALL], getfield(Main, :cc_aut_per_midlow_4), getfield(Main, :us_aut_per_midlow_4!)) + edge_1 = Edge([:ALL], getfield(Main, func_name(:cc, :mid, :low, 1)), getfield(Main, func_name(:us, :mid, :low, 1))) + edge_2 = Edge([:ALL], getfield(Main, func_name(:cc, :mid, :low, 2)), getfield(Main, func_name(:us, :mid, :low, 2))) + edge_3 = Edge([:ALL], getfield(Main, func_name(:cc, :mid, :low, 3)), getfield(Main, func_name(:us, :mid, :low, 3))) + edge_4 = Edge([:ALL], getfield(Main, func_name(:cc, :mid, :low, 4)), getfield(Main, func_name(:us, :mid, :low, 4))) map_edges[:mid][:low] = [edge_1, edge_2, edge_3, edge_4] # * mid => high - edge_1 = Edge([:ALL], getfield(Main, :cc_aut_per_midhigh_1), getfield(Main, :us_aut_per_midhigh_1!)) + edge_1 = Edge([:ALL], getfield(Main, func_name(:cc, :mid, :high, 1)), getfield(Main, func_name(:us, :mid, :high, 1))) map_edges[:mid][:high] = [edge_1] # * mid => final - edge_1 = Edge([nothing], getfield(Main, :cc_aut_per_midfinal_1), getfield(Main, :us_aut_per_midfinal_1!)) + edge_1 = Edge([nothing], getfield(Main, func_name(:cc, :mid, :final, 1)), getfield(Main, func_name(:us, :mid, :final, 1))) map_edges[:mid][:final] = [edge_1] # high # * high => high - edge_1 = Edge([:ALL], getfield(Main, :cc_aut_per_highhigh_1), getfield(Main, :us_aut_per_highhigh_1!)) + edge_1 = Edge([:ALL], getfield(Main, func_name(:cc, :high, :high, 1)), getfield(Main, func_name(:us, :high, :high, 1))) map_edges[:high][:high] = [edge_1] # * high => mid - edge_1 = Edge([:ALL], getfield(Main, :cc_aut_per_highmid_1), getfield(Main, :us_aut_per_highmid_1!)) + edge_1 = Edge([:ALL], getfield(Main, func_name(:cc, :high, :mid, 1)), getfield(Main, func_name(:us, :high, :mid, 1))) map_edges[:high][:mid] = [edge_1] # * high => final - edge_1 = Edge([nothing], getfield(Main, :cc_aut_per_highfinal_1), getfield(Main, :us_aut_per_highfinal_1!)) + edge_1 = Edge([nothing], getfield(Main, func_name(:cc, :high, :final, 1)), getfield(Main, func_name(:us, :high, :final, 1))) map_edges[:high][:final] = [edge_1] ## Constants diff --git a/core/MarkovProcesses.jl b/core/MarkovProcesses.jl index 3485e7562ed87e7c7740d547e366542cb662591b..f0fdc940ae930813c54bbe2a9fd65a01d4337fbb 100644 --- a/core/MarkovProcesses.jl +++ b/core/MarkovProcesses.jl @@ -17,7 +17,7 @@ export VariableModel, ParameterModel, Transition export LHA, StateLHA, Edge, Location, VariableAutomaton # Trajectory related methods -export +, -, δ, dist_lp +export +, -, δ, dist_lp, euclidean_distance export get_obs_var, length_states, length_obs_var export get_state_from_time, get_var_from_time, vectorize export isbounded, times, transitions diff --git a/core/lha.jl b/core/lha.jl index 6b9a0832264fc505375f380c8fa79816715302f3..a9d35de1e9ed37bbd6976af49cdd3c95b1df4a50 100644 --- a/core/lha.jl +++ b/core/lha.jl @@ -104,19 +104,19 @@ end function _find_edge_candidates!(edge_candidates::Vector{Edge}, edges_from_current_loc::Dict{Location,Vector{Edge}}, Λ::Dict{Location,Function}, - Snplus1::StateLHA, constants::Dict{Symbol,Float64}, + Snplus1::StateLHA, x::Vector{Int}, p::Vector{Float64}, only_asynchronous::Bool) nbr_candidates = 0 for target_loc in keys(edges_from_current_loc) for edge in edges_from_current_loc[target_loc] - if Λ[target_loc](x) && getfield(edge, :check_constraints)(Snplus1, constants, x, p) - if edge.transitions[1] == nothing + if Λ[target_loc](x) && getfield(edge, :check_constraints)(Snplus1, x, p) + if getfield(edge, :transitions)[1] == nothing _push_edge!(edge_candidates, edge, nbr_candidates) nbr_candidates += 1 return nbr_candidates end - if !only_asynchronous && edge.transitions[1] != nothing + if !only_asynchronous && getfield(edge, :transitions)[1] != nothing _push_edge!(edge_candidates, edge, nbr_candidates) nbr_candidates += 1 end @@ -133,13 +133,13 @@ function _get_edge_index(edge_candidates::Vector{Edge}, nbr_candidates::Int, for i = 1:nbr_candidates edge = edge_candidates[i] # Asynchronous edge detection: we fire it - if edge.transitions[1] == nothing + if getfield(edge, :transitions)[1] == nothing return (i, bool_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 @@ -163,7 +163,6 @@ function next_state!(Snplus1::StateLHA, A::LHA, @show Sn @show Snplus1 end - constants = getfield(A, :constants) # In terms of values not reference, Snplus1 == Sn # First, we check the asynchronous transitions while first_round || length(edge_candidates) > 0 @@ -172,14 +171,14 @@ function next_state!(Snplus1::StateLHA, A::LHA, current_loc = getfield(Snplus1, :loc) edges_from_current_loc = getfield(A, :map_edges)[current_loc] # Save all edges that satisfies transition predicate (asynchronous ones) - nbr_candidates = _find_edge_candidates!(edge_candidates, edges_from_current_loc, getfield(A, :Λ), Snplus1, constants, xn, p, true) + nbr_candidates = _find_edge_candidates!(edge_candidates, edges_from_current_loc, getfield(A, :Λ), Sn, xn, p, true) #Snplus1=>Sn # 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_candidates, nbr_candidates, detected_event, nothing) # Update the state with the chosen one (if it exists) # Should be xn here if ind_edge > 0 - getfield(edge_candidates[ind_edge], :update_state!)(Snplus1, constants, xn, p) + getfield(edge_candidates[ind_edge], :update_state!)(Snplus1, xn, p) end first_round = false if verbose @@ -193,6 +192,7 @@ function next_state!(Snplus1::StateLHA, A::LHA, break end # For debug + #= if turns > 100 println("Number of turns in next_state! is suspicious") @show first_round, detected_event @@ -200,10 +200,11 @@ function next_state!(Snplus1::StateLHA, A::LHA, @show tnplus1, tr_nplus1, xnplus1 @show edge_candidates for edge in edge_candidates - @show getfield(edge, :check_constraints)(Snplus1, constants, x, p) + @show getfield(edge, :check_constraints)(Snplus1, xn, p) end error("Unpredicted behavior automaton") end + =# end if verbose @show Snplus1 @@ -227,7 +228,7 @@ function next_state!(Snplus1::StateLHA, A::LHA, current_loc = getfield(Snplus1, :loc) edges_from_current_loc = getfield(A, :map_edges)[current_loc] # Save all edges that satisfies transition predicate (synchronous ones) - nbr_candidates = _find_edge_candidates!(edge_candidates, edges_from_current_loc, getfield(A, :Λ), Snplus1, constants, xnplus1, p, false) + nbr_candidates = _find_edge_candidates!(edge_candidates, edges_from_current_loc, getfield(A, :Λ), Snplus1, xnplus1, p, false) # Search the one we must chose ind_edge, detected_event = _get_edge_index(edge_candidates, nbr_candidates, detected_event, tr_nplus1) # Update the state with the chosen one (if it exists) @@ -237,7 +238,7 @@ function next_state!(Snplus1::StateLHA, A::LHA, @show ind_edge, detected_event, nbr_candidates end if ind_edge > 0 - getfield(edge_candidates[ind_edge], :update_state!)(Snplus1, constants, xnplus1, p) + getfield(edge_candidates[ind_edge], :update_state!)(Snplus1, xnplus1, p) end first_round = false if verbose @@ -249,6 +250,7 @@ function next_state!(Snplus1::StateLHA, A::LHA, break end # For debug + #= if turns > 100 println("Number of turns in next_state! is suspicious") @show detected_event @@ -256,10 +258,11 @@ function next_state!(Snplus1::StateLHA, A::LHA, @show tnplus1, tr_nplus1, xnplus1 @show edge_candidates for edge in edge_candidates - @show getfield(edge, :check_constraints)(Snplus1, constants, x, p) + @show getfield(edge, :check_constraints)(Snplus1, x, p) end error("Unpredicted behavior automaton") end + =# end if verbose println("##### End next_state!") end end diff --git a/core/model.jl b/core/model.jl index c636424edc0f93a9dde2741eda4fcbd13a81ffed..4e2a797dcdcf52a97a8afbd368aaebe47d3b4247 100644 --- a/core/model.jl +++ b/core/model.jl @@ -295,7 +295,6 @@ function volatile_simulate(product::SynchronizedModel; getfield(m, :f!)(vec_x, l_t, l_tr, xn, tn, p_sim) if l_t[1] > time_bound tn = l_t[1] - i -= 1 break end if vec_x == xn diff --git a/core/trajectory.jl b/core/trajectory.jl index c875281d863a853c07f48fc97385cddafbda73eb..f2ec60c602ecda285ec157f58193bfa68c886031 100644 --- a/core/trajectory.jl +++ b/core/trajectory.jl @@ -1,4 +1,6 @@ +## About distances + # Top-level Lp distance function """ `dist_lp(l_σ1, l_σ2; verbose, p, str_stat_list, str_stat_trajectory)` @@ -68,6 +70,7 @@ function dist_lp(x_obs::Vector{Int}, t_x::Vector{Float64}, y_obs::Vector{Int}, t verbose::Bool = false, p::Int = 1) current_y_obs = y_obs[1] current_t_y = t_y[2] + nbr_y_obs = length(y_obs) idx = 1 res = 0.0 for i = 1:(length(x_obs)-1) @@ -78,7 +81,7 @@ function dist_lp(x_obs::Vector{Int}, t_x::Vector{Float64}, y_obs::Vector{Int}, t @show t_x[i+1] end last_t_y = t_x[i] - while current_t_y < t_x[i+1] + while current_t_y < t_x[i+1] && idx <= nbr_y_obs rect = abs(current_y_obs - x_obs[i])^p * (current_t_y - last_t_y) res += rect if verbose @@ -172,6 +175,13 @@ function vectorize(σ::AbstractTrajectory, sym_var::Symbol, return trajectory_points end +function euclidean_distance(σ::AbstractTrajectory, sym_obs::Symbol, + tml::AbstractVector{Float64}, observations::AbstractVector{Float64}) + traj_obs = vectorize(σ, sym_obs, tml) + diff_obs = observations - traj_obs + return sqrt(dot(diff_obs, diff_obs)) +end + function check_consistency(σ::AbstractTrajectory) test_length_var = true for i = 1:σ.m.dim_obs_state diff --git a/tests/automata/euclidean_distance.jl b/tests/automata/euclidean_distance.jl new file mode 100644 index 0000000000000000000000000000000000000000..2f0cc1fd592079be162763b200b02543007f47e7 --- /dev/null +++ b/tests/automata/euclidean_distance.jl @@ -0,0 +1,42 @@ + +using MarkovProcesses +import LinearAlgebra: dot +import Distributions: Uniform + +load_automaton("euclidean_distance_automaton") +load_model("SIR") +load_model("ER") + +test_all = true + +# SIR model +nbr_sim = 10 +for i = 1:nbr_sim + set_param!(SIR, [:ki, :kr], [rand(Uniform(5E-5, 3E-3)), rand(Uniform(5E-3, 0.2))]) + let tml_obs, y_obs, sync_SIR, σ, test + tml_obs = rand(Uniform(0.0, 5.0)):1.0:rand(Uniform(50.0, 100.0)) + y_obs = vectorize(simulate(SIR), :I, tml_obs) + sync_SIR = SIR * create_euclidean_distance_automaton(SIR, tml_obs, y_obs, :I) + σ = simulate(sync_SIR) + test = euclidean_distance(σ, :I, tml_obs, y_obs) == σ.state_lha_end[:d] + #@show test, euclidean_distance(σ, tml_obs, y_obs, :I), σ.state_lha_end[:d] + global test_all = test_all && test + end +end + +# ER model +for i = 1:nbr_sim + let tml_obs, y_obs, sync_SIR, σ, test + set_param!(ER, :k3, rand(Uniform(0.0, 100.0))) + tml_obs = rand(Uniform(0.0, 0.2)):1.0:rand(Uniform(0.5,10.0)) + y_obs = vectorize(simulate(ER), :P, tml_obs) + sync_ER = ER * create_euclidean_distance_automaton(ER, tml_obs, y_obs, :P) + σ = simulate(sync_ER) + test = euclidean_distance(σ, :P, tml_obs, y_obs) == σ.state_lha_end[:d] + #@show test, euclidean_distance(σ, tml_obs, y_obs, :P), σ.state_lha_end[:d] + global test_all = test_all && test + end +end + +return test_all + diff --git a/tests/automata/euclidean_distance_single.jl b/tests/automata/euclidean_distance_single.jl new file mode 100644 index 0000000000000000000000000000000000000000..237ed3de3209c8f01166526f7af317e1e977ea7b --- /dev/null +++ b/tests/automata/euclidean_distance_single.jl @@ -0,0 +1,17 @@ + +using MarkovProcesses +import LinearAlgebra: dot +import Distributions: Uniform + +load_automaton("euclidean_distance_automaton") +load_model("SIR") +tml_obs = 0:0.5:200 +set_time_bound!(SIR, 200.0) +y_obs = vectorize(simulate(SIR), :I, tml_obs) +sync_SIR = SIR * create_euclidean_distance_automaton(SIR, tml_obs, y_obs, :I) +σ = simulate(sync_SIR) +test = euclidean_distance(σ, tml_obs, y_obs, :I) == σ.state_lha_end[:d] +@show test, euclidean_distance(σ, tml_obs, y_obs, :I), σ.state_lha_end[:d] + +return test + diff --git a/tests/run_automata.jl b/tests/run_automata.jl index 9046876a1581dc8778ea9eac9b02709e499e4e2f..0d029fd824aa30ef31729410e550174ab2aad006 100644 --- a/tests/run_automata.jl +++ b/tests/run_automata.jl @@ -4,6 +4,8 @@ using Test @testset "Automata tests" begin @test include("automata/absorbing_x0_p.jl") @test include("automata/accept_R5.jl") + @test include("automata/euclidean_distance.jl") + @test include("automata/euclidean_distance_single.jl") @test include("automata/read_trajectory_last_state_F.jl") @test include("automata/read_trajectory_last_state_G.jl") @test include("automata/sync_simulate_last_state_F.jl")