@@ -7,7 +7,7 @@ use crate::hugr::hugrmut::InsertionResult;
7
7
use crate :: hugr:: views:: SiblingSubgraph ;
8
8
use crate :: hugr:: { HugrMut , HugrView } ;
9
9
use crate :: ops:: { OpTag , OpTrait , OpType } ;
10
- use crate :: { Hugr , IncomingPort , Node , OutgoingPort , Port } ;
10
+ use crate :: { Direction , Hugr , IncomingPort , Node , OutgoingPort , Port } ;
11
11
12
12
use derive_more:: derive:: From ;
13
13
use itertools:: { Either , Itertools } ;
@@ -93,6 +93,22 @@ impl<N: HugrNode> OutputBoundaryMap<N> {
93
93
. into_iter ( )
94
94
}
95
95
96
+ /// The keys of the map.
97
+ ///
98
+ /// These will be either outgoing or incoming ports, depending on the
99
+ /// variant of `self`.
100
+ pub fn keys ( & self ) -> impl Iterator < Item = ( N , Port ) > + ' _ {
101
+ match self {
102
+ OutputBoundaryMap :: ByIncoming ( map) => {
103
+ Either :: Left ( map. keys ( ) . map ( |& ( node, port) | ( node, port. into ( ) ) ) )
104
+ }
105
+ OutputBoundaryMap :: ByOutgoing ( map) => {
106
+ Either :: Right ( map. keys ( ) . map ( |& ( node, port) | ( node, port. into ( ) ) ) )
107
+ }
108
+ }
109
+ . into_iter ( )
110
+ }
111
+
96
112
/// Iterate over the boundary map with keys resolved as incoming ports.
97
113
///
98
114
/// By providing the host HUGR `host`, all ports in the keys are resolved
@@ -308,6 +324,14 @@ impl<HostNode: HugrNode> SimpleReplacement<HostNode> {
308
324
)
309
325
}
310
326
327
+ /// Get the direction of the ports in the outgoing boundary.
328
+ pub fn outgoing_boundary_type ( & self ) -> Direction {
329
+ match & self . nu_out {
330
+ OutputBoundaryMap :: ByIncoming ( _) => Direction :: Incoming ,
331
+ OutputBoundaryMap :: ByOutgoing ( _) => Direction :: Outgoing ,
332
+ }
333
+ }
334
+
311
335
/// Get all edges that the replacement would add between ports in `host`.
312
336
///
313
337
/// These correspond to direct edges between the input and output nodes
@@ -364,6 +388,44 @@ impl<HostNode: HugrNode> SimpleReplacement<HostNode> {
364
388
. map ( |rep_out_port| ReplacementPort ( rep_output, rep_out_port) )
365
389
}
366
390
391
+ /// Get the incoming ports connected to the input node of `self.replacement`
392
+ /// that corresponds to the given host input port.
393
+ ///
394
+ /// This is the inverse of [`Self::map_replacement_input`]. Beware that it
395
+ /// is slightly inefficient as it iterates over all host input ports to find
396
+ /// matching `replacement` ports.
397
+ ///
398
+ /// This panics if self.replacement is not a DFG.
399
+ pub fn map_host_input (
400
+ & self ,
401
+ port : impl Into < HostPort < HostNode , IncomingPort > > ,
402
+ ) -> impl Iterator < Item = ReplacementPort < IncomingPort > > + ' _ {
403
+ let host_port = port. into ( ) ;
404
+ let all_repl_node_port = self . nu_inp . keys ( ) . copied ( ) ;
405
+ all_repl_node_port
406
+ . map_into ( )
407
+ . filter ( move |& repl_port| self . map_replacement_input ( repl_port) == Some ( host_port) )
408
+ }
409
+
410
+ /// Get the incoming ports in `subgraph` that corresponds to the given
411
+ /// replacement output port.
412
+ ///
413
+ /// This is the inverse of [`Self::map_host_output`]. Beware that it is
414
+ /// slightly inefficient as it iterates over all replacement output ports
415
+ /// to find matching `subgraph` ports.
416
+ ///
417
+ /// This panics if self.replacement is not a DFG.
418
+ pub fn map_replacement_output (
419
+ & self ,
420
+ port : impl Into < ReplacementPort < IncomingPort > > ,
421
+ ) -> impl Iterator < Item = HostPort < HostNode , Port > > + ' _ {
422
+ let repl_port = port. into ( ) ;
423
+ let all_host_node_port = self . nu_out . keys ( ) ;
424
+ all_host_node_port
425
+ . map_into ( )
426
+ . filter ( move |& host_port| self . map_host_output ( host_port) == Some ( repl_port) )
427
+ }
428
+
367
429
/// Get the incoming port in `subgraph` that corresponds to the given
368
430
/// replacement input port.
369
431
///
0 commit comments