bug: Rewrite when LHS has no inputs
PabloAndresCQ opened this issue · 0 comments
PabloAndresCQ commented
I stumbled upon this during the hack week project for MBQCification. The example below is a simplified version replicating the error.
Code to generate these and reproduce the error:
use hugr::{
builder::{BuildError, DFGBuilder, Dataflow, DataflowHugr},
extension::{
prelude::QB_T, PRELUDE_REGISTRY
},
types::FunctionType, Hugr, HugrView
};
use tket2::{portmatching::{CircuitPattern, PatternMatcher}, Tk2Op};
use urlencoding;
use webbrowser;
// Copied from Dan's
fn viz_hugr(hugr: &impl HugrView) {
let mut base: String = "https://dreampuf.github.io/GraphvizOnline/#".into();
base.push_str(&urlencoding::encode(hugr.dot_string().as_ref()));
webbrowser::open(&base).unwrap();
}
fn alloc() -> Result<Hugr, BuildError> {
let mut h = DFGBuilder::new(FunctionType::new(vec![], vec![QB_T]))?;
let res = h.add_dataflow_op(Tk2Op::QAlloc, [])?;
let q = res.out_wire(0);
h.finish_hugr_with_outputs([q], &PRELUDE_REGISTRY)
}
fn alloc_reset() -> Result<Hugr, BuildError> {
let mut h = DFGBuilder::new(FunctionType::new(vec![], vec![QB_T]))?;
let res = h.add_dataflow_op(Tk2Op::QAlloc, [])?;
let q = res.out_wire(0);
let res = h.add_dataflow_op(Tk2Op::Reset, [q])?;
let q = res.out_wire(0);
h.finish_hugr_with_outputs([q], &PRELUDE_REGISTRY)
}
pub fn circ_example() -> Result<Hugr, BuildError> {
let mut h = DFGBuilder::new(FunctionType::new(vec![QB_T], vec![QB_T]))?;
let mut inps = h.input_wires();
let q_in = inps.next().unwrap();
let res = h.add_dataflow_op(Tk2Op::QAlloc, [])?;
let q_out = res.out_wire(0);
let res = h.add_dataflow_op(Tk2Op::CZ, [q_in, q_out])?;
let q_in = res.out_wire(0);
let q_out = res.out_wire(1);
h.add_dataflow_op(Tk2Op::QFree, [q_in])?;
h.finish_hugr_with_outputs([q_out], &PRELUDE_REGISTRY)
}
fn main() {
let mut circ = circ_example().unwrap();
let lhs = alloc().unwrap();
let rhs = alloc_reset().unwrap();
viz_hugr(&circ);
viz_hugr(&lhs);
viz_hugr(&rhs);
let p = CircuitPattern::try_from_circuit(&lhs).unwrap();
let m = PatternMatcher::from_patterns(vec![p]);
let matches = m.find_matches(&circ);
for matched in matches {
matched
.to_rewrite(&circ, rhs.clone())
.unwrap()
.apply(&mut circ)
.unwrap_or_else(|e| {
dbg!(matched.to_rewrite(&circ, rhs.clone()));
panic!("{}", e)
})
}
}
The error:
A node requested for removal is invalid.
stack backtrace:
0: rust_begin_unwind
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/std/src/panicking.rs:645:5
1: core::panicking::panic_fmt
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/core/src/panicking.rs:72:14
2: core::panicking::panic_display
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/core/src/panicking.rs:196:5
3: mbqcification::main::{{closure}}::panic_cold_display
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/core/src/panic.rs:99:13
4: mbqcification::main::{{closure}}
at ./src/main.rs:75:17
5: core::result::Result<T,E>::unwrap_or_else
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/core/src/result.rs:1426:23
6: mbqcification::main
at ./src/main.rs:69:9
7: core::ops::function::FnOnce::call_once
at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/core/src/ops/function.rs:250:5