diff --git a/REQUIRE b/REQUIRE index 9b6c163..b921bdd 100644 --- a/REQUIRE +++ b/REQUIRE @@ -6,4 +6,5 @@ SymEngine DataStructures Reexport FillArrays -LazySets +LazySets 1.5.3 +Compat diff --git a/src/SX.jl b/src/SX.jl index 2c9fb3c..68ba019 100644 --- a/src/SX.jl +++ b/src/SX.jl @@ -2,6 +2,11 @@ __precompile__(true) module SX +#========================================= +Compatibility for previous Julia versions +=========================================# +include("compat.jl") + import DataStructures, FillArrays using EzXML, Reexport @reexport using HybridSystems, MathematicalSystems, SymEngine diff --git a/src/compat.jl b/src/compat.jl new file mode 100644 index 0000000..55b43d1 --- /dev/null +++ b/src/compat.jl @@ -0,0 +1,10 @@ +using Compat +using Compat: @warn + +@static if VERSION >= v"0.7" + const _parse_s = Base.Meta.parse + const _parse_t = Base.parse +else + const _parse_s = parse + const _parse_t = parse +end diff --git a/src/convert.jl b/src/convert.jl index 65084aa..1da8f0e 100644 --- a/src/convert.jl +++ b/src/convert.jl @@ -143,7 +143,7 @@ function is_hyperplane(expr::Expr)::Bool # convert to symengine expressions lhs = convert(Basic, expr.args[1]) - if :args in fieldnames(expr.args[2]) + if :args in fieldnames(typeof(expr.args[2])) # treats the 4 in :(2*x1 = 4) rhs = convert(Basic, expr.args[2].args[2]) else @@ -276,7 +276,7 @@ function convert(::Type{LazySets.Hyperplane{N}}, expr::Expr; vars::Vector{SymEng lhs = convert(Basic, expr.args[1]) # treats the 4 in :(2*x1 = 4) - rhs = :args in fieldnames(expr.args[2]) ? convert(Basic, expr.args[2].args[2]) : convert(Basic, expr.args[2]) + rhs = :args in fieldnames(typeof(expr.args[2])) ? convert(Basic, expr.args[2].args[2]) : convert(Basic, expr.args[2]) # a1 x1 + ... + an xn + K = 0 eq = lhs - rhs @@ -336,7 +336,7 @@ function free_symbols(expr::Expr, set_type::Type{<:LazySets.Hyperplane}) lhs = convert(Basic, expr.args[1]) # treats the 4 in :(2*x1 = 4) - rhs = :args in fieldnames(expr.args[2]) ? convert(Basic, expr.args[2].args[2]) : convert(Basic, expr.args[2]) + rhs = :args in fieldnames(typeof(expr.args[2])) ? convert(Basic, expr.args[2].args[2]) : convert(Basic, expr.args[2]) return free_symbols(lhs - rhs) end diff --git a/src/io.jl b/src/io.jl index 1ae518e..a19f58a 100644 --- a/src/io.jl +++ b/src/io.jl @@ -102,19 +102,19 @@ function readsxmodel(file; raw_dict=false, transitionlabels = Set{String}() # vector with the invariants for each location - invariants = Vector{Vector{Expr}}(nlocations) + invariants = Vector{Vector{Expr}}(undef, nlocations) # vector with the ODE flow for each location - flows = Vector{Vector{Expr}}(nlocations) + flows = Vector{Vector{Expr}}(undef, nlocations) # assignments for each transition - assignments = Vector{Vector{Expr}}(ntransitions) + assignments = Vector{Vector{Expr}}(undef, ntransitions) # guards for each transition; subsets of state space where the state needs # to be to make the transition - guards = Vector{Vector{Expr}}(ntransitions) + guards = Vector{Vector{Expr}}(undef, ntransitions) - switchings = Vector{AbstractSwitching}(ntransitions) + switchings = Vector{AbstractSwitching}(undef, ntransitions) HDict = Dict("automaton"=>automaton, "variables"=>variables, diff --git a/src/parse.jl b/src/parse.jl index d8a431a..5abac40 100644 --- a/src/parse.jl +++ b/src/parse.jl @@ -135,11 +135,11 @@ function parse_sxmath(s; assignment=false) count_right_parentheses = s -> count(c -> c == ')', collect(s)) @assert count_left_parentheses(s) == count_right_parentheses(s) "the expression $(s) is not well formed" - expr = strip.(split(replace(s, "&&", "&"), "&")) + expr = strip.(split(replace(s, "&&" => "&"), "&")) if assignment - expr = replace.(expr, ":=", "=") + expr = replace.(expr, Ref(":=" => "=")) end - expr = replace.(expr, "==", "=") + expr = replace.(expr, Ref("==" => "=")) # remove irrelevant parentheses from the beginning and the end for (i, expri) in enumerate(expr) @@ -156,7 +156,7 @@ function parse_sxmath(s; assignment=false) end end - return parse.(expr) + return _parse_s.(expr) end """ @@ -248,9 +248,9 @@ function add_variable!(variables, field, id=1) # d1 and d2 are the dimensions (d1=d2=1 for scalars) @assert field["d1"] == "1" && field["d2"] == "1" - varname = parse(field["name"]) - islocal = haskey(field, "local") ? parse(field["local"]) : false - iscontrolled = haskey(field, "controlled") ? parse(field["controlled"]) : true + varname = _parse_s(field["name"]) + islocal = haskey(field, "local") ? _parse_s(field["local"]) : false + iscontrolled = haskey(field, "controlled") ? _parse_s(field["controlled"]) : true dynamicstype = haskey(field, "dynamics") ? field["dynamics"] : "any" variables[varname] = Dict("local"=>islocal, @@ -293,7 +293,7 @@ and similarly `f` is the list of ODEs that define the flow for this location. Both objects are vectors of symbolic expressions `Expr`. """ function parse_location(field) - id = parse(Int, field["id"]) + id = _parse_t(Int, field["id"]) local I, f for element in eachelement(field) if nodename(element) == "invariant" @@ -301,7 +301,7 @@ function parse_location(field) elseif nodename(element) == "flow" f = parse_sxmath(nodecontent(element)) else - warn("field $(nodename(element)) in location $(field["id"]) is ignored") + @warn("field $(nodename(element)) in location $(field["id"]) is ignored") end end return (id, I, f) @@ -330,7 +330,7 @@ the "assignment", or both); in that case this function returns an empty of expressions for those cases. """ function parse_transition(field) - q, r = parse(Int, field["source"]), parse(Int, field["target"]) + q, r = _parse_t(Int, field["source"]), _parse_t(Int, field["target"]) G = Vector{Expr}() A = Vector{Expr}() for element in eachelement(field) @@ -339,7 +339,7 @@ function parse_transition(field) elseif nodename(element) == "assignment" A = parse_sxmath(nodecontent(element), assignment=true) else - warn("field $(nodename(element)) in transition $(field["source"]) → $(field["target"]) is ignored") + @warn("field $(nodename(element)) in transition $(field["source"]) → $(field["target"]) is ignored") end end return (q, r, G, A) diff --git a/src/symbolic.jl b/src/symbolic.jl index d83c9ca..e93ef96 100644 --- a/src/symbolic.jl +++ b/src/symbolic.jl @@ -60,7 +60,7 @@ function linearHS(HDict; ST=ConstrainedLinearControlContinuousSystem, nlocations, ntransitions = HDict["nlocations"], HDict["ntransitions"] # vector of modes (flows, invariants) - modes = Vector{ST}(nlocations) + modes = Vector{ST}(undef, nlocations) for id_location in eachindex(flows) @@ -79,10 +79,10 @@ function linearHS(HDict; ST=ConstrainedLinearControlContinuousSystem, local_state_variables = convert.(Basic, [fi.args[1].args[1] for fi in flows[id_location]]) # dynamics matrix - A = Matrix{N}(n, n) + A = Matrix{N}(undef, n, n) # forcing terms - B = Matrix{N}(n, m) + B = Matrix{N}(undef, n, m) C = zeros(N, n) # constant terms # track if there are constant terms @@ -153,7 +153,7 @@ function linearHS(HDict; ST=ConstrainedLinearControlContinuousSystem, end # reset maps (assignments, guards) for each transition (equations) - resetmaps = Vector{STD}(ntransitions) + resetmaps = Vector{STD}(undef, ntransitions) for id_transition in eachindex(assignments) @@ -172,10 +172,10 @@ function linearHS(HDict; ST=ConstrainedLinearControlContinuousSystem, local_state_variables = convert.(Basic, [ai.args[1].args[1] for ai in assignments[id_transition]]) # dynamics matrix - Ar = Matrix{N}(n, n) + Ar = Matrix{N}(undef, n, n) # forcing terms - Br = Matrix{N}(n, m) + Br = Matrix{N}(undef, n, m) Cr = zeros(N, n) # constant terms # track if there are constant terms diff --git a/test/REQUIRE b/test/REQUIRE new file mode 100644 index 0000000..137767a --- /dev/null +++ b/test/REQUIRE @@ -0,0 +1 @@ +julia 0.6 diff --git a/test/runtests.jl b/test/runtests.jl index 23ec016..8d92a7c 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,5 +1,5 @@ using SX -using Base.Test +using Compat, Compat.Test include("unit_examples.jl") include("unit_parse.jl")