From 4e76141fef73f9b5001654674a459e50336f839d Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Wed, 26 Nov 2025 13:34:50 +0000 Subject: [PATCH 1/2] Remove qubit_types_utils --- tket-py/src/circuit/tk2circuit.rs | 1 - tket/src/modifier.rs | 1 - tket/src/modifier/qubit_types_utils.rs | 95 -------------------------- 3 files changed, 97 deletions(-) delete mode 100644 tket/src/modifier/qubit_types_utils.rs diff --git a/tket-py/src/circuit/tk2circuit.rs b/tket-py/src/circuit/tk2circuit.rs index 72a560f14..d607d9bd8 100644 --- a/tket-py/src/circuit/tk2circuit.rs +++ b/tket-py/src/circuit/tk2circuit.rs @@ -25,7 +25,6 @@ use derive_more::From; use hugr::{Hugr, HugrView, Wire}; use serde::Serialize; use tket::circuit::CircuitHash; -use tket::modifier::qubit_types_utils::contain_qubit_term; use tket::passes::pytket::lower_to_pytket; use tket::passes::CircuitChunks; use tket::serialize::pytket::{DecodeOptions, EncodeOptions}; diff --git a/tket/src/modifier.rs b/tket/src/modifier.rs index 1b7aeb811..b87beebf9 100644 --- a/tket/src/modifier.rs +++ b/tket/src/modifier.rs @@ -20,7 +20,6 @@ pub mod control; pub mod dagger; pub mod modifier_resolver; pub mod power; -pub mod qubit_types_utils; pub use pass::ModifierResolverPass; diff --git a/tket/src/modifier/qubit_types_utils.rs b/tket/src/modifier/qubit_types_utils.rs deleted file mode 100644 index ea842d198..000000000 --- a/tket/src/modifier/qubit_types_utils.rs +++ /dev/null @@ -1,95 +0,0 @@ -//! Utilities for qubit types. -/// This is needed for dager modifier, for example, -/// to decide whether to flip the input and output wires. -use hugr::{ - extension::prelude::qb_t, - std_extensions::collections::{ - array::array_type_def, borrow_array::borrow_array_type_def, - value_array::value_array_type_def, - }, - types::{CustomType, SumType, Term, Type, TypeEnum, TypeRV}, -}; - -/// Checks if a type is quantum or an array/list of quantum types. -pub fn contain_qubits(ty: &Type) -> bool { - contain_qubits_rv(&ty.clone().into()) -} - -fn contain_qubits_in_array(custom_type: &CustomType) -> bool { - let name = custom_type.name(); - let array_type_defs = [ - array_type_def(), - value_array_type_def(), - borrow_array_type_def(), - ]; - if array_type_defs.iter().any(|def| *def.name() == *name) { - if let Some(arg) = custom_type.args().get(1) { - return contain_qubit_term(arg); - } - } - false -} - -fn contain_qubits_rv(ty: &TypeRV) -> bool { - if *ty == qb_t() { - return true; - } else if let TypeEnum::Extension(custom_type) = ty.as_type_enum() { - if contain_qubits_in_array(custom_type) { - return true; - } - } else if let TypeEnum::Sum(sub_type) = ty.as_type_enum() { - match sub_type { - // we consider unit type as a quantum type - SumType::Unit { .. } => return false, - SumType::General { rows } => { - return rows.iter().any(|tys| tys.iter().any(contain_qubits_rv)) - } - _ => {} - } - } - false -} - -/// Checks if a term is quantum or an array/list/tuple of quantum types. -pub fn contain_qubit_term(term: &Term) -> bool { - // TODO: A lot of other cases are just ignored here. - match term { - Term::Runtime(ty) => contain_qubits(ty), - Term::ListType(term) | Term::TupleType(term) => contain_qubit_term(term), - // Note that we are not checking parameters of types here, but rather whether the term itself is quantum type. - _ => false, - } -} - -#[cfg(test)] -mod tests { - use hugr::{ - std_extensions::collections::array::array_type, - types::{Signature, SumType}, - }; - - use crate::extension::bool::bool_type; - - use super::*; - #[test] - fn test_is_quantum_type() { - // has qubits - assert!(contain_qubits(&qb_t())); - assert!(contain_qubits(&array_type(3, qb_t()))); - assert!(contain_qubits( - &SumType::new(vec![qb_t(), array_type(2, qb_t())]).into() - )); - assert!(contain_qubits( - &SumType::new(vec![hugr::type_row![], qb_t().into()]).into() - )); - - // No qubuits - assert!(!contain_qubits(&bool_type())); - assert!(!contain_qubits( - &SumType::new(vec![hugr::type_row![]]).into() - )); - assert!(!contain_qubits(&Type::new_function(Signature::new_endo( - qb_t() - )))) - } -} From e2bd8ddb807a7d90b74f7e134bb3df0558566a79 Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Wed, 26 Nov 2025 13:35:08 +0000 Subject: [PATCH 2/2] Use TypeUnpacker instead of contain_qubits --- tket/src/modifier/modifier_resolver.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tket/src/modifier/modifier_resolver.rs b/tket/src/modifier/modifier_resolver.rs index 99b039a91..33d1404d8 100644 --- a/tket/src/modifier/modifier_resolver.rs +++ b/tket/src/modifier/modifier_resolver.rs @@ -111,13 +111,11 @@ pub mod dfg_modify; pub mod global_phase_modify; pub mod tket_op_modify; -use super::qubit_types_utils::contain_qubits; use super::{CombinedModifier, ModifierFlags}; -use crate::{ - extension::{global_phase::GlobalPhase, modifier::Modifier}, - modifier::modifier_resolver::global_phase_modify::delete_phase, - TketOp, -}; +use crate::passes::unpack_container::TypeUnpacker; +use crate::{extension::global_phase::GlobalPhase, modifier::Modifier, TketOp}; +use global_phase_modify::delete_phase; + use hugr::{ builder::{BuildError, CFGBuilder, Container, Dataflow, SubContainer}, core::HugrNode, @@ -324,6 +322,7 @@ pub struct ModifierResolver { // ``` // _modified_functions: HashMap, // ``` + qubit_finder: TypeUnpacker, } impl ModifierResolver { @@ -335,6 +334,7 @@ impl ModifierResolver { controls: Vec::default(), worklist: VecDeque::default(), call_map: HashMap::default(), + qubit_finder: TypeUnpacker::for_qubits(), } } } @@ -854,7 +854,7 @@ impl ModifierResolver { loop { // Wire inputs until the first quantum type while let Some(ty) = in_ty { - if contain_qubits(ty) { + if self.qubit_finder.contains_element_type(ty) { break; } self.map_insert(old_in_wire, new_in_wire)?; @@ -865,7 +865,7 @@ impl ModifierResolver { // Wire outputs until the first quantum type while let Some(ty) = out_ty { - if contain_qubits(ty) { + if self.qubit_finder.contains_element_type(ty) { break; } self.map_insert(old_out_wire, new_out_wire)?; @@ -876,7 +876,7 @@ impl ModifierResolver { // If both are quantum types, wire them in the opposite direction until the next non-quantum type while let Some(ty) = in_ty { - if !contain_qubits(ty) { + if !self.qubit_finder.contains_element_type(ty) { break; } let new_in = if !self.modifiers.dagger { @@ -893,7 +893,7 @@ impl ModifierResolver { in_ty = inputs.next(); } while let Some(ty) = out_ty { - if !contain_qubits(ty) { + if !self.qubit_finder.contains_element_type(ty) { break; } let new_out = if !self.modifiers.dagger {