@@ -152,7 +152,7 @@ function Symbolics.connect(var1::ConnectableSymbolicT, var2::ConnectableSymbolic
152152        vars:: ConnectableSymbolicT... )
153153    allvars =  (var1, var2, vars... )
154154    validate_causal_variables_connection (allvars)
155-     return  Equation (Connection (), Connection (map (SymbolicWithNameof, allvars)))
155+     return  Equation (Connection (), Connection (map (SymbolicWithNameof, unwrap .( allvars) )))
156156end 
157157
158158function  flowvar (sys:: AbstractSystem )
@@ -328,14 +328,12 @@ namespaced by `namespace`.
328328  `ignored_connects[1]`, purely to avoid unnecessary recomputation. 
329329""" 
330330function  connection2set! (connectionsets, namespace, ss, isouter;
331-         ignored_connects  =  ( HierarchySystemT[], HierarchyVariableT[]), 
332-         namespaced_ignored_systems  =  ODESystem[] )
333-     ignored_systems, ignored_variables  =  ignored_connects 
331+         ignored_systems  =  HierarchySystemT[], ignored_variables  =   HierarchyVariableT[])
332+     ns_ignored_systems  =   from_hierarchy .(ignored_systems )
333+     ns_ignored_variables  =   from_hierarchy .(ignored_variables) 
334334    #  ignore specified systems
335335    ss =  filter (ss) do  s
336-         all (namespaced_ignored_systems) do  igsys
337-             nameof (igsys) !=  nameof (s)
338-         end 
336+         ! any (x ->  nameof (x) ==  nameof (s), ns_ignored_systems)
339337    end 
340338    #  `ignored_variables` for each `s` in `ss`
341339    corresponding_ignored_variables =  map (
@@ -434,15 +432,95 @@ function generate_connection_set(
434432    connectionsets =  ConnectionSet[]
435433    domain_csets =  ConnectionSet[]
436434    sys =  generate_connection_set! (
437-         connectionsets, domain_csets, sys, find, replace, scalarize, nothing ,
438-         #  include systems to be ignored
439-         ignored_connections (sys))
435+         connectionsets, domain_csets, sys, find, replace, scalarize, nothing , ignored_connections (sys))
440436    csets =  merge (connectionsets)
441437    domain_csets =  merge ([csets; domain_csets], true )
442438
443439    sys, (csets, domain_csets)
444440end 
445441
442+ """ 
443+     $(TYPEDSIGNATURES)  
444+ 
445+ For a list of `systems` in a connect equation, return the subset of it to ignore (as a 
446+ list of hierarchical systems) based on `ignored_system_aps`, the analysis points to be 
447+ ignored. All analysis points in `ignored_system_aps` must contain systems (connectors) 
448+ as their input/outputs. 
449+ """ 
450+ function  systems_to_ignore (ignored_system_aps:: Vector{HierarchyAnalysisPointT} ,
451+         systems:: Union{Vector{<:AbstractSystem}, Tuple{Vararg{<:AbstractSystem}}} )
452+     to_ignore =  HierarchySystemT[]
453+     for  ap in  ignored_system_aps
454+         #  if `systems` contains the input of the AP, ignore any outputs of the AP present in it.
455+         isys_hierarchy =  HierarchySystemT ([ap[1 ]. input; @view  ap[2 : end ]])
456+         isys =  from_hierarchy (isys_hierarchy)
457+         any (x ->  nameof (x) ==  nameof (isys), systems) ||  continue 
458+ 
459+         for  outsys in  ap[1 ]. outputs
460+             osys_hierarchy =  HierarchySystemT ([outsys; @view  ap[2 : end ]])
461+             osys =  from_hierarchy (osys_hierarchy)
462+             any (x ->  nameof (x) ==  nameof (osys), systems) ||  continue 
463+             push! (to_ignore, HierarchySystemT (osys_hierarchy))
464+         end 
465+     end 
466+ 
467+     return  to_ignore
468+ end 
469+ 
470+ """ 
471+     $(TYPEDSIGNATURES)  
472+ 
473+ For a list of `systems` in a connect equation, return the subset of their variables to 
474+ ignore (as a list of hierarchical variables) based on `ignored_system_aps`, the analysis 
475+ points to be ignored. All analysis points in `ignored_system_aps` must contain variables 
476+ as their input/outputs. 
477+ """ 
478+ function  variables_to_ignore (ignored_variable_aps:: Vector{HierarchyAnalysisPointT} ,
479+         systems:: Union{Vector{<:AbstractSystem}, Tuple{Vararg{<:AbstractSystem}}} )
480+     to_ignore =  HierarchyVariableT[]
481+     for  ap in  ignored_variable_aps
482+         ivar_hierarchy =  HierarchyVariableT ([ap[1 ]. input; @view  ap[2 : end ]])
483+         ivar =  from_hierarchy (ivar_hierarchy)
484+         any (x ->  any (isequal (ivar), renamespace .((x,), unknowns (x))), systems) ||  continue 
485+ 
486+         for  outvar in  ap[1 ]. outputs
487+             ovar_hierarchy =  HierarchyVariableT ([as_hierarchy (outvar); @view  ap[2 : end ]])
488+             ovar =  from_hierarchy (ovar_hierarchy)
489+             any (x ->  any (isequal (ovar), renamespace .((x,), unknowns (x))), systems) || 
490+                 continue 
491+             push! (to_ignore, HierarchyVariableT (ovar_hierarchy))
492+         end 
493+     end 
494+     return  to_ignore
495+ end 
496+ 
497+ """ 
498+     $(TYPEDSIGNATURES)  
499+ 
500+ For a list of variables `vars` in a connect equation, return the subset of them ignore 
501+ (as a list of symbolic variables) based on `ignored_system_aps`, the analysis points to 
502+ be ignored. All analysis points in `ignored_system_aps` must contain variables as their 
503+ input/outputs. 
504+ """ 
505+ function  variables_to_ignore (ignored_variable_aps:: Vector{HierarchyAnalysisPointT} ,
506+         vars:: Union{Vector{<:BasicSymbolic}, Tuple{Vararg{<:BasicSymbolic}}} )
507+     to_ignore =  eltype (vars)[]
508+     for  ap in  ignored_variable_aps
509+         ivar_hierarchy =  HierarchyVariableT ([ap[1 ]. input; @view  ap[2 : end ]])
510+         ivar =  from_hierarchy (ivar_hierarchy)
511+         any (isequal (ivar), vars) ||  continue 
512+ 
513+         for  outvar in  ap[1 ]. outputs
514+             ovar_hierarchy =  HierarchyVariableT ([outvar; @view  ap[2 : end ]])
515+             ovar =  from_hierarchy (ovar_hierarchy)
516+             any (isequal (ovar), vars) ||  continue 
517+             push! (to_ignore, ovar)
518+         end 
519+     end 
520+ 
521+     return  to_ignore
522+ end 
523+ 
446524""" 
447525    $(TYPEDSIGNATURES)  
448526
@@ -456,26 +534,12 @@ Generate connection sets from `connect` equations.
456534- `sys` is the system whose equations are to be searched. 
457535- `namespace` is a system representing the namespace in which `sys` exists, or `nothing` 
458536  for no namespace (if `sys` is top-level). 
459- - `ignored_connects` is a tuple. The first (second) element is a list of systems 
460-   (variables) in the format returned by `as_hierarchy` to be ignored when generating 
461-   connections. This is typically because the connections they are used in were removed by 
462-   analysis point transformations. 
463537""" 
464538function  generate_connection_set! (connectionsets, domain_csets,
465539        sys:: AbstractSystem , find, replace, scalarize, namespace =  nothing ,
466-         ignored_connects =  (HierarchySystemT [], HierarchyVariableT []))
540+         ignored_connects =  (HierarchyAnalysisPointT [], HierarchyAnalysisPointT []))
467541    subsys =  get_systems (sys)
468-     ignored_systems, ignored_variables =  ignored_connects
469-     #  turn hierarchies into namespaced systems
470-     namespaced_ignored_systems =  from_hierarchy .(ignored_systems)
471-     namespaced_ignored_variables =  from_hierarchy .(ignored_variables)
472-     namespaced_ignored =  (namespaced_ignored_systems, namespaced_ignored_variables)
473-     #  filter the subsystems of `sys` to exclude ignored ones
474-     filtered_subsys =  filter (subsys) do  ss
475-         all (namespaced_ignored_systems) do  igsys
476-             nameof (igsys) !=  nameof (ss)
477-         end 
478-     end 
542+     ignored_system_aps, ignored_variable_aps =  ignored_connects
479543
480544    isouter =  generate_isouter (sys)
481545    eqs′ =  get_eqs (sys)
@@ -501,8 +565,12 @@ function generate_connection_set!(connectionsets, domain_csets,
501565            neweq isa  AbstractArray ?  append! (eqs, neweq) :  push! (eqs, neweq)
502566        else 
503567            if  lhs isa  Connection &&  get_systems (lhs) ===  :domain 
504-                 connection2set! (domain_csets, namespace, get_systems (rhs), isouter;
505-                     ignored_connects, namespaced_ignored_systems)
568+                 connected_systems =  get_systems (rhs)
569+                 connection2set! (domain_csets, namespace, connected_systems, isouter;
570+                     ignored_systems =  systems_to_ignore (
571+                         ignored_system_aps, connected_systems),
572+                     ignored_variables =  variables_to_ignore (
573+                         ignored_variable_aps, connected_systems))
506574            elseif  isconnection (rhs)
507575                push! (cts, get_systems (rhs))
508576            else 
@@ -519,22 +587,19 @@ function generate_connection_set!(connectionsets, domain_csets,
519587    #  all connectors are eventually inside connectors.
520588    T =  ConnectionElement
521589    #  only generate connection sets for systems that are not ignored
522-     for  s in  filtered_subsys 
590+     for  s in  subsys 
523591        isconnector (s) ||  continue 
524592        is_domain_connector (s) &&  continue 
525-         _ignored_variables =  ignored_systems_for_subsystem (s, ignored_variables)
526-         _namespaced_ignored_variables =  from_hierarchy .(_ignored_variables)
527593        for  v in  unknowns (s)
528594            Flow ===  get_connection_type (v) ||  continue 
529-             #  ignore specified variables
530-             any (isequal (v), _namespaced_ignored_variables) &&  continue 
531595            push! (connectionsets, ConnectionSet ([T (LazyNamespace (namespace, s), v, false )]))
532596        end 
533597    end 
534598
535599    for  ct in  cts
536600        connection2set! (connectionsets, namespace, ct, isouter;
537-             ignored_connects, namespaced_ignored_systems)
601+             ignored_systems =  systems_to_ignore (ignored_system_aps, ct),
602+             ignored_variables =  variables_to_ignore (ignored_variable_aps, ct))
538603    end 
539604
540605    #  pre order traversal
@@ -558,14 +623,15 @@ ignored by `generate_connection_set!` (`expand_variable_connections`), filter
558623their hierarchy to not include `subsys`. 
559624""" 
560625function  ignored_systems_for_subsystem (
561-         subsys:: AbstractSystem , ignored_systems:: Vector{<:HierarchyT} )
626+         subsys:: AbstractSystem , ignored_systems:: Vector {<: Union {
627+             HierarchyT, HierarchyAnalysisPointT}})
562628    result =  eltype (ignored_systems)[]
563629    #  in case `subsys` is namespaced, get its hierarchy and compare suffixes
564630    #  instead of the just the last element
565631    suffix =  reverse! (namespace_hierarchy (nameof (subsys)))
566632    N =  length (suffix)
567633    for  igsys in  ignored_systems
568-         if  igsys[(end  -  N +  1 ): end ] ==  suffix
634+         if  length (igsys)  >  N  &&   igsys[(end  -  N +  1 ): end ] ==  suffix
569635            push! (result, copy (igsys))
570636            for  i in  1 : N
571637                pop! (result[end ])
@@ -684,7 +750,6 @@ function expand_variable_connections(sys::AbstractSystem; ignored_variables = no
684750    if  ignored_variables ===  nothing 
685751        ignored_variables =  ignored_connections (sys)[2 ]
686752    end 
687-     namespaced_ignored =  from_hierarchy .(ignored_variables)
688753    eqs =  copy (get_eqs (sys))
689754    valid_idxs =  trues (length (eqs))
690755    additional_eqs =  Equation[]
@@ -694,14 +759,11 @@ function expand_variable_connections(sys::AbstractSystem; ignored_variables = no
694759        connection =  eq. rhs
695760        elements =  get_systems (connection)
696761        is_causal_variable_connection (connection) ||  continue 
697-         elements =  filter (elements) do  el
698-             all (namespaced_ignored) do  var
699-                 getname (var) !=  getname (el. var)
700-             end 
701-         end 
702762
703763        valid_idxs[i] =  false 
704764        elements =  map (x ->  x. var, elements)
765+         to_ignore =  variables_to_ignore (ignored_variables, elements)
766+         elements =  setdiff (elements, to_ignore)
705767        outvar =  first (elements)
706768        for  invar in  Iterators. drop (elements, 1 )
707769            push! (additional_eqs, outvar ~  invar)
0 commit comments