microsoft/qdk

Public

mirrored from https://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
minestarks-patch-1

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

compiler/qsc_eval/src/intrinsic/tests.rs

1886lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use std::f64::consts;
5
6use crate::backend::{Backend, SparseSim};
7use crate::tests::eval_graph;
8use crate::Env;
9use crate::{
10 output::{GenericReceiver, Receiver},
11 val::Value,
12 Error,
13};
14use expect_test::{expect, Expect};
15use indoc::indoc;
16use num_bigint::BigInt;
17use qsc_data_structures::language_features::LanguageFeatures;
18use qsc_data_structures::target::TargetCapabilityFlags;
19use qsc_fir::fir;
20use qsc_frontend::compile::{self, compile, PackageStore, SourceMap};
21use qsc_lowerer::map_hir_package_to_fir;
22use qsc_passes::{run_core_passes, run_default_passes, PackageType};
23
24#[derive(Default)]
25struct CustomSim {
26 sim: SparseSim,
27}
28
29impl Backend for CustomSim {
30 type ResultType = bool;
31
32 fn ccx(&mut self, ctl0: usize, ctl1: usize, q: usize) {
33 self.sim.ccx(ctl0, ctl1, q);
34 }
35
36 fn cx(&mut self, ctl: usize, q: usize) {
37 self.sim.cx(ctl, q);
38 }
39
40 fn cy(&mut self, ctl: usize, q: usize) {
41 self.sim.cy(ctl, q);
42 }
43
44 fn cz(&mut self, ctl: usize, q: usize) {
45 self.sim.cz(ctl, q);
46 }
47
48 fn h(&mut self, q: usize) {
49 self.sim.h(q);
50 }
51
52 fn m(&mut self, q: usize) -> Self::ResultType {
53 self.sim.m(q)
54 }
55
56 fn mresetz(&mut self, q: usize) -> Self::ResultType {
57 self.sim.mresetz(q)
58 }
59
60 fn reset(&mut self, q: usize) {
61 self.sim.reset(q);
62 }
63
64 fn rx(&mut self, theta: f64, q: usize) {
65 self.sim.rx(theta, q);
66 }
67
68 fn rxx(&mut self, theta: f64, q0: usize, q1: usize) {
69 self.sim.rxx(theta, q0, q1);
70 }
71
72 fn ry(&mut self, theta: f64, q: usize) {
73 self.sim.ry(theta, q);
74 }
75
76 fn ryy(&mut self, theta: f64, q0: usize, q1: usize) {
77 self.sim.ryy(theta, q0, q1);
78 }
79
80 fn rz(&mut self, theta: f64, q: usize) {
81 self.sim.rz(theta, q);
82 }
83
84 fn rzz(&mut self, theta: f64, q0: usize, q1: usize) {
85 self.sim.rzz(theta, q0, q1);
86 }
87
88 fn sadj(&mut self, q: usize) {
89 self.sim.sadj(q);
90 }
91
92 fn s(&mut self, q: usize) {
93 self.sim.s(q);
94 }
95
96 fn swap(&mut self, q0: usize, q1: usize) {
97 self.sim.swap(q0, q1);
98 }
99
100 fn tadj(&mut self, q: usize) {
101 self.sim.tadj(q);
102 }
103
104 fn t(&mut self, q: usize) {
105 self.sim.t(q);
106 }
107
108 fn x(&mut self, q: usize) {
109 self.sim.x(q);
110 }
111
112 fn y(&mut self, q: usize) {
113 self.sim.y(q);
114 }
115
116 fn z(&mut self, q: usize) {
117 self.sim.z(q);
118 }
119
120 fn qubit_allocate(&mut self) -> usize {
121 self.sim.qubit_allocate()
122 }
123
124 fn qubit_release(&mut self, q: usize) -> bool {
125 self.sim.qubit_release(q)
126 }
127
128 fn qubit_swap_id(&mut self, q0: usize, q1: usize) {
129 self.sim.qubit_swap_id(q0, q1);
130 }
131
132 fn capture_quantum_state(
133 &mut self,
134 ) -> (Vec<(num_bigint::BigUint, num_complex::Complex<f64>)>, usize) {
135 self.sim.capture_quantum_state()
136 }
137
138 fn qubit_is_zero(&mut self, q: usize) -> bool {
139 self.sim.qubit_is_zero(q)
140 }
141
142 fn custom_intrinsic(&mut self, name: &str, arg: Value) -> Option<Result<Value, String>> {
143 match name {
144 "Add1" => Some(Ok(Value::Int(arg.unwrap_int() + 1))),
145 "Check" => Some(Err("cannot verify input".to_string())),
146 _ => self.sim.custom_intrinsic(name, arg),
147 }
148 }
149}
150
151fn check_intrinsic(file: &str, expr: &str, out: &mut impl Receiver) -> Result<Value, Error> {
152 let mut core = compile::core();
153 run_core_passes(&mut core);
154 let fir_store = fir::PackageStore::new();
155 let core_fir = qsc_lowerer::Lowerer::new().lower_package(&core.package, &fir_store);
156 let mut store = PackageStore::new(core);
157
158 let mut std = compile::std(&store, TargetCapabilityFlags::all());
159 assert!(std.errors.is_empty());
160 assert!(run_default_passes(store.core(), &mut std, PackageType::Lib).is_empty());
161 let std_fir = qsc_lowerer::Lowerer::new().lower_package(&std.package, &fir_store);
162 let std_id = store.insert(std);
163
164 let sources = SourceMap::new([("test".into(), file.into())], Some(expr.into()));
165 let mut unit = compile(
166 &store,
167 &[(std_id, None)],
168 sources,
169 TargetCapabilityFlags::all(),
170 LanguageFeatures::default(),
171 );
172 assert!(unit.errors.is_empty());
173 assert!(run_default_passes(store.core(), &mut unit, PackageType::Lib).is_empty());
174 let unit_fir = qsc_lowerer::Lowerer::new().lower_package(&unit.package, &fir_store);
175 let entry = unit_fir.entry_exec_graph.clone();
176
177 let id = store.insert(unit);
178
179 let mut fir_store = fir::PackageStore::new();
180 fir_store.insert(
181 map_hir_package_to_fir(qsc_hir::hir::PackageId::CORE),
182 core_fir,
183 );
184 fir_store.insert(map_hir_package_to_fir(std_id), std_fir);
185 fir_store.insert(map_hir_package_to_fir(id), unit_fir);
186
187 eval_graph(
188 entry,
189 &mut CustomSim::default(),
190 &fir_store,
191 map_hir_package_to_fir(id),
192 &mut Env::default(),
193 out,
194 )
195 .map_err(|e| e.0)
196}
197
198fn check_intrinsic_result(file: &str, expr: &str, expect: &Expect) {
199 let mut stdout = vec![];
200 let mut out = GenericReceiver::new(&mut stdout);
201 match check_intrinsic(file, expr, &mut out) {
202 Ok(result) => expect.assert_eq(&result.to_string()),
203 Err(e) => expect.assert_eq(&e.to_string()),
204 }
205}
206
207fn check_intrinsic_output(file: &str, expr: &str, expect: &Expect) {
208 let mut stdout = vec![];
209 let mut out = GenericReceiver::new(&mut stdout);
210 match check_intrinsic(file, expr, &mut out) {
211 Ok(..) => expect.assert_eq(
212 &String::from_utf8(stdout).expect("content should be convertable to string"),
213 ),
214 Err(e) => expect.assert_eq(&e.to_string()),
215 }
216}
217
218fn check_intrinsic_value(file: &str, expr: &str, val: &Value) {
219 let mut stdout = vec![];
220 let mut out = GenericReceiver::new(&mut stdout);
221 match check_intrinsic(file, expr, &mut out) {
222 Ok(result) => assert_eq!(&result, val),
223 Err(e) => panic!("{e:?}"),
224 }
225}
226
227#[test]
228fn int_as_double() {
229 check_intrinsic_result(
230 "",
231 "Microsoft.Quantum.Convert.IntAsDouble(2)",
232 &expect!["2.0"],
233 );
234}
235
236#[test]
237fn int_as_double_precision_loss() {
238 check_intrinsic_result(
239 "",
240 "Microsoft.Quantum.Convert.IntAsDouble(9_223_372_036_854_775_807)",
241 &expect!["9223372036854775808.0"],
242 );
243}
244
245#[test]
246fn double_as_string_with_precision() {
247 check_intrinsic_result(
248 "",
249 "Microsoft.Quantum.Convert.DoubleAsStringWithPrecision(0.8414709848078965, 4)",
250 &expect!["0.8415"],
251 );
252}
253
254#[test]
255fn double_as_string_with_precision_extend() {
256 check_intrinsic_result(
257 "",
258 "Microsoft.Quantum.Convert.DoubleAsStringWithPrecision(0.8, 5)",
259 &expect!["0.80000"],
260 );
261}
262
263#[test]
264fn double_as_string_with_precision_negative_error() {
265 check_intrinsic_result(
266 "",
267 "Microsoft.Quantum.Convert.DoubleAsStringWithPrecision(0.8, -5)",
268 &expect!["negative integers cannot be used here: -5"],
269 );
270}
271
272#[test]
273fn double_as_string_with_zero_precision() {
274 check_intrinsic_result(
275 "",
276 "Microsoft.Quantum.Convert.DoubleAsStringWithPrecision(0.47, 0)",
277 &expect!["0."],
278 );
279}
280
281#[test]
282fn double_as_string_with_zero_precision_rounding() {
283 check_intrinsic_result(
284 "",
285 "Microsoft.Quantum.Convert.DoubleAsStringWithPrecision(0.913, 0)",
286 &expect!["1."],
287 );
288}
289
290#[test]
291fn dump_machine() {
292 check_intrinsic_output(
293 "",
294 "Microsoft.Quantum.Diagnostics.DumpMachine()",
295 &expect![[r#"
296 STATE:
297 No qubits allocated
298 "#]],
299 );
300}
301
302#[test]
303fn dump_machine_qubit_count() {
304 check_intrinsic_output(
305 "",
306 indoc! {"{
307 use qs = Qubit[4];
308 Microsoft.Quantum.Diagnostics.DumpMachine();
309 }"},
310 &expect![[r#"
311 STATE:
312 |0000⟩: 1.0000+0.0000𝑖
313 "#]],
314 );
315}
316
317#[test]
318fn dump_machine_endianness() {
319 check_intrinsic_output(
320 "",
321 indoc! {"{
322 use qs = Qubit[4];
323 X(qs[1]);
324 Microsoft.Quantum.Diagnostics.DumpMachine();
325 X(qs[1]);
326 }"},
327 &expect![[r#"
328 STATE:
329 |0100⟩: 1.0000+0.0000𝑖
330 "#]],
331 );
332}
333
334#[test]
335fn dump_register_all_qubits() {
336 check_intrinsic_output(
337 "",
338 indoc! {"{
339 use qs = Qubit[4];
340 X(qs[1]);
341 Microsoft.Quantum.Diagnostics.DumpRegister(qs);
342 X(qs[1]);
343 }"},
344 &expect![[r#"
345 STATE:
346 |0100⟩: 1.0000+0.0000𝑖
347 "#]],
348 );
349}
350
351#[test]
352fn dump_register_subset_qubits() {
353 check_intrinsic_output(
354 "",
355 indoc! {"{
356 use qs = Qubit[4];
357 X(qs[1]);
358 Microsoft.Quantum.Diagnostics.DumpRegister([qs[1], qs[2]]);
359 X(qs[1]);
360 }"},
361 &expect![[r#"
362 STATE:
363 |10⟩: 1.0000+0.0000𝑖
364 "#]],
365 );
366}
367
368#[test]
369fn dump_register_subset_entangled_within_subset_is_separable() {
370 check_intrinsic_output(
371 "",
372 indoc! {"{
373 use (q1, q2, q3) = (Qubit(), Qubit(), Qubit());
374 H(q1);
375 CNOT(q1, q3);
376 Microsoft.Quantum.Diagnostics.DumpRegister([q1, q3]);
377 Reset(q1);
378 Reset(q2);
379 Reset(q3);
380 }"},
381 &expect![[r#"
382 STATE:
383 |00⟩: 0.7071+0.0000𝑖
384 |11⟩: 0.7071+0.0000𝑖
385 "#]],
386 );
387}
388
389#[test]
390fn dump_register_subset_entangled_with_other_qubits_not_separable() {
391 check_intrinsic_result(
392 "",
393 indoc! {"{
394 use (q1, q2, q3) = (Qubit(), Qubit(), Qubit());
395 H(q1);
396 CNOT(q1, q3);
397 Microsoft.Quantum.Diagnostics.DumpRegister([q1, q2]);
398 }"},
399 &expect!["qubits are not separable"],
400 );
401}
402
403#[test]
404fn dump_register_other_qubits_superposition_is_separable() {
405 check_intrinsic_output(
406 "",
407 indoc! {"{
408 use qs = Qubit[3];
409 H(qs[0]);
410 H(qs[2]);
411 Microsoft.Quantum.Diagnostics.DumpRegister(qs[...1]);
412 ResetAll(qs);
413 }"},
414 &expect![[r#"
415 STATE:
416 |00⟩: 0.7071+0.0000𝑖
417 |10⟩: 0.7071+0.0000𝑖
418 "#]],
419 );
420}
421
422#[test]
423fn dump_register_other_qubits_one_state_is_separable() {
424 check_intrinsic_output(
425 "",
426 indoc! {"{
427 use qs = Qubit[3];
428 H(qs[0]);
429 X(qs[2]);
430 Microsoft.Quantum.Diagnostics.DumpRegister(qs[...1]);
431 ResetAll(qs);
432 }"},
433 &expect![[r#"
434 STATE:
435 |00⟩: 0.7071+0.0000𝑖
436 |10⟩: 0.7071+0.0000𝑖
437 "#]],
438 );
439}
440
441#[test]
442fn dump_register_other_qubits_phase_reflected_in_subset() {
443 check_intrinsic_output(
444 "",
445 indoc! {"{
446 use qs = Qubit[3];
447 H(qs[0]);
448 X(qs[2]);
449 Z(qs[2]);
450 Microsoft.Quantum.Diagnostics.DumpRegister(qs[...1]);
451 ResetAll(qs);
452 }"},
453 &expect![[r#"
454 STATE:
455 |00⟩: −0.7071+0.0000𝑖
456 |10⟩: −0.7071+0.0000𝑖
457 "#]],
458 );
459}
460
461#[test]
462fn dump_register_qubits_reorder_output() {
463 check_intrinsic_output(
464 "",
465 indoc! {"{
466 use qs = Qubit[5];
467 H(qs[0]);
468 X(qs[2]);
469 Microsoft.Quantum.Diagnostics.DumpMachine();
470 Microsoft.Quantum.Diagnostics.DumpRegister(qs[2..-1...]);
471 ResetAll(qs);
472 }"},
473 &expect![[r#"
474 STATE:
475 |00100⟩: 0.7071+0.0000𝑖
476 |10100⟩: 0.7071+0.0000𝑖
477 STATE:
478 |100⟩: 0.7071+0.0000𝑖
479 |101⟩: 0.7071+0.0000𝑖
480 "#]],
481 );
482}
483
484#[test]
485fn dump_register_qubits_reorder_output_should_be_sorted() {
486 check_intrinsic_output(
487 "",
488 indoc! {"{
489 use qs = Qubit[5];
490 H(qs[0]);
491 H(qs[2]);
492 Microsoft.Quantum.Diagnostics.DumpMachine();
493 Microsoft.Quantum.Diagnostics.DumpRegister(qs[0..2..3]);
494 ResetAll(qs);
495 }"},
496 &expect![[r#"
497 STATE:
498 |00000⟩: 0.5000+0.0000𝑖
499 |00100⟩: 0.5000+0.0000𝑖
500 |10000⟩: 0.5000+0.0000𝑖
501 |10100⟩: 0.5000+0.0000𝑖
502 STATE:
503 |00⟩: 0.5000+0.0000𝑖
504 |01⟩: 0.5000+0.0000𝑖
505 |10⟩: 0.5000+0.0000𝑖
506 |11⟩: 0.5000+0.0000𝑖
507 "#]],
508 );
509}
510
511#[test]
512fn dump_register_qubits_not_unique_fails() {
513 check_intrinsic_result(
514 "",
515 indoc! {"{
516 use qs = Qubit[3];
517 H(qs[0]);
518 Microsoft.Quantum.Diagnostics.DumpRegister([qs[0], qs[0]]);
519 }"},
520 &expect!["qubits in invocation are not unique"],
521 );
522}
523
524#[test]
525fn dump_register_qubits_already_released_fails() {
526 check_intrinsic_result(
527 "",
528 indoc! {"{
529 let q = { use q = Qubit(); q };
530 Microsoft.Quantum.Diagnostics.DumpRegister([q]);
531 }"},
532 &expect!["qubit used after release"],
533 );
534}
535
536#[test]
537fn dump_register_target_in_minus_with_other_in_zero() {
538 check_intrinsic_output(
539 "",
540 indoc! {"{
541 use qs = Qubit[2];
542 X(qs[0]);
543 H(qs[0]);
544 Microsoft.Quantum.Diagnostics.DumpRegister([qs[0]]);
545 ResetAll(qs);
546 }"},
547 &expect![[r#"
548 STATE:
549 |0⟩: 0.7071+0.0000𝑖
550 |1⟩: −0.7071+0.0000𝑖
551 "#]],
552 );
553}
554
555#[test]
556fn dump_register_target_in_minus_with_other_in_one() {
557 check_intrinsic_output(
558 "",
559 indoc! {"{
560 use qs = Qubit[2];
561 X(qs[1]);
562 X(qs[0]);
563 H(qs[0]);
564 Microsoft.Quantum.Diagnostics.DumpRegister([qs[0]]);
565 ResetAll(qs);
566 }"},
567 &expect![[r#"
568 STATE:
569 |0⟩: 0.7071+0.0000𝑖
570 |1⟩: −0.7071+0.0000𝑖
571 "#]],
572 );
573}
574
575#[test]
576fn dump_register_all_qubits_normalized_is_same_as_dump_machine() {
577 check_intrinsic_output(
578 "",
579 indoc! {
580 "{
581 import Std.Diagnostics.*;
582 use qs = Qubit[2];
583
584 let alpha = -4.20025;
585 let beta = 2.04776;
586 let gamma = -5.47097;
587
588 within{
589 Ry(alpha, qs[0]);
590 Ry(beta, qs[1]);
591 CNOT(qs[0], qs[1]);
592 Ry(gamma, qs[1]);
593 }
594 apply{
595 DumpRegister(qs);
596 DumpMachine();
597 }
598 }"
599 },
600 &expect![[r#"
601 STATE:
602 |00⟩: 0.0709+0.0000𝑖
603 |01⟩: 0.5000+0.0000𝑖
604 |10⟩: 0.5000+0.0000𝑖
605 |11⟩: 0.7036+0.0000𝑖
606 STATE:
607 |00⟩: 0.0709+0.0000𝑖
608 |01⟩: 0.5000+0.0000𝑖
609 |10⟩: 0.5000+0.0000𝑖
610 |11⟩: 0.7036+0.0000𝑖
611 "#]],
612 );
613}
614
615#[test]
616fn message() {
617 check_intrinsic_output(
618 "",
619 r#"Message("Hello, World!")"#,
620 &expect![[r#"
621 Hello, World!
622 "#]],
623 );
624}
625
626#[test]
627fn check_zero() {
628 check_intrinsic_result(
629 "",
630 "{use q = Qubit(); Microsoft.Quantum.Diagnostics.CheckZero(q)}",
631 &expect!["true"],
632 );
633}
634
635#[test]
636fn check_zero_false() {
637 check_intrinsic_result(
638 "",
639 indoc! {"{
640 use q = Qubit();
641 X(q);
642 let isZero = Microsoft.Quantum.Diagnostics.CheckZero(q);
643 X(q);
644 isZero
645 }"},
646 &expect!["false"],
647 );
648}
649
650#[test]
651fn check_zero_qubit_already_released_fails() {
652 check_intrinsic_result(
653 "",
654 indoc! {"{
655 let q = { use q = Qubit(); q };
656 Microsoft.Quantum.Diagnostics.CheckZero(q)
657 }"},
658 &expect!["qubit used after release"],
659 );
660}
661
662#[test]
663fn length() {
664 check_intrinsic_value("", "Length([1, 2, 3])", &Value::Int(3));
665}
666
667#[test]
668fn arccos() {
669 check_intrinsic_value(
670 "",
671 "Microsoft.Quantum.Math.ArcCos(0.3)",
672 &Value::Double((0.3f64).acos()),
673 );
674}
675
676#[test]
677fn arcsin() {
678 check_intrinsic_value(
679 "",
680 "Microsoft.Quantum.Math.ArcSin(0.3)",
681 &Value::Double((0.3f64).asin()),
682 );
683}
684
685#[test]
686fn arctan() {
687 check_intrinsic_value(
688 "",
689 "Microsoft.Quantum.Math.ArcTan(0.3)",
690 &Value::Double((0.3f64).atan()),
691 );
692}
693
694#[test]
695fn arctan2() {
696 check_intrinsic_value(
697 "",
698 "Microsoft.Quantum.Math.ArcTan2(0.3, 0.7)",
699 &Value::Double((0.3f64).atan2(0.7)),
700 );
701}
702
703#[test]
704fn cos() {
705 check_intrinsic_value(
706 "",
707 "Microsoft.Quantum.Math.Cos(Microsoft.Quantum.Math.PI())",
708 &Value::Double((consts::PI).cos()),
709 );
710}
711
712#[test]
713fn cosh() {
714 check_intrinsic_value(
715 "",
716 "Microsoft.Quantum.Math.Cosh(Microsoft.Quantum.Math.PI())",
717 &Value::Double((consts::PI).cosh()),
718 );
719}
720
721#[test]
722fn sin() {
723 check_intrinsic_value(
724 "",
725 "Microsoft.Quantum.Math.Sin(Microsoft.Quantum.Math.PI())",
726 &Value::Double((consts::PI).sin()),
727 );
728}
729
730#[test]
731fn sinh() {
732 check_intrinsic_value(
733 "",
734 "Microsoft.Quantum.Math.Sinh(Microsoft.Quantum.Math.PI())",
735 &Value::Double((consts::PI).sinh()),
736 );
737}
738
739#[test]
740fn tan() {
741 check_intrinsic_value(
742 "",
743 "Microsoft.Quantum.Math.Tan(Microsoft.Quantum.Math.PI())",
744 &Value::Double((consts::PI).tan()),
745 );
746}
747
748#[test]
749fn tanh() {
750 check_intrinsic_value(
751 "",
752 "Microsoft.Quantum.Math.Tanh(Microsoft.Quantum.Math.PI())",
753 &Value::Double((consts::PI).tanh()),
754 );
755}
756
757#[test]
758fn draw_random_int() {
759 check_intrinsic_value(
760 "",
761 "Microsoft.Quantum.Random.DrawRandomInt(5,5)",
762 &Value::Int(5),
763 );
764}
765
766#[test]
767fn draw_random_double() {
768 check_intrinsic_value(
769 "",
770 "Microsoft.Quantum.Random.DrawRandomDouble(5.0,5.0)",
771 &Value::Double(5.0),
772 );
773}
774
775#[test]
776fn draw_random_bool() {
777 check_intrinsic_value(
778 "",
779 "Microsoft.Quantum.Random.DrawRandomBool(0.0)",
780 &Value::Bool(false),
781 );
782 check_intrinsic_value(
783 "",
784 "Microsoft.Quantum.Random.DrawRandomBool(1.0)",
785 &Value::Bool(true),
786 );
787}
788
789#[test]
790fn truncate() {
791 check_intrinsic_value("", "Microsoft.Quantum.Math.Truncate(3.1)", &Value::Int(3));
792 check_intrinsic_value("", "Microsoft.Quantum.Math.Truncate(3.9)", &Value::Int(3));
793 check_intrinsic_value("", "Microsoft.Quantum.Math.Truncate(-3.1)", &Value::Int(-3));
794 check_intrinsic_value("", "Microsoft.Quantum.Math.Truncate(-3.9)", &Value::Int(-3));
795}
796
797#[test]
798fn sqrt() {
799 check_intrinsic_value("", "Microsoft.Quantum.Math.Sqrt(0.0)", &Value::Double(0.0));
800 check_intrinsic_value("", "Microsoft.Quantum.Math.Sqrt(81.0)", &Value::Double(9.0));
801}
802
803#[test]
804fn log() {
805 check_intrinsic_value("", "Microsoft.Quantum.Math.Log(1.0)", &Value::Double(0.0));
806 check_intrinsic_value(
807 "",
808 "Microsoft.Quantum.Math.Log(Microsoft.Quantum.Math.E())",
809 &Value::Double(1.0),
810 );
811}
812
813#[test]
814fn int_as_bigint() {
815 check_intrinsic_value(
816 "",
817 "Microsoft.Quantum.Convert.IntAsBigInt(0)",
818 &Value::BigInt(BigInt::from(0)),
819 );
820 check_intrinsic_value(
821 "",
822 "Microsoft.Quantum.Convert.IntAsBigInt(-10000)",
823 &Value::BigInt(BigInt::from(-10000)),
824 );
825}
826
827#[test]
828fn ccx() {
829 check_intrinsic_result(
830 "",
831 indoc! {r#"{
832 use (q1, q2, q3) = (Qubit(), Qubit(), Qubit());
833 QIR.Intrinsic.__quantum__qis__ccx__body(q1, q2, q3);
834 if not Microsoft.Quantum.Diagnostics.CheckZero(q3) {
835 fail "Qubit should still be in zero state.";
836 }
837 X(q1);
838 X(q2);
839 QIR.Intrinsic.__quantum__qis__ccx__body(q1, q2, q3);
840 if Microsoft.Quantum.Diagnostics.CheckZero(q3) {
841 fail "Qubit should be in one state.";
842 }
843 X(q3);
844 X(q2);
845 X(q1);
846 Microsoft.Quantum.Diagnostics.CheckZero(q3)
847 }"#},
848 &expect!["true"],
849 );
850}
851
852#[test]
853fn cx() {
854 check_intrinsic_result(
855 "",
856 indoc! {r#"{
857 use (q1, q2) = (Qubit(), Qubit());
858 QIR.Intrinsic.__quantum__qis__cx__body(q1, q2);
859 if not Microsoft.Quantum.Diagnostics.CheckZero(q2) {
860 fail "Qubit should still be in zero state.";
861 }
862 X(q1);
863 QIR.Intrinsic.__quantum__qis__cx__body(q1, q2);
864 if Microsoft.Quantum.Diagnostics.CheckZero(q2) {
865 fail "Qubit should be in one state.";
866 }
867 X(q2);
868 X(q1);
869 Microsoft.Quantum.Diagnostics.CheckZero(q2)
870 }"#},
871 &expect!["true"],
872 );
873}
874
875#[test]
876fn cy() {
877 check_intrinsic_result(
878 "",
879 indoc! {r#"{
880 use (q1, q2) = (Qubit(), Qubit());
881 QIR.Intrinsic.__quantum__qis__cy__body(q1, q2);
882 if not Microsoft.Quantum.Diagnostics.CheckZero(q2) {
883 fail "Qubit should still be in zero state.";
884 }
885 X(q1);
886 QIR.Intrinsic.__quantum__qis__cy__body(q1, q2);
887 if Microsoft.Quantum.Diagnostics.CheckZero(q2) {
888 fail "Qubit should be in one state.";
889 }
890 Y(q2);
891 X(q1);
892 Microsoft.Quantum.Diagnostics.CheckZero(q2)
893 }"#},
894 &expect!["true"],
895 );
896}
897
898#[test]
899fn cz() {
900 check_intrinsic_result(
901 "",
902 indoc! {r#"{
903 use (q1, q2) = (Qubit(), Qubit());
904 H(q2);
905 QIR.Intrinsic.__quantum__qis__cz__body(q1, q2);
906 H(q2);
907 if not Microsoft.Quantum.Diagnostics.CheckZero(q2) {
908 fail "Qubit should still be in zero state.";
909 }
910 X(q1);
911 H(q2);
912 QIR.Intrinsic.__quantum__qis__cz__body(q1, q2);
913 H(q2);
914 if Microsoft.Quantum.Diagnostics.CheckZero(q2) {
915 fail "Qubit should be in one state.";
916 }
917 X(q2);
918 X(q1);
919 Microsoft.Quantum.Diagnostics.CheckZero(q2)
920 }"#},
921 &expect!["true"],
922 );
923}
924
925#[test]
926fn rx() {
927 check_intrinsic_result(
928 "",
929 indoc! {r#"{
930 use q1 = Qubit();
931 let pi = Microsoft.Quantum.Math.PI();
932 QIR.Intrinsic.__quantum__qis__rx__body(pi, q1);
933 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
934 fail "Qubit should be in one state.";
935 }
936 X(q1);
937 Microsoft.Quantum.Diagnostics.CheckZero(q1)
938 }"#},
939 &expect!["true"],
940 );
941}
942
943#[test]
944fn rx_qubit_already_released_fails() {
945 check_intrinsic_result(
946 "",
947 indoc! {"{
948 let q = { use q = Qubit(); q };
949 QIR.Intrinsic.__quantum__qis__rx__body(3.14, q)
950 }"},
951 &expect!["qubit used after release"],
952 );
953}
954
955#[test]
956fn rxx() {
957 check_intrinsic_result(
958 "",
959 indoc! {r#"{
960 use (q1, q2) = (Qubit(), Qubit());
961 let pi = Microsoft.Quantum.Math.PI();
962 QIR.Intrinsic.__quantum__qis__rxx__body(pi, q1, q2);
963 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
964 fail "Qubit should be in one state.";
965 }
966 if Microsoft.Quantum.Diagnostics.CheckZero(q2) {
967 fail "Qubit 2 should be in one state.";
968 }
969 X(q2);
970 X(q1);
971 (Microsoft.Quantum.Diagnostics.CheckZero(q1), Microsoft.Quantum.Diagnostics.CheckZero(q2))
972 }"#},
973 &expect!["(true, true)"],
974 );
975}
976
977#[test]
978fn rxx_qubits_already_released_fails() {
979 check_intrinsic_result(
980 "",
981 indoc! {"{
982 let q1 = { use q = Qubit(); q };
983 let q2 = { use q = Qubit(); q };
984 QIR.Intrinsic.__quantum__qis__rxx__body(3.14, q1, q2)
985 }"},
986 &expect!["qubit used after release"],
987 );
988}
989
990#[test]
991fn ry() {
992 check_intrinsic_result(
993 "",
994 indoc! {r#"{
995 use q1 = Qubit();
996 let pi = Microsoft.Quantum.Math.PI();
997 QIR.Intrinsic.__quantum__qis__ry__body(pi, q1);
998 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
999 fail "Qubit should be in one state.";
1000 }
1001 Y(q1);
1002 Microsoft.Quantum.Diagnostics.CheckZero(q1)
1003 }"#},
1004 &expect!["true"],
1005 );
1006}
1007
1008#[test]
1009fn ry_qubit_already_released_fails() {
1010 check_intrinsic_result(
1011 "",
1012 indoc! {"{
1013 let q = { use q = Qubit(); q };
1014 QIR.Intrinsic.__quantum__qis__ry__body(3.14, q)
1015 }"},
1016 &expect!["qubit used after release"],
1017 );
1018}
1019
1020#[test]
1021fn ryy() {
1022 check_intrinsic_result(
1023 "",
1024 indoc! {r#"{
1025 use (q1, q2) = (Qubit(), Qubit());
1026 let pi = Microsoft.Quantum.Math.PI();
1027 QIR.Intrinsic.__quantum__qis__ryy__body(pi, q1, q2);
1028 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1029 fail "Qubit should be in one state.";
1030 }
1031 if Microsoft.Quantum.Diagnostics.CheckZero(q2) {
1032 fail "Qubit 2 should be in one state.";
1033 }
1034 Y(q2);
1035 Y(q1);
1036 (Microsoft.Quantum.Diagnostics.CheckZero(q1), Microsoft.Quantum.Diagnostics.CheckZero(q2))
1037 }"#},
1038 &expect!["(true, true)"],
1039 );
1040}
1041
1042#[test]
1043fn ryy_qubits_already_released_fails() {
1044 check_intrinsic_result(
1045 "",
1046 indoc! {"{
1047 let q1 = { use q = Qubit(); q };
1048 let q2 = { use q = Qubit(); q };
1049 QIR.Intrinsic.__quantum__qis__ryy__body(3.14, q1, q2)
1050 }"},
1051 &expect!["qubit used after release"],
1052 );
1053}
1054
1055#[test]
1056fn rz() {
1057 check_intrinsic_result(
1058 "",
1059 indoc! {r#"{
1060 use q1 = Qubit();
1061 let pi = Microsoft.Quantum.Math.PI();
1062 H(q1);
1063 QIR.Intrinsic.__quantum__qis__rz__body(pi, q1);
1064 H(q1);
1065 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1066 fail "Qubit should be in one state.";
1067 }
1068 H(q1);
1069 Z(q1);
1070 H(q1);
1071 Microsoft.Quantum.Diagnostics.CheckZero(q1)
1072 }"#},
1073 &expect!["true"],
1074 );
1075}
1076
1077#[test]
1078fn rz_qubit_already_released_fails() {
1079 check_intrinsic_result(
1080 "",
1081 indoc! {"{
1082 let q = { use q = Qubit(); q };
1083 QIR.Intrinsic.__quantum__qis__rz__body(3.14, q)
1084 }"},
1085 &expect!["qubit used after release"],
1086 );
1087}
1088
1089#[test]
1090fn rzz() {
1091 check_intrinsic_result(
1092 "",
1093 indoc! {r#"{
1094 use (q1, q2) = (Qubit(), Qubit());
1095 let pi = Microsoft.Quantum.Math.PI();
1096 H(q1);
1097 H(q2);
1098 QIR.Intrinsic.__quantum__qis__rzz__body(pi, q1, q2);
1099 H(q1);
1100 H(q2);
1101 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1102 fail "Qubit should be in one state.";
1103 }
1104 if Microsoft.Quantum.Diagnostics.CheckZero(q2) {
1105 fail "Qubit 2 should be in one state.";
1106 }
1107 H(q2);
1108 H(q1);
1109 Z(q2);
1110 Z(q1);
1111 H(q2);
1112 H(q1);
1113 (Microsoft.Quantum.Diagnostics.CheckZero(q1), Microsoft.Quantum.Diagnostics.CheckZero(q2))
1114 }"#},
1115 &expect!["(true, true)"],
1116 );
1117}
1118
1119#[test]
1120fn rzz_qubits_already_released_fails() {
1121 check_intrinsic_result(
1122 "",
1123 indoc! {"{
1124 let q1 = { use q = Qubit(); q };
1125 let q2 = { use q = Qubit(); q };
1126 QIR.Intrinsic.__quantum__qis__rzz__body(3.14, q1, q2)
1127 }"},
1128 &expect!["qubit used after release"],
1129 );
1130}
1131
1132#[test]
1133fn h() {
1134 check_intrinsic_result(
1135 "",
1136 indoc! {r#"{
1137 use q1 = Qubit();
1138 QIR.Intrinsic.__quantum__qis__h__body(q1);
1139 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1140 fail "Qubit should be in one state.";
1141 }
1142 H(q1);
1143 Microsoft.Quantum.Diagnostics.CheckZero(q1)
1144 }"#},
1145 &expect!["true"],
1146 );
1147}
1148
1149#[test]
1150fn h_qubit_already_released_fails() {
1151 check_intrinsic_result(
1152 "",
1153 indoc! {"{
1154 let q = { use q = Qubit(); q };
1155 QIR.Intrinsic.__quantum__qis__h__body(q)
1156 }"},
1157 &expect!["qubit used after release"],
1158 );
1159}
1160
1161#[test]
1162fn s() {
1163 check_intrinsic_result(
1164 "",
1165 indoc! {r#"{
1166 use q1 = Qubit();
1167 H(q1);
1168 QIR.Intrinsic.__quantum__qis__s__body(q1);
1169 H(q1);
1170 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1171 fail "Qubit should be in one state.";
1172 }
1173 H(q1);
1174 QIR.Intrinsic.__quantum__qis__s__body(q1);
1175 QIR.Intrinsic.__quantum__qis__s__body(q1);
1176 QIR.Intrinsic.__quantum__qis__s__body(q1);
1177 H(q1);
1178 Microsoft.Quantum.Diagnostics.CheckZero(q1)
1179 }"#},
1180 &expect!["true"],
1181 );
1182}
1183
1184#[test]
1185fn s_qubit_already_released_fails() {
1186 check_intrinsic_result(
1187 "",
1188 indoc! {"{
1189 let q = { use q = Qubit(); q };
1190 QIR.Intrinsic.__quantum__qis__s__body(q)
1191 }"},
1192 &expect!["qubit used after release"],
1193 );
1194}
1195
1196#[test]
1197fn sadj() {
1198 check_intrinsic_result(
1199 "",
1200 indoc! {r#"{
1201 use q1 = Qubit();
1202 H(q1);
1203 QIR.Intrinsic.__quantum__qis__s__adj(q1);
1204 H(q1);
1205 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1206 fail "Qubit should be in one state.";
1207 }
1208 H(q1);
1209 QIR.Intrinsic.__quantum__qis__s__adj(q1);
1210 QIR.Intrinsic.__quantum__qis__s__adj(q1);
1211 QIR.Intrinsic.__quantum__qis__s__adj(q1);
1212 H(q1);
1213 Microsoft.Quantum.Diagnostics.CheckZero(q1)
1214 }"#},
1215 &expect!["true"],
1216 );
1217}
1218
1219#[test]
1220fn sadj_qubit_already_released_fails() {
1221 check_intrinsic_result(
1222 "",
1223 indoc! {"{
1224 let q = { use q = Qubit(); q };
1225 QIR.Intrinsic.__quantum__qis__s__adj(q)
1226 }"},
1227 &expect!["qubit used after release"],
1228 );
1229}
1230
1231#[test]
1232fn t() {
1233 check_intrinsic_result(
1234 "",
1235 indoc! {r#"{
1236 use q1 = Qubit();
1237 H(q1);
1238 QIR.Intrinsic.__quantum__qis__t__body(q1);
1239 QIR.Intrinsic.__quantum__qis__t__body(q1);
1240 H(q1);
1241 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1242 fail "Qubit should be in one state.";
1243 }
1244 H(q1);
1245 QIR.Intrinsic.__quantum__qis__t__body(q1);
1246 QIR.Intrinsic.__quantum__qis__t__body(q1);
1247 QIR.Intrinsic.__quantum__qis__t__body(q1);
1248 QIR.Intrinsic.__quantum__qis__t__body(q1);
1249 QIR.Intrinsic.__quantum__qis__t__body(q1);
1250 QIR.Intrinsic.__quantum__qis__t__body(q1);
1251 H(q1);
1252 Microsoft.Quantum.Diagnostics.CheckZero(q1)
1253 }"#},
1254 &expect!["true"],
1255 );
1256}
1257
1258#[test]
1259fn t_qubit_already_released_fails() {
1260 check_intrinsic_result(
1261 "",
1262 indoc! {"{
1263 let q = { use q = Qubit(); q };
1264 QIR.Intrinsic.__quantum__qis__t__body(q)
1265 }"},
1266 &expect!["qubit used after release"],
1267 );
1268}
1269
1270#[test]
1271fn tadj() {
1272 check_intrinsic_result(
1273 "",
1274 indoc! {r#"{
1275 use q1 = Qubit();
1276 H(q1);
1277 QIR.Intrinsic.__quantum__qis__t__adj(q1);
1278 QIR.Intrinsic.__quantum__qis__t__adj(q1);
1279 H(q1);
1280 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1281 fail "Qubit should be in one state.";
1282 }
1283 H(q1);
1284 QIR.Intrinsic.__quantum__qis__t__adj(q1);
1285 QIR.Intrinsic.__quantum__qis__t__adj(q1);
1286 QIR.Intrinsic.__quantum__qis__t__adj(q1);
1287 QIR.Intrinsic.__quantum__qis__t__adj(q1);
1288 QIR.Intrinsic.__quantum__qis__t__adj(q1);
1289 QIR.Intrinsic.__quantum__qis__t__adj(q1);
1290 H(q1);
1291 Microsoft.Quantum.Diagnostics.CheckZero(q1)
1292 }"#},
1293 &expect!["true"],
1294 );
1295}
1296
1297#[test]
1298fn tadj_qubit_already_released_fails() {
1299 check_intrinsic_result(
1300 "",
1301 indoc! {"{
1302 let q = { use q = Qubit(); q };
1303 QIR.Intrinsic.__quantum__qis__t__adj(q)
1304 }"},
1305 &expect!["qubit used after release"],
1306 );
1307}
1308
1309#[test]
1310fn x() {
1311 check_intrinsic_result(
1312 "",
1313 indoc! {r#"{
1314 use q1 = Qubit();
1315 QIR.Intrinsic.__quantum__qis__x__body(q1);
1316 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1317 fail "Qubit should be in one state.";
1318 }
1319 QIR.Intrinsic.__quantum__qis__x__body(q1);
1320 Microsoft.Quantum.Diagnostics.CheckZero(q1)
1321 }"#},
1322 &expect!["true"],
1323 );
1324}
1325
1326#[test]
1327fn x_qubit_already_released_fails() {
1328 check_intrinsic_result(
1329 "",
1330 indoc! {"{
1331 let q = { use q = Qubit(); q };
1332 QIR.Intrinsic.__quantum__qis__x__body(q)
1333 }"},
1334 &expect!["qubit used after release"],
1335 );
1336}
1337
1338#[test]
1339fn y() {
1340 check_intrinsic_result(
1341 "",
1342 indoc! {r#"{
1343 use q1 = Qubit();
1344 QIR.Intrinsic.__quantum__qis__y__body(q1);
1345 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1346 fail "Qubit should be in one state.";
1347 }
1348 QIR.Intrinsic.__quantum__qis__y__body(q1);
1349 Microsoft.Quantum.Diagnostics.CheckZero(q1)
1350 }"#},
1351 &expect!["true"],
1352 );
1353}
1354
1355#[test]
1356fn y_qubit_already_released_fails() {
1357 check_intrinsic_result(
1358 "",
1359 indoc! {"{
1360 let q = { use q = Qubit(); q };
1361 QIR.Intrinsic.__quantum__qis__y__body(q)
1362 }"},
1363 &expect!["qubit used after release"],
1364 );
1365}
1366
1367#[test]
1368fn z() {
1369 check_intrinsic_result(
1370 "",
1371 indoc! {r#"{
1372 use q1 = Qubit();
1373 H(q1);
1374 QIR.Intrinsic.__quantum__qis__z__body(q1);
1375 H(q1);
1376 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1377 fail "Qubit should be in one state.";
1378 }
1379 H(q1);
1380 QIR.Intrinsic.__quantum__qis__z__body(q1);
1381 H(q1);
1382 Microsoft.Quantum.Diagnostics.CheckZero(q1)
1383 }"#},
1384 &expect!["true"],
1385 );
1386}
1387
1388#[test]
1389fn z_qubit_already_released_fails() {
1390 check_intrinsic_result(
1391 "",
1392 indoc! {"{
1393 let q = { use q = Qubit(); q };
1394 QIR.Intrinsic.__quantum__qis__z__body(q)
1395 }"},
1396 &expect!["qubit used after release"],
1397 );
1398}
1399
1400#[test]
1401fn swap() {
1402 check_intrinsic_result(
1403 "",
1404 indoc! {r#"{
1405 use (q1, q2) = (Qubit(), Qubit());
1406 X(q2);
1407 QIR.Intrinsic.__quantum__qis__swap__body(q1, q2);
1408 if not Microsoft.Quantum.Diagnostics.CheckZero(q2) {
1409 fail "Qubit should be swapped to zero state.";
1410 }
1411 if Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1412 fail "Qubit should swapped to one state.";
1413 }
1414 X(q1);
1415 (Microsoft.Quantum.Diagnostics.CheckZero(q2), Microsoft.Quantum.Diagnostics.CheckZero(q2))
1416 }"#},
1417 &expect!["(true, true)"],
1418 );
1419}
1420
1421#[test]
1422fn swap_qubits_already_released_fails() {
1423 check_intrinsic_result(
1424 "",
1425 indoc! {"{
1426 let q1 = { use q = Qubit(); q };
1427 let q2 = { use q = Qubit(); q };
1428 QIR.Intrinsic.__quantum__qis__swap__body(q1, q2)
1429 }"},
1430 &expect!["qubit used after release"],
1431 );
1432}
1433
1434#[test]
1435fn reset() {
1436 check_intrinsic_result(
1437 "",
1438 indoc! {r#"{
1439 use q1 = Qubit();
1440 QIR.Intrinsic.__quantum__qis__reset__body(q1);
1441 if not Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1442 fail "Qubit should be in zero state.";
1443 }
1444 X(q1);
1445 QIR.Intrinsic.__quantum__qis__reset__body(q1);
1446 Microsoft.Quantum.Diagnostics.CheckZero(q1)
1447 }"#},
1448 &expect!["true"],
1449 );
1450}
1451
1452#[test]
1453fn reset_qubit_already_released_fails() {
1454 check_intrinsic_result(
1455 "",
1456 indoc! {"{
1457 let q = { use q = Qubit(); q };
1458 QIR.Intrinsic.__quantum__qis__reset__body(q)
1459 }"},
1460 &expect!["qubit used after release"],
1461 );
1462}
1463
1464#[test]
1465fn reset_all() {
1466 check_intrinsic_result(
1467 "",
1468 indoc! {r#"{
1469 use register = Qubit[2];
1470 ResetAll(register);
1471 if not Microsoft.Quantum.Diagnostics.CheckAllZero(register) {
1472 fail "Qubits should be in zero state.";
1473 }
1474
1475 for q in register {
1476 X(q);
1477 }
1478
1479 ResetAll(register);
1480 Microsoft.Quantum.Diagnostics.CheckAllZero(register)
1481 }"#},
1482 &expect!["true"],
1483 );
1484}
1485
1486#[test]
1487fn m() {
1488 check_intrinsic_result(
1489 "",
1490 indoc! {r#"{
1491 use q1 = Qubit();
1492 if not Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1493 fail "Qubit should be in zero state.";
1494 }
1495 let res1 = QIR.Intrinsic.__quantum__qis__m__body(q1);
1496 if One == res1 {
1497 fail "Qubit should measure Zero"
1498 }
1499 if not Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1500 fail "Qubit should be in zero state.";
1501 }
1502 X(q1);
1503 let res2 = (QIR.Intrinsic.__quantum__qis__m__body(q1), Microsoft.Quantum.Diagnostics.CheckZero(q1));
1504 X(q1);
1505 res2
1506 }"#},
1507 &expect!["(One, false)"],
1508 );
1509}
1510
1511#[test]
1512fn m_qubit_already_released_fails() {
1513 check_intrinsic_result(
1514 "",
1515 indoc! {"{
1516 let q = { use q = Qubit(); q };
1517 QIR.Intrinsic.__quantum__qis__m__body(q)
1518 }"},
1519 &expect!["qubit used after release"],
1520 );
1521}
1522
1523#[test]
1524fn mresetz() {
1525 check_intrinsic_result(
1526 "",
1527 indoc! {r#"{
1528 use q1 = Qubit();
1529 if not Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1530 fail "Qubit should be in zero state.";
1531 }
1532 let res1 = QIR.Intrinsic.__quantum__qis__mresetz__body(q1);
1533 if One == res1 {
1534 fail "Qubit should measure Zero"
1535 }
1536 if not Microsoft.Quantum.Diagnostics.CheckZero(q1) {
1537 fail "Qubit should be in zero state.";
1538 }
1539 X(q1);
1540 let res2 = QIR.Intrinsic.__quantum__qis__mresetz__body(q1);
1541 (res2, Microsoft.Quantum.Diagnostics.CheckZero(q1))
1542 }"#},
1543 &expect!["(One, true)"],
1544 );
1545}
1546
1547#[test]
1548fn mresetz_qubit_already_released_fails() {
1549 check_intrinsic_result(
1550 "",
1551 indoc! {"{
1552 let q = { use q = Qubit(); q };
1553 QIR.Intrinsic.__quantum__qis__mresetz__body(q)
1554 }"},
1555 &expect!["qubit used after release"],
1556 );
1557}
1558
1559#[test]
1560fn unknown_intrinsic() {
1561 check_intrinsic_result(
1562 indoc! {"
1563 namespace Test {
1564 function Foo() : Int {
1565 body intrinsic;
1566 }
1567 }
1568 "},
1569 "Test.Foo()",
1570 &expect!["unknown intrinsic `Foo`"],
1571 );
1572}
1573
1574#[test]
1575fn custom_intrinsic_success() {
1576 check_intrinsic_result(
1577 indoc! {"
1578 namespace Test {
1579 function Add1(input : Int) : Int {
1580 body intrinsic;
1581 }
1582 }
1583 "},
1584 "Test.Add1(1)",
1585 &expect!["2"],
1586 );
1587}
1588
1589#[test]
1590fn custom_intrinsic_failure() {
1591 check_intrinsic_result(
1592 indoc! {"
1593 namespace Test {
1594 function Check(input : Int) : Int {
1595 body intrinsic;
1596 }
1597 }
1598 "},
1599 "Test.Check(1)",
1600 &expect!["intrinsic callable `Check` failed: cannot verify input"],
1601 );
1602}
1603
1604#[test]
1605fn qubit_nested_bind_not_released() {
1606 check_intrinsic_output(
1607 "",
1608 indoc! {"{
1609 use aux = Qubit();
1610 use q = Qubit();
1611 {
1612 let temp = q;
1613 X(temp);
1614 }
1615 Microsoft.Quantum.Diagnostics.DumpMachine();
1616 X(q);
1617 }"},
1618 &expect![[r#"
1619 STATE:
1620 |01⟩: 1.0000+0.0000𝑖
1621 "#]],
1622 );
1623}
1624
1625#[test]
1626fn qubit_release_non_zero_failure() {
1627 check_intrinsic_output(
1628 "",
1629 indoc! {"{
1630 use q = Qubit();
1631 X(q);
1632 }"},
1633 &expect!["Qubit0 released while not in |0⟩ state"],
1634 );
1635}
1636
1637#[test]
1638fn qubit_double_release_fails() {
1639 check_intrinsic_result(
1640 "",
1641 indoc! {"{
1642 let q = QIR.Runtime.__quantum__rt__qubit_allocate();
1643 QIR.Runtime.__quantum__rt__qubit_release(q);
1644 QIR.Runtime.__quantum__rt__qubit_release(q);
1645 }"},
1646 &expect!["qubit double release"],
1647 );
1648}
1649
1650#[test]
1651fn qubit_not_unique_two_qubit_error() {
1652 check_intrinsic_output(
1653 "",
1654 indoc! {"{
1655 use q = Qubit();
1656 CNOT(q , q);
1657 }"},
1658 &expect!["qubits in invocation are not unique"],
1659 );
1660}
1661
1662#[test]
1663fn qubit_not_unique_two_qubit_rotation_error() {
1664 check_intrinsic_output(
1665 "",
1666 indoc! {"{
1667 use q = Qubit();
1668 Rxx(0.1, q, q);
1669 }"},
1670 &expect!["qubits in invocation are not unique"],
1671 );
1672}
1673
1674#[test]
1675fn qubit_not_unique_three_qubit_error_first_second() {
1676 check_intrinsic_output(
1677 "",
1678 indoc! {"{
1679 use q = Qubit();
1680 use a = Qubit();
1681 CCNOT(q , q, a);
1682 }"},
1683 &expect!["qubits in invocation are not unique"],
1684 );
1685}
1686
1687#[test]
1688fn qubit_not_unique_three_qubit_error_first_third() {
1689 check_intrinsic_output(
1690 "",
1691 indoc! {"{
1692 use q = Qubit();
1693 use a = Qubit();
1694 CCNOT(q , a, q);
1695 }"},
1696 &expect!["qubits in invocation are not unique"],
1697 );
1698}
1699
1700#[test]
1701fn qubit_not_unique_three_qubit_error_second_third() {
1702 check_intrinsic_output(
1703 "",
1704 indoc! {"{
1705 use q = Qubit();
1706 use a = Qubit();
1707 CCNOT(a , q, q);
1708 }"},
1709 &expect!["qubits in invocation are not unique"],
1710 );
1711}
1712
1713#[test]
1714fn single_qubit_rotation_nan_error() {
1715 check_intrinsic_output(
1716 "",
1717 indoc! {"{
1718 use q = Qubit();
1719 Rx(Microsoft.Quantum.Math.ArcSin(2.0), q);
1720 }"},
1721 &expect!["invalid rotation angle: NaN"],
1722 );
1723}
1724
1725#[test]
1726fn two_qubit_rotation_nan_error() {
1727 check_intrinsic_output(
1728 "",
1729 indoc! {"{
1730 use (q1, q2) = (Qubit(), Qubit());
1731 Rxx(Microsoft.Quantum.Math.ArcSin(2.0), q1, q2);
1732 }"},
1733 &expect!["invalid rotation angle: NaN"],
1734 );
1735}
1736
1737#[test]
1738fn single_qubit_rotation_inf_error() {
1739 check_intrinsic_output(
1740 "",
1741 indoc! {"{
1742 use q = Qubit();
1743 Rx(-Microsoft.Quantum.Math.Log(0.0), q);
1744 }"},
1745 &expect!["invalid rotation angle: inf"],
1746 );
1747}
1748
1749#[test]
1750fn two_qubit_rotation_inf_error() {
1751 check_intrinsic_output(
1752 "",
1753 indoc! {"{
1754 use (q1, q2) = (Qubit(), Qubit());
1755 Rxx(-Microsoft.Quantum.Math.Log(0.0), q1, q2);
1756 }"},
1757 &expect!["invalid rotation angle: inf"],
1758 );
1759}
1760
1761#[test]
1762fn single_qubit_rotation_neg_inf_error() {
1763 check_intrinsic_output(
1764 "",
1765 indoc! {"{
1766 use q = Qubit();
1767 Rx(Microsoft.Quantum.Math.Log(0.0), q);
1768 }"},
1769 &expect!["invalid rotation angle: -inf"],
1770 );
1771}
1772
1773#[test]
1774fn two_qubit_rotation_neg_inf_error() {
1775 check_intrinsic_output(
1776 "",
1777 indoc! {"{
1778 use (q1, q2) = (Qubit(), Qubit());
1779 Rxx(Microsoft.Quantum.Math.Log(0.0), q1, q2);
1780 }"},
1781 &expect!["invalid rotation angle: -inf"],
1782 );
1783}
1784
1785#[test]
1786fn stop_counting_operation_before_start_fails() {
1787 check_intrinsic_output(
1788 "",
1789 indoc! {"{
1790 Std.Diagnostics.StopCountingOperation(I);
1791 }"},
1792 &expect!["callable not counted"],
1793 );
1794}
1795
1796#[test]
1797fn stop_counting_function_before_start_fails() {
1798 check_intrinsic_output(
1799 "",
1800 indoc! {"{
1801 function Foo() : Unit {}
1802 Std.Diagnostics.StopCountingFunction(Foo);
1803 }"},
1804 &expect!["callable not counted"],
1805 );
1806}
1807
1808#[test]
1809fn start_counting_operation_called_twice_before_stop_fails() {
1810 check_intrinsic_output(
1811 "",
1812 indoc! {"{
1813 Std.Diagnostics.StartCountingOperation(I);
1814 Std.Diagnostics.StartCountingOperation(I);
1815 }"},
1816 &expect!["callable already counted"],
1817 );
1818}
1819
1820#[test]
1821fn start_counting_function_called_twice_before_stop_fails() {
1822 check_intrinsic_output(
1823 "",
1824 indoc! {"{
1825 function Foo() : Unit {}
1826 Std.Diagnostics.StartCountingFunction(Foo);
1827 Std.Diagnostics.StartCountingFunction(Foo);
1828 }"},
1829 &expect!["callable already counted"],
1830 );
1831}
1832
1833#[test]
1834fn stop_counting_qubits_before_start_fails() {
1835 check_intrinsic_output(
1836 "",
1837 indoc! {"{
1838 Std.Diagnostics.StopCountingQubits();
1839 }"},
1840 &expect!["qubits not counted"],
1841 );
1842}
1843
1844#[test]
1845fn start_counting_qubits_called_twice_before_stop_fails() {
1846 check_intrinsic_output(
1847 "",
1848 indoc! {"{
1849 Std.Diagnostics.StartCountingQubits();
1850 Std.Diagnostics.StartCountingQubits();
1851 }"},
1852 &expect!["qubits already counted"],
1853 );
1854}
1855
1856#[test]
1857fn check_pauli_noise() {
1858 check_intrinsic_output(
1859 "",
1860 indoc! {"{
1861 import Std.Diagnostics.*;
1862 use q = Qubit();
1863 ConfigurePauliNoise(BitFlipNoise(1.0));
1864 ApplyIdleNoise(q);
1865 ConfigurePauliNoise(NoNoise());
1866 DumpMachine();
1867 Reset(q);
1868 }"},
1869 &expect![[r#"
1870 STATE:
1871 |1⟩: 1.0000+0.0000𝑖
1872 "#]],
1873 );
1874}
1875
1876#[test]
1877fn applyidlenoise_qubit_already_released_fails() {
1878 check_intrinsic_output(
1879 "",
1880 indoc! {"{
1881 let q = { use q = Qubit(); q };
1882 Std.Diagnostics.ApplyIdleNoise(q);
1883 }"},
1884 &expect!["qubit used after release"],
1885 );
1886}
1887