microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
dmitryv/select-updated

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc_passes/src/spec_gen/tests.rs

2119lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4#![allow(clippy::too_many_lines)]
5#![allow(clippy::needless_raw_string_hashes)]
6
7use expect_test::{expect, Expect};
8use indoc::indoc;
9use qsc_frontend::compile::{self, compile, PackageStore, RuntimeCapabilityFlags, SourceMap};
10use qsc_hir::{validate::Validator, visit::Visitor};
11
12use crate::spec_gen::generate_specs;
13
14fn check(file: &str, expect: &Expect) {
15 let store = PackageStore::new(compile::core());
16 let sources = SourceMap::new([("test".into(), file.into())], None);
17 let mut unit = compile(&store, &[], sources, RuntimeCapabilityFlags::all());
18 assert!(unit.errors.is_empty(), "{:?}", unit.errors);
19
20 let errors = generate_specs(store.core(), &mut unit.package, &mut unit.assigner);
21 Validator::default().visit_package(&unit.package);
22 if errors.is_empty() {
23 expect.assert_eq(&unit.package.to_string());
24 } else {
25 expect.assert_debug_eq(&errors);
26 }
27}
28
29#[test]
30fn generate_specs_body_intrinsic_should_fail() {
31 check(
32 indoc! {"
33 namespace test {
34 operation A(q : Qubit) : Unit is Adj + Ctl {
35 body intrinsic;
36 }
37 }
38 "},
39 &expect![[r#"
40 [
41 MissingBody(
42 Span {
43 lo: 74,
44 hi: 89,
45 },
46 ),
47 ]
48 "#]],
49 );
50}
51
52#[test]
53fn generate_specs_body_auto_should_fail() {
54 check(
55 indoc! {"
56 namespace test {
57 operation A(q : Qubit) : Unit {
58 body auto;
59 }
60 }
61 "},
62 &expect![[r#"
63 [
64 InvalidBodyGen(
65 Span {
66 lo: 61,
67 hi: 71,
68 },
69 ),
70 ]
71 "#]],
72 );
73}
74
75#[test]
76fn generate_specs_body_self_should_fail() {
77 check(
78 indoc! {"
79 namespace test {
80 operation A(q : Qubit) : Unit {
81 body self;
82 }
83 }
84 "},
85 &expect![[r#"
86 [
87 InvalidBodyGen(
88 Span {
89 lo: 61,
90 hi: 71,
91 },
92 ),
93 ]
94 "#]],
95 );
96}
97
98#[test]
99fn generate_specs_body_invert_should_fail() {
100 check(
101 indoc! {"
102 namespace test {
103 operation A(q : Qubit) : Unit {
104 body invert;
105 }
106 }
107 "},
108 &expect![[r#"
109 [
110 InvalidBodyGen(
111 Span {
112 lo: 61,
113 hi: 73,
114 },
115 ),
116 ]
117 "#]],
118 );
119}
120
121#[test]
122fn generate_specs_body_distribute_should_fail() {
123 check(
124 indoc! {"
125 namespace test {
126 operation A(q : Qubit) : Unit {
127 body distribute;
128 }
129 }
130 "},
131 &expect![[r#"
132 [
133 InvalidBodyGen(
134 Span {
135 lo: 61,
136 hi: 77,
137 },
138 ),
139 ]
140 "#]],
141 );
142}
143
144#[test]
145fn generate_specs_ctl_intrinsic_should_fail() {
146 check(
147 indoc! {"
148 namespace test {
149 operation A(q : Qubit) : Unit is Adj + Ctl {
150 body ... {}
151 controlled intrinsic;
152 }
153 }
154 "},
155 &expect![[r#"
156 [
157 InvalidCtlGen(
158 Span {
159 lo: 94,
160 hi: 115,
161 },
162 ),
163 ]
164 "#]],
165 );
166}
167
168#[test]
169fn generate_specs_ctl_self_should_fail() {
170 check(
171 indoc! {"
172 namespace test {
173 operation A(q : Qubit) : Unit is Adj + Ctl {
174 body ... {}
175 controlled self;
176 }
177 }
178 "},
179 &expect![[r#"
180 [
181 InvalidCtlGen(
182 Span {
183 lo: 94,
184 hi: 110,
185 },
186 ),
187 ]
188 "#]],
189 );
190}
191
192#[test]
193fn generate_specs_ctl_invert_should_fail() {
194 check(
195 indoc! {"
196 namespace test {
197 operation A(q : Qubit) : Unit is Adj + Ctl {
198 body ... {}
199 controlled invert;
200 }
201 }
202 "},
203 &expect![[r#"
204 [
205 InvalidCtlGen(
206 Span {
207 lo: 94,
208 hi: 112,
209 },
210 ),
211 ]
212 "#]],
213 );
214}
215
216#[test]
217fn generate_specs_adj_intrinsic_should_fail() {
218 check(
219 indoc! {"
220 namespace test {
221 operation A(q : Qubit) : Unit is Adj + Ctl {
222 body ... {}
223 adjoint intrinsic;
224 }
225 }
226 "},
227 &expect![[r#"
228 [
229 InvalidAdjGen(
230 Span {
231 lo: 94,
232 hi: 112,
233 },
234 ),
235 ]
236 "#]],
237 );
238}
239
240#[test]
241fn generate_specs_adjoint_distribute_should_fail() {
242 check(
243 indoc! {"
244 namespace test {
245 operation A(q : Qubit) : Unit is Adj + Ctl {
246 body ... {}
247 adjoint distribute;
248 }
249 }
250 "},
251 &expect![[r#"
252 [
253 InvalidAdjGen(
254 Span {
255 lo: 94,
256 hi: 113,
257 },
258 ),
259 ]
260 "#]],
261 );
262}
263
264#[test]
265fn generate_ctl() {
266 check(
267 indoc! {"
268 namespace test {
269 operation A(q : Qubit) : Unit is Ctl {
270 body ... {}
271 controlled (ctls, ...) {}
272 }
273 operation B(q : Qubit) : Unit is Ctl {
274 A(q);
275 }
276 }
277 "},
278 &expect![[r#"
279 Package:
280 Item 0 [0-184] (Public):
281 Namespace (Ident 20 [10-14] "test"): Item 1, Item 2
282 Item 1 [21-119] (Public):
283 Parent: 0
284 Callable 0 [21-119] (operation):
285 name: Ident 1 [31-32] "A"
286 input: Pat 2 [33-42] [Type Qubit]: Bind: Ident 3 [33-34] "q"
287 output: Unit
288 functors: Ctl
289 body: SpecDecl 4 [68-79]: Impl:
290 Block 5 [77-79]: <empty>
291 adj: <none>
292 ctl: SpecDecl 6 [88-113]: Impl:
293 Pat 7 [100-104] [Type Qubit[]]: Bind: Ident 8 [100-104] "ctls"
294 Block 9 [111-113]: <empty>
295 ctl-adj: <none>
296 Item 2 [124-182] (Public):
297 Parent: 0
298 Callable 10 [124-182] (operation):
299 name: Ident 11 [134-135] "B"
300 input: Pat 12 [136-145] [Type Qubit]: Bind: Ident 13 [136-137] "q"
301 output: Unit
302 functors: Ctl
303 body: SpecDecl 14 [124-182]: Impl:
304 Block 15 [161-182] [Type Unit]:
305 Stmt 16 [171-176]: Semi: Expr 17 [171-175] [Type Unit]: Call:
306 Expr 18 [171-172] [Type (Qubit => Unit is Ctl)]: Var: Item 1
307 Expr 19 [173-174] [Type Qubit]: Var: Local 13
308 adj: <none>
309 ctl: SpecDecl 23 [124-182]: Impl:
310 Pat 24 [124-182] [Type Qubit[]]: Bind: Ident 25 [124-182] "ctls"
311 Block 26 [161-182] [Type Unit]:
312 Stmt 27 [171-176]: Semi: Expr 28 [171-175] [Type Unit]: Call:
313 Expr 29 [171-172] [Type ((Qubit[], Qubit) => Unit is Ctl)]: UnOp (Functor Ctl):
314 Expr 30 [171-172] [Type (Qubit => Unit is Ctl)]: Var: Item 1
315 Expr 31 [173-174] [Type (Qubit[], Qubit)]: Tuple:
316 Expr 32 [173-174] [Type Qubit[]]: Var: Local 25
317 Expr 33 [173-174] [Type Qubit]: Var: Local 13
318 ctl-adj: <none>"#]],
319 );
320}
321
322#[test]
323fn generate_ctl_auto() {
324 check(
325 indoc! {"
326 namespace test {
327 operation A(q : Qubit) : Unit is Ctl {
328 body ... {}
329 controlled (ctls, ...) {}
330 }
331 operation B(q : Qubit) : Unit is Ctl {
332 body ... {
333 A(q);
334 }
335 controlled auto;
336 }
337 }
338 "},
339 &expect![[r#"
340 Package:
341 Item 0 [0-242] (Public):
342 Namespace (Ident 21 [10-14] "test"): Item 1, Item 2
343 Item 1 [21-119] (Public):
344 Parent: 0
345 Callable 0 [21-119] (operation):
346 name: Ident 1 [31-32] "A"
347 input: Pat 2 [33-42] [Type Qubit]: Bind: Ident 3 [33-34] "q"
348 output: Unit
349 functors: Ctl
350 body: SpecDecl 4 [68-79]: Impl:
351 Block 5 [77-79]: <empty>
352 adj: <none>
353 ctl: SpecDecl 6 [88-113]: Impl:
354 Pat 7 [100-104] [Type Qubit[]]: Bind: Ident 8 [100-104] "ctls"
355 Block 9 [111-113]: <empty>
356 ctl-adj: <none>
357 Item 2 [124-240] (Public):
358 Parent: 0
359 Callable 10 [124-240] (operation):
360 name: Ident 11 [134-135] "B"
361 input: Pat 12 [136-145] [Type Qubit]: Bind: Ident 13 [136-137] "q"
362 output: Unit
363 functors: Ctl
364 body: SpecDecl 14 [171-209]: Impl:
365 Block 15 [180-209] [Type Unit]:
366 Stmt 16 [194-199]: Semi: Expr 17 [194-198] [Type Unit]: Call:
367 Expr 18 [194-195] [Type (Qubit => Unit is Ctl)]: Var: Item 1
368 Expr 19 [196-197] [Type Qubit]: Var: Local 13
369 adj: <none>
370 ctl: SpecDecl 23 [218-234]: Impl:
371 Pat 24 [218-234] [Type Qubit[]]: Bind: Ident 25 [218-234] "ctls"
372 Block 26 [180-209] [Type Unit]:
373 Stmt 27 [194-199]: Semi: Expr 28 [194-198] [Type Unit]: Call:
374 Expr 29 [194-195] [Type ((Qubit[], Qubit) => Unit is Ctl)]: UnOp (Functor Ctl):
375 Expr 30 [194-195] [Type (Qubit => Unit is Ctl)]: Var: Item 1
376 Expr 31 [196-197] [Type (Qubit[], Qubit)]: Tuple:
377 Expr 32 [196-197] [Type Qubit[]]: Var: Local 25
378 Expr 33 [196-197] [Type Qubit]: Var: Local 13
379 ctl-adj: <none>"#]],
380 );
381}
382
383#[test]
384fn generate_ctladj_distrib() {
385 check(
386 indoc! {"
387 namespace test {
388 operation A(q : Qubit) : Unit is Ctl + Adj {
389 body ... {}
390 adjoint ... {}
391 controlled (ctls, ...) {}
392 }
393 operation B(q : Qubit) : Unit is Ctl + Adj {
394 body ... {
395 A(q);
396 }
397 adjoint ... {
398 Adjoint A(q);
399 }
400 }
401 }
402 "},
403 &expect![[r#"
404 Package:
405 Item 0 [0-310] (Public):
406 Namespace (Ident 29 [10-14] "test"): Item 1, Item 2
407 Item 1 [21-148] (Public):
408 Parent: 0
409 Callable 0 [21-148] (operation):
410 name: Ident 1 [31-32] "A"
411 input: Pat 2 [33-42] [Type Qubit]: Bind: Ident 3 [33-34] "q"
412 output: Unit
413 functors: Adj + Ctl
414 body: SpecDecl 4 [74-85]: Impl:
415 Block 5 [83-85]: <empty>
416 adj: SpecDecl 6 [94-108]: Impl:
417 Block 7 [106-108]: <empty>
418 ctl: SpecDecl 8 [117-142]: Impl:
419 Pat 9 [129-133] [Type Qubit[]]: Bind: Ident 10 [129-133] "ctls"
420 Block 11 [140-142]: <empty>
421 ctl-adj: SpecDecl 34 [21-148]: Impl:
422 Pat 35 [21-148] [Type Qubit[]]: Bind: Ident 36 [21-148] "ctls"
423 Block 37 [106-108]: <empty>
424 Item 2 [153-308] (Public):
425 Parent: 0
426 Callable 12 [153-308] (operation):
427 name: Ident 13 [163-164] "B"
428 input: Pat 14 [165-174] [Type Qubit]: Bind: Ident 15 [165-166] "q"
429 output: Unit
430 functors: Adj + Ctl
431 body: SpecDecl 16 [206-244]: Impl:
432 Block 17 [215-244] [Type Unit]:
433 Stmt 18 [229-234]: Semi: Expr 19 [229-233] [Type Unit]: Call:
434 Expr 20 [229-230] [Type (Qubit => Unit is Adj + Ctl)]: Var: Item 1
435 Expr 21 [231-232] [Type Qubit]: Var: Local 15
436 adj: SpecDecl 22 [253-302]: Impl:
437 Block 23 [265-302] [Type Unit]:
438 Stmt 24 [279-292]: Semi: Expr 25 [279-291] [Type Unit]: Call:
439 Expr 26 [279-288] [Type (Qubit => Unit is Adj + Ctl)]: UnOp (Functor Adj):
440 Expr 27 [287-288] [Type (Qubit => Unit is Adj + Ctl)]: Var: Item 1
441 Expr 28 [289-290] [Type Qubit]: Var: Local 15
442 ctl: SpecDecl 39 [153-308]: Impl:
443 Pat 40 [153-308] [Type Qubit[]]: Bind: Ident 41 [153-308] "ctls"
444 Block 42 [215-244] [Type Unit]:
445 Stmt 43 [229-234]: Semi: Expr 44 [229-233] [Type Unit]: Call:
446 Expr 45 [229-230] [Type ((Qubit[], Qubit) => Unit is Adj + Ctl)]: UnOp (Functor Ctl):
447 Expr 46 [229-230] [Type (Qubit => Unit is Adj + Ctl)]: Var: Item 1
448 Expr 47 [231-232] [Type (Qubit[], Qubit)]: Tuple:
449 Expr 48 [231-232] [Type Qubit[]]: Var: Local 41
450 Expr 49 [231-232] [Type Qubit]: Var: Local 15
451 ctl-adj: SpecDecl 51 [153-308]: Impl:
452 Pat 52 [153-308] [Type Qubit[]]: Bind: Ident 53 [153-308] "ctls"
453 Block 54 [265-302] [Type Unit]:
454 Stmt 55 [279-292]: Semi: Expr 56 [279-291] [Type Unit]: Call:
455 Expr 57 [279-288] [Type ((Qubit[], Qubit) => Unit is Adj + Ctl)]: UnOp (Functor Ctl):
456 Expr 58 [279-288] [Type (Qubit => Unit is Adj + Ctl)]: UnOp (Functor Adj):
457 Expr 59 [287-288] [Type (Qubit => Unit is Adj + Ctl)]: Var: Item 1
458 Expr 60 [289-290] [Type (Qubit[], Qubit)]: Tuple:
459 Expr 61 [289-290] [Type Qubit[]]: Var: Local 53
460 Expr 62 [289-290] [Type Qubit]: Var: Local 15"#]],
461 );
462}
463
464#[test]
465fn generate_ctl_skip_conjugate_apply_block() {
466 check(
467 indoc! {"
468 namespace test {
469 operation A(q : Qubit) : Unit is Ctl {
470 body ... {}
471 controlled (ctls, ...) {}
472 }
473 operation B(q : Qubit) : Unit is Ctl {
474 within {
475 A(q);
476 }
477 apply {
478 A(q);
479 }
480 }
481 }
482 "},
483 &expect![[r#"
484 Package:
485 Item 0 [0-259] (Public):
486 Namespace (Ident 28 [10-14] "test"): Item 1, Item 2
487 Item 1 [21-119] (Public):
488 Parent: 0
489 Callable 0 [21-119] (operation):
490 name: Ident 1 [31-32] "A"
491 input: Pat 2 [33-42] [Type Qubit]: Bind: Ident 3 [33-34] "q"
492 output: Unit
493 functors: Ctl
494 body: SpecDecl 4 [68-79]: Impl:
495 Block 5 [77-79]: <empty>
496 adj: <none>
497 ctl: SpecDecl 6 [88-113]: Impl:
498 Pat 7 [100-104] [Type Qubit[]]: Bind: Ident 8 [100-104] "ctls"
499 Block 9 [111-113]: <empty>
500 ctl-adj: <none>
501 Item 2 [124-257] (Public):
502 Parent: 0
503 Callable 10 [124-257] (operation):
504 name: Ident 11 [134-135] "B"
505 input: Pat 12 [136-145] [Type Qubit]: Bind: Ident 13 [136-137] "q"
506 output: Unit
507 functors: Ctl
508 body: SpecDecl 14 [124-257]: Impl:
509 Block 15 [161-257] [Type Unit]:
510 Stmt 16 [171-251]: Expr: Expr 17 [171-251] [Type Unit]: Conjugate:
511 Block 18 [178-207] [Type Unit]:
512 Stmt 19 [192-197]: Semi: Expr 20 [192-196] [Type Unit]: Call:
513 Expr 21 [192-193] [Type (Qubit => Unit is Ctl)]: Var: Item 1
514 Expr 22 [194-195] [Type Qubit]: Var: Local 13
515 Block 23 [222-251] [Type Unit]:
516 Stmt 24 [236-241]: Semi: Expr 25 [236-240] [Type Unit]: Call:
517 Expr 26 [236-237] [Type (Qubit => Unit is Ctl)]: Var: Item 1
518 Expr 27 [238-239] [Type Qubit]: Var: Local 13
519 adj: <none>
520 ctl: SpecDecl 31 [124-257]: Impl:
521 Pat 32 [124-257] [Type Qubit[]]: Bind: Ident 33 [124-257] "ctls"
522 Block 34 [161-257] [Type Unit]:
523 Stmt 35 [171-251]: Expr: Expr 36 [171-251] [Type Unit]: Conjugate:
524 Block 37 [178-207] [Type Unit]:
525 Stmt 38 [192-197]: Semi: Expr 39 [192-196] [Type Unit]: Call:
526 Expr 40 [192-193] [Type (Qubit => Unit is Ctl)]: Var: Item 1
527 Expr 41 [194-195] [Type Qubit]: Var: Local 13
528 Block 42 [222-251] [Type Unit]:
529 Stmt 43 [236-241]: Semi: Expr 44 [236-240] [Type Unit]: Call:
530 Expr 45 [236-237] [Type ((Qubit[], Qubit) => Unit is Ctl)]: UnOp (Functor Ctl):
531 Expr 46 [236-237] [Type (Qubit => Unit is Ctl)]: Var: Item 1
532 Expr 47 [238-239] [Type (Qubit[], Qubit)]: Tuple:
533 Expr 48 [238-239] [Type Qubit[]]: Var: Local 33
534 Expr 49 [238-239] [Type Qubit]: Var: Local 13
535 ctl-adj: <none>"#]],
536 );
537}
538
539#[test]
540fn generate_ctl_op_missing_functor() {
541 check(
542 indoc! {"
543 namespace test {
544 operation A(q : Qubit) : Unit {
545 }
546 operation B(q : Qubit) : Unit is Ctl {
547 A(q);
548 }
549 }
550 "},
551 &expect![[r#"
552 [
553 CtlGen(
554 MissingCtlFunctor(
555 Span {
556 lo: 110,
557 hi: 111,
558 },
559 ),
560 ),
561 ]
562 "#]],
563 );
564}
565
566#[test]
567fn generate_ctl_with_function_calls() {
568 check(
569 indoc! {"
570 namespace test {
571 function Foo() : Unit {}
572 operation A() : Unit is Ctl {}
573 operation B() : Unit is Ctl {
574 Foo();
575 A();
576 }
577 }
578 "},
579 &expect![[r#"
580 Package:
581 Item 0 [0-150] (Public):
582 Namespace (Ident 23 [10-14] "test"): Item 1, Item 2, Item 3
583 Item 1 [21-45] (Public):
584 Parent: 0
585 Callable 0 [21-45] (function):
586 name: Ident 1 [30-33] "Foo"
587 input: Pat 2 [33-35] [Type Unit]: Unit
588 output: Unit
589 functors: empty set
590 body: SpecDecl 3 [21-45]: Impl:
591 Block 4 [43-45]: <empty>
592 adj: <none>
593 ctl: <none>
594 ctl-adj: <none>
595 Item 2 [50-80] (Public):
596 Parent: 0
597 Callable 5 [50-80] (operation):
598 name: Ident 6 [60-61] "A"
599 input: Pat 7 [61-63] [Type Unit]: Unit
600 output: Unit
601 functors: Ctl
602 body: SpecDecl 8 [50-80]: Impl:
603 Block 9 [78-80]: <empty>
604 adj: <none>
605 ctl: SpecDecl 27 [50-80]: Impl:
606 Pat 28 [50-80] [Type Qubit[]]: Bind: Ident 29 [50-80] "ctls"
607 Block 30 [78-80]: <empty>
608 ctl-adj: <none>
609 Item 3 [85-148] (Public):
610 Parent: 0
611 Callable 10 [85-148] (operation):
612 name: Ident 11 [95-96] "B"
613 input: Pat 12 [96-98] [Type Unit]: Unit
614 output: Unit
615 functors: Ctl
616 body: SpecDecl 13 [85-148]: Impl:
617 Block 14 [113-148] [Type Unit]:
618 Stmt 15 [123-129]: Semi: Expr 16 [123-128] [Type Unit]: Call:
619 Expr 17 [123-126] [Type (Unit -> Unit)]: Var: Item 1
620 Expr 18 [126-128] [Type Unit]: Unit
621 Stmt 19 [138-142]: Semi: Expr 20 [138-141] [Type Unit]: Call:
622 Expr 21 [138-139] [Type (Unit => Unit is Ctl)]: Var: Item 2
623 Expr 22 [139-141] [Type Unit]: Unit
624 adj: <none>
625 ctl: SpecDecl 32 [85-148]: Impl:
626 Pat 33 [85-148] [Type Qubit[]]: Bind: Ident 34 [85-148] "ctls"
627 Block 35 [113-148] [Type Unit]:
628 Stmt 36 [123-129]: Semi: Expr 37 [123-128] [Type Unit]: Call:
629 Expr 38 [123-126] [Type (Unit -> Unit)]: Var: Item 1
630 Expr 39 [126-128] [Type Unit]: Unit
631 Stmt 40 [138-142]: Semi: Expr 41 [138-141] [Type Unit]: Call:
632 Expr 42 [138-139] [Type ((Qubit[], Unit) => Unit is Ctl)]: UnOp (Functor Ctl):
633 Expr 43 [138-139] [Type (Unit => Unit is Ctl)]: Var: Item 2
634 Expr 44 [139-141] [Type (Qubit[], Unit)]: Tuple:
635 Expr 45 [139-141] [Type Qubit[]]: Var: Local 34
636 Expr 46 [139-141] [Type Unit]: Unit
637 ctl-adj: <none>"#]],
638 );
639}
640
641#[test]
642fn generate_adj_self() {
643 check(
644 indoc! {r#"
645 namespace test {
646 operation B(input : Int) : Unit is Adj {}
647 operation A(q : Qubit) : Unit is Adj {
648 body ... { B(1); B(2); }
649 adjoint self;
650 }
651 }
652 "#},
653 &expect![[r#"
654 Package:
655 Item 0 [0-168] (Public):
656 Namespace (Ident 21 [10-14] "test"): Item 1, Item 2
657 Item 1 [21-62] (Public):
658 Parent: 0
659 Callable 0 [21-62] (operation):
660 name: Ident 1 [31-32] "B"
661 input: Pat 2 [33-44] [Type Int]: Bind: Ident 3 [33-38] "input"
662 output: Unit
663 functors: Adj
664 body: SpecDecl 4 [21-62]: Impl:
665 Block 5 [60-62]: <empty>
666 adj: SpecDecl 23 [21-62]: Impl:
667 Block 24 [60-62]: <empty>
668 ctl: <none>
669 ctl-adj: <none>
670 Item 2 [67-166] (Public):
671 Parent: 0
672 Callable 6 [67-166] (operation):
673 name: Ident 7 [77-78] "A"
674 input: Pat 8 [79-88] [Type Qubit]: Bind: Ident 9 [79-80] "q"
675 output: Unit
676 functors: Adj
677 body: SpecDecl 10 [114-138]: Impl:
678 Block 11 [123-138] [Type Unit]:
679 Stmt 12 [125-130]: Semi: Expr 13 [125-129] [Type Unit]: Call:
680 Expr 14 [125-126] [Type (Int => Unit is Adj)]: Var: Item 1
681 Expr 15 [127-128] [Type Int]: Lit: Int(1)
682 Stmt 16 [131-136]: Semi: Expr 17 [131-135] [Type Unit]: Call:
683 Expr 18 [131-132] [Type (Int => Unit is Adj)]: Var: Item 1
684 Expr 19 [133-134] [Type Int]: Lit: Int(2)
685 adj: SpecDecl 25 [147-160]: Impl:
686 Block 26 [123-138] [Type Unit]:
687 Stmt 27 [125-130]: Semi: Expr 28 [125-129] [Type Unit]: Call:
688 Expr 29 [125-126] [Type (Int => Unit is Adj)]: Var: Item 1
689 Expr 30 [127-128] [Type Int]: Lit: Int(1)
690 Stmt 31 [131-136]: Semi: Expr 32 [131-135] [Type Unit]: Call:
691 Expr 33 [131-132] [Type (Int => Unit is Adj)]: Var: Item 1
692 Expr 34 [133-134] [Type Int]: Lit: Int(2)
693 ctl: <none>
694 ctl-adj: <none>"#]],
695 );
696}
697
698#[test]
699fn generate_ctladj_self() {
700 check(
701 indoc! {r#"
702 namespace test {
703 operation B(input : Int) : Unit is Ctl + Adj {}
704 operation A(q : Qubit) : Unit is Ctl + Adj {
705 body ... { B(1); B(2); }
706 adjoint self;
707 }
708 }
709 "#},
710 &expect![[r#"
711 Package:
712 Item 0 [0-180] (Public):
713 Namespace (Ident 21 [10-14] "test"): Item 1, Item 2
714 Item 1 [21-68] (Public):
715 Parent: 0
716 Callable 0 [21-68] (operation):
717 name: Ident 1 [31-32] "B"
718 input: Pat 2 [33-44] [Type Int]: Bind: Ident 3 [33-38] "input"
719 output: Unit
720 functors: Adj + Ctl
721 body: SpecDecl 4 [21-68]: Impl:
722 Block 5 [66-68]: <empty>
723 adj: SpecDecl 32 [21-68]: Impl:
724 Block 33 [66-68]: <empty>
725 ctl: SpecDecl 28 [21-68]: Impl:
726 Pat 29 [21-68] [Type Qubit[]]: Bind: Ident 30 [21-68] "ctls"
727 Block 31 [66-68]: <empty>
728 ctl-adj: SpecDecl 35 [21-68]: Impl:
729 Pat 36 [21-68] [Type Qubit[]]: Bind: Ident 37 [21-68] "ctls"
730 Block 38 [66-68]: <empty>
731 Item 2 [73-178] (Public):
732 Parent: 0
733 Callable 6 [73-178] (operation):
734 name: Ident 7 [83-84] "A"
735 input: Pat 8 [85-94] [Type Qubit]: Bind: Ident 9 [85-86] "q"
736 output: Unit
737 functors: Adj + Ctl
738 body: SpecDecl 10 [126-150]: Impl:
739 Block 11 [135-150] [Type Unit]:
740 Stmt 12 [137-142]: Semi: Expr 13 [137-141] [Type Unit]: Call:
741 Expr 14 [137-138] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
742 Expr 15 [139-140] [Type Int]: Lit: Int(1)
743 Stmt 16 [143-148]: Semi: Expr 17 [143-147] [Type Unit]: Call:
744 Expr 18 [143-144] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
745 Expr 19 [145-146] [Type Int]: Lit: Int(2)
746 adj: SpecDecl 58 [159-172]: Impl:
747 Block 59 [135-150] [Type Unit]:
748 Stmt 60 [137-142]: Semi: Expr 61 [137-141] [Type Unit]: Call:
749 Expr 62 [137-138] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
750 Expr 63 [139-140] [Type Int]: Lit: Int(1)
751 Stmt 64 [143-148]: Semi: Expr 65 [143-147] [Type Unit]: Call:
752 Expr 66 [143-144] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
753 Expr 67 [145-146] [Type Int]: Lit: Int(2)
754 ctl: SpecDecl 40 [73-178]: Impl:
755 Pat 41 [73-178] [Type Qubit[]]: Bind: Ident 42 [73-178] "ctls"
756 Block 43 [135-150] [Type Unit]:
757 Stmt 44 [137-142]: Semi: Expr 45 [137-141] [Type Unit]: Call:
758 Expr 46 [137-138] [Type ((Qubit[], Int) => Unit is Adj + Ctl)]: UnOp (Functor Ctl):
759 Expr 47 [137-138] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
760 Expr 48 [139-140] [Type (Qubit[], Int)]: Tuple:
761 Expr 49 [139-140] [Type Qubit[]]: Var: Local 42
762 Expr 50 [139-140] [Type Int]: Lit: Int(1)
763 Stmt 51 [143-148]: Semi: Expr 52 [143-147] [Type Unit]: Call:
764 Expr 53 [143-144] [Type ((Qubit[], Int) => Unit is Adj + Ctl)]: UnOp (Functor Ctl):
765 Expr 54 [143-144] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
766 Expr 55 [145-146] [Type (Qubit[], Int)]: Tuple:
767 Expr 56 [145-146] [Type Qubit[]]: Var: Local 42
768 Expr 57 [145-146] [Type Int]: Lit: Int(2)
769 ctl-adj: SpecDecl 68 [73-178]: Impl:
770 Pat 69 [73-178] [Type Qubit[]]: Bind: Ident 70 [73-178] "ctls"
771 Block 71 [135-150] [Type Unit]:
772 Stmt 72 [137-142]: Semi: Expr 73 [137-141] [Type Unit]: Call:
773 Expr 74 [137-138] [Type ((Qubit[], Int) => Unit is Adj + Ctl)]: UnOp (Functor Ctl):
774 Expr 75 [137-138] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
775 Expr 76 [139-140] [Type (Qubit[], Int)]: Tuple:
776 Expr 77 [139-140] [Type Qubit[]]: Var: Local 70
777 Expr 78 [139-140] [Type Int]: Lit: Int(1)
778 Stmt 79 [143-148]: Semi: Expr 80 [143-147] [Type Unit]: Call:
779 Expr 81 [143-144] [Type ((Qubit[], Int) => Unit is Adj + Ctl)]: UnOp (Functor Ctl):
780 Expr 82 [143-144] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
781 Expr 83 [145-146] [Type (Qubit[], Int)]: Tuple:
782 Expr 84 [145-146] [Type Qubit[]]: Var: Local 70
783 Expr 85 [145-146] [Type Int]: Lit: Int(2)"#]],
784 );
785}
786
787#[test]
788fn generate_adj_invert() {
789 check(
790 indoc! {r#"
791 namespace test {
792 operation B(input : Int) : Unit is Adj {}
793 operation A(q : Qubit) : Unit is Adj {
794 B(1);
795 B(2);
796 }
797 }
798 "#},
799 &expect![[r#"
800 Package:
801 Item 0 [0-141] (Public):
802 Namespace (Ident 20 [10-14] "test"): Item 1, Item 2
803 Item 1 [21-62] (Public):
804 Parent: 0
805 Callable 0 [21-62] (operation):
806 name: Ident 1 [31-32] "B"
807 input: Pat 2 [33-44] [Type Int]: Bind: Ident 3 [33-38] "input"
808 output: Unit
809 functors: Adj
810 body: SpecDecl 4 [21-62]: Impl:
811 Block 5 [60-62]: <empty>
812 adj: SpecDecl 23 [21-62]: Impl:
813 Block 24 [60-62]: <empty>
814 ctl: <none>
815 ctl-adj: <none>
816 Item 2 [67-139] (Public):
817 Parent: 0
818 Callable 6 [67-139] (operation):
819 name: Ident 7 [77-78] "A"
820 input: Pat 8 [79-88] [Type Qubit]: Bind: Ident 9 [79-80] "q"
821 output: Unit
822 functors: Adj
823 body: SpecDecl 10 [67-139]: Impl:
824 Block 11 [104-139] [Type Unit]:
825 Stmt 12 [114-119]: Semi: Expr 13 [114-118] [Type Unit]: Call:
826 Expr 14 [114-115] [Type (Int => Unit is Adj)]: Var: Item 1
827 Expr 15 [116-117] [Type Int]: Lit: Int(1)
828 Stmt 16 [128-133]: Semi: Expr 17 [128-132] [Type Unit]: Call:
829 Expr 18 [128-129] [Type (Int => Unit is Adj)]: Var: Item 1
830 Expr 19 [130-131] [Type Int]: Lit: Int(2)
831 adj: SpecDecl 25 [67-139]: Impl:
832 Block 26 [104-139] [Type Unit]:
833 Stmt 27 [128-133]: Semi: Expr 28 [128-132] [Type Unit]: Call:
834 Expr 29 [128-129] [Type (Int => Unit is Adj)]: UnOp (Functor Adj):
835 Expr 30 [128-129] [Type (Int => Unit is Adj)]: Var: Item 1
836 Expr 31 [130-131] [Type Int]: Lit: Int(2)
837 Stmt 32 [114-119]: Semi: Expr 33 [114-118] [Type Unit]: Call:
838 Expr 34 [114-115] [Type (Int => Unit is Adj)]: UnOp (Functor Adj):
839 Expr 35 [114-115] [Type (Int => Unit is Adj)]: Var: Item 1
840 Expr 36 [116-117] [Type Int]: Lit: Int(1)
841 ctl: <none>
842 ctl-adj: <none>"#]],
843 );
844}
845
846#[test]
847fn generate_adj_auto() {
848 check(
849 indoc! {r#"
850 namespace test {
851 operation B(input : Int) : Unit is Adj {}
852 operation A(q : Qubit) : Unit is Adj {
853 body ... {
854 B(1);
855 B(2);
856 }
857 adjoint auto;
858 }
859 }
860 "#},
861 &expect![[r#"
862 Package:
863 Item 0 [0-200] (Public):
864 Namespace (Ident 21 [10-14] "test"): Item 1, Item 2
865 Item 1 [21-62] (Public):
866 Parent: 0
867 Callable 0 [21-62] (operation):
868 name: Ident 1 [31-32] "B"
869 input: Pat 2 [33-44] [Type Int]: Bind: Ident 3 [33-38] "input"
870 output: Unit
871 functors: Adj
872 body: SpecDecl 4 [21-62]: Impl:
873 Block 5 [60-62]: <empty>
874 adj: SpecDecl 23 [21-62]: Impl:
875 Block 24 [60-62]: <empty>
876 ctl: <none>
877 ctl-adj: <none>
878 Item 2 [67-198] (Public):
879 Parent: 0
880 Callable 6 [67-198] (operation):
881 name: Ident 7 [77-78] "A"
882 input: Pat 8 [79-88] [Type Qubit]: Bind: Ident 9 [79-80] "q"
883 output: Unit
884 functors: Adj
885 body: SpecDecl 10 [114-170]: Impl:
886 Block 11 [123-170] [Type Unit]:
887 Stmt 12 [137-142]: Semi: Expr 13 [137-141] [Type Unit]: Call:
888 Expr 14 [137-138] [Type (Int => Unit is Adj)]: Var: Item 1
889 Expr 15 [139-140] [Type Int]: Lit: Int(1)
890 Stmt 16 [155-160]: Semi: Expr 17 [155-159] [Type Unit]: Call:
891 Expr 18 [155-156] [Type (Int => Unit is Adj)]: Var: Item 1
892 Expr 19 [157-158] [Type Int]: Lit: Int(2)
893 adj: SpecDecl 25 [179-192]: Impl:
894 Block 26 [123-170] [Type Unit]:
895 Stmt 27 [155-160]: Semi: Expr 28 [155-159] [Type Unit]: Call:
896 Expr 29 [155-156] [Type (Int => Unit is Adj)]: UnOp (Functor Adj):
897 Expr 30 [155-156] [Type (Int => Unit is Adj)]: Var: Item 1
898 Expr 31 [157-158] [Type Int]: Lit: Int(2)
899 Stmt 32 [137-142]: Semi: Expr 33 [137-141] [Type Unit]: Call:
900 Expr 34 [137-138] [Type (Int => Unit is Adj)]: UnOp (Functor Adj):
901 Expr 35 [137-138] [Type (Int => Unit is Adj)]: Var: Item 1
902 Expr 36 [139-140] [Type Int]: Lit: Int(1)
903 ctl: <none>
904 ctl-adj: <none>"#]],
905 );
906}
907
908#[test]
909fn generate_adj_invert_skips_within_block() {
910 check(
911 indoc! {r#"
912 namespace test {
913 operation B(input : Int) : Unit is Adj {}
914 operation A(q : Qubit) : Unit is Adj {
915 within {
916 B(1);
917 B(2);
918 }
919 apply {
920 B(3);
921 B(4);
922 }
923 }
924 }
925 "#},
926 &expect![[r#"
927 Package:
928 Item 0 [0-238] (Public):
929 Namespace (Ident 32 [10-14] "test"): Item 1, Item 2
930 Item 1 [21-62] (Public):
931 Parent: 0
932 Callable 0 [21-62] (operation):
933 name: Ident 1 [31-32] "B"
934 input: Pat 2 [33-44] [Type Int]: Bind: Ident 3 [33-38] "input"
935 output: Unit
936 functors: Adj
937 body: SpecDecl 4 [21-62]: Impl:
938 Block 5 [60-62]: <empty>
939 adj: SpecDecl 35 [21-62]: Impl:
940 Block 36 [60-62]: <empty>
941 ctl: <none>
942 ctl-adj: <none>
943 Item 2 [67-236] (Public):
944 Parent: 0
945 Callable 6 [67-236] (operation):
946 name: Ident 7 [77-78] "A"
947 input: Pat 8 [79-88] [Type Qubit]: Bind: Ident 9 [79-80] "q"
948 output: Unit
949 functors: Adj
950 body: SpecDecl 10 [67-236]: Impl:
951 Block 11 [104-236] [Type Unit]:
952 Stmt 12 [114-230]: Expr: Expr 13 [114-230] [Type Unit]: Conjugate:
953 Block 14 [121-168] [Type Unit]:
954 Stmt 15 [135-140]: Semi: Expr 16 [135-139] [Type Unit]: Call:
955 Expr 17 [135-136] [Type (Int => Unit is Adj)]: Var: Item 1
956 Expr 18 [137-138] [Type Int]: Lit: Int(1)
957 Stmt 19 [153-158]: Semi: Expr 20 [153-157] [Type Unit]: Call:
958 Expr 21 [153-154] [Type (Int => Unit is Adj)]: Var: Item 1
959 Expr 22 [155-156] [Type Int]: Lit: Int(2)
960 Block 23 [183-230] [Type Unit]:
961 Stmt 24 [197-202]: Semi: Expr 25 [197-201] [Type Unit]: Call:
962 Expr 26 [197-198] [Type (Int => Unit is Adj)]: Var: Item 1
963 Expr 27 [199-200] [Type Int]: Lit: Int(3)
964 Stmt 28 [215-220]: Semi: Expr 29 [215-219] [Type Unit]: Call:
965 Expr 30 [215-216] [Type (Int => Unit is Adj)]: Var: Item 1
966 Expr 31 [217-218] [Type Int]: Lit: Int(4)
967 adj: SpecDecl 37 [67-236]: Impl:
968 Block 38 [104-236] [Type Unit]:
969 Stmt 39 [114-230]: Expr: Expr 40 [114-230] [Type Unit]: Conjugate:
970 Block 41 [121-168] [Type Unit]:
971 Stmt 42 [135-140]: Semi: Expr 43 [135-139] [Type Unit]: Call:
972 Expr 44 [135-136] [Type (Int => Unit is Adj)]: Var: Item 1
973 Expr 45 [137-138] [Type Int]: Lit: Int(1)
974 Stmt 46 [153-158]: Semi: Expr 47 [153-157] [Type Unit]: Call:
975 Expr 48 [153-154] [Type (Int => Unit is Adj)]: Var: Item 1
976 Expr 49 [155-156] [Type Int]: Lit: Int(2)
977 Block 50 [183-230] [Type Unit]:
978 Stmt 51 [215-220]: Semi: Expr 52 [215-219] [Type Unit]: Call:
979 Expr 53 [215-216] [Type (Int => Unit is Adj)]: UnOp (Functor Adj):
980 Expr 54 [215-216] [Type (Int => Unit is Adj)]: Var: Item 1
981 Expr 55 [217-218] [Type Int]: Lit: Int(4)
982 Stmt 56 [197-202]: Semi: Expr 57 [197-201] [Type Unit]: Call:
983 Expr 58 [197-198] [Type (Int => Unit is Adj)]: UnOp (Functor Adj):
984 Expr 59 [197-198] [Type (Int => Unit is Adj)]: Var: Item 1
985 Expr 60 [199-200] [Type Int]: Lit: Int(3)
986 ctl: <none>
987 ctl-adj: <none>"#]],
988 );
989}
990
991#[test]
992fn generate_adj_invert_with_if_exprs() {
993 check(
994 indoc! {r#"
995 namespace test {
996 operation B(input : Int) : Unit is Adj {}
997 operation A(q : Qubit) : Unit is Adj {
998 B(1);
999 let val = if true {false} else {true};
1000 B(2);
1001 if false {B(3); B(4);} else {B(5); let val = true; B(6);}
1002 B(7);
1003 }
1004 }
1005 "#},
1006 &expect![[r#"
1007 Package:
1008 Item 0 [0-268] (Public):
1009 Namespace (Ident 64 [10-14] "test"): Item 1, Item 2
1010 Item 1 [21-62] (Public):
1011 Parent: 0
1012 Callable 0 [21-62] (operation):
1013 name: Ident 1 [31-32] "B"
1014 input: Pat 2 [33-44] [Type Int]: Bind: Ident 3 [33-38] "input"
1015 output: Unit
1016 functors: Adj
1017 body: SpecDecl 4 [21-62]: Impl:
1018 Block 5 [60-62]: <empty>
1019 adj: SpecDecl 67 [21-62]: Impl:
1020 Block 68 [60-62]: <empty>
1021 ctl: <none>
1022 ctl-adj: <none>
1023 Item 2 [67-266] (Public):
1024 Parent: 0
1025 Callable 6 [67-266] (operation):
1026 name: Ident 7 [77-78] "A"
1027 input: Pat 8 [79-88] [Type Qubit]: Bind: Ident 9 [79-80] "q"
1028 output: Unit
1029 functors: Adj
1030 body: SpecDecl 10 [67-266]: Impl:
1031 Block 11 [104-266] [Type Unit]:
1032 Stmt 12 [114-119]: Semi: Expr 13 [114-118] [Type Unit]: Call:
1033 Expr 14 [114-115] [Type (Int => Unit is Adj)]: Var: Item 1
1034 Expr 15 [116-117] [Type Int]: Lit: Int(1)
1035 Stmt 16 [128-166]: Local (Immutable):
1036 Pat 17 [132-135] [Type Bool]: Bind: Ident 18 [132-135] "val"
1037 Expr 19 [138-165] [Type Bool]: If:
1038 Expr 20 [141-145] [Type Bool]: Lit: Bool(true)
1039 Expr 21 [146-153] [Type Bool]: Expr Block: Block 22 [146-153] [Type Bool]:
1040 Stmt 23 [147-152]: Expr: Expr 24 [147-152] [Type Bool]: Lit: Bool(false)
1041 Expr 25 [154-165] [Type Bool]: Expr Block: Block 26 [159-165] [Type Bool]:
1042 Stmt 27 [160-164]: Expr: Expr 28 [160-164] [Type Bool]: Lit: Bool(true)
1043 Stmt 29 [175-180]: Semi: Expr 30 [175-179] [Type Unit]: Call:
1044 Expr 31 [175-176] [Type (Int => Unit is Adj)]: Var: Item 1
1045 Expr 32 [177-178] [Type Int]: Lit: Int(2)
1046 Stmt 33 [189-246]: Expr: Expr 34 [189-246] [Type Unit]: If:
1047 Expr 35 [192-197] [Type Bool]: Lit: Bool(false)
1048 Expr 36 [198-211] [Type Unit]: Expr Block: Block 37 [198-211] [Type Unit]:
1049 Stmt 38 [199-204]: Semi: Expr 39 [199-203] [Type Unit]: Call:
1050 Expr 40 [199-200] [Type (Int => Unit is Adj)]: Var: Item 1
1051 Expr 41 [201-202] [Type Int]: Lit: Int(3)
1052 Stmt 42 [205-210]: Semi: Expr 43 [205-209] [Type Unit]: Call:
1053 Expr 44 [205-206] [Type (Int => Unit is Adj)]: Var: Item 1
1054 Expr 45 [207-208] [Type Int]: Lit: Int(4)
1055 Expr 46 [212-246] [Type Unit]: Expr Block: Block 47 [217-246] [Type Unit]:
1056 Stmt 48 [218-223]: Semi: Expr 49 [218-222] [Type Unit]: Call:
1057 Expr 50 [218-219] [Type (Int => Unit is Adj)]: Var: Item 1
1058 Expr 51 [220-221] [Type Int]: Lit: Int(5)
1059 Stmt 52 [224-239]: Local (Immutable):
1060 Pat 53 [228-231] [Type Bool]: Bind: Ident 54 [228-231] "val"
1061 Expr 55 [234-238] [Type Bool]: Lit: Bool(true)
1062 Stmt 56 [240-245]: Semi: Expr 57 [240-244] [Type Unit]: Call:
1063 Expr 58 [240-241] [Type (Int => Unit is Adj)]: Var: Item 1
1064 Expr 59 [242-243] [Type Int]: Lit: Int(6)
1065 Stmt 60 [255-260]: Semi: Expr 61 [255-259] [Type Unit]: Call:
1066 Expr 62 [255-256] [Type (Int => Unit is Adj)]: Var: Item 1
1067 Expr 63 [257-258] [Type Int]: Lit: Int(7)
1068 adj: SpecDecl 69 [67-266]: Impl:
1069 Block 70 [104-266] [Type Unit]:
1070 Stmt 71 [128-166]: Local (Immutable):
1071 Pat 72 [132-135] [Type Bool]: Bind: Ident 73 [132-135] "val"
1072 Expr 74 [138-165] [Type Bool]: If:
1073 Expr 75 [141-145] [Type Bool]: Lit: Bool(true)
1074 Expr 76 [146-153] [Type Bool]: Expr Block: Block 77 [146-153] [Type Bool]:
1075 Stmt 78 [147-152]: Expr: Expr 79 [147-152] [Type Bool]: Lit: Bool(false)
1076 Expr 80 [154-165] [Type Bool]: Expr Block: Block 81 [159-165] [Type Bool]:
1077 Stmt 82 [160-164]: Expr: Expr 83 [160-164] [Type Bool]: Lit: Bool(true)
1078 Stmt 84 [255-260]: Semi: Expr 85 [255-259] [Type Unit]: Call:
1079 Expr 86 [255-256] [Type (Int => Unit is Adj)]: UnOp (Functor Adj):
1080 Expr 87 [255-256] [Type (Int => Unit is Adj)]: Var: Item 1
1081 Expr 88 [257-258] [Type Int]: Lit: Int(7)
1082 Stmt 89 [189-246]: Expr: Expr 90 [189-246] [Type Unit]: If:
1083 Expr 91 [192-197] [Type Bool]: Lit: Bool(false)
1084 Expr 92 [198-211] [Type Unit]: Expr Block: Block 93 [198-211] [Type Unit]:
1085 Stmt 94 [205-210]: Semi: Expr 95 [205-209] [Type Unit]: Call:
1086 Expr 96 [205-206] [Type (Int => Unit is Adj)]: UnOp (Functor Adj):
1087 Expr 97 [205-206] [Type (Int => Unit is Adj)]: Var: Item 1
1088 Expr 98 [207-208] [Type Int]: Lit: Int(4)
1089 Stmt 99 [199-204]: Semi: Expr 100 [199-203] [Type Unit]: Call:
1090 Expr 101 [199-200] [Type (Int => Unit is Adj)]: UnOp (Functor Adj):
1091 Expr 102 [199-200] [Type (Int => Unit is Adj)]: Var: Item 1
1092 Expr 103 [201-202] [Type Int]: Lit: Int(3)
1093 Expr 104 [212-246] [Type Unit]: Expr Block: Block 105 [217-246] [Type Unit]:
1094 Stmt 106 [224-239]: Local (Immutable):
1095 Pat 107 [228-231] [Type Bool]: Bind: Ident 108 [228-231] "val"
1096 Expr 109 [234-238] [Type Bool]: Lit: Bool(true)
1097 Stmt 110 [240-245]: Semi: Expr 111 [240-244] [Type Unit]: Call:
1098 Expr 112 [240-241] [Type (Int => Unit is Adj)]: UnOp (Functor Adj):
1099 Expr 113 [240-241] [Type (Int => Unit is Adj)]: Var: Item 1
1100 Expr 114 [242-243] [Type Int]: Lit: Int(6)
1101 Stmt 115 [218-223]: Semi: Expr 116 [218-222] [Type Unit]: Call:
1102 Expr 117 [218-219] [Type (Int => Unit is Adj)]: UnOp (Functor Adj):
1103 Expr 118 [218-219] [Type (Int => Unit is Adj)]: Var: Item 1
1104 Expr 119 [220-221] [Type Int]: Lit: Int(5)
1105 Stmt 120 [175-180]: Semi: Expr 121 [175-179] [Type Unit]: Call:
1106 Expr 122 [175-176] [Type (Int => Unit is Adj)]: UnOp (Functor Adj):
1107 Expr 123 [175-176] [Type (Int => Unit is Adj)]: Var: Item 1
1108 Expr 124 [177-178] [Type Int]: Lit: Int(2)
1109 Stmt 125 [114-119]: Semi: Expr 126 [114-118] [Type Unit]: Call:
1110 Expr 127 [114-115] [Type (Int => Unit is Adj)]: UnOp (Functor Adj):
1111 Expr 128 [114-115] [Type (Int => Unit is Adj)]: Var: Item 1
1112 Expr 129 [116-117] [Type Int]: Lit: Int(1)
1113 ctl: <none>
1114 ctl-adj: <none>"#]],
1115 );
1116}
1117
1118#[test]
1119fn generate_adj_invert_with_range_loop() {
1120 check(
1121 indoc! {r#"
1122 namespace test {
1123 operation B(input : Int) : Unit is Adj {}
1124 operation A(q : Qubit) : Unit is Adj {
1125 for i in 0..5 {
1126 B(1);
1127 B(2);
1128 }
1129 }
1130 }
1131 "#},
1132 &expect![[r#"
1133 Package:
1134 Item 0 [0-183] (Public):
1135 Namespace (Ident 28 [10-14] "test"): Item 1, Item 2
1136 Item 1 [21-62] (Public):
1137 Parent: 0
1138 Callable 0 [21-62] (operation):
1139 name: Ident 1 [31-32] "B"
1140 input: Pat 2 [33-44] [Type Int]: Bind: Ident 3 [33-38] "input"
1141 output: Unit
1142 functors: Adj
1143 body: SpecDecl 4 [21-62]: Impl:
1144 Block 5 [60-62]: <empty>
1145 adj: SpecDecl 31 [21-62]: Impl:
1146 Block 32 [60-62]: <empty>
1147 ctl: <none>
1148 ctl-adj: <none>
1149 Item 2 [67-181] (Public):
1150 Parent: 0
1151 Callable 6 [67-181] (operation):
1152 name: Ident 7 [77-78] "A"
1153 input: Pat 8 [79-88] [Type Qubit]: Bind: Ident 9 [79-80] "q"
1154 output: Unit
1155 functors: Adj
1156 body: SpecDecl 10 [67-181]: Impl:
1157 Block 11 [104-181] [Type Unit]:
1158 Stmt 12 [114-175]: Expr: Expr 13 [114-175] [Type Unit]: For:
1159 Pat 14 [118-119] [Type Int]: Bind: Ident 15 [118-119] "i"
1160 Expr 16 [123-127] [Type Range]: Range:
1161 Expr 17 [123-124] [Type Int]: Lit: Int(0)
1162 <no step>
1163 Expr 18 [126-127] [Type Int]: Lit: Int(5)
1164 Block 19 [128-175] [Type Unit]:
1165 Stmt 20 [142-147]: Semi: Expr 21 [142-146] [Type Unit]: Call:
1166 Expr 22 [142-143] [Type (Int => Unit is Adj)]: Var: Item 1
1167 Expr 23 [144-145] [Type Int]: Lit: Int(1)
1168 Stmt 24 [160-165]: Semi: Expr 25 [160-164] [Type Unit]: Call:
1169 Expr 26 [160-161] [Type (Int => Unit is Adj)]: Var: Item 1
1170 Expr 27 [162-163] [Type Int]: Lit: Int(2)
1171 adj: SpecDecl 34 [67-181]: Impl:
1172 Block 35 [104-181] [Type Unit]:
1173 Stmt 36 [114-175]: Expr: Expr 37 [0-0] [Type Unit]: Expr Block: Block 38 [0-0] [Type Unit]:
1174 Stmt 39 [0-0]: Local (Immutable):
1175 Pat 40 [0-0] [Type Range]: Bind: Ident 41 [0-0] "@range"
1176 Expr 42 [123-127] [Type Range]: Range:
1177 Expr 43 [123-124] [Type Int]: Lit: Int(0)
1178 <no step>
1179 Expr 44 [126-127] [Type Int]: Lit: Int(5)
1180 Stmt 45 [0-0]: Expr: Expr 46 [0-0] [Type Unit]: For:
1181 Pat 47 [118-119] [Type Int]: Bind: Ident 48 [118-119] "i"
1182 Expr 49 [0-0] [Type Range]: Range:
1183 Expr 50 [0-0] [Type Int]: BinOp (Add):
1184 Expr 51 [0-0] [Type Int]: Field:
1185 Expr 52 [0-0] [Type Range]: Var: Local 41
1186 Prim(Start)
1187 Expr 53 [0-0] [Type Int]: BinOp (Mul):
1188 Expr 54 [0-0] [Type Int]: BinOp (Div):
1189 Expr 55 [0-0] [Type Int]: BinOp (Sub):
1190 Expr 56 [0-0] [Type Int]: Field:
1191 Expr 57 [0-0] [Type Range]: Var: Local 41
1192 Prim(End)
1193 Expr 58 [0-0] [Type Int]: Field:
1194 Expr 59 [0-0] [Type Range]: Var: Local 41
1195 Prim(Start)
1196 Expr 60 [0-0] [Type Int]: Field:
1197 Expr 61 [0-0] [Type Range]: Var: Local 41
1198 Prim(Step)
1199 Expr 62 [0-0] [Type Int]: Field:
1200 Expr 63 [0-0] [Type Range]: Var: Local 41
1201 Prim(Step)
1202 Expr 64 [0-0] [Type Int]: UnOp (Neg):
1203 Expr 65 [0-0] [Type Int]: Field:
1204 Expr 66 [0-0] [Type Range]: Var: Local 41
1205 Prim(Step)
1206 Expr 67 [0-0] [Type Int]: Field:
1207 Expr 68 [0-0] [Type Range]: Var: Local 41
1208 Prim(Start)
1209 Block 69 [128-175] [Type Unit]:
1210 Stmt 70 [160-165]: Semi: Expr 71 [160-164] [Type Unit]: Call:
1211 Expr 72 [160-161] [Type (Int => Unit is Adj)]: UnOp (Functor Adj):
1212 Expr 73 [160-161] [Type (Int => Unit is Adj)]: Var: Item 1
1213 Expr 74 [162-163] [Type Int]: Lit: Int(2)
1214 Stmt 75 [142-147]: Semi: Expr 76 [142-146] [Type Unit]: Call:
1215 Expr 77 [142-143] [Type (Int => Unit is Adj)]: UnOp (Functor Adj):
1216 Expr 78 [142-143] [Type (Int => Unit is Adj)]: Var: Item 1
1217 Expr 79 [144-145] [Type Int]: Lit: Int(1)
1218 ctl: <none>
1219 ctl-adj: <none>"#]],
1220 );
1221}
1222
1223#[test]
1224fn generate_adj_invert_with_array_loop() {
1225 check(
1226 indoc! {r#"
1227 namespace test {
1228 operation B(input : Int) : Unit is Adj {}
1229 operation A(q : Qubit) : Unit is Adj {
1230 for val in [0, 1, 2] {
1231 B(1);
1232 B(2);
1233 }
1234 }
1235 }
1236 "#},
1237 &expect![[r#"
1238 Package:
1239 Item 0 [0-190] (Public):
1240 Namespace (Ident 29 [10-14] "test"): Item 1, Item 2
1241 Item 1 [21-62] (Public):
1242 Parent: 0
1243 Callable 0 [21-62] (operation):
1244 name: Ident 1 [31-32] "B"
1245 input: Pat 2 [33-44] [Type Int]: Bind: Ident 3 [33-38] "input"
1246 output: Unit
1247 functors: Adj
1248 body: SpecDecl 4 [21-62]: Impl:
1249 Block 5 [60-62]: <empty>
1250 adj: SpecDecl 32 [21-62]: Impl:
1251 Block 33 [60-62]: <empty>
1252 ctl: <none>
1253 ctl-adj: <none>
1254 Item 2 [67-188] (Public):
1255 Parent: 0
1256 Callable 6 [67-188] (operation):
1257 name: Ident 7 [77-78] "A"
1258 input: Pat 8 [79-88] [Type Qubit]: Bind: Ident 9 [79-80] "q"
1259 output: Unit
1260 functors: Adj
1261 body: SpecDecl 10 [67-188]: Impl:
1262 Block 11 [104-188] [Type Unit]:
1263 Stmt 12 [114-182]: Expr: Expr 13 [114-182] [Type Unit]: For:
1264 Pat 14 [118-121] [Type Int]: Bind: Ident 15 [118-121] "val"
1265 Expr 16 [125-134] [Type Int[]]: Array:
1266 Expr 17 [126-127] [Type Int]: Lit: Int(0)
1267 Expr 18 [129-130] [Type Int]: Lit: Int(1)
1268 Expr 19 [132-133] [Type Int]: Lit: Int(2)
1269 Block 20 [135-182] [Type Unit]:
1270 Stmt 21 [149-154]: Semi: Expr 22 [149-153] [Type Unit]: Call:
1271 Expr 23 [149-150] [Type (Int => Unit is Adj)]: Var: Item 1
1272 Expr 24 [151-152] [Type Int]: Lit: Int(1)
1273 Stmt 25 [167-172]: Semi: Expr 26 [167-171] [Type Unit]: Call:
1274 Expr 27 [167-168] [Type (Int => Unit is Adj)]: Var: Item 1
1275 Expr 28 [169-170] [Type Int]: Lit: Int(2)
1276 adj: SpecDecl 36 [67-188]: Impl:
1277 Block 37 [104-188] [Type Unit]:
1278 Stmt 38 [114-182]: Expr: Expr 39 [0-0] [Type Unit]: Expr Block: Block 40 [0-0] [Type Unit]:
1279 Stmt 41 [0-0]: Local (Immutable):
1280 Pat 42 [0-0] [Type Int[]]: Bind: Ident 43 [0-0] "@array"
1281 Expr 44 [125-134] [Type Int[]]: Array:
1282 Expr 45 [126-127] [Type Int]: Lit: Int(0)
1283 Expr 46 [129-130] [Type Int]: Lit: Int(1)
1284 Expr 47 [132-133] [Type Int]: Lit: Int(2)
1285 Stmt 48 [0-0]: Expr: Expr 49 [0-0] [Type Unit]: For:
1286 Pat 50 [0-0] [Type Int]: Bind: Ident 51 [0-0] "@index"
1287 Expr 52 [0-0] [Type Range]: Range:
1288 Expr 53 [0-0] [Type Int]: BinOp (Sub):
1289 Expr 54 [0-0] [Type Int]: Call:
1290 Expr 55 [0-0] [Type (Int[] -> Int)]: Var:
1291 res: Item 1 (Package 0)
1292 generics:
1293 Int
1294 Expr 56 [0-0] [Type Int[]]: Var: Local 43
1295 Expr 57 [0-0] [Type Int]: Lit: Int(1)
1296 Expr 58 [0-0] [Type Int]: Lit: Int(-1)
1297 Expr 59 [0-0] [Type Int]: Lit: Int(0)
1298 Block 60 [135-182] [Type Unit]:
1299 Stmt 61 [0-0]: Local (Immutable):
1300 Pat 62 [118-121] [Type Int]: Bind: Ident 63 [118-121] "val"
1301 Expr 64 [0-0] [Type Int]: Index:
1302 Expr 65 [0-0] [Type Int[]]: Var: Local 43
1303 Expr 66 [0-0] [Type Int]: Var: Local 51
1304 Stmt 67 [167-172]: Semi: Expr 68 [167-171] [Type Unit]: Call:
1305 Expr 69 [167-168] [Type (Int => Unit is Adj)]: UnOp (Functor Adj):
1306 Expr 70 [167-168] [Type (Int => Unit is Adj)]: Var: Item 1
1307 Expr 71 [169-170] [Type Int]: Lit: Int(2)
1308 Stmt 72 [149-154]: Semi: Expr 73 [149-153] [Type Unit]: Call:
1309 Expr 74 [149-150] [Type (Int => Unit is Adj)]: UnOp (Functor Adj):
1310 Expr 75 [149-150] [Type (Int => Unit is Adj)]: Var: Item 1
1311 Expr 76 [151-152] [Type Int]: Lit: Int(1)
1312 ctl: <none>
1313 ctl-adj: <none>"#]],
1314 );
1315}
1316
1317#[test]
1318fn generate_adj_invert_with_nested_loops() {
1319 check(
1320 indoc! {r#"
1321 namespace test {
1322 operation B(input : Int) : Unit is Adj {}
1323 operation A(q : Qubit) : Unit is Adj {
1324 for val in [0, 1, 2] {
1325 B(1);
1326 let arr = [true, false, true];
1327 for val in arr {
1328 B(2);
1329 B(3);
1330 }
1331 B(4);
1332 }
1333 }
1334 }
1335 "#},
1336 &expect![[r#"
1337 Package:
1338 Item 0 [0-320] (Public):
1339 Namespace (Ident 50 [10-14] "test"): Item 1, Item 2
1340 Item 1 [21-62] (Public):
1341 Parent: 0
1342 Callable 0 [21-62] (operation):
1343 name: Ident 1 [31-32] "B"
1344 input: Pat 2 [33-44] [Type Int]: Bind: Ident 3 [33-38] "input"
1345 output: Unit
1346 functors: Adj
1347 body: SpecDecl 4 [21-62]: Impl:
1348 Block 5 [60-62]: <empty>
1349 adj: SpecDecl 53 [21-62]: Impl:
1350 Block 54 [60-62]: <empty>
1351 ctl: <none>
1352 ctl-adj: <none>
1353 Item 2 [67-318] (Public):
1354 Parent: 0
1355 Callable 6 [67-318] (operation):
1356 name: Ident 7 [77-78] "A"
1357 input: Pat 8 [79-88] [Type Qubit]: Bind: Ident 9 [79-80] "q"
1358 output: Unit
1359 functors: Adj
1360 body: SpecDecl 10 [67-318]: Impl:
1361 Block 11 [104-318] [Type Unit]:
1362 Stmt 12 [114-312]: Expr: Expr 13 [114-312] [Type Unit]: For:
1363 Pat 14 [118-121] [Type Int]: Bind: Ident 15 [118-121] "val"
1364 Expr 16 [125-134] [Type Int[]]: Array:
1365 Expr 17 [126-127] [Type Int]: Lit: Int(0)
1366 Expr 18 [129-130] [Type Int]: Lit: Int(1)
1367 Expr 19 [132-133] [Type Int]: Lit: Int(2)
1368 Block 20 [135-312] [Type Unit]:
1369 Stmt 21 [149-154]: Semi: Expr 22 [149-153] [Type Unit]: Call:
1370 Expr 23 [149-150] [Type (Int => Unit is Adj)]: Var: Item 1
1371 Expr 24 [151-152] [Type Int]: Lit: Int(1)
1372 Stmt 25 [167-197]: Local (Immutable):
1373 Pat 26 [171-174] [Type Bool[]]: Bind: Ident 27 [171-174] "arr"
1374 Expr 28 [177-196] [Type Bool[]]: Array:
1375 Expr 29 [178-182] [Type Bool]: Lit: Bool(true)
1376 Expr 30 [184-189] [Type Bool]: Lit: Bool(false)
1377 Expr 31 [191-195] [Type Bool]: Lit: Bool(true)
1378 Stmt 32 [210-284]: Expr: Expr 33 [210-284] [Type Unit]: For:
1379 Pat 34 [214-217] [Type Bool]: Bind: Ident 35 [214-217] "val"
1380 Expr 36 [221-224] [Type Bool[]]: Var: Local 27
1381 Block 37 [225-284] [Type Unit]:
1382 Stmt 38 [243-248]: Semi: Expr 39 [243-247] [Type Unit]: Call:
1383 Expr 40 [243-244] [Type (Int => Unit is Adj)]: Var: Item 1
1384 Expr 41 [245-246] [Type Int]: Lit: Int(2)
1385 Stmt 42 [265-270]: Semi: Expr 43 [265-269] [Type Unit]: Call:
1386 Expr 44 [265-266] [Type (Int => Unit is Adj)]: Var: Item 1
1387 Expr 45 [267-268] [Type Int]: Lit: Int(3)
1388 Stmt 46 [297-302]: Semi: Expr 47 [297-301] [Type Unit]: Call:
1389 Expr 48 [297-298] [Type (Int => Unit is Adj)]: Var: Item 1
1390 Expr 49 [299-300] [Type Int]: Lit: Int(4)
1391 adj: SpecDecl 59 [67-318]: Impl:
1392 Block 60 [104-318] [Type Unit]:
1393 Stmt 61 [114-312]: Expr: Expr 62 [0-0] [Type Unit]: Expr Block: Block 63 [0-0] [Type Unit]:
1394 Stmt 64 [0-0]: Local (Immutable):
1395 Pat 65 [0-0] [Type Int[]]: Bind: Ident 66 [0-0] "@array"
1396 Expr 67 [125-134] [Type Int[]]: Array:
1397 Expr 68 [126-127] [Type Int]: Lit: Int(0)
1398 Expr 69 [129-130] [Type Int]: Lit: Int(1)
1399 Expr 70 [132-133] [Type Int]: Lit: Int(2)
1400 Stmt 71 [0-0]: Expr: Expr 72 [0-0] [Type Unit]: For:
1401 Pat 73 [0-0] [Type Int]: Bind: Ident 74 [0-0] "@index"
1402 Expr 75 [0-0] [Type Range]: Range:
1403 Expr 76 [0-0] [Type Int]: BinOp (Sub):
1404 Expr 77 [0-0] [Type Int]: Call:
1405 Expr 78 [0-0] [Type (Int[] -> Int)]: Var:
1406 res: Item 1 (Package 0)
1407 generics:
1408 Int
1409 Expr 79 [0-0] [Type Int[]]: Var: Local 66
1410 Expr 80 [0-0] [Type Int]: Lit: Int(1)
1411 Expr 81 [0-0] [Type Int]: Lit: Int(-1)
1412 Expr 82 [0-0] [Type Int]: Lit: Int(0)
1413 Block 83 [135-312] [Type Unit]:
1414 Stmt 84 [0-0]: Local (Immutable):
1415 Pat 85 [118-121] [Type Int]: Bind: Ident 86 [118-121] "val"
1416 Expr 87 [0-0] [Type Int]: Index:
1417 Expr 88 [0-0] [Type Int[]]: Var: Local 66
1418 Expr 89 [0-0] [Type Int]: Var: Local 74
1419 Stmt 90 [167-197]: Local (Immutable):
1420 Pat 91 [171-174] [Type Bool[]]: Bind: Ident 92 [171-174] "arr"
1421 Expr 93 [177-196] [Type Bool[]]: Array:
1422 Expr 94 [178-182] [Type Bool]: Lit: Bool(true)
1423 Expr 95 [184-189] [Type Bool]: Lit: Bool(false)
1424 Expr 96 [191-195] [Type Bool]: Lit: Bool(true)
1425 Stmt 97 [297-302]: Semi: Expr 98 [297-301] [Type Unit]: Call:
1426 Expr 99 [297-298] [Type (Int => Unit is Adj)]: UnOp (Functor Adj):
1427 Expr 100 [297-298] [Type (Int => Unit is Adj)]: Var: Item 1
1428 Expr 101 [299-300] [Type Int]: Lit: Int(4)
1429 Stmt 102 [210-284]: Expr: Expr 103 [0-0] [Type Unit]: Expr Block: Block 104 [0-0] [Type Unit]:
1430 Stmt 105 [0-0]: Local (Immutable):
1431 Pat 106 [0-0] [Type Bool[]]: Bind: Ident 107 [0-0] "@array"
1432 Expr 108 [221-224] [Type Bool[]]: Var: Local 92
1433 Stmt 109 [0-0]: Expr: Expr 110 [0-0] [Type Unit]: For:
1434 Pat 111 [0-0] [Type Int]: Bind: Ident 112 [0-0] "@index"
1435 Expr 113 [0-0] [Type Range]: Range:
1436 Expr 114 [0-0] [Type Int]: BinOp (Sub):
1437 Expr 115 [0-0] [Type Int]: Call:
1438 Expr 116 [0-0] [Type (Bool[] -> Int)]: Var:
1439 res: Item 1 (Package 0)
1440 generics:
1441 Bool
1442 Expr 117 [0-0] [Type Bool[]]: Var: Local 107
1443 Expr 118 [0-0] [Type Int]: Lit: Int(1)
1444 Expr 119 [0-0] [Type Int]: Lit: Int(-1)
1445 Expr 120 [0-0] [Type Int]: Lit: Int(0)
1446 Block 121 [225-284] [Type Unit]:
1447 Stmt 122 [0-0]: Local (Immutable):
1448 Pat 123 [214-217] [Type Bool]: Bind: Ident 124 [214-217] "val"
1449 Expr 125 [0-0] [Type Bool]: Index:
1450 Expr 126 [0-0] [Type Bool[]]: Var: Local 107
1451 Expr 127 [0-0] [Type Int]: Var: Local 112
1452 Stmt 128 [265-270]: Semi: Expr 129 [265-269] [Type Unit]: Call:
1453 Expr 130 [265-266] [Type (Int => Unit is Adj)]: UnOp (Functor Adj):
1454 Expr 131 [265-266] [Type (Int => Unit is Adj)]: Var: Item 1
1455 Expr 132 [267-268] [Type Int]: Lit: Int(3)
1456 Stmt 133 [243-248]: Semi: Expr 134 [243-247] [Type Unit]: Call:
1457 Expr 135 [243-244] [Type (Int => Unit is Adj)]: UnOp (Functor Adj):
1458 Expr 136 [243-244] [Type (Int => Unit is Adj)]: Var: Item 1
1459 Expr 137 [245-246] [Type Int]: Lit: Int(2)
1460 Stmt 138 [149-154]: Semi: Expr 139 [149-153] [Type Unit]: Call:
1461 Expr 140 [149-150] [Type (Int => Unit is Adj)]: UnOp (Functor Adj):
1462 Expr 141 [149-150] [Type (Int => Unit is Adj)]: Var: Item 1
1463 Expr 142 [151-152] [Type Int]: Lit: Int(1)
1464 ctl: <none>
1465 ctl-adj: <none>"#]],
1466 );
1467}
1468
1469#[test]
1470fn generate_ctladj_distribute() {
1471 check(
1472 indoc! {r#"
1473 namespace test {
1474 operation B(input : Int) : Unit is Ctl + Adj {}
1475 operation A(q : Qubit) : Unit is Ctl + Adj {
1476 body ... { B(1); B(2); }
1477 }
1478 }
1479 "#},
1480 &expect![[r#"
1481 Package:
1482 Item 0 [0-158] (Public):
1483 Namespace (Ident 20 [10-14] "test"): Item 1, Item 2
1484 Item 1 [21-68] (Public):
1485 Parent: 0
1486 Callable 0 [21-68] (operation):
1487 name: Ident 1 [31-32] "B"
1488 input: Pat 2 [33-44] [Type Int]: Bind: Ident 3 [33-38] "input"
1489 output: Unit
1490 functors: Adj + Ctl
1491 body: SpecDecl 4 [21-68]: Impl:
1492 Block 5 [66-68]: <empty>
1493 adj: SpecDecl 32 [21-68]: Impl:
1494 Block 33 [66-68]: <empty>
1495 ctl: SpecDecl 28 [21-68]: Impl:
1496 Pat 29 [21-68] [Type Qubit[]]: Bind: Ident 30 [21-68] "ctls"
1497 Block 31 [66-68]: <empty>
1498 ctl-adj: SpecDecl 35 [21-68]: Impl:
1499 Pat 36 [21-68] [Type Qubit[]]: Bind: Ident 37 [21-68] "ctls"
1500 Block 38 [66-68]: <empty>
1501 Item 2 [73-156] (Public):
1502 Parent: 0
1503 Callable 6 [73-156] (operation):
1504 name: Ident 7 [83-84] "A"
1505 input: Pat 8 [85-94] [Type Qubit]: Bind: Ident 9 [85-86] "q"
1506 output: Unit
1507 functors: Adj + Ctl
1508 body: SpecDecl 10 [126-150]: Impl:
1509 Block 11 [135-150] [Type Unit]:
1510 Stmt 12 [137-142]: Semi: Expr 13 [137-141] [Type Unit]: Call:
1511 Expr 14 [137-138] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1512 Expr 15 [139-140] [Type Int]: Lit: Int(1)
1513 Stmt 16 [143-148]: Semi: Expr 17 [143-147] [Type Unit]: Call:
1514 Expr 18 [143-144] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1515 Expr 19 [145-146] [Type Int]: Lit: Int(2)
1516 adj: SpecDecl 58 [73-156]: Impl:
1517 Block 59 [135-150] [Type Unit]:
1518 Stmt 60 [143-148]: Semi: Expr 61 [143-147] [Type Unit]: Call:
1519 Expr 62 [143-144] [Type (Int => Unit is Adj + Ctl)]: UnOp (Functor Adj):
1520 Expr 63 [143-144] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1521 Expr 64 [145-146] [Type Int]: Lit: Int(2)
1522 Stmt 65 [137-142]: Semi: Expr 66 [137-141] [Type Unit]: Call:
1523 Expr 67 [137-138] [Type (Int => Unit is Adj + Ctl)]: UnOp (Functor Adj):
1524 Expr 68 [137-138] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1525 Expr 69 [139-140] [Type Int]: Lit: Int(1)
1526 ctl: SpecDecl 40 [73-156]: Impl:
1527 Pat 41 [73-156] [Type Qubit[]]: Bind: Ident 42 [73-156] "ctls"
1528 Block 43 [135-150] [Type Unit]:
1529 Stmt 44 [137-142]: Semi: Expr 45 [137-141] [Type Unit]: Call:
1530 Expr 46 [137-138] [Type ((Qubit[], Int) => Unit is Adj + Ctl)]: UnOp (Functor Ctl):
1531 Expr 47 [137-138] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1532 Expr 48 [139-140] [Type (Qubit[], Int)]: Tuple:
1533 Expr 49 [139-140] [Type Qubit[]]: Var: Local 42
1534 Expr 50 [139-140] [Type Int]: Lit: Int(1)
1535 Stmt 51 [143-148]: Semi: Expr 52 [143-147] [Type Unit]: Call:
1536 Expr 53 [143-144] [Type ((Qubit[], Int) => Unit is Adj + Ctl)]: UnOp (Functor Ctl):
1537 Expr 54 [143-144] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1538 Expr 55 [145-146] [Type (Qubit[], Int)]: Tuple:
1539 Expr 56 [145-146] [Type Qubit[]]: Var: Local 42
1540 Expr 57 [145-146] [Type Int]: Lit: Int(2)
1541 ctl-adj: SpecDecl 71 [73-156]: Impl:
1542 Pat 72 [73-156] [Type Qubit[]]: Bind: Ident 73 [73-156] "ctls"
1543 Block 74 [135-150] [Type Unit]:
1544 Stmt 75 [143-148]: Semi: Expr 76 [143-147] [Type Unit]: Call:
1545 Expr 77 [143-144] [Type ((Qubit[], Int) => Unit is Adj + Ctl)]: UnOp (Functor Ctl):
1546 Expr 78 [143-144] [Type (Int => Unit is Adj + Ctl)]: UnOp (Functor Adj):
1547 Expr 79 [143-144] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1548 Expr 80 [145-146] [Type (Qubit[], Int)]: Tuple:
1549 Expr 81 [145-146] [Type Qubit[]]: Var: Local 73
1550 Expr 82 [145-146] [Type Int]: Lit: Int(2)
1551 Stmt 83 [137-142]: Semi: Expr 84 [137-141] [Type Unit]: Call:
1552 Expr 85 [137-138] [Type ((Qubit[], Int) => Unit is Adj + Ctl)]: UnOp (Functor Ctl):
1553 Expr 86 [137-138] [Type (Int => Unit is Adj + Ctl)]: UnOp (Functor Adj):
1554 Expr 87 [137-138] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1555 Expr 88 [139-140] [Type (Qubit[], Int)]: Tuple:
1556 Expr 89 [139-140] [Type Qubit[]]: Var: Local 73
1557 Expr 90 [139-140] [Type Int]: Lit: Int(1)"#]],
1558 );
1559}
1560
1561#[test]
1562fn generate_ctladj_auto_to_distribute() {
1563 check(
1564 indoc! {r#"
1565 namespace test {
1566 operation B(input : Int) : Unit is Ctl + Adj {}
1567 operation A(q : Qubit) : Unit is Ctl + Adj {
1568 body ... { B(1); B(2); }
1569 controlled adjoint auto;
1570 }
1571 }
1572 "#},
1573 &expect![[r#"
1574 Package:
1575 Item 0 [0-191] (Public):
1576 Namespace (Ident 21 [10-14] "test"): Item 1, Item 2
1577 Item 1 [21-68] (Public):
1578 Parent: 0
1579 Callable 0 [21-68] (operation):
1580 name: Ident 1 [31-32] "B"
1581 input: Pat 2 [33-44] [Type Int]: Bind: Ident 3 [33-38] "input"
1582 output: Unit
1583 functors: Adj + Ctl
1584 body: SpecDecl 4 [21-68]: Impl:
1585 Block 5 [66-68]: <empty>
1586 adj: SpecDecl 33 [21-68]: Impl:
1587 Block 34 [66-68]: <empty>
1588 ctl: SpecDecl 29 [21-68]: Impl:
1589 Pat 30 [21-68] [Type Qubit[]]: Bind: Ident 31 [21-68] "ctls"
1590 Block 32 [66-68]: <empty>
1591 ctl-adj: SpecDecl 36 [21-68]: Impl:
1592 Pat 37 [21-68] [Type Qubit[]]: Bind: Ident 38 [21-68] "ctls"
1593 Block 39 [66-68]: <empty>
1594 Item 2 [73-189] (Public):
1595 Parent: 0
1596 Callable 6 [73-189] (operation):
1597 name: Ident 7 [83-84] "A"
1598 input: Pat 8 [85-94] [Type Qubit]: Bind: Ident 9 [85-86] "q"
1599 output: Unit
1600 functors: Adj + Ctl
1601 body: SpecDecl 10 [126-150]: Impl:
1602 Block 11 [135-150] [Type Unit]:
1603 Stmt 12 [137-142]: Semi: Expr 13 [137-141] [Type Unit]: Call:
1604 Expr 14 [137-138] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1605 Expr 15 [139-140] [Type Int]: Lit: Int(1)
1606 Stmt 16 [143-148]: Semi: Expr 17 [143-147] [Type Unit]: Call:
1607 Expr 18 [143-144] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1608 Expr 19 [145-146] [Type Int]: Lit: Int(2)
1609 adj: SpecDecl 59 [73-189]: Impl:
1610 Block 60 [135-150] [Type Unit]:
1611 Stmt 61 [143-148]: Semi: Expr 62 [143-147] [Type Unit]: Call:
1612 Expr 63 [143-144] [Type (Int => Unit is Adj + Ctl)]: UnOp (Functor Adj):
1613 Expr 64 [143-144] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1614 Expr 65 [145-146] [Type Int]: Lit: Int(2)
1615 Stmt 66 [137-142]: Semi: Expr 67 [137-141] [Type Unit]: Call:
1616 Expr 68 [137-138] [Type (Int => Unit is Adj + Ctl)]: UnOp (Functor Adj):
1617 Expr 69 [137-138] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1618 Expr 70 [139-140] [Type Int]: Lit: Int(1)
1619 ctl: SpecDecl 41 [73-189]: Impl:
1620 Pat 42 [73-189] [Type Qubit[]]: Bind: Ident 43 [73-189] "ctls"
1621 Block 44 [135-150] [Type Unit]:
1622 Stmt 45 [137-142]: Semi: Expr 46 [137-141] [Type Unit]: Call:
1623 Expr 47 [137-138] [Type ((Qubit[], Int) => Unit is Adj + Ctl)]: UnOp (Functor Ctl):
1624 Expr 48 [137-138] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1625 Expr 49 [139-140] [Type (Qubit[], Int)]: Tuple:
1626 Expr 50 [139-140] [Type Qubit[]]: Var: Local 43
1627 Expr 51 [139-140] [Type Int]: Lit: Int(1)
1628 Stmt 52 [143-148]: Semi: Expr 53 [143-147] [Type Unit]: Call:
1629 Expr 54 [143-144] [Type ((Qubit[], Int) => Unit is Adj + Ctl)]: UnOp (Functor Ctl):
1630 Expr 55 [143-144] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1631 Expr 56 [145-146] [Type (Qubit[], Int)]: Tuple:
1632 Expr 57 [145-146] [Type Qubit[]]: Var: Local 43
1633 Expr 58 [145-146] [Type Int]: Lit: Int(2)
1634 ctl-adj: SpecDecl 72 [73-189]: Impl:
1635 Pat 73 [73-189] [Type Qubit[]]: Bind: Ident 74 [73-189] "ctls"
1636 Block 75 [135-150] [Type Unit]:
1637 Stmt 76 [143-148]: Semi: Expr 77 [143-147] [Type Unit]: Call:
1638 Expr 78 [143-144] [Type ((Qubit[], Int) => Unit is Adj + Ctl)]: UnOp (Functor Ctl):
1639 Expr 79 [143-144] [Type (Int => Unit is Adj + Ctl)]: UnOp (Functor Adj):
1640 Expr 80 [143-144] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1641 Expr 81 [145-146] [Type (Qubit[], Int)]: Tuple:
1642 Expr 82 [145-146] [Type Qubit[]]: Var: Local 74
1643 Expr 83 [145-146] [Type Int]: Lit: Int(2)
1644 Stmt 84 [137-142]: Semi: Expr 85 [137-141] [Type Unit]: Call:
1645 Expr 86 [137-138] [Type ((Qubit[], Int) => Unit is Adj + Ctl)]: UnOp (Functor Ctl):
1646 Expr 87 [137-138] [Type (Int => Unit is Adj + Ctl)]: UnOp (Functor Adj):
1647 Expr 88 [137-138] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1648 Expr 89 [139-140] [Type (Qubit[], Int)]: Tuple:
1649 Expr 90 [139-140] [Type Qubit[]]: Var: Local 74
1650 Expr 91 [139-140] [Type Int]: Lit: Int(1)"#]],
1651 );
1652}
1653
1654#[test]
1655fn generate_ctladj_auto_to_invert() {
1656 check(
1657 indoc! {r#"
1658 namespace test {
1659 operation B(input : Int) : Unit is Ctl + Adj {}
1660 operation A(q : Qubit) : Unit is Ctl + Adj {
1661 body ... { B(1); B(2); }
1662 controlled (ctls, ...) { Controlled B(ctls, 1); Controlled B(ctls, 2); }
1663 controlled adjoint auto;
1664 }
1665 }
1666 "#},
1667 &expect![[r#"
1668 Package:
1669 Item 0 [0-272] (Public):
1670 Namespace (Ident 39 [10-14] "test"): Item 1, Item 2
1671 Item 1 [21-68] (Public):
1672 Parent: 0
1673 Callable 0 [21-68] (operation):
1674 name: Ident 1 [31-32] "B"
1675 input: Pat 2 [33-44] [Type Int]: Bind: Ident 3 [33-38] "input"
1676 output: Unit
1677 functors: Adj + Ctl
1678 body: SpecDecl 4 [21-68]: Impl:
1679 Block 5 [66-68]: <empty>
1680 adj: SpecDecl 50 [21-68]: Impl:
1681 Block 51 [66-68]: <empty>
1682 ctl: SpecDecl 46 [21-68]: Impl:
1683 Pat 47 [21-68] [Type Qubit[]]: Bind: Ident 48 [21-68] "ctls"
1684 Block 49 [66-68]: <empty>
1685 ctl-adj: SpecDecl 53 [21-68]: Impl:
1686 Pat 54 [21-68] [Type Qubit[]]: Bind: Ident 55 [21-68] "ctls"
1687 Block 56 [66-68]: <empty>
1688 Item 2 [73-270] (Public):
1689 Parent: 0
1690 Callable 6 [73-270] (operation):
1691 name: Ident 7 [83-84] "A"
1692 input: Pat 8 [85-94] [Type Qubit]: Bind: Ident 9 [85-86] "q"
1693 output: Unit
1694 functors: Adj + Ctl
1695 body: SpecDecl 10 [126-150]: Impl:
1696 Block 11 [135-150] [Type Unit]:
1697 Stmt 12 [137-142]: Semi: Expr 13 [137-141] [Type Unit]: Call:
1698 Expr 14 [137-138] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1699 Expr 15 [139-140] [Type Int]: Lit: Int(1)
1700 Stmt 16 [143-148]: Semi: Expr 17 [143-147] [Type Unit]: Call:
1701 Expr 18 [143-144] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1702 Expr 19 [145-146] [Type Int]: Lit: Int(2)
1703 adj: SpecDecl 57 [73-270]: Impl:
1704 Block 58 [135-150] [Type Unit]:
1705 Stmt 59 [143-148]: Semi: Expr 60 [143-147] [Type Unit]: Call:
1706 Expr 61 [143-144] [Type (Int => Unit is Adj + Ctl)]: UnOp (Functor Adj):
1707 Expr 62 [143-144] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1708 Expr 63 [145-146] [Type Int]: Lit: Int(2)
1709 Stmt 64 [137-142]: Semi: Expr 65 [137-141] [Type Unit]: Call:
1710 Expr 66 [137-138] [Type (Int => Unit is Adj + Ctl)]: UnOp (Functor Adj):
1711 Expr 67 [137-138] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1712 Expr 68 [139-140] [Type Int]: Lit: Int(1)
1713 ctl: SpecDecl 20 [159-231]: Impl:
1714 Pat 21 [171-175] [Type Qubit[]]: Bind: Ident 22 [171-175] "ctls"
1715 Block 23 [182-231] [Type Unit]:
1716 Stmt 24 [184-206]: Semi: Expr 25 [184-205] [Type Unit]: Call:
1717 Expr 26 [184-196] [Type ((Qubit[], Int) => Unit is Adj + Ctl)]: UnOp (Functor Ctl):
1718 Expr 27 [195-196] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1719 Expr 28 [196-205] [Type (Qubit[], Int)]: Tuple:
1720 Expr 29 [197-201] [Type Qubit[]]: Var: Local 22
1721 Expr 30 [203-204] [Type Int]: Lit: Int(1)
1722 Stmt 31 [207-229]: Semi: Expr 32 [207-228] [Type Unit]: Call:
1723 Expr 33 [207-219] [Type ((Qubit[], Int) => Unit is Adj + Ctl)]: UnOp (Functor Ctl):
1724 Expr 34 [218-219] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1725 Expr 35 [219-228] [Type (Qubit[], Int)]: Tuple:
1726 Expr 36 [220-224] [Type Qubit[]]: Var: Local 22
1727 Expr 37 [226-227] [Type Int]: Lit: Int(2)
1728 ctl-adj: SpecDecl 69 [73-270]: Impl:
1729 Pat 70 [171-175] [Type Qubit[]]: Bind: Ident 71 [171-175] "ctls"
1730 Block 72 [182-231] [Type Unit]:
1731 Stmt 73 [207-229]: Semi: Expr 74 [207-228] [Type Unit]: Call:
1732 Expr 75 [207-219] [Type ((Qubit[], Int) => Unit is Adj + Ctl)]: UnOp (Functor Adj):
1733 Expr 76 [207-219] [Type ((Qubit[], Int) => Unit is Adj + Ctl)]: UnOp (Functor Ctl):
1734 Expr 77 [218-219] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1735 Expr 78 [219-228] [Type (Qubit[], Int)]: Tuple:
1736 Expr 79 [220-224] [Type Qubit[]]: Var: Local 71
1737 Expr 80 [226-227] [Type Int]: Lit: Int(2)
1738 Stmt 81 [184-206]: Semi: Expr 82 [184-205] [Type Unit]: Call:
1739 Expr 83 [184-196] [Type ((Qubit[], Int) => Unit is Adj + Ctl)]: UnOp (Functor Adj):
1740 Expr 84 [184-196] [Type ((Qubit[], Int) => Unit is Adj + Ctl)]: UnOp (Functor Ctl):
1741 Expr 85 [195-196] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1742 Expr 86 [196-205] [Type (Qubit[], Int)]: Tuple:
1743 Expr 87 [197-201] [Type Qubit[]]: Var: Local 71
1744 Expr 88 [203-204] [Type Int]: Lit: Int(1)"#]],
1745 );
1746}
1747
1748#[test]
1749fn generate_ctladj_invert() {
1750 check(
1751 indoc! {r#"
1752 namespace test {
1753 operation B(input : Int) : Unit is Ctl + Adj {}
1754 operation A(q : Qubit) : Unit is Ctl + Adj {
1755 body ... { B(1); B(2); }
1756 controlled adjoint invert;
1757 }
1758 }
1759 "#},
1760 &expect![[r#"
1761 Package:
1762 Item 0 [0-193] (Public):
1763 Namespace (Ident 21 [10-14] "test"): Item 1, Item 2
1764 Item 1 [21-68] (Public):
1765 Parent: 0
1766 Callable 0 [21-68] (operation):
1767 name: Ident 1 [31-32] "B"
1768 input: Pat 2 [33-44] [Type Int]: Bind: Ident 3 [33-38] "input"
1769 output: Unit
1770 functors: Adj + Ctl
1771 body: SpecDecl 4 [21-68]: Impl:
1772 Block 5 [66-68]: <empty>
1773 adj: SpecDecl 32 [21-68]: Impl:
1774 Block 33 [66-68]: <empty>
1775 ctl: SpecDecl 28 [21-68]: Impl:
1776 Pat 29 [21-68] [Type Qubit[]]: Bind: Ident 30 [21-68] "ctls"
1777 Block 31 [66-68]: <empty>
1778 ctl-adj: SpecDecl 35 [21-68]: Impl:
1779 Pat 36 [21-68] [Type Qubit[]]: Bind: Ident 37 [21-68] "ctls"
1780 Block 38 [66-68]: <empty>
1781 Item 2 [73-191] (Public):
1782 Parent: 0
1783 Callable 6 [73-191] (operation):
1784 name: Ident 7 [83-84] "A"
1785 input: Pat 8 [85-94] [Type Qubit]: Bind: Ident 9 [85-86] "q"
1786 output: Unit
1787 functors: Adj + Ctl
1788 body: SpecDecl 10 [126-150]: Impl:
1789 Block 11 [135-150] [Type Unit]:
1790 Stmt 12 [137-142]: Semi: Expr 13 [137-141] [Type Unit]: Call:
1791 Expr 14 [137-138] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1792 Expr 15 [139-140] [Type Int]: Lit: Int(1)
1793 Stmt 16 [143-148]: Semi: Expr 17 [143-147] [Type Unit]: Call:
1794 Expr 18 [143-144] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1795 Expr 19 [145-146] [Type Int]: Lit: Int(2)
1796 adj: SpecDecl 58 [73-191]: Impl:
1797 Block 59 [135-150] [Type Unit]:
1798 Stmt 60 [143-148]: Semi: Expr 61 [143-147] [Type Unit]: Call:
1799 Expr 62 [143-144] [Type (Int => Unit is Adj + Ctl)]: UnOp (Functor Adj):
1800 Expr 63 [143-144] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1801 Expr 64 [145-146] [Type Int]: Lit: Int(2)
1802 Stmt 65 [137-142]: Semi: Expr 66 [137-141] [Type Unit]: Call:
1803 Expr 67 [137-138] [Type (Int => Unit is Adj + Ctl)]: UnOp (Functor Adj):
1804 Expr 68 [137-138] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1805 Expr 69 [139-140] [Type Int]: Lit: Int(1)
1806 ctl: SpecDecl 40 [73-191]: Impl:
1807 Pat 41 [73-191] [Type Qubit[]]: Bind: Ident 42 [73-191] "ctls"
1808 Block 43 [135-150] [Type Unit]:
1809 Stmt 44 [137-142]: Semi: Expr 45 [137-141] [Type Unit]: Call:
1810 Expr 46 [137-138] [Type ((Qubit[], Int) => Unit is Adj + Ctl)]: UnOp (Functor Ctl):
1811 Expr 47 [137-138] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1812 Expr 48 [139-140] [Type (Qubit[], Int)]: Tuple:
1813 Expr 49 [139-140] [Type Qubit[]]: Var: Local 42
1814 Expr 50 [139-140] [Type Int]: Lit: Int(1)
1815 Stmt 51 [143-148]: Semi: Expr 52 [143-147] [Type Unit]: Call:
1816 Expr 53 [143-144] [Type ((Qubit[], Int) => Unit is Adj + Ctl)]: UnOp (Functor Ctl):
1817 Expr 54 [143-144] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1818 Expr 55 [145-146] [Type (Qubit[], Int)]: Tuple:
1819 Expr 56 [145-146] [Type Qubit[]]: Var: Local 42
1820 Expr 57 [145-146] [Type Int]: Lit: Int(2)
1821 ctl-adj: SpecDecl 70 [159-185]: Impl:
1822 Pat 71 [73-191] [Type Qubit[]]: Bind: Ident 72 [73-191] "ctls"
1823 Block 73 [135-150] [Type Unit]:
1824 Stmt 74 [143-148]: Semi: Expr 75 [143-147] [Type Unit]: Call:
1825 Expr 76 [143-144] [Type ((Qubit[], Int) => Unit is Adj + Ctl)]: UnOp (Functor Adj):
1826 Expr 77 [143-144] [Type ((Qubit[], Int) => Unit is Adj + Ctl)]: UnOp (Functor Ctl):
1827 Expr 78 [143-144] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1828 Expr 79 [145-146] [Type (Qubit[], Int)]: Tuple:
1829 Expr 80 [145-146] [Type Qubit[]]: Var: Local 72
1830 Expr 81 [145-146] [Type Int]: Lit: Int(2)
1831 Stmt 82 [137-142]: Semi: Expr 83 [137-141] [Type Unit]: Call:
1832 Expr 84 [137-138] [Type ((Qubit[], Int) => Unit is Adj + Ctl)]: UnOp (Functor Adj):
1833 Expr 85 [137-138] [Type ((Qubit[], Int) => Unit is Adj + Ctl)]: UnOp (Functor Ctl):
1834 Expr 86 [137-138] [Type (Int => Unit is Adj + Ctl)]: Var: Item 1
1835 Expr 87 [139-140] [Type (Qubit[], Int)]: Tuple:
1836 Expr 88 [139-140] [Type Qubit[]]: Var: Local 72
1837 Expr 89 [139-140] [Type Int]: Lit: Int(1)"#]],
1838 );
1839}
1840
1841#[test]
1842fn lambda_adj_calls_adj() {
1843 check(
1844 indoc! {r#"
1845 namespace A {
1846 operation X(q : Qubit) : () is Adj {}
1847 operation Foo(op : Qubit => () is Adj) : () {}
1848 operation Bar() : () { Foo(q => X(q)); }
1849 }
1850 "#},
1851 &expect![[r#"
1852 Package:
1853 Item 0 [0-153] (Public):
1854 Namespace (Ident 32 [10-11] "A"): Item 1, Item 2, Item 3
1855 Item 1 [18-55] (Public):
1856 Parent: 0
1857 Callable 0 [18-55] (operation):
1858 name: Ident 1 [28-29] "X"
1859 input: Pat 2 [30-39] [Type Qubit]: Bind: Ident 3 [30-31] "q"
1860 output: Unit
1861 functors: Adj
1862 body: SpecDecl 4 [18-55]: Impl:
1863 Block 5 [53-55]: <empty>
1864 adj: SpecDecl 35 [18-55]: Impl:
1865 Block 36 [53-55]: <empty>
1866 ctl: <none>
1867 ctl-adj: <none>
1868 Item 2 [60-106] (Public):
1869 Parent: 0
1870 Callable 6 [60-106] (operation):
1871 name: Ident 7 [70-73] "Foo"
1872 generics:
1873 0: functor (Adj)
1874 input: Pat 8 [74-97] [Type (Qubit => Unit is Param<0>)]: Bind: Ident 9 [74-76] "op"
1875 output: Unit
1876 functors: empty set
1877 body: SpecDecl 10 [60-106]: Impl:
1878 Block 11 [104-106]: <empty>
1879 adj: <none>
1880 ctl: <none>
1881 ctl-adj: <none>
1882 Item 3 [111-151] (Public):
1883 Parent: 0
1884 Callable 12 [111-151] (operation):
1885 name: Ident 13 [121-124] "Bar"
1886 input: Pat 14 [124-126] [Type Unit]: Unit
1887 output: Unit
1888 functors: empty set
1889 body: SpecDecl 15 [111-151]: Impl:
1890 Block 16 [132-151] [Type Unit]:
1891 Stmt 17 [134-149]: Semi: Expr 18 [134-148] [Type Unit]: Call:
1892 Expr 19 [134-137] [Type ((Qubit => Unit is Adj) => Unit)]: Var:
1893 res: Item 2
1894 generics:
1895 Adj
1896 Expr 20 [138-147] [Type (Qubit => Unit is Adj)]: Closure([], 4)
1897 adj: <none>
1898 ctl: <none>
1899 ctl-adj: <none>
1900 Item 4 [138-147] (Internal):
1901 Parent: 3
1902 Callable 27 [138-147] (operation):
1903 name: Ident 28 [0-0] "lambda"
1904 input: Pat 26 [138-147] [Type (Qubit,)]: Tuple:
1905 Pat 21 [138-139] [Type Qubit]: Bind: Ident 22 [138-139] "q"
1906 output: Unit
1907 functors: Adj
1908 body: SpecDecl 29 [143-147]: Impl:
1909 Block 30 [143-147] [Type Unit]:
1910 Stmt 31 [143-147]: Expr: Expr 23 [143-147] [Type Unit]: Call:
1911 Expr 24 [143-144] [Type (Qubit => Unit is Adj)]: Var: Item 1
1912 Expr 25 [145-146] [Type Qubit]: Var: Local 22
1913 adj: SpecDecl 37 [138-147]: Impl:
1914 Block 38 [143-147] [Type Unit]:
1915 Stmt 39 [143-147]: Expr: Expr 40 [143-147] [Type Unit]: Call:
1916 Expr 41 [143-144] [Type (Qubit => Unit is Adj)]: UnOp (Functor Adj):
1917 Expr 42 [143-144] [Type (Qubit => Unit is Adj)]: Var: Item 1
1918 Expr 43 [145-146] [Type Qubit]: Var: Local 22
1919 ctl: <none>
1920 ctl-adj: <none>"#]],
1921 );
1922}
1923
1924#[test]
1925fn lambda_adj_calls_non_adj() {
1926 check(
1927 indoc! {r#"
1928 namespace A {
1929 operation M(q : Qubit) : Result { Zero }
1930 operation Foo(op : Qubit => () is Adj) : () {}
1931 operation Bar() : () { Foo(q => { M(q); }); }
1932 }
1933 "#},
1934 &expect![[r#"
1935 [
1936 AdjGen(
1937 MissingAdjFunctor(
1938 Span {
1939 lo: 148,
1940 hi: 149,
1941 },
1942 ),
1943 ),
1944 ]
1945 "#]],
1946 );
1947}
1948
1949#[test]
1950fn op_array_forget_functors_with_lambdas() {
1951 check(
1952 "
1953 namespace A {
1954 operation Foo(q : Qubit) : () {}
1955 operation Bar(q : Qubit) : () is Adj {}
1956 operation Baz(q : Qubit) : () is Adj + Ctl {}
1957 operation Main() : () {
1958 let ops = [Foo, q => Bar(q), q => Baz(q)];
1959 }
1960 }
1961 ",
1962 &expect![[r#"
1963 Package:
1964 Item 0 [13-328] (Public):
1965 Namespace (Ident 52 [23-24] "A"): Item 1, Item 2, Item 3, Item 4
1966 Item 1 [43-75] (Public):
1967 Parent: 0
1968 Callable 0 [43-75] (operation):
1969 name: Ident 1 [53-56] "Foo"
1970 input: Pat 2 [57-66] [Type Qubit]: Bind: Ident 3 [57-58] "q"
1971 output: Unit
1972 functors: empty set
1973 body: SpecDecl 4 [43-75]: Impl:
1974 Block 5 [73-75]: <empty>
1975 adj: <none>
1976 ctl: <none>
1977 ctl-adj: <none>
1978 Item 2 [92-131] (Public):
1979 Parent: 0
1980 Callable 6 [92-131] (operation):
1981 name: Ident 7 [102-105] "Bar"
1982 input: Pat 8 [106-115] [Type Qubit]: Bind: Ident 9 [106-107] "q"
1983 output: Unit
1984 functors: Adj
1985 body: SpecDecl 10 [92-131]: Impl:
1986 Block 11 [129-131]: <empty>
1987 adj: SpecDecl 57 [92-131]: Impl:
1988 Block 58 [129-131]: <empty>
1989 ctl: <none>
1990 ctl-adj: <none>
1991 Item 3 [148-193] (Public):
1992 Parent: 0
1993 Callable 12 [148-193] (operation):
1994 name: Ident 13 [158-161] "Baz"
1995 input: Pat 14 [162-171] [Type Qubit]: Bind: Ident 15 [162-163] "q"
1996 output: Unit
1997 functors: Adj + Ctl
1998 body: SpecDecl 16 [148-193]: Impl:
1999 Block 17 [191-193]: <empty>
2000 adj: SpecDecl 64 [148-193]: Impl:
2001 Block 65 [191-193]: <empty>
2002 ctl: SpecDecl 60 [148-193]: Impl:
2003 Pat 61 [148-193] [Type Qubit[]]: Bind: Ident 62 [148-193] "ctls"
2004 Block 63 [191-193]: <empty>
2005 ctl-adj: SpecDecl 67 [148-193]: Impl:
2006 Pat 68 [148-193] [Type Qubit[]]: Bind: Ident 69 [148-193] "ctls"
2007 Block 70 [191-193]: <empty>
2008 Item 4 [210-314] (Public):
2009 Parent: 0
2010 Callable 18 [210-314] (operation):
2011 name: Ident 19 [220-224] "Main"
2012 input: Pat 20 [224-226] [Type Unit]: Unit
2013 output: Unit
2014 functors: empty set
2015 body: SpecDecl 21 [210-314]: Impl:
2016 Block 22 [232-314] [Type Unit]:
2017 Stmt 23 [254-296]: Local (Immutable):
2018 Pat 24 [258-261] [Type (Qubit => Unit)[]]: Bind: Ident 25 [258-261] "ops"
2019 Expr 26 [264-295] [Type (Qubit => Unit)[]]: Array:
2020 Expr 27 [265-268] [Type (Qubit => Unit)]: Var: Item 1
2021 Expr 28 [270-281] [Type (Qubit => Unit)]: Closure([], 5)
2022 Expr 40 [283-294] [Type (Qubit => Unit)]: Closure([], 6)
2023 adj: <none>
2024 ctl: <none>
2025 ctl-adj: <none>
2026 Item 5 [270-281] (Internal):
2027 Parent: 4
2028 Callable 35 [270-281] (operation):
2029 name: Ident 36 [0-0] "lambda"
2030 input: Pat 34 [270-281] [Type (Qubit,)]: Tuple:
2031 Pat 29 [270-271] [Type Qubit]: Bind: Ident 30 [270-271] "q"
2032 output: Unit
2033 functors: empty set
2034 body: SpecDecl 37 [275-281]: Impl:
2035 Block 38 [275-281] [Type Unit]:
2036 Stmt 39 [275-281]: Expr: Expr 31 [275-281] [Type Unit]: Call:
2037 Expr 32 [275-278] [Type (Qubit => Unit is Adj)]: Var: Item 2
2038 Expr 33 [279-280] [Type Qubit]: Var: Local 30
2039 adj: <none>
2040 ctl: <none>
2041 ctl-adj: <none>
2042 Item 6 [283-294] (Internal):
2043 Parent: 4
2044 Callable 47 [283-294] (operation):
2045 name: Ident 48 [0-0] "lambda"
2046 input: Pat 46 [283-294] [Type (Qubit,)]: Tuple:
2047 Pat 41 [283-284] [Type Qubit]: Bind: Ident 42 [283-284] "q"
2048 output: Unit
2049 functors: empty set
2050 body: SpecDecl 49 [288-294]: Impl:
2051 Block 50 [288-294] [Type Unit]:
2052 Stmt 51 [288-294]: Expr: Expr 43 [288-294] [Type Unit]: Call:
2053 Expr 44 [288-291] [Type (Qubit => Unit is Adj + Ctl)]: Var: Item 3
2054 Expr 45 [292-293] [Type Qubit]: Var: Local 42
2055 adj: <none>
2056 ctl: <none>
2057 ctl-adj: <none>"#]],
2058 );
2059}
2060
2061#[test]
2062fn op_array_unsupported_functors_with_lambdas() {
2063 check(
2064 "
2065 namespace A {
2066 operation Foo(q : Qubit) : () {}
2067 operation Bar(q : Qubit) : () is Adj {}
2068 operation Baz(q : Qubit) : () is Adj + Ctl {}
2069 operation Main() : () {
2070 let ops = [q => Foo(q), q => Bar(q), Baz];
2071 }
2072 }
2073 ",
2074 &expect![[r#"
2075 [
2076 CtlGen(
2077 MissingCtlFunctor(
2078 Span {
2079 lo: 270,
2080 hi: 273,
2081 },
2082 ),
2083 ),
2084 AdjGen(
2085 MissingAdjFunctor(
2086 Span {
2087 lo: 270,
2088 hi: 273,
2089 },
2090 ),
2091 ),
2092 CtlGen(
2093 MissingCtlFunctor(
2094 Span {
2095 lo: 270,
2096 hi: 273,
2097 },
2098 ),
2099 ),
2100 CtlGen(
2101 MissingCtlFunctor(
2102 Span {
2103 lo: 283,
2104 hi: 286,
2105 },
2106 ),
2107 ),
2108 CtlGen(
2109 MissingCtlFunctor(
2110 Span {
2111 lo: 283,
2112 hi: 286,
2113 },
2114 ),
2115 ),
2116 ]
2117 "#]],
2118 );
2119}