From 8bd24410d9588b07f12c3a388e21800f5b728de4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Borgna?= <121866228+aborgna-q@users.noreply.github.com> Date: Fri, 1 Mar 2024 17:25:10 +0000 Subject: [PATCH] feat: Add `PatternMatch::nodes` and `subcircuit` + matching example (#299) In addition to the getter methods for `PatternMatch`, adds an example in the `portmatching` module docs using it. Closes #297 . --- tket2/src/portmatching.rs | 55 ++++++++++++++++++++++++++++++- tket2/src/portmatching/matcher.rs | 10 ++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/tket2/src/portmatching.rs b/tket2/src/portmatching.rs index a35bae2d..8e74695e 100644 --- a/tket2/src/portmatching.rs +++ b/tket2/src/portmatching.rs @@ -1,4 +1,57 @@ -//! Pattern matching for circuits +//! Pattern matching for circuits. +//! +//! This module provides a way to define circuit patterns and match +//! them against circuits. +//! +//! # Examples +//! ``` +//! use tket2::portmatching::{CircuitPattern, PatternMatcher}; +//! use tket2::Tk2Op; +//! use hugr::builder::{DFGBuilder, Dataflow, DataflowHugr}; +//! use hugr::extension::prelude::QB_T; +//! use hugr::ops::handle::NodeHandle; +//! use hugr::types::FunctionType; +//! +//! # fn doctest() -> Result<(), Box> { +//! // Define a simple pattern that matches a single qubit allocation. +//! let circuit_pattern = { +//! let mut dfg = DFGBuilder::new(FunctionType::new(vec![], vec![QB_T]))?; +//! let alloc = dfg.add_dataflow_op(Tk2Op::QAlloc, [])?; +//! dfg.finish_hugr_with_outputs(alloc.outputs(), &tket2::extension::REGISTRY) +//! }?; +//! let pattern = CircuitPattern::try_from_circuit(&circuit_pattern)?; +//! +//! // Define a circuit that contains a qubit allocation. +//! // +//! // -----[Z]--x--- +//! // | +//! // 0|--[Z]--o--- +//! let (circuit, alloc_node) = { +//! let mut dfg = DFGBuilder::new(FunctionType::new(vec![QB_T], vec![QB_T, QB_T]))?; +//! let [input_wire] = dfg.input_wires_arr(); +//! let alloc = dfg.add_dataflow_op(Tk2Op::QAlloc, [])?; +//! let [alloc_wire] = alloc.outputs_arr(); +//! +//! let mut circuit = dfg.as_circuit(vec![input_wire, alloc_wire]); +//! circuit +//! .append(Tk2Op::Z, [1])? +//! .append(Tk2Op::Z, [0])? +//! .append(Tk2Op::CX, [1, 0])?; +//! let outputs = circuit.finish(); +//! +//! let circuit = dfg.finish_hugr_with_outputs(outputs, &tket2::extension::REGISTRY)?; +//! (circuit, alloc.node()) +//! }; +//! +//! // Create a pattern matcher and find matches. +//! let matcher = PatternMatcher::from_patterns(vec![pattern]); +//! let matches = matcher.find_matches(&circuit); +//! +//! assert_eq!(matches.len(), 1); +//! assert_eq!(matches[0].nodes(), [alloc_node]); +//! # Ok(()) +//! # } +//! ``` pub mod matcher; pub mod pattern; diff --git a/tket2/src/portmatching/matcher.rs b/tket2/src/portmatching/matcher.rs index 732804de..ff9274a2 100644 --- a/tket2/src/portmatching/matcher.rs +++ b/tket2/src/portmatching/matcher.rs @@ -92,6 +92,16 @@ impl PatternMatch { self.root } + /// Returns the matched subcircuit in the original circuit. + pub fn subcircuit(&self) -> &Subcircuit { + &self.position + } + + /// Returns the matched nodes in the original circuit. + pub fn nodes(&self) -> &[Node] { + self.position.nodes() + } + /// Create a pattern match from the image of a pattern root. /// /// This checks at construction time that the match is convex. This will