From 667eebf5bc683744850b865566b14ae8930576c1 Mon Sep 17 00:00:00 2001 From: Mahmoud Bentriou <mahmoud.bentriou@centralesupelec.fr> Date: Wed, 9 Dec 2020 11:58:47 +0100 Subject: [PATCH] Some special cases with absorbing states were fixed in the construction of automata: it wasn't an issue about the simulation code of LHA but an issue of LHA designs. Improvement of a Cosmos utils method. Now A.constants is a NamedTuple. distributed_mean_value_lha now takes several variables. --- automata/automaton_F.jl | 72 ++++++++++---- automata/automaton_G.jl | 62 ++++++------ automata/automaton_G_and_F.jl | 110 ++++++++++++---------- core/common.jl | 2 +- core/lha.jl | 18 ++-- core/model.jl | 2 +- core/utils.jl | 9 +- tests/cosmos/distance_F/ER_1D.jl | 8 +- tests/cosmos/distance_F/dist_F_ER.lha | 14 ++- tests/cosmos/distance_G/ER_R5.jl | 6 +- tests/cosmos/distance_G/dist_G_ER.lha | 1 - tests/cosmos/distance_G_F/ER_R6.jl | 15 +-- tests/cosmos/distance_G_F/dist_G_F_ER.lha | 11 ++- 13 files changed, 197 insertions(+), 133 deletions(-) diff --git a/automata/automaton_F.jl b/automata/automaton_F.jl index 0a64bd1..756c195 100644 --- a/automata/automaton_F.jl +++ b/automata/automaton_F.jl @@ -45,52 +45,90 @@ function create_automaton_F(m::ContinuousTimeModel, x1::Float64, x2::Float64, t1 # l1 loc : we construct the edges of the form l1 => (..) tuple = ("l1", "l2") cc_aut_F_l1l2_1(A::LHA, S::StateLHA) = - (A.constants["x1"] <= S["n"] <= A.constants["x2"]) && - (A.constants["t1"] <= S.time <= A.constants["t2"]) + S.time >= A.constants.t1 && + (A.constants.x1 <= S["n"] <= A.constants.x2) + us_aut_F_l1l2_1!(A::LHA, S::StateLHA, x::Vector{Int}) = + (S.loc = "l2"; + S["d"] = 0) + edge1 = Edge([nothing], cc_aut_F_l1l2_1, us_aut_F_l1l2_1!) + + cc_aut_F_l1l2_4(A::LHA, S::StateLHA) = + S.time >= A.constants.t1 && + S["d"] == 0 + us_aut_F_l1l2_4!(A::LHA, S::StateLHA, x::Vector{Int}) = + (S.loc = "l2") + edge4 = Edge([nothing], cc_aut_F_l1l2_4, us_aut_F_l1l2_4!) + + cc_aut_F_l1l2_2(A::LHA, S::StateLHA) = + (S.time >= A.constants.t2) && + (S["n"] < A.constants.x1 || S["n"] > A.constants.x2) + us_aut_F_l1l2_2!(A::LHA, S::StateLHA, x::Vector{Int}) = + (S.loc = "l2"; + S["d"] = min(abs(S["n"] - A.constants.x1), abs(S["n"] - A.constants.x2))) + edge2 = Edge([nothing], cc_aut_F_l1l2_2, us_aut_F_l1l2_2!) + + cc_aut_F_l1l2_3(A::LHA, S::StateLHA) = + istrue(S["isabs"]) && S.time <= A.constants.t2 + us_aut_F_l1l2_3!(A::LHA, S::StateLHA, x::Vector{Int}) = + (S.loc = "l2") + edge3 = Edge([nothing], cc_aut_F_l1l2_3, us_aut_F_l1l2_3!) + + map_edges[tuple] = [edge1, edge2, edge3, edge4] + #= + tuple = ("l1", "l2") + cc_aut_F_l1l2_1(A::LHA, S::StateLHA) = + (A.constants.x1 <= S["n"] <= A.constants.x2) && + (A.constants.t1 <= S.time <= A.constants.t2) us_aut_F_l1l2_1!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l2"; S["d"] = 0) edge1 = Edge([nothing], cc_aut_F_l1l2_1, us_aut_F_l1l2_1!) cc_aut_F_l1l2_2(A::LHA, S::StateLHA) = - S["d"] > 0 && - (S.time > A.constants["t2"] || istrue(S["isabs"])) + S["d"] > 0 && istrue(S["isabs"]) us_aut_F_l1l2_2!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l2") edge2 = Edge([nothing], cc_aut_F_l1l2_2, us_aut_F_l1l2_2!) + + cc_aut_F_l1l2_4(A::LHA, S::StateLHA) = + S["d"] >= Inf && S.time >= A.constants.t2 + us_aut_F_l1l2_4!(A::LHA, S::StateLHA, x::Vector{Int}) = + (S.loc = "l2"; + S["d"] = min(abs(S["n"] - A.constants.x1), abs(S["n"] - A.constants.x2))); + edge4 = Edge([nothing], cc_aut_F_l1l2_4, us_aut_F_l1l2_4!) cc_aut_F_l1l2_3(A::LHA, S::StateLHA) = S["d"] == 0 && - S.time >= A.constants["t1"] + S.time >= A.constants.t1 us_aut_F_l1l2_3!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l2") edge3 = Edge([nothing], cc_aut_F_l1l2_3, us_aut_F_l1l2_3!) - map_edges[tuple] = [edge1, edge2, edge3] - + map_edges[tuple] = [edge1, edge2, edge3, edge4] + =# tuple = ("l1", "l3") cc_aut_F_l1l3_1(A::LHA, S::StateLHA) = - (A.constants["x1"] <= S["n"] <= A.constants["x2"]) + (A.constants.x1 <= S["n"] <= A.constants.x2) us_aut_F_l1l3_1!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l3"; S["d"] = 0;) edge1 = Edge([nothing], cc_aut_F_l1l3_1, us_aut_F_l1l3_1!) cc_aut_F_l1l3_2(A::LHA, S::StateLHA) = - (S["n"] < A.constants["x1"] || S["n"] > A.constants["x2"]) && - (S.time <= A.constants["t1"]) + (S["n"] < A.constants.x1 || S["n"] > A.constants.x2) && + (S.time <= A.constants.t1) us_aut_F_l1l3_2!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l3"; - S["d"] = min(sqrt((S.time - A.constants["t1"])^2 + (S["n"] - A.constants["x2"])^2), - sqrt((S.time - A.constants["t1"])^2 + (S["n"] - A.constants["x1"])^2))) + S["d"] = min(sqrt((S.time - A.constants.t1)^2 + (S["n"] - A.constants.x2)^2), + sqrt((S.time - A.constants.t1)^2 + (S["n"] - A.constants.x1)^2))) edge2 = Edge([nothing], cc_aut_F_l1l3_2, us_aut_F_l1l3_2!) cc_aut_F_l1l3_3(A::LHA, S::StateLHA) = - (S["n"] < A.constants["x1"] || S["n"] > A.constants["x2"]) && - (A.constants["t1"] <= S.time <= A.constants["t2"]) + (S["n"] < A.constants.x1 || S["n"] > A.constants.x2) && + (A.constants.t1 <= S.time <= A.constants.t2) us_aut_F_l1l3_3!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l3"; - S["d"] = min(S["d"], min(abs(S["n"] - A.constants["x1"]), abs(S["n"] - A.constants["x2"])))) + S["d"] = min(S["d"], min(abs(S["n"] - A.constants.x1), abs(S["n"] - A.constants.x2)))) edge3 = Edge([nothing], cc_aut_F_l1l3_3, us_aut_F_l1l3_3!) map_edges[tuple] = [edge1, edge2, edge3] @@ -104,14 +142,14 @@ function create_automaton_F(m::ContinuousTimeModel, x1::Float64, x2::Float64, t1 edge1 = Edge(["ALL"], cc_aut_F_l3l1_1, us_aut_F_l3l1_1!) tuple = ("l3", "l2") cc_aut_F_l3l2_1(A::LHA, S::StateLHA) = - (S.time >= A.constants["t2"]) + (S.time >= A.constants.t2) us_aut_F_l3l2_1!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l2") edge2 = Edge([nothing], cc_aut_F_l3l2_1, us_aut_F_l3l2_1!) map_edges[tuple] = [edge1, edge2] ## Constants - constants = Dict{String,Float64}("x1" => x1, "x2" => x2, "t1" => t1, "t2" => t2) + constants = (x1 = x1, x2 = x2, t1 = t1, t2 = t2) A = LHA(m.transitions, locations, Λ_F, locations_init, locations_final, map_var_automaton_idx, flow, map_edges, constants, m.map_var_idx) diff --git a/automata/automaton_G.jl b/automata/automaton_G.jl index 13572fc..0eec8d7 100644 --- a/automata/automaton_G.jl +++ b/automata/automaton_G.jl @@ -45,27 +45,27 @@ function create_automaton_G(m::ContinuousTimeModel, x1::Float64, x2::Float64, t1 # l1 loc tuple = ("l1", "l3") cc_aut_G_l1l3_1(A::LHA, S::StateLHA) = - S.time <= A.constants["t1"] && - S["n"] < A.constants["x1"] || S["n"] > A.constants["x2"] + S.time <= A.constants.t1 && + S["n"] < A.constants.x1 || S["n"] > A.constants.x2 us_aut_G_l1l3_1!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l3"; - S["d"] = min(abs(A.constants["x1"] - S["n"]), abs(A.constants["x2"] - S["n"])); + S["d"] = min(abs(A.constants.x1 - S["n"]), abs(A.constants.x2 - S["n"])); S["in"] = false) edge1 = Edge([nothing], cc_aut_G_l1l3_1, us_aut_G_l1l3_1!) cc_aut_G_l1l3_3(A::LHA, S::StateLHA) = !istrue(S["in"]) && - (A.constants["t1"] <= S.time <= A.constants["t2"]) && - (A.constants["x1"] <= S["n"] <= A.constants["x2"]) + (A.constants.t1 <= S.time <= A.constants.t2) && + (A.constants.x1 <= S["n"] <= A.constants.x2) us_aut_G_l1l3_3!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l3"; - S["d"] = S["d"] * (S.time - A.constants["t1"]); + S["d"] = S["d"] * (S.time - A.constants.t1); S["tprime"] = 0.0) edge3 = Edge([nothing], cc_aut_G_l1l3_3, us_aut_G_l1l3_3!) cc_aut_G_l1l3_2(A::LHA, S::StateLHA) = - (S.time <= A.constants["t1"]) && - (A.constants["x1"] <= S["n"] <= A.constants["x2"]) + (S.time <= A.constants.t1) && + (A.constants.x1 <= S["n"] <= A.constants.x2) us_aut_G_l1l3_2!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l3"; S["d"] = 0; @@ -74,8 +74,8 @@ function create_automaton_G(m::ContinuousTimeModel, x1::Float64, x2::Float64, t1 cc_aut_G_l1l3_4(A::LHA, S::StateLHA) = istrue(S["in"]) && - (A.constants["t1"] <= S.time <= A.constants["t2"]) && - (A.constants["x1"] <= S["n"] <= A.constants["x2"]) + (A.constants.t1 <= S.time <= A.constants.t2) && + (A.constants.x1 <= S["n"] <= A.constants.x2) us_aut_G_l1l3_4!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l3"; S["tprime"] = 0.0) @@ -86,16 +86,16 @@ function create_automaton_G(m::ContinuousTimeModel, x1::Float64, x2::Float64, t1 tuple = ("l1", "l4") cc_aut_G_l1l4_1(A::LHA, S::StateLHA) = !istrue(S["in"]) && - (A.constants["t1"] <= S.time <= A.constants["t2"]) && - (S["n"] < A.constants["x1"] || S["n"] > A.constants["x2"]) + (A.constants.t1 <= S.time <= A.constants.t2) && + (S["n"] < A.constants.x1 || S["n"] > A.constants.x2) us_aut_G_l1l4_1!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l4"; - S["d"] += S["d"] * (S.time - A.constants["t1"])) + S["d"] += S["d"] * (S.time - A.constants.t1)) edge1 = Edge([nothing], cc_aut_G_l1l4_1, us_aut_G_l1l4_1!) cc_aut_G_l1l4_2(A::LHA, S::StateLHA) = istrue(S["in"]) && - (A.constants["t1"] <= S.time <= A.constants["t2"]) && - (S["n"] < A.constants["x1"] || S["n"] > A.constants["x2"]) + (A.constants.t1 <= S.time <= A.constants.t2) && + (S["n"] < A.constants.x1 || S["n"] > A.constants.x2) us_aut_G_l1l4_2!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l4") edge2 = Edge([nothing], cc_aut_G_l1l4_2, us_aut_G_l1l4_2!) @@ -104,32 +104,32 @@ function create_automaton_G(m::ContinuousTimeModel, x1::Float64, x2::Float64, t1 tuple = ("l1", "l2") cc_aut_G_l1l2_1(A::LHA, S::StateLHA) = istrue(S["in"]) && - S.time >= A.constants["t2"] + S.time >= A.constants.t2 us_aut_G_l1l2_1!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l2") edge1 = Edge([nothing], cc_aut_G_l1l2_1, us_aut_G_l1l2_1!) cc_aut_G_l1l2_2(A::LHA, S::StateLHA) = !istrue(S["in"]) && - S.time >= A.constants["t2"] + S.time >= A.constants.t2 us_aut_G_l1l2_2!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l2"; - S["d"] = S["d"] * (A.constants["t2"] - A.constants["t1"])) + S["d"] = S["d"] * (A.constants.t2 - A.constants.t1)) edge2 = Edge([nothing], cc_aut_G_l1l2_2, us_aut_G_l1l2_2!) cc_aut_G_l1l2_3(A::LHA, S::StateLHA) = istrue(S["isabs"]) && - S.time <= A.constants["t1"] + S.time <= A.constants.t1 us_aut_G_l1l2_3!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l2"; - S["d"] = (A.constants["t2"] - A.constants["t1"]) * - min(abs(A.constants["x1"] - S["n"]), abs(A.constants["x1"] - S["n"]))) + S["d"] = (A.constants.t2 - A.constants.t1) * + min(abs(A.constants.x1 - S["n"]), abs(A.constants.x2 - S["n"]))) edge3 = Edge([nothing], cc_aut_G_l1l2_3, us_aut_G_l1l2_3!) cc_aut_G_l1l2_4(A::LHA, S::StateLHA) = istrue(S["isabs"]) && - (A.constants["t1"] <= S.time <= A.constants["t2"]) + (A.constants.t1 <= S.time <= A.constants.t2) us_aut_G_l1l2_4!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l2"; - S["d"] += (A.constants["t2"] - S.time) * - min(abs(A.constants["x1"] - S["n"]), abs(A.constants["x1"] - S["n"]))) + S["d"] += (A.constants.t2 - S.time) * + min(abs(A.constants.x1 - S["n"]), abs(A.constants.x2 - S["n"]))) edge4 = Edge([nothing], cc_aut_G_l1l2_4, us_aut_G_l1l2_4!) map_edges[tuple] = [edge1, edge2, edge3, edge4] @@ -147,14 +147,14 @@ function create_automaton_G(m::ContinuousTimeModel, x1::Float64, x2::Float64, t1 tuple = ("l3", "l2") cc_aut_G_l3l2_2(A::LHA, S::StateLHA) = istrue(S["in"]) && - S.time >= A.constants["t2"] + S.time >= A.constants.t2 us_aut_G_l3l2_2!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l2"; - S["d"] = S["d"] * (A.constants["t2"] - A.constants["t1"])) + S["d"] = S["d"] * (A.constants.t2 - A.constants.t1)) edge2 = Edge([nothing], cc_aut_G_l3l2_2, us_aut_G_l3l2_2!) cc_aut_G_l3l2_1(A::LHA, S::StateLHA) = !istrue(S["in"]) && - S.time >= A.constants["t2"] + S.time >= A.constants.t2 us_aut_G_l3l2_1!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l2") edge1 = Edge([nothing], cc_aut_G_l3l2_1, us_aut_G_l3l2_1!) @@ -166,7 +166,7 @@ function create_automaton_G(m::ContinuousTimeModel, x1::Float64, x2::Float64, t1 cc_aut_G_l4l1_1(A::LHA, S::StateLHA) = true us_aut_G_l4l1_1!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l1"; - S["d"] += S["tprime"] * min(abs(A.constants["x1"] - S["n"]), abs(A.constants["x2"] - S["n"])); + S["d"] += S["tprime"] * min(abs(A.constants.x1 - S["n"]), abs(A.constants.x2 - S["n"])); S["tprime"] = 0.0; S["n"] = get_value(A, x, str_obs); S["in"] = true; @@ -176,17 +176,17 @@ function create_automaton_G(m::ContinuousTimeModel, x1::Float64, x2::Float64, t1 tuple = ("l4", "l2") cc_aut_G_l4l2_1(A::LHA, S::StateLHA) = - (S.time >= A.constants["t2"]) + (S.time >= A.constants.t2) us_aut_G_l4l2_1!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l2"; - S["d"] += S["tprime"] * min(abs(A.constants["x1"] - S["n"]), abs(A.constants["x2"] - S["n"])); + S["d"] += S["tprime"] * min(abs(A.constants.x1 - S["n"]), abs(A.constants.x2 - S["n"])); S["tprime"] = 0.0) edge1 = Edge([nothing], cc_aut_G_l4l2_1, us_aut_G_l4l2_1!) map_edges[tuple] = [edge1] ## Constants - constants = Dict{String,Float64}("x1" => x1, "x2" => x2, "t1" => t1, "t2" => t2) + constants = (x1 = x1, x2 = x2, t1 = t1, t2 = t2) A = LHA(m.transitions, locations, Λ_F, locations_init, locations_final, map_var_automaton_idx, flow, map_edges, constants, m.map_var_idx) diff --git a/automata/automaton_G_and_F.jl b/automata/automaton_G_and_F.jl index a6af4e9..e9b91c4 100644 --- a/automata/automaton_G_and_F.jl +++ b/automata/automaton_G_and_F.jl @@ -55,27 +55,27 @@ function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float # l1G loc tuple = ("l1G", "l3G") cc_aut_G_l1Gl3G_1(A::LHA, S::StateLHA) = - S.time <= A.constants["t1"] && - S["n"] < A.constants["x1"] || S["n"] > A.constants["x2"] + S.time <= A.constants.t1 && + S["n"] < A.constants.x1 || S["n"] > A.constants.x2 us_aut_G_l1Gl3G_1!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l3G"; - S["d"] = min(abs(A.constants["x1"] - S["n"]), abs(A.constants["x2"] - S["n"])); + S["d"] = min(abs(A.constants.x1 - S["n"]), abs(A.constants.x2 - S["n"])); S["in"] = false) edge1 = Edge([nothing], cc_aut_G_l1Gl3G_1, us_aut_G_l1Gl3G_1!) cc_aut_G_l1Gl3G_3(A::LHA, S::StateLHA) = !istrue(S["in"]) && - (A.constants["t1"] <= S.time <= A.constants["t2"]) && - (A.constants["x1"] <= S["n"] <= A.constants["x2"]) + (A.constants.t1 <= S.time <= A.constants.t2) && + (A.constants.x1 <= S["n"] <= A.constants.x2) us_aut_G_l1Gl3G_3!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l3G"; - S["d"] = S["d"] * (S.time - A.constants["t1"]); + S["d"] = S["d"] * (S.time - A.constants.t1); S["tprime"] = 0.0) edge3 = Edge([nothing], cc_aut_G_l1Gl3G_3, us_aut_G_l1Gl3G_3!) cc_aut_G_l1Gl3G_2(A::LHA, S::StateLHA) = - (S.time <= A.constants["t1"]) && - (A.constants["x1"] <= S["n"] <= A.constants["x2"]) + (S.time <= A.constants.t1) && + (A.constants.x1 <= S["n"] <= A.constants.x2) us_aut_G_l1Gl3G_2!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l3G"; S["d"] = 0; @@ -84,8 +84,8 @@ function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float cc_aut_G_l1Gl3G_4(A::LHA, S::StateLHA) = istrue(S["in"]) && - (A.constants["t1"] <= S.time <= A.constants["t2"]) && - (A.constants["x1"] <= S["n"] <= A.constants["x2"]) + (A.constants.t1 <= S.time <= A.constants.t2) && + (A.constants.x1 <= S["n"] <= A.constants.x2) us_aut_G_l1Gl3G_4!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l3G"; S["tprime"] = 0.0) @@ -96,16 +96,16 @@ function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float tuple = ("l1G", "l4G") cc_aut_G_l1Gl4G_1(A::LHA, S::StateLHA) = !istrue(S["in"]) && - (A.constants["t1"] <= S.time <= A.constants["t2"]) && - (S["n"] < A.constants["x1"] || S["n"] > A.constants["x2"]) + (A.constants.t1 <= S.time <= A.constants.t2) && + (S["n"] < A.constants.x1 || S["n"] > A.constants.x2) us_aut_G_l1Gl4G_1!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l4G"; - S["d"] += S["d"] * (S.time - A.constants["t1"])) + S["d"] += S["d"] * (S.time - A.constants.t1)) edge1 = Edge([nothing], cc_aut_G_l1Gl4G_1, us_aut_G_l1Gl4G_1!) cc_aut_G_l1Gl4G_2(A::LHA, S::StateLHA) = istrue(S["in"]) && - (A.constants["t1"] <= S.time <= A.constants["t2"]) && - (S["n"] < A.constants["x1"] || S["n"] > A.constants["x2"]) + (A.constants.t1 <= S.time <= A.constants.t2) && + (S["n"] < A.constants.x1 || S["n"] > A.constants.x2) us_aut_G_l1Gl4G_2!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l4G") edge2 = Edge([nothing], cc_aut_G_l1Gl4G_2, us_aut_G_l1Gl4G_2!) @@ -114,32 +114,32 @@ function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float tuple = ("l1G", "l2G") cc_aut_G_l1Gl2G_1(A::LHA, S::StateLHA) = istrue(S["in"]) && - S.time >= A.constants["t2"] + S.time >= A.constants.t2 us_aut_G_l1Gl2G_1!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l2G") edge1 = Edge([nothing], cc_aut_G_l1Gl2G_1, us_aut_G_l1Gl2G_1!) cc_aut_G_l1Gl2G_2(A::LHA, S::StateLHA) = !istrue(S["in"]) && - S.time >= A.constants["t2"] + S.time >= A.constants.t2 us_aut_G_l1Gl2G_2!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l2G"; - S["d"] = S["d"] * (A.constants["t2"] - A.constants["t1"])) + S["d"] = S["d"] * (A.constants.t2 - A.constants.t1)) edge2 = Edge([nothing], cc_aut_G_l1Gl2G_2, us_aut_G_l1Gl2G_2!) cc_aut_G_l1Gl2G_3(A::LHA, S::StateLHA) = istrue(S["isabs"]) && - S.time <= A.constants["t1"] + S.time <= A.constants.t1 us_aut_G_l1Gl2G_3!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l2G"; - S["d"] = (A.constants["t2"] - A.constants["t1"]) * - min(abs(A.constants["x1"] - S["n"]), abs(A.constants["x1"] - S["n"]))) + S["d"] = (A.constants.t2 - A.constants.t1) * + min(abs(A.constants.x1 - S["n"]), abs(A.constants.x2 - S["n"]))) edge3 = Edge([nothing], cc_aut_G_l1Gl2G_3, us_aut_G_l1Gl2G_3!) cc_aut_G_l1Gl2G_4(A::LHA, S::StateLHA) = istrue(S["isabs"]) && - (A.constants["t1"] <= S.time <= A.constants["t2"]) + (A.constants.t1 <= S.time <= A.constants.t2) us_aut_G_l1Gl2G_4!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l2G"; - S["d"] += (A.constants["t2"] - S.time) * - min(abs(A.constants["x1"] - S["n"]), abs(A.constants["x1"] - S["n"]))) + S["d"] += (A.constants.t2 - S.time) * + min(abs(A.constants.x1 - S["n"]), abs(A.constants.x2 - S["n"]))) edge4 = Edge([nothing], cc_aut_G_l1Gl2G_4, us_aut_G_l1Gl2G_4!) map_edges[tuple] = [edge1, edge2, edge3, edge4] @@ -157,14 +157,14 @@ function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float tuple = ("l3G", "l2G") cc_aut_G_l3Gl2G_2(A::LHA, S::StateLHA) = istrue(S["in"]) && - S.time >= A.constants["t2"] + S.time >= A.constants.t2 us_aut_G_l3Gl2G_2!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l2G"; - S["d"] = S["d"] * (A.constants["t2"] - A.constants["t1"])) + S["d"] = S["d"] * (A.constants.t2 - A.constants.t1)) edge2 = Edge([nothing], cc_aut_G_l3Gl2G_2, us_aut_G_l3Gl2G_2!) cc_aut_G_l3Gl2G_1(A::LHA, S::StateLHA) = !istrue(S["in"]) && - S.time >= A.constants["t2"] + S.time >= A.constants.t2 us_aut_G_l3Gl2G_1!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l2G") edge1 = Edge([nothing], cc_aut_G_l3Gl2G_1, us_aut_G_l3Gl2G_1!) @@ -176,7 +176,7 @@ function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float cc_aut_G_l4Gl1G_1(A::LHA, S::StateLHA) = true us_aut_G_l4Gl1G_1!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l1G"; - S["d"] += S["tprime"] * min(abs(A.constants["x1"] - S["n"]), abs(A.constants["x2"] - S["n"])); + S["d"] += S["tprime"] * min(abs(A.constants.x1 - S["n"]), abs(A.constants.x2 - S["n"])); S["tprime"] = 0.0; S["n"] = get_value(A, x, str_obs_G); S["in"] = true; @@ -186,10 +186,10 @@ function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float tuple = ("l4G", "l2G") cc_aut_G_l4Gl2G_1(A::LHA, S::StateLHA) = - (S.time >= A.constants["t2"]) + (S.time >= A.constants.t2) us_aut_G_l4Gl2G_1!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l2G"; - S["d"] += S["tprime"] * min(abs(A.constants["x1"] - S["n"]), abs(A.constants["x2"] - S["n"])); + S["d"] += S["tprime"] * min(abs(A.constants.x1 - S["n"]), abs(A.constants.x2 - S["n"])); S["tprime"] = 0.0) edge1 = Edge([nothing], cc_aut_G_l4Gl2G_1, us_aut_G_l4Gl2G_1!) @@ -209,53 +209,61 @@ function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float # l1F loc : we construct the edges of the form l1F => (..) tuple = ("l1F", "l2F") cc_aut_F_l1Fl2F_1(A::LHA, S::StateLHA) = - (A.constants["x3"] <= S["n"] <= A.constants["x4"]) && - (A.constants["t3"] <= S.time <= A.constants["t4"]) + S.time >= A.constants.t3 && + (A.constants.x3 <= S["n"] <= A.constants.x4) us_aut_F_l1Fl2F_1!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l2F"; S["dprime"] = 0) edge1 = Edge([nothing], cc_aut_F_l1Fl2F_1, us_aut_F_l1Fl2F_1!) + + cc_aut_F_l1Fl2F_4(A::LHA, S::StateLHA) = + S.time >= A.constants.t3 && + S["dprime"] == 0 + us_aut_F_l1Fl2F_4!(A::LHA, S::StateLHA, x::Vector{Int}) = + (S.loc = "l2F") + edge4 = Edge([nothing], cc_aut_F_l1Fl2F_4, us_aut_F_l1Fl2F_4!) cc_aut_F_l1Fl2F_2(A::LHA, S::StateLHA) = - S["dprime"] > 0 && - (S.time > A.constants["t4"] || istrue(S["isabs"])) + (S.time >= A.constants.t4) && + (S["n"] < A.constants.x3 || S["n"] > A.constants.x4) us_aut_F_l1Fl2F_2!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l2F"; + S["dprime"] = min(abs(S["n"] - A.constants.x3), abs(S["n"] - A.constants.x4)); S["d"] += S["dprime"]) edge2 = Edge([nothing], cc_aut_F_l1Fl2F_2, us_aut_F_l1Fl2F_2!) - + cc_aut_F_l1Fl2F_3(A::LHA, S::StateLHA) = - S["dprime"] == 0 && - S.time >= A.constants["t3"] + istrue(S["isabs"]) && S.time <= A.constants.t4 us_aut_F_l1Fl2F_3!(A::LHA, S::StateLHA, x::Vector{Int}) = - (S.loc = "l2F") + (S.loc = "l2F"; + S["d"] += S["dprime"]) edge3 = Edge([nothing], cc_aut_F_l1Fl2F_3, us_aut_F_l1Fl2F_3!) - - map_edges[tuple] = [edge1, edge2, edge3] + + map_edges[tuple] = [edge1, edge2, edge3, edge4] tuple = ("l1F", "l3F") cc_aut_F_l1Fl3F_1(A::LHA, S::StateLHA) = - (A.constants["x3"] <= S["n"] <= A.constants["x4"]) + (A.constants.x3 <= S["n"] <= A.constants.x4) us_aut_F_l1Fl3F_1!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l3F"; S["dprime"] = 0;) edge1 = Edge([nothing], cc_aut_F_l1Fl3F_1, us_aut_F_l1Fl3F_1!) cc_aut_F_l1Fl3F_2(A::LHA, S::StateLHA) = - (S["n"] < A.constants["x3"] || S["n"] > A.constants["x4"]) && - (S.time <= A.constants["t3"]) + (S["n"] < A.constants.x3 || S["n"] > A.constants.x4) && + (S.time <= A.constants.t3) us_aut_F_l1Fl3F_2!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l3F"; - S["dprime"] = min(sqrt((S.time - A.constants["t3"])^2 + (S["n"] - A.constants["x4"])^2), - sqrt((S.time - A.constants["t3"])^2 + (S["n"] - A.constants["x3"])^2))) + S["dprime"] = min(sqrt((S.time - A.constants.t3)^2 + (S["n"] - A.constants.x4)^2), + sqrt((S.time - A.constants.t3)^2 + (S["n"] - A.constants.x3)^2))) edge2 = Edge([nothing], cc_aut_F_l1Fl3F_2, us_aut_F_l1Fl3F_2!) cc_aut_F_l1Fl3F_3(A::LHA, S::StateLHA) = - (S["n"] < A.constants["x3"] || S["n"] > A.constants["x4"]) && - (A.constants["t3"] <= S.time <= A.constants["t4"]) + (S["n"] < A.constants.x3 || S["n"] > A.constants.x4) && + (A.constants.t3 <= S.time <= A.constants.t4) us_aut_F_l1Fl3F_3!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l3F"; - S["dprime"] = min(S["dprime"], min(abs(S["n"] - A.constants["x3"]), abs(S["n"] - A.constants["x4"])))) + S["dprime"] = min(S["dprime"], min(abs(S["n"] - A.constants.x3), abs(S["n"] - A.constants.x4)))) edge3 = Edge([nothing], cc_aut_F_l1Fl3F_3, us_aut_F_l1Fl3F_3!) map_edges[tuple] = [edge1, edge2, edge3] @@ -269,15 +277,15 @@ function create_automaton_G_and_F(m::ContinuousTimeModel, x1::Float64, x2::Float edge1 = Edge(["ALL"], cc_aut_F_l3Fl1F_1, us_aut_F_l3Fl1F_1!) tuple = ("l3F", "l2F") cc_aut_F_l3Fl2F_1(A::LHA, S::StateLHA) = - (S.time >= A.constants["t4"]) + (S.time >= A.constants.t4) us_aut_F_l3Fl2F_1!(A::LHA, S::StateLHA, x::Vector{Int}) = (S.loc = "l2F") edge2 = Edge([nothing], cc_aut_F_l3Fl2F_1, us_aut_F_l3Fl2F_1!) map_edges[tuple] = [edge1, edge2] ## Constants - constants = Dict{String,Float64}("x1" => x1, "x2" => x2, "t1" => t1, "t2" => t2, - "x3" => x3, "x4" => x4, "t3" => t3, "t4" => t4) + constants = (x1 = x1, x2 = x2, t1 = t1, t2 = t2, + x3 = x3, x4 = x4, t3 = t3, t4 = t4) A = LHA(m.transitions, locations, Λ_F, locations_init, locations_final, map_var_automaton_idx, flow, map_edges, constants, m.map_var_idx) diff --git a/core/common.jl b/core/common.jl index 08f0b38..3687ff7 100644 --- a/core/common.jl +++ b/core/common.jl @@ -51,7 +51,7 @@ struct LHA map_var_automaton_idx::Dict{VariableAutomaton,Int} # nvar keys : str_var => idx in values flow::Dict{Location,Vector{Float64}} # output of length nvar map_edges::Dict{Tuple{Location,Location},Vector{Edge}} - constants::Dict{String,Float64} + constants::NamedTuple map_var_model_idx::Dict{String,Int} # of dim d (of a model) end diff --git a/core/lha.jl b/core/lha.jl index e1686b0..81c4387 100644 --- a/core/lha.jl +++ b/core/lha.jl @@ -5,6 +5,8 @@ get_value(A::LHA, x::Vector{Int}, var::String) = x[A.map_var_model_idx[var]] copy(S::StateLHA) = StateLHA(S.A, S.loc, S.values, S.time) # Not overring getproperty, setproperty to avoid a conversion Symbol => String for the dict key getindex(S::StateLHA, var::VariableAutomaton) = (S.values)[(S.A).map_var_automaton_idx[var]] +getindex(S::StateLHA, l_var::Vector{VariableAutomaton}) = + [S[var] for var in l_var] setindex!(S::StateLHA, val::Float64, var::VariableAutomaton) = (S.values)[(S.A).map_var_automaton_idx[var]] = val setindex!(S::StateLHA, val::Int, var::VariableAutomaton) = (S.values)[(S.A).map_var_automaton_idx[var]] = convert(Float64, val) setindex!(S::StateLHA, val::Bool, var::VariableAutomaton) = (S.values)[(S.A).map_var_automaton_idx[var]] = convert(Float64, val) @@ -37,6 +39,9 @@ function Base.copyto!(Sdest::StateLHA, Ssrc::StateLHA) Sdest.time = Ssrc.time end +# In future check_consistency(LHA), check if constant has the name +# of one of the LHA fields + isaccepted(S::StateLHA) = (S.loc in (S.A).locations_final) # Methods for synchronize / read the trajectory @@ -59,7 +64,7 @@ function _find_edge_candidates!(edge_candidates::Vector{Edge}, current_loc::Loca for edge in A.map_edges[tuple_edges] if edge.check_constraints(A, Snplus1) if edge.transitions[1] == nothing - pushfirst!(edge_candidates, edge) + push!(edge_candidates, edge) end if !only_asynchronous && edge.transitions[1] != nothing push!(edge_candidates, edge) @@ -76,15 +81,16 @@ function _get_edge_index(edge_candidates::Vector{Edge}, bool_event = detected_event for i in eachindex(edge_candidates) edge = edge_candidates[i] - # Asynchronous detection - if edge.transitions[1] == nothing + # Asynchronous edge detection: we fire it + if edge.transitions[1] == nothing return (i, bool_event) end # Synchronous detection if !detected_event && tr_nplus1 != nothing if (length(edge.transitions) == 1 && edge.transitions[1] == "ALL") || (tr_nplus1 in edge.transitions) - return (i, true) + ind_edge = i + bool_event = true end end end @@ -92,8 +98,8 @@ function _get_edge_index(edge_candidates::Vector{Edge}, end function next_state!(Snplus1::StateLHA, A::LHA, - xnplus1::Vector{Int}, tnplus1::Float64, tr_nplus1::Transition, - Sn::StateLHA; verbose::Bool = false) + xnplus1::Vector{Int}, tnplus1::Float64, tr_nplus1::Transition, + Sn::StateLHA; verbose::Bool = false) # En fait d'apres observation de Cosmos, après qu'on ait lu la transition on devrait stop. edge_candidates = Edge[] first_round::Bool = true diff --git a/core/model.jl b/core/model.jl index f4b9dd5..d99120e 100644 --- a/core/model.jl +++ b/core/model.jl @@ -341,7 +341,7 @@ end Distribute over workers the computation of the mean value of a LHA over `nbr_sim` simulations of the model. """ -function distribute_mean_value_lha(sm::SynchronizedModel, str_var::String, nbr_sim::Int) +function distribute_mean_value_lha(sm::SynchronizedModel, str_var::Union{String,Vector{String}}, nbr_sim::Int) sum_val = @distributed (+) for i = 1:nbr_sim volatile_simulate(sm)[str_var] end diff --git a/core/utils.jl b/core/utils.jl index 68c60b1..2656503 100644 --- a/core/utils.jl +++ b/core/utils.jl @@ -7,12 +7,15 @@ end function cosmos_get_values(name_file::String) output_file = open(name_file) - dict_values = Dict{String}{Float64}() + dict_values = Dict{String}{Vector{Float64}}() while !eof(output_file) line = readline(output_file) splitted_line = split(line, ':') - if (length(splitted_line) > 1) && tryparse(Float64, splitted_line[2]) !== nothing - dict_values[splitted_line[1]] = parse(Float64, splitted_line[2]) + if (length(splitted_line) > 1) && tryparse(Float64, splitted_line[2]) !== nothing + if !haskey(dict_values, splitted_line[1]) + dict_values[splitted_line[1]] = zeros(0) + end + push!(dict_values[splitted_line[1]], parse(Float64, splitted_line[2])) end end close(output_file) diff --git a/tests/cosmos/distance_F/ER_1D.jl b/tests/cosmos/distance_F/ER_1D.jl index 49b98c7..e95f0d0 100644 --- a/tests/cosmos/distance_F/ER_1D.jl +++ b/tests/cosmos/distance_F/ER_1D.jl @@ -45,9 +45,9 @@ for exp in l_exp #run(command) run(pipeline(command, stderr=devnull)) dict_values = cosmos_get_values("Result_dist_F_$(str_model).res") - l_dist_cosmos[i] = dict_values["Estimated value"] - nb_sim = dict_values["Total paths"] - nb_accepted = dict_values["Accepted paths"] + l_dist_cosmos[i] = dict_values["Estimated value"][1] + nb_sim = dict_values["Total paths"][1] + nb_accepted = dict_values["Accepted paths"][1] nb_sim = convert(Int, nb_sim) # MarkovProcesses estimation set_param!(ER, "k3", convert(Float64, k3)) @@ -56,7 +56,7 @@ for exp in l_exp nb_accepts_pkg = distribute_prob_accept_lha(sync_ER, nb_sim) #@info "About accepts" nb_sim nb_accepted nb_accepts_pkg test = isapprox(l_dist_cosmos[i], l_dist_pkg[i]; atol = width*1.01) || - (mat_dist_cosmos[i,j] == 9997999 && mat_dist_pkg[i,j] == Inf) + (l_dist_cosmos[i] == 9997999 && l_dist_pkg[i] == Inf) test2 = nb_accepts_pkg == (nb_sim / nb_accepted) global test_all = test_all && test && test2 if !test diff --git a/tests/cosmos/distance_F/dist_F_ER.lha b/tests/cosmos/distance_F/dist_F_ER.lha index ebc9518..ffd585e 100644 --- a/tests/cosmos/distance_F/dist_F_ER.lha +++ b/tests/cosmos/distance_F/dist_F_ER.lha @@ -26,10 +26,16 @@ Locations={ Edges={ ((l0,l1), #, t>=0, {n=P,test_abs=k_1*(E*S)+k_2*ES,d=9997999}); -((l1,l2),#, n>=x1 & n<=x2 & t>=t1 & t<=t2 ,{d=0}); -((l1,l2),#, t>=t2 , #); -((l1,l2),#, test_abs=0 , #); -((l1,l2),#, d=0 & t>=t1, #); +((l1,l2), #, t>=t1 & n>=x1 & n<=x2, {d=0}); +((l1,l2), #, t>=t1 & d=0, #); +((l1,l2), #, t>=t2 & n<=x1-1, {d=min(((n-x1)^2)^0.5,((n-x2)^2)^0.5)}); +((l1,l2), #, t>=t2 & n>=x2+1, {d=min(((n-x1)^2)^0.5,((n-x2)^2)^0.5)}); +((l1,l2), #, test_abs=0 & t<=t2, #); + +%((l1,l2),#, n>=x1 & n<=x2 & t>=t1 & t<=t2 ,{d=0}); +%((l1,l2),#, t>=t2 & d=9997999, {d=min(((n-x1)^2)^0.5,((n-x2)^2)^0.5)}); +%((l1,l2),#, d=0 & t>=t1, #); +%((l1,l2),#, test_abs=0 , #); ((l1,l3), #, n>=x1 & n<=x2, {d=0}); ((l1,l3), #, t<=t1 & n<=x1-1, {d=min(((t-t1)^2+(n-x2)^2)^0.5,((t-t1)^2+(n-x1)^2)^0.5)}); diff --git a/tests/cosmos/distance_G/ER_R5.jl b/tests/cosmos/distance_G/ER_R5.jl index dfcf423..db892d9 100644 --- a/tests/cosmos/distance_G/ER_R5.jl +++ b/tests/cosmos/distance_G/ER_R5.jl @@ -39,9 +39,9 @@ for i = 1:nb_k1 --verbose 0` run(pipeline(command, stderr=devnull)) dict_values = cosmos_get_values("Result_dist_G_$(str_model).res") - mat_dist_cosmos[i,j] = dict_values["Estimated value"] - nb_sim = dict_values["Total paths"] - nb_accepted = dict_values["Accepted paths"] + mat_dist_cosmos[i,j] = dict_values["Estimated value"][1] + nb_sim = dict_values["Total paths"][1] + nb_accepted = dict_values["Accepted paths"][1] nb_sim = convert(Int, nb_sim) # MarkovProcesses estimation set_param!(ER, "k1", convert(Float64, k1)) diff --git a/tests/cosmos/distance_G/dist_G_ER.lha b/tests/cosmos/distance_G/dist_G_ER.lha index 7b7e700..2ec3196 100644 --- a/tests/cosmos/distance_G/dist_G_ER.lha +++ b/tests/cosmos/distance_G/dist_G_ER.lha @@ -12,7 +12,6 @@ VariablesList = {t, tprime, d, n, in, test_abs}; LocationsList = {l0, l1, l2, l3, l4}; -AVG(Last(t)); AVG(Last(d)); InitialLocations={l0}; diff --git a/tests/cosmos/distance_G_F/ER_R6.jl b/tests/cosmos/distance_G_F/ER_R6.jl index 921a4c8..6dd069f 100644 --- a/tests/cosmos/distance_G_F/ER_R6.jl +++ b/tests/cosmos/distance_G_F/ER_R6.jl @@ -25,7 +25,9 @@ test_all = true nb_k1 = length(l_k1) nb_k2 = length(l_k2) mat_dist_cosmos = zeros(nb_k1,nb_k2) +mat_dist_prime_cosmos = zeros(nb_k1,nb_k2) mat_dist_pkg = zeros(nb_k1,nb_k2) +mat_dist_prime_pkg = zeros(nb_k1,nb_k2) mat_full_k1 = zeros(nb_k1,nb_k2) mat_full_k2 = zeros(nb_k1,nb_k2) for i = 1:nb_k1 @@ -40,23 +42,24 @@ for i = 1:nb_k1 --verbose 0` run(pipeline(command, stderr=devnull)) dict_values = cosmos_get_values("Result_dist_G_F_$(str_model).res") - mat_dist_cosmos[i,j] = dict_values["Estimated value"] - nb_sim = dict_values["Total paths"] - nb_accepted = dict_values["Accepted paths"] + mat_dist_cosmos[i,j] = dict_values["Estimated value"][1] + mat_dist_prime_cosmos[i,j] = dict_values["Estimated value"][2] + nb_sim = dict_values["Total paths"][1] + nb_accepted = dict_values["Accepted paths"][1] nb_sim = convert(Int, nb_sim) # MarkovProcesses estimation set_param!(ER, "k1", convert(Float64, k1)) set_param!(ER, "k2", convert(Float64, k2)) sync_ER = ER*A_G_F - mat_dist_pkg[i,j] = distribute_mean_value_lha(sync_ER, "d", nb_sim) + mat_dist_pkg[i,j], mat_dist_prime_pkg[i,j] = distribute_mean_value_lha(sync_ER, ["d","dprime"], nb_sim) nb_accepts_pkg = distribute_prob_accept_lha(sync_ER, nb_sim) - #@info "Computed distances" mat_dist_pkg[i,j] mat_dist_cosmos[i,j] + #@info "Computed distances" mat_dist_pkg[i,j] mat_dist_prime_pkg[i,j] mat_dist_cosmos[i,j] mat_dist_prime_cosmos[i,j] #@info "About accepts" nb_sim nb_accepted nb_accepts_pkg test = (isapprox(mat_dist_cosmos[i,j], mat_dist_pkg[i,j]; atol = width*1.01)) || (mat_dist_cosmos[i,j] == 9997999 && mat_dist_pkg[i,j] == Inf) test2 = nb_accepts_pkg == (nb_sim / nb_accepted) if !test - @info "Distances too different" (k1,k2) mat_dist_pkg[i,j] mat_dist_cosmos[i,j] + @info "Distances too different" (k1,k2) mat_dist_pkg[i,j] mat_dist_prime_pkg[i,j] mat_dist_cosmos[i,j] mat_dist_prime_cosmos[i,j] end if !test2 @info "Different proportion of accepted trajectories" nb_sim nb_accepted nb_accepts_pkg diff --git a/tests/cosmos/distance_G_F/dist_G_F_ER.lha b/tests/cosmos/distance_G_F/dist_G_F_ER.lha index 9dadbc4..36fa220 100644 --- a/tests/cosmos/distance_G_F/dist_G_F_ER.lha +++ b/tests/cosmos/distance_G_F/dist_G_F_ER.lha @@ -16,8 +16,8 @@ VariablesList = {t, tprime, d, dprime, n, in, test_abs}; LocationsList = {l0G, l1G, l2G, l3G, l4G, l1F, l2F, l3F}; -AVG(Last(t)); AVG(Last(d)); +AVG(Last(dprime)); InitialLocations={l0G}; FinalLocations={l2F}; @@ -65,10 +65,11 @@ Edges={ % From G to F automaton ((l2G,l1F), #, t>=0, {n=P,test_abs=k_1*(E*S)+k_2*ES,dprime=9997999}); -((l1F,l2F), #, n>=x3 & n<=x4 & t>=t3 & t<=t4, {dprime=0}); -((l1F,l2F), #, t>=t4, {d=d+dprime}); -((l1F,l2F), #, test_abs=0 , {d=d+dprime}); -((l1F,l2F), #, dprime=0 & t>=t3, #); +((l1F,l2F), #, t>=t3 & n>=x3 & n<=x4, {dprime=0}); +((l1F,l2F), #, t>=t3 & dprime=0, #); +((l1F,l2F), #, t>=t4 & n<=x3-1, {dprime=min(((n-x3)^2)^0.5,((n-x4)^2)^0.5),d=d+dprime}); +((l1F,l2F), #, t>=t4 & n>=x4+1, {dprime=min(((n-x3)^2)^0.5,((n-x4)^2)^0.5),d=d+dprime}); +((l1F,l2F), #, test_abs=0 & t<=t4, {d=d+dprime}); ((l1F,l3F), #, n>=x3 & n<=x4, {dprime=0}); ((l1F,l3F), #, t<=t3 & n<=x3-1, {dprime=min(((t-t3)^2+(n-x4)^2)^0.5,((t-t3)^2+(n-x3)^2)^0.5)}); -- GitLab