Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add PatternMatch::nodes and subcircuit + matching example #299

Merged
merged 1 commit into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 54 additions & 1 deletion tket2/src/portmatching.rs
Original file line number Diff line number Diff line change
@@ -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<dyn std::error::Error>> {
//! // 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;
Expand Down
10 changes: 10 additions & 0 deletions tket2/src/portmatching/matcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading