@@ -219,7 +219,8 @@ for prop in [
219
219
:domain
220
220
:ivs
221
221
:dvs
222
- :connection_type
222
+ :connector_type
223
+ :connections
223
224
:preface
224
225
]
225
226
fname1 = Symbol (:get_ , prop)
@@ -282,7 +283,7 @@ function getvar(sys::AbstractSystem, name::Symbol; namespace=false)
282
283
elseif ! isempty (systems)
283
284
i = findfirst (x-> nameof (x)== name, systems)
284
285
if i != = nothing
285
- return namespace ? rename (systems[i], renamespace (sys, name) ) : systems[i]
286
+ return namespace ? renamespace (sys, systems[i] ) : systems[i]
286
287
end
287
288
end
288
289
@@ -355,6 +356,7 @@ GlobalScope(sym::Union{Num, Symbolic}) = setmetadata(sym, SymScope, GlobalScope(
355
356
356
357
renamespace (sys, eq:: Equation ) = namespace_equation (eq, sys)
357
358
359
+ renamespace (names:: AbstractVector , x) = foldr (renamespace, names, init= x)
358
360
function renamespace (sys, x)
359
361
x = unwrap (x)
360
362
if x isa Symbolic
@@ -367,6 +369,8 @@ function renamespace(sys, x)
367
369
x
368
370
end
369
371
end
372
+ elseif x isa AbstractSystem
373
+ rename (x, renamespace (sys, nameof (x)))
370
374
else
371
375
Symbol (getname (sys), :₊ , x)
372
376
end
@@ -562,7 +566,24 @@ function round_trip_expr(t, var2name)
562
566
args = map (Base. Fix2 (round_trip_expr, var2name), arguments (t))
563
567
return :($ f ($ (args... )))
564
568
end
565
- round_trip_eq (eq, var2name) = Expr (:call , :~ , round_trip_expr (eq. lhs, var2name), round_trip_expr (eq. rhs, var2name))
569
+
570
+ function round_trip_eq (eq:: Equation , var2name)
571
+ if eq. lhs isa Connection
572
+ syss = get_systems (eq. rhs)
573
+ call = Expr (:call , connect)
574
+ for sys in syss
575
+ strs = split (string (nameof (sys)), " ₊" )
576
+ s = Symbol (strs[1 ])
577
+ for st in strs[2 : end ]
578
+ s = Expr (:., s, Meta. quot (Symbol (st)))
579
+ end
580
+ push! (call. args, s)
581
+ end
582
+ call
583
+ else
584
+ Expr (:call , (~ ), round_trip_expr (eq. lhs, var2name), round_trip_expr (eq. rhs, var2name))
585
+ end
586
+ end
566
587
567
588
function push_eqs! (stmt, eqs, var2name)
568
589
eqs_name = gensym (:eqs )
@@ -854,6 +875,7 @@ topological sort of the observed equations. When `simplify=true`, the `simplify`
854
875
function will be applied during the tearing process.
855
876
"""
856
877
function structural_simplify (sys:: AbstractSystem ; simplify= false )
878
+ sys = expand_connections (sys)
857
879
sys = initialize_system_structure (alias_elimination (sys))
858
880
check_consistency (sys)
859
881
if sys isa ODESystem
@@ -905,71 +927,6 @@ function check_eqs_u0(eqs, dvs, u0; check_length=true, kwargs...)
905
927
return nothing
906
928
end
907
929
908
- # ##
909
- # ## Connectors
910
- # ##
911
-
912
- function with_connection_type (expr)
913
- @assert expr isa Expr && (expr. head == :function || (expr. head == :(= ) &&
914
- expr. args[1 ] isa Expr &&
915
- expr. args[1 ]. head == :call ))
916
-
917
- sig = expr. args[1 ]
918
- body = expr. args[2 ]
919
-
920
- fname = sig. args[1 ]
921
- args = sig. args[2 : end ]
922
-
923
- quote
924
- struct $ fname
925
- $ (gensym ()) -> 1 # this removes the default constructor
926
- end
927
- function $fname ($ (args... ))
928
- function f ()
929
- $ body
930
- end
931
- res = f ()
932
- $ isdefined (res, :connection_type ) ? $ Setfield. @set! (res. connection_type = $ fname) : res
933
- end
934
- end
935
- end
936
-
937
- macro connector (expr)
938
- esc (with_connection_type (expr))
939
- end
940
-
941
- promote_connect_rule (:: Type{T} , :: Type{S} ) where {T, S} = Union{}
942
- promote_connect_rule (:: Type{T} , :: Type{T} ) where {T} = T
943
- promote_connect_type (t1:: Type , t2:: Type , ts:: Type... ) = promote_connect_type (promote_connect_rule (t1, t2), ts... )
944
- @inline function promote_connect_type (:: Type{T} , :: Type{S} ) where {T,S}
945
- promote_connect_result (
946
- T,
947
- S,
948
- promote_connect_rule (T,S),
949
- promote_connect_rule (S,T)
950
- )
951
- end
952
-
953
- promote_connect_result (:: Type , :: Type , :: Type{T} , :: Type{Union{}} ) where {T} = T
954
- promote_connect_result (:: Type , :: Type , :: Type{Union{}} , :: Type{S} ) where {S} = S
955
- promote_connect_result (:: Type , :: Type , :: Type{T} , :: Type{T} ) where {T} = T
956
- function promote_connect_result (:: Type{T} , :: Type{S} , :: Type{P1} , :: Type{P2} ) where {T,S,P1,P2}
957
- throw (ArgumentError (" connection promotion for $T and $S resulted in $P1 and $P2 . " *
958
- " Define promotion only in one direction." ))
959
- end
960
-
961
- throw_connector_promotion (T, S) = throw (ArgumentError (" Don't know how to connect systems of type $S and $T " ))
962
- promote_connect_result (:: Type{T} ,:: Type{S} ,:: Type{Union{}} ,:: Type{Union{}} ) where {T,S} = throw_connector_promotion (T,S)
963
-
964
- promote_connect_type (:: Type{T} , :: Type{T} ) where {T} = T
965
- function promote_connect_type (T, S)
966
- error (" Don't know how to connect systems of type $S and $T " )
967
- end
968
-
969
- function connect (syss... )
970
- connect (promote_connect_type (map (get_connection_type, syss)... ), syss... )
971
- end
972
-
973
930
# ##
974
931
# ## Inheritance & composition
975
932
# ##
@@ -990,7 +947,7 @@ function Base.hash(sys::AbstractSystem, s::UInt)
990
947
end
991
948
992
949
"""
993
- $(TYPEDSIGNATURES)
950
+ $(TYPEDSIGNATURES)
994
951
995
952
entend the `basesys` with `sys`, the resulting system would inherit `sys`'s name
996
953
by default.
1026
983
Base.:(& )(sys:: AbstractSystem , basesys:: AbstractSystem ; name:: Symbol = nameof (sys)) = extend (sys, basesys; name= name)
1027
984
1028
985
"""
1029
- $(SIGNATURES)
986
+ $(SIGNATURES)
1030
987
1031
988
compose multiple systems together. The resulting system would inherit the first
1032
989
system's name.
0 commit comments