Skip to content

Commit f98aa8e

Browse files
committed
address comments
1 parent 84d59fb commit f98aa8e

File tree

4 files changed

+165
-113
lines changed

4 files changed

+165
-113
lines changed

hugr-core/src/core.rs

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ pub use itertools::Either;
77
use derive_more::From;
88
use itertools::Either::{Left, Right};
99

10-
use crate::hugr::HugrError;
10+
use crate::{HugrView, hugr::HugrError};
1111

1212
/// A handle to a node in the HUGR.
1313
#[derive(
@@ -219,17 +219,55 @@ impl<N: HugrNode> Wire<N> {
219219
Self(node, port.into())
220220
}
221221

222-
/// The node that this wire is connected to.
222+
/// Create a new wire from a node and a port that is connected to the wire.
223+
///
224+
/// If `port` is an incoming port, the wire is traversed to find the unique
225+
/// outgoing port that is connected to the wire. Otherwise, this is
226+
/// equivalent to constructing a wire using [`Wire::new`].
227+
///
228+
/// ## Panics
229+
///
230+
/// This will panic if the wire is not connected to a unique outgoing port.
231+
#[inline]
232+
pub fn from_connected_port(
233+
node: N,
234+
port: impl Into<Port>,
235+
hugr: &impl HugrView<Node = N>,
236+
) -> Self {
237+
let (node, outgoing) = match port.into().as_directed() {
238+
Either::Left(incoming) => hugr
239+
.single_linked_output(node, incoming)
240+
.expect("invalid dfg port"),
241+
Either::Right(outgoing) => (node, outgoing),
242+
};
243+
Self::new(node, outgoing)
244+
}
245+
246+
/// The node of the unique outgoing port that the wire is connected to.
223247
#[inline]
224248
pub fn node(&self) -> N {
225249
self.0
226250
}
227251

228-
/// The output port that this wire is connected to.
252+
/// The unique outgoing port that the wire is connected to.
229253
#[inline]
230254
pub fn source(&self) -> OutgoingPort {
231255
self.1
232256
}
257+
258+
/// Get all ports connected to the wire.
259+
///
260+
/// Return a chained iterator of the unique outgoing port, followed by all
261+
/// incoming ports connected to the wire.
262+
pub fn all_connected_ports<'h, H: HugrView<Node = N>>(
263+
&self,
264+
hugr: &'h H,
265+
) -> impl Iterator<Item = (N, Port)> + use<'h, N, H> {
266+
let node = self.node();
267+
let out_port = self.source();
268+
269+
std::iter::once((node, out_port.into())).chain(hugr.linked_ports(node, out_port))
270+
}
233271
}
234272

235273
impl<N: HugrNode> std::fmt::Display for Wire<N> {

hugr-persistent/src/persistent_hugr.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,7 @@ impl<R> PersistentHugr<R> {
489489
.unique()
490490
}
491491

492+
/// Get the child commit that deletes `node`.
492493
pub(crate) fn find_deleting_commit(
493494
&self,
494495
node @ PatchNode(commit_id, _): PatchNode,
@@ -500,6 +501,12 @@ impl<R> PersistentHugr<R> {
500501
})
501502
}
502503

504+
/// Convert a node ID specific to a commit HUGR into a patch node in the
505+
/// [`PersistentHugr`].
506+
pub(crate) fn to_persistent_node(&self, node: Node, commit_id: CommitId) -> PatchNode {
507+
PatchNode(commit_id, node)
508+
}
509+
503510
/// Check if a patch node is in the PersistentHugr, that is, it belongs to
504511
/// a commit in the state space and is not deleted by any child commit.
505512
pub fn contains_node(&self, PatchNode(commit_id, node): PatchNode) -> bool {

hugr-persistent/src/state_space.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -308,10 +308,12 @@ impl<R> CommitStateSpace<R> {
308308

309309
/// Get the boundary inputs linked to `(node, port)` in `child`.
310310
///
311+
/// `child` should be a child commit of the owner of `node`.
312+
///
311313
/// ## Panics
312314
///
313-
/// Panics if `(node, port)` is not a boundary edge, or if `child` is not
314-
/// a valid commit ID.
315+
/// Panics if `(node, port)` is not a boundary edge, if `child` is not
316+
/// a valid commit ID or if it is the base commit.
315317
pub(crate) fn linked_child_inputs(
316318
&self,
317319
node: PatchNode,
@@ -336,6 +338,9 @@ impl<R> CommitStateSpace<R> {
336338

337339
/// Get the single boundary output linked to `(node, port)` in `child`.
338340
///
341+
/// `child` should be a child commit of the owner of `node` (or `None` will
342+
/// be returned).
343+
///
339344
/// ## Panics
340345
///
341346
/// Panics if `child` is not a valid commit ID.
@@ -346,7 +351,7 @@ impl<R> CommitStateSpace<R> {
346351
child: CommitId,
347352
) -> Option<(PatchNode, OutgoingPort)> {
348353
let parent_hugrs = ParentsView::from_commit(child, self);
349-
let repl = self.replacement(child).expect("valid child commit");
354+
let repl = self.replacement(child)?;
350355
match repl.linked_replacement_output((node, port), &parent_hugrs)? {
351356
BoundaryPort::Host(patch_node, port) => (patch_node, port),
352357
BoundaryPort::Replacement(node, port) => (PatchNode(child, node), port),
@@ -356,6 +361,8 @@ impl<R> CommitStateSpace<R> {
356361

357362
/// Get the boundary ports linked to `(node, port)` in `child`.
358363
///
364+
/// `child` should be a child commit of the owner of `node`.
365+
///
359366
/// See [`Self::linked_child_inputs`] and [`Self::linked_child_output`] for
360367
/// more details.
361368
pub(crate) fn linked_child_ports(

0 commit comments

Comments
 (0)