diff --git a/test_files/nam_6_3.rwr b/test_files/nam_6_3.rwr index ed587540..9feac5e2 100644 Binary files a/test_files/nam_6_3.rwr and b/test_files/nam_6_3.rwr differ diff --git a/test_files/small_eccs.rwr b/test_files/small_eccs.rwr index 0d9bba82..637215e9 100644 Binary files a/test_files/small_eccs.rwr and b/test_files/small_eccs.rwr differ diff --git a/tket2-py/tket2/data/nam_6_3.rwr b/tket2-py/tket2/data/nam_6_3.rwr index ed587540..9feac5e2 100644 Binary files a/tket2-py/tket2/data/nam_6_3.rwr and b/tket2-py/tket2/data/nam_6_3.rwr differ diff --git a/tket2/src/json/op.rs b/tket2/src/json/op.rs index 07f09082..32e77b80 100644 --- a/tket2/src/json/op.rs +++ b/tket2/src/json/op.rs @@ -49,6 +49,7 @@ impl JsonOp { /// [`JsonOp::new_from_op`] for a version that generates a signature if none /// is defined. #[allow(unused)] + #[allow(clippy::question_mark)] pub fn new(op: circuit_json::Operation) -> Option { let Some(sig) = &op.signature else { return None; diff --git a/tket2/src/portmatching/matcher.rs b/tket2/src/portmatching/matcher.rs index 4a555487..732804de 100644 --- a/tket2/src/portmatching/matcher.rs +++ b/tket2/src/portmatching/matcher.rs @@ -12,7 +12,7 @@ use hugr::hugr::views::sibling_subgraph::{ InvalidReplacement, InvalidSubgraph, InvalidSubgraphBoundary, TopoConvexChecker, }; use hugr::hugr::views::SiblingSubgraph; -use hugr::ops::OpType; +use hugr::ops::{OpName, OpType}; use hugr::{Hugr, IncomingPort, Node, OutgoingPort, Port, PortIndex}; use itertools::Itertools; use portgraph::algorithms::ConvexChecker; @@ -20,6 +20,7 @@ use portmatching::{ automaton::{LineBuilder, ScopeAutomaton}, EdgeProperty, PatternID, }; +use smol_str::SmolStr; use thiserror::Error; #[cfg(feature = "pyo3")] @@ -27,40 +28,41 @@ use pyo3::prelude::*; use crate::{ circuit::Circuit, - ops::NotTk2Op, rewrite::{CircuitRewrite, Subcircuit}, - Tk2Op, }; /// Matchable operations in a circuit. -/// -/// We currently support [`Tk2Op`] and a the HUGR load constant operation. -// TODO: Support OpType::Const, but blocked by use of F64 (Eq support required) #[derive( Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Serialize, serde::Deserialize, )] -pub(crate) enum MatchOp { - /// A TKET2 operation. - Op(Tk2Op), - /// A HUGR load constant operation. - LoadConstant, -} - -impl From for MatchOp { - fn from(op: Tk2Op) -> Self { - Self::Op(op) - } +pub(crate) struct MatchOp { + /// The operation identifier + op_name: SmolStr, + /// The encoded operation, if necessary for comparisons. + /// + /// This as a temporary hack for comparing parametric operations, since + /// OpType doesn't implement Eq, Hash, or Ord. + encoded: Option>, } -impl TryFrom for MatchOp { - type Error = NotTk2Op; - - fn try_from(value: OpType) -> Result { - match value { - OpType::LeafOp(op) => Ok(Self::Op(op.try_into()?)), - OpType::LoadConstant(_) => Ok(Self::LoadConstant), - _ => Err(NotTk2Op), - } +impl From for MatchOp { + fn from(op: OpType) -> Self { + let op_name = op.name(); + // Avoid encoding some operations if we know they can be uniquely + // identified by their name. + let encoded = match op { + OpType::Module(_) => None, + OpType::LeafOp(leaf) + if leaf + .as_extension_op() + .map(|ext| ext.args().is_empty()) + .unwrap_or_default() => + { + None + } + _ => rmp_serde::encode::to_vec(&op).ok(), + }; + Self { op_name, encoded } } } @@ -448,8 +450,7 @@ pub(crate) fn validate_circuit_node( let NodeID::HugrNode(node) = node else { return false; }; - let v_weight = MatchOp::try_from(circ.get_optype(node).clone()); - v_weight.is_ok_and(|w| &w == prop) + &MatchOp::from(circ.get_optype(node).clone()) == prop } } diff --git a/tket2/src/portmatching/pattern.rs b/tket2/src/portmatching/pattern.rs index e99a061e..fc0ecc21 100644 --- a/tket2/src/portmatching/pattern.rs +++ b/tket2/src/portmatching/pattern.rs @@ -37,7 +37,7 @@ impl CircuitPattern { let mut pattern = Pattern::new(); for cmd in circuit.commands() { let op = cmd.optype().clone(); - pattern.require(cmd.node().into(), op.try_into().unwrap()); + pattern.require(cmd.node().into(), op.into()); 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)