@@ -189,7 +189,7 @@ impl<N: HugrNode> SiblingSubgraph<N> {
189
189
. collect_vec ( ) ;
190
190
validate_subgraph ( hugr, & nodes, & inputs, & outputs) ?;
191
191
192
- if !subpg. is_convex_with_checker ( checker) {
192
+ if nodes . len ( ) > 1 && !subpg. is_convex_with_checker ( checker) {
193
193
return Err ( InvalidSubgraph :: NotConvex ) ;
194
194
}
195
195
@@ -238,12 +238,9 @@ impl<N: HugrNode> SiblingSubgraph<N> {
238
238
) -> Result < Self , InvalidSubgraph < N > > {
239
239
let nodes = nodes. into ( ) ;
240
240
241
- // If there's one or less nodes, we don't need to check convexity.
242
- match nodes. as_slice ( ) {
243
- [ ] => return Err ( InvalidSubgraph :: EmptySubgraph ) ,
244
- [ node] => return Ok ( Self :: from_node ( * node, hugr) ) ,
245
- _ => { }
246
- } ;
241
+ if nodes. is_empty ( ) {
242
+ return Err ( InvalidSubgraph :: EmptySubgraph ) ;
243
+ }
247
244
248
245
let nodes_set = nodes. iter ( ) . copied ( ) . collect :: < HashSet < _ > > ( ) ;
249
246
let incoming_edges = nodes
@@ -1239,4 +1236,37 @@ mod tests {
1239
1236
let rep = subg. create_simple_replacement ( & h, replacement) . unwrap ( ) ;
1240
1237
rep. apply ( & mut h) . unwrap ( ) ;
1241
1238
}
1239
+
1240
+ /// Test the behaviour of the sibling subgraph when built from a single node.
1241
+ #[ test]
1242
+ fn single_node_subgraph ( ) {
1243
+ // A hugr with a single NOT operation, with disconnected output.
1244
+ let mut b = DFGBuilder :: new (
1245
+ Signature :: new ( bool_t ( ) , type_row ! [ ] )
1246
+ . with_extension_delta ( crate :: std_extensions:: logic:: EXTENSION_ID ) ,
1247
+ )
1248
+ . unwrap ( ) ;
1249
+ let inw = b. input_wires ( ) . exactly_one ( ) . unwrap ( ) ;
1250
+ let not_n = b. add_dataflow_op ( LogicOp :: Not , [ inw] ) . unwrap ( ) ;
1251
+ // Unconnected output, discarded
1252
+ let h = b. finish_hugr_with_outputs ( [ ] ) . unwrap ( ) ;
1253
+
1254
+ // When built with `from_node`, the subgraph's signature is the same as the node's.
1255
+ // (bool input, bool output)
1256
+ let subg = SiblingSubgraph :: from_node ( not_n. node ( ) , & h) ;
1257
+ assert_eq ! ( subg. nodes( ) . len( ) , 1 ) ;
1258
+ assert_eq ! (
1259
+ subg. signature( & h) . io( ) ,
1260
+ Signature :: new( vec![ bool_t( ) ] , vec![ bool_t( ) ] ) . io( )
1261
+ ) ;
1262
+
1263
+ // `from_nodes` is different, is it only uses incoming and outgoing edges to compute the signature.
1264
+ // In this case, the output is disconnected, so it is not part of the subgraph signature.
1265
+ let subg = SiblingSubgraph :: try_from_nodes ( [ not_n. node ( ) ] , & h) . unwrap ( ) ;
1266
+ assert_eq ! ( subg. nodes( ) . len( ) , 1 ) ;
1267
+ assert_eq ! (
1268
+ subg. signature( & h) . io( ) ,
1269
+ Signature :: new( vec![ bool_t( ) ] , vec![ ] ) . io( )
1270
+ ) ;
1271
+ }
1242
1272
}
0 commit comments