use onq::core::QduId;
use onq::operations::Operation;
use onq::vm::{Instruction, ProgramBuilder, OnqVm};
fn qid(id: u64) -> QduId {
QduId(id)
}
#[test]
fn test_vm_classical_loop() -> Result<(), Box<dyn std::error::Error>> {
println!("\n--- Test: ONQ-VM Classical Loop ---");
let program = ProgramBuilder::new()
.pb_add(Instruction::LoadImmediate { register: "count".to_string(), value: 0 })
.pb_add(Instruction::LoadImmediate { register: "limit".to_string(), value: 5 })
.pb_add(Instruction::Label("loop_start".to_string()))
.pb_add(Instruction::CmpEq {
r_dest: "cond".to_string(),
r_src1: "count".to_string(),
r_src2: "limit".to_string(),
})
.pb_add(Instruction::BranchIfZero { register: "cond".to_string(), label: "continue_loop".to_string() })
.pb_add(Instruction::Jump("loop_end".to_string()))
.pb_add(Instruction::Label("continue_loop".to_string()))
.pb_add(Instruction::Addi {
r_dest: "count".to_string(),
r_src: "count".to_string(),
value: 1,
})
.pb_add(Instruction::Jump("loop_start".to_string()))
.pb_add(Instruction::Label("loop_end".to_string()))
.pb_add(Instruction::Halt)
.build()?;
println!("Program:\n{}", program);
let mut vm = OnqVm::new();
vm.run(&program)?;
println!("Final Classical Memory: {:?}", vm.get_classical_memory());
assert_eq!(vm.get_classical_register("count"), 5, "Counter should reach 5");
assert_eq!(vm.get_classical_register("limit"), 5, "Limit should be 5");
assert_eq!(vm.get_classical_register("cond"), 1, "Final condition (count==limit) should be true (1)");
Ok(())
}
#[test]
fn test_vm_conditional_quantum() -> Result<(), Box<dyn std::error::Error>> {
println!("\n--- Test: ONQ-VM Conditional Quantum Op ---");
let program = ProgramBuilder::new()
.pb_add(Instruction::QuantumOp(Operation::InteractionPattern {
target: qid(0),
pattern_id: "Superposition".to_string(),
}))
.pb_add(Instruction::Stabilize { targets: vec![qid(0)] })
.pb_add(Instruction::Record { qdu: qid(0), register: "m0".to_string() })
.pb_add(Instruction::BranchIfZero { register: "m0".to_string(), label: "apply_flip".to_string() })
.pb_add(Instruction::Jump("after_flip".to_string()))
.pb_add(Instruction::Label("apply_flip".to_string()))
.pb_add(Instruction::QuantumOp(Operation::InteractionPattern {
target: qid(1), pattern_id: "QualityFlip".to_string(),
}))
.pb_add(Instruction::Label("after_flip".to_string()))
.pb_add(Instruction::Stabilize { targets: vec![qid(1)] })
.pb_add(Instruction::Record { qdu: qid(1), register: "m1".to_string() })
.pb_add(Instruction::Halt)
.build()?;
println!("Program:\n{}", program);
let mut vm = OnqVm::new();
vm.run(&program)?;
let final_mem = vm.get_classical_memory();
println!("Final Classical Memory: {:?}", final_mem);
let m0 = vm.get_classical_register("m0");
let m1 = vm.get_classical_register("m1");
assert_ne!(m0, m1, "m0 and m1 should have opposite values due to conditional flip. m0={}, m1={}", m0, m1);
Ok(())
}