diff --git a/Cargo.toml b/Cargo.toml index 32c77013..80a546a0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ missing_docs = "warn" [workspace.dependencies] tket2 = { path = "./tket2" } -quantinuum-hugr = { git = "https://github.com/CQCL/hugr", rev = "0edee65" } +quantinuum-hugr = { git = "https://github.com/CQCL/hugr", rev = "25d03aa" } portgraph = { version = "0.11" } pyo3 = { version = "0.20" } itertools = { version = "0.12.0" } diff --git a/tket2/src/circuit/command.rs b/tket2/src/circuit/command.rs index 192247b5..f0575b1d 100644 --- a/tket2/src/circuit/command.rs +++ b/tket2/src/circuit/command.rs @@ -466,7 +466,13 @@ impl<'circ, Circ: Circuit> std::fmt::Debug for CommandIterator<'circ, Circ> { #[cfg(test)] mod test { + use hugr::builder::{Container, DFGBuilder, Dataflow, DataflowHugr}; + use hugr::extension::prelude::QB_T; + use hugr::ops::handle::NodeHandle; use hugr::ops::OpName; + use hugr::std_extensions::arithmetic::float_ops::FLOAT_OPS_REGISTRY; + use hugr::std_extensions::arithmetic::float_types::ConstF64; + use hugr::types::FunctionType; use itertools::Itertools; use crate::utils::build_simple_circuit; @@ -534,4 +540,65 @@ mod test { assert_eq!(commands.next(), None); } + + /// Commands iterator with non-linear wires. + #[test] + fn commands_nonlinear() { + let qb_row = vec![QB_T; 1]; + let mut h = DFGBuilder::new(FunctionType::new(qb_row.clone(), qb_row)).unwrap(); + let [q_in] = h.input_wires_arr(); + + let constant = h.add_constant(ConstF64::new(0.5)).unwrap(); + let loaded_const = h.load_const(&constant).unwrap(); + let rz = h + .add_dataflow_op(Tk2Op::RzF64, [q_in, loaded_const]) + .unwrap(); + + let circ = h + .finish_hugr_with_outputs(rz.outputs(), &FLOAT_OPS_REGISTRY) + .unwrap(); + + assert_eq!(CommandIterator::new(&circ).count(), 3); + let mut commands = CommandIterator::new(&circ); + + // First command is the constant definition. + // It has a single output. + let const_cmd = commands.next().unwrap(); + assert_eq!(const_cmd.optype().name().as_str(), "const:custom:f64(0.5)"); + assert_eq_iter!(const_cmd.inputs().map(|(u, _, _)| u), [],); + assert_eq_iter!( + const_cmd.outputs().map(|(u, _, _)| u), + [CircuitUnit::Wire(Wire::new(constant.node(), 0))], + ); + + // Next, the load constant command. + // It has a single input and a single output. + let load_const_cmd = commands.next().unwrap(); + let load_const_node = load_const_cmd.node(); + assert_eq!(load_const_cmd.optype().name().as_str(), "LoadConstant"); + assert_eq_iter!( + load_const_cmd.inputs().map(|(u, _, _)| u), + [CircuitUnit::Wire(Wire::new(constant.node(), 0))], + ); + assert_eq_iter!( + load_const_cmd.outputs().map(|(u, _, _)| u), + [CircuitUnit::Wire(Wire::new(load_const_node, 0))], + ); + + // Finally, the rz command. + // It has the qubit and loaded constant as input and a single output. + let rz_cmd = commands.next().unwrap(); + assert_eq!(rz_cmd.optype().name().as_str(), "quantum.tket2.RzF64"); + assert_eq_iter!( + rz_cmd.inputs().map(|(u, _, _)| u), + [ + CircuitUnit::Linear(0), + CircuitUnit::Wire(Wire::new(load_const_node, 0)) + ], + ); + assert_eq_iter!( + rz_cmd.outputs().map(|(u, _, _)| u), + [CircuitUnit::Linear(0)], + ); + } } diff --git a/tket2/src/circuit/units.rs b/tket2/src/circuit/units.rs index 7094278f..1f6b0eec 100644 --- a/tket2/src/circuit/units.rs +++ b/tket2/src/circuit/units.rs @@ -140,13 +140,9 @@ where Direction::Outgoing => sig.output, Direction::Incoming => sig.input, }; - if direction == Direction::Incoming { - if let Some(static_port) = optype.static_input_port() { - if let Some(EdgeKind::Static(static_type)) = optype.port_kind(static_port) { - types.to_mut().push(static_type); - } - } - } + if let Some(EdgeKind::Static(static_type)) = optype.static_port_kind(direction) { + types.to_mut().push(static_type); + }; if let Some(EdgeKind::Static(other)) = optype.other_port_kind(direction) { types.to_mut().push(other); } diff --git a/tket2/src/json/tests.rs b/tket2/src/json/tests.rs index f518bbf6..df9b0a27 100644 --- a/tket2/src/json/tests.rs +++ b/tket2/src/json/tests.rs @@ -109,8 +109,8 @@ fn circ_add_angles_constants() -> Hugr { let qb = h.input_wires().next().unwrap(); - let point2 = h.add_load_const(ConstF64::new(0.2).into()).unwrap(); - let point3 = h.add_load_const(ConstF64::new(0.3).into()).unwrap(); + let point2 = h.add_load_const(ConstF64::new(0.2)).unwrap(); + let point3 = h.add_load_const(ConstF64::new(0.3)).unwrap(); let point5 = h .add_dataflow_op(Tk2Op::AngleAdd, [point2, point3]) .unwrap()