Skip to content

Commit 8eebd40

Browse files
authored
Merge pull request #339 from JuliaReach/schillic/parametric
Remove type constraint from parametric systems
2 parents 3f14741 + 120b8ca commit 8eebd40

File tree

6 files changed

+254
-192
lines changed

6 files changed

+254
-192
lines changed

src/MathematicalSystems.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,11 @@ export ContinuousIdentitySystem,
9595
SecondOrderConstrainedLinearControlContinuousSystem,
9696
SecondOrderConstrainedAffineControlContinuousSystem,
9797
SecondOrderContinuousSystem,
98-
SecondOrderConstrainedContinuousSystem
98+
SecondOrderConstrainedContinuousSystem,
99+
LinearParametricContinuousSystem,
100+
LinearParametricDiscreteSystem,
101+
LinearControlParametricContinuousSystem,
102+
LinearControlParametricDiscreteSystem
99103

100104
#==================================
101105
Concrete Types for Discrete Systems

src/macros.jl

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ function _parse_system(exprs::NTuple{N,Expr}) where {N}
267267
noise_var = nothing
268268
dimension = nothing
269269
initial_state = nothing # for initial-value problems
270+
parametric = false
270271

271272
# main loop to parse the subexpressions in exprs
272273
for ex in exprs
@@ -315,6 +316,10 @@ function _parse_system(exprs::NTuple{N,Expr}) where {N}
315316
end
316317
initial_state = X0
317318

319+
elseif @capture(ex, A Set_) # COV_EXCL_LINE
320+
parametric = true
321+
push!(constraints, ex) # parse a constraint
322+
318323
elseif @capture(ex, state_ Set_) # COV_EXCL_LINE
319324
push!(constraints, ex) # parse a constraint
320325

@@ -361,7 +366,7 @@ function _parse_system(exprs::NTuple{N,Expr}) where {N}
361366
end
362367

363368
return dynamic_equation, AT, constraints,
364-
state_var, input_var, noise_var, dimension, initial_state
369+
state_var, input_var, noise_var, dimension, initial_state, parametric
365370
end
366371

367372
"""
@@ -676,7 +681,7 @@ end
676681
# Take the vectors of tuples providing the variable and fields names for the
677682
# lhs, the rhs and the sets, combine them, and return a vector of field names
678683
# and a vector of variable names.
679-
function constructor_input(lhs, rhs, set)
684+
function constructor_input(lhs, rhs, set, parametric)
680685
rhs_fields = [tuple[2] for tuple in rhs]
681686
lhs_fields = [tuple[2] for tuple in lhs]
682687
set_fields = [tuple[2] for tuple in set]
@@ -687,15 +692,40 @@ function constructor_input(lhs, rhs, set)
687692
set_var_names = [tuple[1] for tuple in set]
688693
field_names = (rhs_fields..., lhs_fields..., set_fields...)
689694
var_names = (rhs_var_names..., lhs_var_names..., set_var_names...)
695+
if parametric
696+
# strip off normal matrices from expressions (they are just variables)
697+
if length(field_names) == 2
698+
@assert field_names == (:A, :AS)
699+
field_names = (field_names[2],)
700+
@assert length(var_names) == 2
701+
@assert var_names == (:A, :AS)
702+
var_names = (var_names[2],)
703+
elseif length(field_names) == 4
704+
@assert field_names == (:A, :B, :AS, :BS)
705+
field_names = (field_names[3], field_names[4])
706+
@assert length(var_names) == 4
707+
@assert (var_names[3], var_names[4]) == (:AS, :BS)
708+
var_names = (var_names[3], var_names[4])
709+
else
710+
throw(ArgumentError("the entry $(field_names) does not match a " *
711+
"parametric `MathematicalSystems.jl` structure"))
712+
end
713+
end
690714
return field_names, var_names
691715
end
692716

693717
# extract the variable name and the field name for a set expression. The method
694718
# checks whether the set belongs to the `state`, `input` or `noise` and returns a
695719
# tuple of symbols where the field name is either `:X`, `:U` or `:W` and
696720
# the variable name is the value parsed as Set_
697-
function extract_set_parameter(expr, state, input, noise) # input => to check set definitions
698-
if @capture(expr, x_ Set_)
721+
function extract_set_parameter(expr, state, input, noise, parametric) # input => to check set definitions
722+
if parametric
723+
if @capture(expr, A Set_)
724+
return Set, :AS
725+
elseif @capture(expr, B Set_)
726+
return Set, :BS
727+
end
728+
elseif @capture(expr, x_ Set_)
699729
if x == state
700730
return Set, :X
701731
elseif x == input
@@ -766,11 +796,13 @@ function _sort(parameters::Vector{<:Tuple{Any,Symbol}}, order::NTuple{N,Symbol})
766796
return order_parameters
767797
end
768798

769-
function _get_system_type(dyn_eq, AT, constr, state, input, noise, dim)
799+
function _get_system_type(dyn_eq, AT, constr, state, input, noise, dim, parametric)
770800
lhs, rhs = extract_dyn_equation_parameters(dyn_eq, state, input, noise, dim, AT)
771-
ordered_rhs = _sort(rhs, (:A, :B, :c, :D, :f, :statedim, :inputdim, :noisedim))
772-
ordered_set = _sort(extract_set_parameter.(constr, state, input, noise), (:X, :U, :W))
773-
field_names, var_names = constructor_input(lhs, ordered_rhs, ordered_set)
801+
ordered_rhs = _sort(rhs, (:A, :B, :c, :D, :f, :statedim, :inputdim, :noisedim, :AS, :BS))
802+
extract_set_parameter.(constr, state, input, noise, parametric)
803+
ordered_set = _sort(extract_set_parameter.(constr, state, input, noise, parametric),
804+
(:X, :U, :W, :AS, :BS))
805+
field_names, var_names = constructor_input(lhs, ordered_rhs, ordered_set, parametric)
774806
sys_type = _corresponding_type(AT, field_names)
775807
return sys_type, var_names
776808
end
@@ -891,8 +923,9 @@ ConstrainedBlackBoxControlDiscreteSystem{typeof(f), BallInf{Float64, Vector{Floa
891923
"""
892924
macro system(expr...)
893925
try
894-
dyn_eq, AT, constr, state, input, noise, dim, x0 = _parse_system(expr)
895-
sys_type, var_names = _get_system_type(dyn_eq, AT, constr, state, input, noise, dim)
926+
dyn_eq, AT, constr, state, input, noise, dim, x0, parametric = _parse_system(expr)
927+
sys_type, var_names = _get_system_type(dyn_eq, AT, constr, state, input, noise, dim,
928+
parametric)
896929
sys = Expr(:call, :($sys_type), :($(var_names...)))
897930
if isnothing(x0)
898931
return esc(sys)
@@ -961,8 +994,9 @@ macro ivp(expr...)
961994
ivp = Expr(:call, InitialValueProblem, :($(expr[1])), :($x0))
962995
return esc(ivp)
963996
else
964-
dyn_eq, AT, constr, state, input, noise, dim, x0 = _parse_system(expr)
965-
sys_type, var_names = _get_system_type(dyn_eq, AT, constr, state, input, noise, dim)
997+
dyn_eq, AT, constr, state, input, noise, dim, x0, parametric = _parse_system(expr)
998+
sys_type, var_names = _get_system_type(dyn_eq, AT, constr, state, input, noise, dim,
999+
parametric)
9661000
sys = Expr(:call, :($sys_type), :($(var_names...)))
9671001
if isnothing(x0)
9681002
return throw(ArgumentError("an initial-value problem should define the " *

0 commit comments

Comments
 (0)