Skip to content

Commit 1f126c0

Browse files
authored
feat(tket2-hseries)!: Redefine QSystemOp::LazyMeasure and introduce QSystemOp::LazyMeasureReset (#741)
Done in the process of addressing #740 BREAKING CHANGE: The signature of `QSystemOp::LazyMeasure` is changed to consume its qubit.
1 parent 5a69e23 commit 1f126c0

File tree

3 files changed

+56
-9
lines changed

3 files changed

+56
-9
lines changed

tket2-exts/src/tket2_exts/data/tket2/qsystem.json

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,41 @@
1313
"extension": "tket2.qsystem",
1414
"name": "LazyMeasure",
1515
"description": "Lazily measure a qubit and lose it.",
16+
"signature": {
17+
"params": [],
18+
"body": {
19+
"input": [
20+
{
21+
"t": "Q"
22+
}
23+
],
24+
"output": [
25+
{
26+
"t": "Opaque",
27+
"extension": "tket2.futures",
28+
"id": "Future",
29+
"args": [
30+
{
31+
"tya": "Type",
32+
"ty": {
33+
"t": "Sum",
34+
"s": "Unit",
35+
"size": 2
36+
}
37+
}
38+
],
39+
"bound": "A"
40+
}
41+
],
42+
"runtime_reqs": []
43+
}
44+
},
45+
"binary": false
46+
},
47+
"LazyMeasureReset": {
48+
"extension": "tket2.qsystem",
49+
"name": "LazyMeasureReset",
50+
"description": "Lazily measure a qubit and reset it to the Z |0> eigenstate.",
1651
"signature": {
1752
"params": [],
1853
"body": {

tket2-hseries/src/extension/qsystem.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ lazy_static! {
8282
pub enum QSystemOp {
8383
Measure,
8484
LazyMeasure,
85+
LazyMeasureReset,
8586
Rz,
8687
PhasedX,
8788
ZZMax,
@@ -98,7 +99,8 @@ impl MakeOpDef for QSystemOp {
9899
let one_qb_row = TypeRow::from(vec![qb_t()]);
99100
let two_qb_row = TypeRow::from(vec![qb_t(), qb_t()]);
100101
match self {
101-
LazyMeasure => Signature::new(qb_t(), vec![qb_t(), future_type(bool_t())]),
102+
LazyMeasure => Signature::new(qb_t(), future_type(bool_t())),
103+
LazyMeasureReset => Signature::new(qb_t(), vec![qb_t(), future_type(bool_t())]),
102104
Reset => Signature::new(one_qb_row.clone(), one_qb_row),
103105
ZZMax => Signature::new(two_qb_row.clone(), two_qb_row),
104106
ZZPhase => Signature::new(vec![qb_t(), qb_t(), float64_type()], two_qb_row),
@@ -136,6 +138,9 @@ impl MakeOpDef for QSystemOp {
136138
QSystemOp::QFree => "Free a qubit (lose track of it).",
137139
QSystemOp::Reset => "Reset a qubit to the Z |0> eigenstate.",
138140
QSystemOp::MeasureReset => "Measure a qubit and reset it to the Z |0> eigenstate.",
141+
QSystemOp::LazyMeasureReset => {
142+
"Lazily measure a qubit and reset it to the Z |0> eigenstate."
143+
}
139144
}
140145
.to_string()
141146
}
@@ -155,9 +160,16 @@ impl MakeRegisteredOp for QSystemOp {
155160
/// "tket2.qsystem" operations.
156161
pub trait QSystemOpBuilder: Dataflow + UnwrapBuilder {
157162
/// Add a "tket2.qsystem.LazyMeasure" op.
158-
fn add_lazy_measure(&mut self, qb: Wire) -> Result<[Wire; 2], BuildError> {
163+
fn add_lazy_measure(&mut self, qb: Wire) -> Result<Wire, BuildError> {
159164
Ok(self
160165
.add_dataflow_op(QSystemOp::LazyMeasure, [qb])?
166+
.out_wire(0))
167+
}
168+
169+
/// Add a "tket2.qsystem.LazyMeasureReset" op.
170+
fn add_lazy_measure_reset(&mut self, qb: Wire) -> Result<[Wire; 2], BuildError> {
171+
Ok(self
172+
.add_dataflow_op(QSystemOp::LazyMeasureReset, [qb])?
161173
.outputs_arr())
162174
}
163175

@@ -439,7 +451,7 @@ mod test {
439451
FunctionBuilder::new("circuit", Signature::new(qb_t(), vec![qb_t(), bool_t()]))
440452
.unwrap();
441453
let [qb] = func_builder.input_wires_arr();
442-
let [qb, lazy_b] = func_builder.add_lazy_measure(qb).unwrap();
454+
let [qb, lazy_b] = func_builder.add_lazy_measure_reset(qb).unwrap();
443455
let [b] = func_builder.add_read(lazy_b, bool_t()).unwrap();
444456
func_builder.finish_hugr_with_outputs([qb, b]).unwrap()
445457
};

tket2-hseries/src/lazify_measure.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ lazy_static! {
101101
static ref MEASURE_READ_HUGR: Hugr = {
102102
let mut builder = DFGBuilder::new(Signature::new(qb_t(), vec![qb_t(), bool_t()])).unwrap();
103103
let [qb] = builder.input_wires_arr();
104-
let [qb, lazy_r] = builder.add_lazy_measure(qb).unwrap();
104+
let [qb, lazy_r] = builder.add_lazy_measure_reset(qb).unwrap();
105105
let [r] = builder.add_read(lazy_r, bool_t()).unwrap();
106106
builder.finish_hugr_with_outputs([qb, r]).unwrap()
107107
};
@@ -113,7 +113,7 @@ fn measure_replacement(num_dups: usize) -> Hugr {
113113
let num_out_types = out_types.len();
114114
let mut builder = DFGBuilder::new(Signature::new(qb_t(), out_types)).unwrap();
115115
let [qb] = builder.input_wires_arr();
116-
let [qb, mut future_r] = builder.add_lazy_measure(qb).unwrap();
116+
let [qb, mut future_r] = builder.add_lazy_measure_reset(qb).unwrap();
117117
let mut future_rs = vec![];
118118
if num_dups > 0 {
119119
for _ in 0..num_dups - 1 {
@@ -221,20 +221,20 @@ mod test {
221221
LazifyMeasurePass::default().run(&mut hugr).unwrap();
222222
assert!(hugr.validate_no_extensions().is_ok());
223223
let mut num_read = 0;
224-
let mut num_lazy_measure = 0;
224+
let mut num_lazy_measure_reset = 0;
225225
for n in hugr.nodes() {
226226
let ot = hugr.get_optype(n);
227227
if let Some(FutureOpDef::Read) = ot.cast() {
228228
num_read += 1;
229-
} else if let Some(QSystemOp::LazyMeasure) = ot.cast() {
230-
num_lazy_measure += 1;
229+
} else if let Some(QSystemOp::LazyMeasureReset) = ot.cast() {
230+
num_lazy_measure_reset += 1;
231231
} else {
232232
assert_eq!(ot.cast::<Tk2Op>(), None)
233233
}
234234
}
235235

236236
assert_eq!(1, num_read);
237-
assert_eq!(1, num_lazy_measure);
237+
assert_eq!(1, num_lazy_measure_reset);
238238
}
239239

240240
#[test]

0 commit comments

Comments
 (0)