Skip to content

Commit f1825d6

Browse files
authored
feat!: Add insert_region to HugrMut (#2463)
Required for #2462, as we will no longer be able to insert a conditional using `insert_hugr`. BREAKING CHANGE: Added new `insert_region` method to `HugrMut`
1 parent 1e5265b commit f1825d6

File tree

4 files changed

+70
-19
lines changed

4 files changed

+70
-19
lines changed

hugr-core/src/builder/build_traits.rs

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,20 @@ pub trait Container {
8282
self.add_child_node(constant.into()).into()
8383
}
8484

85-
/// Insert a HUGR as a child of the container.
85+
/// Insert a HUGR's entrypoint region as a child of the container.
86+
///
87+
/// To insert an arbitrary region of a HUGR, use [`Container::add_hugr_region`].
8688
fn add_hugr(&mut self, child: Hugr) -> InsertionResult {
89+
let region = child.entrypoint();
90+
self.add_hugr_region(child, region)
91+
}
92+
93+
/// Insert a HUGR region as a child of the container.
94+
///
95+
/// To insert the entrypoint region of a HUGR, use [`Container::add_hugr`].
96+
fn add_hugr_region(&mut self, child: Hugr, region: Node) -> InsertionResult {
8797
let parent = self.container_node();
88-
self.hugr_mut().insert_hugr(parent, child)
98+
self.hugr_mut().insert_region(parent, child, region)
8999
}
90100

91101
/// Insert a copy of a HUGR as a child of the container.
@@ -200,6 +210,10 @@ pub trait Dataflow: Container {
200210
/// Insert a hugr-defined op to the sibling graph, wiring up the
201211
/// `input_wires` to the incoming ports of the resulting root node.
202212
///
213+
/// Inserts everything from the entrypoint region of the HUGR.
214+
/// See [`Dataflow::add_hugr_region_with_wires`] for a generic version that allows
215+
/// inserting a region other than the entrypoint.
216+
///
203217
/// # Errors
204218
///
205219
/// This function will return an error if there is an error when adding the
@@ -209,9 +223,29 @@ pub trait Dataflow: Container {
209223
hugr: Hugr,
210224
input_wires: impl IntoIterator<Item = Wire>,
211225
) -> Result<BuildHandle<DataflowOpID>, BuildError> {
212-
let optype = hugr.get_optype(hugr.entrypoint()).clone();
226+
let region = hugr.entrypoint();
227+
self.add_hugr_region_with_wires(hugr, region, input_wires)
228+
}
229+
230+
/// Insert a hugr-defined op to the sibling graph, wiring up the
231+
/// `input_wires` to the incoming ports of the resulting root node.
232+
///
233+
/// `region` must be a node in the `hugr`. See [`Dataflow::add_hugr_with_wires`]
234+
/// for a helper that inserts the entrypoint region to the HUGR.
235+
///
236+
/// # Errors
237+
///
238+
/// This function will return an error if there is an error when adding the
239+
/// node.
240+
fn add_hugr_region_with_wires(
241+
&mut self,
242+
hugr: Hugr,
243+
region: Node,
244+
input_wires: impl IntoIterator<Item = Wire>,
245+
) -> Result<BuildHandle<DataflowOpID>, BuildError> {
246+
let optype = hugr.get_optype(region).clone();
213247
let num_outputs = optype.value_output_count();
214-
let node = self.add_hugr(hugr).inserted_entrypoint;
248+
let node = self.add_hugr_region(hugr, region).inserted_entrypoint;
215249

216250
wire_up_inputs(input_wires, node, self).map_err(|error| BuildError::OperationWiring {
217251
op: Box::new(optype),

hugr-core/src/hugr/hugrmut.rs

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,23 @@ pub trait HugrMut: HugrMutInternals {
183183
/// # Panics
184184
///
185185
/// If the root node is not in the graph.
186-
fn insert_hugr(&mut self, root: Self::Node, other: Hugr) -> InsertionResult<Node, Self::Node>;
186+
fn insert_hugr(&mut self, root: Self::Node, other: Hugr) -> InsertionResult<Node, Self::Node> {
187+
let region = other.entrypoint();
188+
Self::insert_region(self, root, other, region)
189+
}
190+
191+
/// Insert a sub-region of another hugr into this one, under a given parent node.
192+
///
193+
/// # Panics
194+
///
195+
/// - If the root node is not in the graph.
196+
/// - If the `region` node is not in `other`.
197+
fn insert_region(
198+
&mut self,
199+
root: Self::Node,
200+
other: Hugr,
201+
region: Node,
202+
) -> InsertionResult<Node, Self::Node>;
187203

188204
/// Copy another hugr into this one, under a given parent node.
189205
///
@@ -247,15 +263,17 @@ pub trait HugrMut: HugrMutInternals {
247263
ExtensionRegistry: Extend<Reg>;
248264
}
249265

250-
/// Records the result of inserting a Hugr or view
251-
/// via [`HugrMut::insert_hugr`] or [`HugrMut::insert_from_view`].
266+
/// Records the result of inserting a Hugr or view via [`HugrMut::insert_hugr`],
267+
/// [`HugrMut::insert_from_view`], or [`HugrMut::insert_region`].
252268
///
253-
/// Contains a map from the nodes in the source HUGR to the nodes in the
254-
/// target HUGR, using their respective `Node` types.
269+
/// Contains a map from the nodes in the source HUGR to the nodes in the target
270+
/// HUGR, using their respective `Node` types.
255271
pub struct InsertionResult<SourceN = Node, TargetN = Node> {
256-
/// The node, after insertion, that was the entrypoint of the inserted Hugr.
272+
/// The node, after insertion, that was the root of the inserted Hugr.
257273
///
258-
/// That is, the value in [`InsertionResult::node_map`] under the key that was the [`HugrView::entrypoint`].
274+
/// That is, the value in [`InsertionResult::node_map`] under the key that
275+
/// was the the `region` passed to [`HugrMut::insert_region`] or the
276+
/// [`HugrView::entrypoint`] in the other cases.
259277
pub inserted_entrypoint: TargetN,
260278
/// Map from nodes in the Hugr/view that was inserted, to their new
261279
/// positions in the Hugr into which said was inserted.
@@ -394,17 +412,14 @@ impl HugrMut for Hugr {
394412
(src_port, dst_port)
395413
}
396414

397-
fn insert_hugr(
415+
fn insert_region(
398416
&mut self,
399417
root: Self::Node,
400418
mut other: Hugr,
419+
region: Node,
401420
) -> InsertionResult<Node, Self::Node> {
402-
let node_map = insert_hugr_internal(self, &other, other.entry_descendants(), |&n| {
403-
if n == other.entrypoint() {
404-
Some(root)
405-
} else {
406-
None
407-
}
421+
let node_map = insert_hugr_internal(self, &other, other.descendants(region), |&n| {
422+
if n == region { Some(root) } else { None }
408423
});
409424
// Merge the extension sets.
410425
self.extensions.extend(other.extensions());
@@ -420,7 +435,7 @@ impl HugrMut for Hugr {
420435
self.metadata.set(new_node_pg, meta);
421436
}
422437
InsertionResult {
423-
inserted_entrypoint: node_map[&other.entrypoint()],
438+
inserted_entrypoint: node_map[&region],
424439
node_map,
425440
}
426441
}

hugr-core/src/hugr/views/impls.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ macro_rules! hugr_mut_methods {
115115
fn disconnect(&mut self, node: Self::Node, port: impl Into<crate::Port>);
116116
fn add_other_edge(&mut self, src: Self::Node, dst: Self::Node) -> (crate::OutgoingPort, crate::IncomingPort);
117117
fn insert_hugr(&mut self, root: Self::Node, other: crate::Hugr) -> crate::hugr::hugrmut::InsertionResult<crate::Node, Self::Node>;
118+
fn insert_region(&mut self, root: Self::Node, other: crate::Hugr, region: crate::Node) -> crate::hugr::hugrmut::InsertionResult<crate::Node, Self::Node>;
118119
fn insert_from_view<Other: crate::hugr::HugrView>(&mut self, root: Self::Node, other: &Other) -> crate::hugr::hugrmut::InsertionResult<Other::Node, Self::Node>;
119120
fn insert_subgraph<Other: crate::hugr::HugrView>(&mut self, root: Self::Node, other: &Other, subgraph: &crate::hugr::views::SiblingSubgraph<Other::Node>) -> std::collections::HashMap<Other::Node, Self::Node>;
120121
fn use_extension(&mut self, extension: impl Into<std::sync::Arc<crate::extension::Extension>>);

hugr-core/src/hugr/views/rerooted.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ impl<H: HugrMut> HugrMut for Rerooted<H> {
138138
fn disconnect(&mut self, node: Self::Node, port: impl Into<crate::Port>);
139139
fn add_other_edge(&mut self, src: Self::Node, dst: Self::Node) -> (crate::OutgoingPort, crate::IncomingPort);
140140
fn insert_hugr(&mut self, root: Self::Node, other: crate::Hugr) -> crate::hugr::hugrmut::InsertionResult<crate::Node, Self::Node>;
141+
fn insert_region(&mut self, root: Self::Node, other: crate::Hugr, region: crate::Node) -> crate::hugr::hugrmut::InsertionResult<crate::Node, Self::Node>;
141142
fn insert_from_view<Other: crate::hugr::HugrView>(&mut self, root: Self::Node, other: &Other) -> crate::hugr::hugrmut::InsertionResult<Other::Node, Self::Node>;
142143
fn insert_subgraph<Other: crate::hugr::HugrView>(&mut self, root: Self::Node, other: &Other, subgraph: &crate::hugr::views::SiblingSubgraph<Other::Node>) -> std::collections::HashMap<Other::Node, Self::Node>;
143144
fn use_extension(&mut self, extension: impl Into<std::sync::Arc<crate::extension::Extension>>);

0 commit comments

Comments
 (0)