From cb908635adb56b89b5284eb9cb402211cfdbe4a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Borgna?= <121866228+aborgna-q@users.noreply.github.com> Date: Fri, 28 Jun 2024 09:22:22 +0100 Subject: [PATCH] fix: Portmatching not matching const edges (#444) Patterns with constant value definitions failed at construction time, because the code only read the wire types from the dataflow signature (which does not include const wires). --- tket2/src/portmatching.rs | 19 +++++++++++-------- tket2/src/portmatching/pattern.rs | 9 +++++++-- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/tket2/src/portmatching.rs b/tket2/src/portmatching.rs index b1b57d4e..ca8a2fce 100644 --- a/tket2/src/portmatching.rs +++ b/tket2/src/portmatching.rs @@ -56,6 +56,7 @@ pub mod matcher; pub mod pattern; +use hugr::types::EdgeKind; use hugr::{HugrView, OutgoingPort}; use itertools::Itertools; pub use matcher::{PatternMatch, PatternMatcher}; @@ -98,6 +99,7 @@ enum PEdge { } #[derive(Debug, Clone, Error)] +#[non_exhaustive] enum InvalidEdgeProperty { /// The port is linked to multiple edges. #[error("port {0:?} is linked to multiple edges")] @@ -106,8 +108,8 @@ enum InvalidEdgeProperty { #[error("port {0:?} is not linked to any edge")] NoLinkedEdge(Port), /// The port does not have a type. - #[error("port {0:?} does not have a type")] - UntypedPort(Port), + #[error("{0}:{1} does not have a type")] + UntypedPort(Node, Port), } impl PEdge { @@ -127,12 +129,13 @@ impl PEdge { if hugr.get_optype(dst_node).tag() == OpTag::Input { return Ok(Self::InputEdge { src }); } - let port_type = hugr - .signature(node) - .unwrap() - .port_type(src) - .cloned() - .ok_or(InvalidEdgeProperty::UntypedPort(src))?; + + // Get the port type for either value or constant ports. + let port_type = match hugr.get_optype(node).port_kind(src) { + Some(EdgeKind::Value(typ)) => typ, + Some(EdgeKind::Const(typ)) => typ, + _ => return Err(InvalidEdgeProperty::UntypedPort(node, src)), + }; let is_reversible = type_is_linear(&port_type); Ok(Self::InternalEdge { src, diff --git a/tket2/src/portmatching/pattern.rs b/tket2/src/portmatching/pattern.rs index 1ce53171..e90a627a 100644 --- a/tket2/src/portmatching/pattern.rs +++ b/tket2/src/portmatching/pattern.rs @@ -42,11 +42,16 @@ impl CircuitPattern { for in_offset in 0..cmd.input_count() { let in_offset: IncomingPort = in_offset.into(); let edge_prop = PEdge::try_from_port(cmd.node(), in_offset.into(), circuit) - .expect("Invalid HUGR"); + .unwrap_or_else(|e| panic!("Invalid HUGR, {e}")); let (prev_node, prev_port) = hugr .linked_outputs(cmd.node(), in_offset) .exactly_one() - .expect("invalid HUGR"); + .unwrap_or_else(|_| { + panic!( + "{} input port {in_offset} does not have a single neighbour", + cmd.node() + ) + }); let prev_node = match edge_prop { PEdge::InternalEdge { .. } => NodeID::HugrNode(prev_node), PEdge::InputEdge { .. } => NodeID::new_copy(prev_node, prev_port),