diff --git a/hugr-core/src/hugr/views/sibling_subgraph.rs b/hugr-core/src/hugr/views/sibling_subgraph.rs index 167d76419..2d4c2c2bf 100644 --- a/hugr-core/src/hugr/views/sibling_subgraph.rs +++ b/hugr-core/src/hugr/views/sibling_subgraph.rs @@ -211,7 +211,7 @@ impl SiblingSubgraph { /// The subgraph signature will be given by the types of the incoming and /// outgoing edges ordered by the node order in `nodes` and within each node /// by the port order. - + /// /// The in- and out-arity of the signature will match the /// number of incoming and outgoing edges respectively. In particular, the /// assumption is made that no two incoming edges have the same source @@ -238,6 +238,14 @@ impl SiblingSubgraph { checker: &impl ConvexChecker, ) -> Result { let nodes = nodes.into(); + + // If there's one or less nodes, we don't need to check convexity. + match nodes.as_slice() { + [] => return Err(InvalidSubgraph::EmptySubgraph), + [node] => return Ok(Self::from_node(*node, hugr)), + _ => {} + }; + let nodes_set = nodes.iter().copied().collect::>(); let incoming_edges = nodes .iter() @@ -265,6 +273,31 @@ impl SiblingSubgraph { Self::try_new_with_checker(inputs, outputs, hugr, checker) } + /// Create a subgraph containing a single node. + /// + /// The subgraph signature will be given by signature of the node. + pub fn from_node(node: Node, hugr: &impl HugrView) -> Self { + // TODO once https://github.com/CQCL/portgraph/issues/155 + // is fixed we can just call try_from_nodes here. + // Until then, doing this saves a lot of work. + let nodes = vec![node]; + let inputs = hugr + .node_inputs(node) + .filter(|&p| hugr.is_linked(node, p)) + .map(|p| vec![(node, p)]) + .collect_vec(); + let outputs = hugr + .node_outputs(node) + .filter_map(|p| hugr.is_linked(node, p).then_some((node, p))) + .collect_vec(); + + Self { + nodes, + inputs, + outputs, + } + } + /// An iterator over the nodes in the subgraph. pub fn nodes(&self) -> &[Node] { &self.nodes