@@ -473,12 +473,6 @@ impl PersistentHugr {
473
473
loop {
474
474
let commit_id = out_node. 0 ;
475
475
476
- let is_input = || {
477
- let Some ( repl) = self . replacement ( commit_id) else {
478
- return false ;
479
- } ;
480
- repl. get_replacement_io ( ) [ 0 ] == out_node. 1
481
- } ;
482
476
if let Some ( deleted_by) = self . find_deleting_commit ( out_node) {
483
477
( out_node, out_port) = self
484
478
. state_space
@@ -494,7 +488,10 @@ impl PersistentHugr {
494
488
} )
495
489
. expect ( "out_node is connected to output node (which is never deleted)" )
496
490
} ;
497
- } else if is_input ( ) {
491
+ } else if self
492
+ . replacement ( commit_id)
493
+ . is_some_and ( |repl| repl. get_replacement_io ( ) [ 0 ] == out_node. 1 )
494
+ {
498
495
// out_node is an input node
499
496
( out_node, out_port) = self
500
497
. as_state_space ( )
@@ -562,22 +559,22 @@ impl PersistentHugr {
562
559
// linked port in a parent commit), or
563
560
// (ii) they are deleted by a child commit and is not the same as the out_node
564
561
// (then there will be a linked port in a child commit)
565
- let ( is_linked_to_output, deleted_by_child) : ( IteratorNonEmpty , BTreeSet < _ > ) = hugr
562
+ let is_linked_to_output = curr_repl_out. is_some_and ( |curr_repl_out| {
563
+ hugr. linked_inputs ( out_node. 1 , out_port)
564
+ . any ( |( in_node, _) | in_node == curr_repl_out)
565
+ } ) ;
566
+
567
+ let deleted_by_child: BTreeSet < _ > = hugr
566
568
. linked_inputs ( out_node. 1 , out_port)
569
+ . filter ( |( in_node, _) | Some ( in_node) != curr_repl_out. as_ref ( ) )
567
570
. filter_map ( |( in_node, _) | {
568
- if Some ( in_node) == curr_repl_out {
569
- // Flag that we have found a link to output
570
- Some ( Either :: Left ( ( ) ) )
571
- } else {
572
- let other_deleted_by =
573
- self . find_deleting_commit ( PatchNode ( commit_id, in_node) ) ?;
574
- // (out_node, out_port) -> (in_node, in_port) is a boundary edge
575
- // into the child commit `other_deleted_by`
576
- ( Some ( other_deleted_by) != out_deleted_by)
577
- . then_some ( Either :: Right ( other_deleted_by) )
578
- }
571
+ self . find_deleting_commit ( PatchNode ( commit_id, in_node) )
572
+ . filter ( |other_deleted_by|
573
+ // (out_node, out_port) -> (in_node, in_port) is a boundary edge
574
+ // into the child commit `other_deleted_by`
575
+ ( Some ( other_deleted_by) != out_deleted_by. as_ref ( ) ) )
579
576
} )
580
- . partition_map ( |x| x ) ;
577
+ . collect ( ) ;
581
578
582
579
// Convert an incoming port to the unique outgoing port that it is linked to
583
580
let to_outgoing_port = |( PatchNode ( commit_id, in_node) , in_port) | {
@@ -588,7 +585,7 @@ impl PersistentHugr {
588
585
( PatchNode ( commit_id, out_node) , out_port)
589
586
} ;
590
587
591
- if is_linked_to_output. 0 {
588
+ if is_linked_to_output {
592
589
// Traverse boundary to parent(s)
593
590
let new_ins = self
594
591
. as_state_space ( )
@@ -752,34 +749,5 @@ fn find_conflicting_node<'a>(
752
749
} )
753
750
}
754
751
755
- /// A wrapper around a boolean that implements `Extend<V>`. The boolean
756
- /// is true if a non-empty iterator was appended to `self`.
757
- #[ derive( Debug , Copy , Clone , Default ) ]
758
- struct IteratorNonEmpty ( bool ) ;
759
-
760
- impl < V > Extend < V > for IteratorNonEmpty {
761
- fn extend < T : IntoIterator < Item = V > > ( & mut self , iter : T ) {
762
- self . 0 |= iter. into_iter ( ) . next ( ) . is_some ( ) ;
763
- }
764
- }
765
-
766
752
#[ cfg( test) ]
767
753
mod tests;
768
-
769
- #[ cfg( test) ]
770
- mod test_iterator_non_empty {
771
- use super :: IteratorNonEmpty ;
772
-
773
- use rstest:: rstest;
774
-
775
- #[ rstest]
776
- #[ case( vec![ ] ) ]
777
- #[ case( vec![ 1 ] ) ]
778
- #[ case( vec![ 1 , 2 , 3 ] ) ]
779
- fn test_extend ( #[ case] input : Vec < i32 > ) {
780
- let expected = !input. is_empty ( ) ;
781
- let mut res = IteratorNonEmpty :: default ( ) ;
782
- res. extend ( input) ;
783
- assert_eq ! ( res. 0 , expected) ;
784
- }
785
- }
0 commit comments