microsoft/qdk

Public

mirrored fromhttps://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
minestarks/dev-container

Branches

Tags

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

Clone

HTTPS

Download ZIP

library/std/src/Std/OpenQASM/Intrinsic.qs

656lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4/// This file defines the standard gates for OpenQASM and Qiskit.
5/// It is an internal implementation detail for OpenQASM compilation
6/// and is not intended for use outside of this context.
7
8// OpenQASM 3.0 intrinsics
9export gphase, U;
10
11// OpenQASM 2.0 intrinsics
12export CX; // `U` exported above.
13
14// stdgates.inc <https://github.com/openqasm/openqasm/blob/spec/v3.1.0/examples/stdgates.inc>
15// main gate definitions
16export p, x, y, z, h, s, sdg, t, tdg, sx, rx, ry, rz, cx, cy, cz, cp, crx, cry, crz, ch, swap, ccx, cswap, cu;
17
18// stdgates.inc OpenQASM 2.0 backwards compatibility gates
19// `CX` is already exported above, so we don't need to export it again.
20export phase, cphase, id, u1, u2, u3;
21
22// qelib1.inc <https://github.com/openqasm/openqasm/blob/2.0/examples/qelib1.inc>
23// QE Hardware primitives are defined above as the OpenQASM 2.0 compatibility gates.
24// QE Standard Gates are defined above as the stdgates.inc gates.
25// Standard rotations are defined above as the stdgates.inc gates.
26
27// Most QE Standard User-Defined Gates are defined above as the stdgates.inc gates.
28// Remaining QE Standard User-Defined Gates:
29export cu1, cu3;
30
31// gates that qiskit won't emit qasm defs for that are NOT part of stgates.inc
32// but are have the _standard_gate property in Qiskit:
33
34// QIR intrinsics missing from qasm std library, that Qiskit won't emit qasm defs for
35export rxx, ryy, rzz;
36
37// Remaining gates that are not in the qasm std library, but are standard gates in Qiskit
38// that Qiskit wont emit correctly.
39export dcx, ecr, r, rzx, cs, csdg, sxdg, csx, rccx, c3sqrtx, c3x, rc3x, xx_minus_yy, xx_plus_yy, ccz;
40
41export mresetz_checked;
42
43export __quantum__qis__barrier__body;
44
45import Std.OpenQASM.Angle.Angle;
46import Std.OpenQASM.Angle.AngleAsDouble;
47import Std.OpenQASM.Angle.DoubleAsAngle;
48import Std.OpenQASM.Angle.AddAngles;
49import Std.OpenQASM.Angle.SubtractAngles;
50import Std.OpenQASM.Angle.DivideAngleByInt;
51import Std.OpenQASM.Angle.NegAngle;
52
53function ZERO_ANGLE() : Angle {
54 return DoubleAsAngle(0., 1);
55}
56
57function PI_OVER_2() : Angle {
58 return DoubleAsAngle(Std.Math.PI() / 2., 53);
59}
60
61function PI_OVER_4() : Angle {
62 return DoubleAsAngle(Std.Math.PI() / 4., 53);
63}
64
65function PI_OVER_8() : Angle {
66 return DoubleAsAngle(Std.Math.PI() / 8., 53);
67}
68
69function PI_ANGLE() : Angle {
70 return DoubleAsAngle(Std.Math.PI(), 53);
71}
72
73function NEG_PI_OVER_2() : Angle {
74 return DoubleAsAngle(-Std.Math.PI() / 2., 53);
75}
76
77function NEG_PI_OVER_4() : Angle {
78 return DoubleAsAngle(-Std.Math.PI() / 4., 53);
79}
80
81function NEG_PI_OVER_8() : Angle {
82 return DoubleAsAngle(-Std.Math.PI() / 8., 53);
83}
84
85operation gphase(theta : Angle) : Unit is Adj + Ctl {
86 body ... {
87 Exp([], AngleAsDouble(theta), [])
88 }
89 adjoint auto;
90 controlled auto;
91 controlled adjoint auto;
92}
93
94operation U(theta : Angle, phi : Angle, lambda : Angle, qubit : Qubit) : Unit is Adj + Ctl {
95 body ... {
96 let theta = AngleAsDouble(theta);
97 let phi = AngleAsDouble(phi);
98 let lambda = AngleAsDouble(lambda);
99
100 Std.Intrinsic.Rz(lambda, qubit);
101 Std.Intrinsic.Ry(theta, qubit);
102 Std.Intrinsic.Rz(phi, qubit);
103 Std.Intrinsic.R(PauliI, -lambda - phi - theta, qubit);
104 }
105 adjoint auto;
106 controlled auto;
107 controlled adjoint auto;
108}
109operation CX(ctrl : Qubit, qubit : Qubit) : Unit is Adj + Ctl {
110 Std.Canon.CX(ctrl, qubit);
111}
112
113operation p(lambda : Angle, qubit : Qubit) : Unit is Adj + Ctl {
114 Controlled gphase([qubit], lambda);
115}
116
117operation x(qubit : Qubit) : Unit is Adj + Ctl {
118 Std.Intrinsic.X(qubit);
119}
120
121operation y(qubit : Qubit) : Unit is Adj + Ctl {
122 Std.Intrinsic.Y(qubit);
123}
124
125operation z(qubit : Qubit) : Unit is Adj + Ctl {
126 Std.Intrinsic.Z(qubit);
127}
128
129operation h(qubit : Qubit) : Unit is Adj + Ctl {
130 Std.Intrinsic.H(qubit);
131}
132
133operation s(qubit : Qubit) : Unit is Adj + Ctl {
134 Std.Intrinsic.S(qubit);
135}
136
137operation sdg(qubit : Qubit) : Unit is Adj + Ctl {
138 Adjoint Std.Intrinsic.S(qubit);
139}
140
141operation t(qubit : Qubit) : Unit is Adj + Ctl {
142 Std.Intrinsic.T(qubit);
143}
144
145operation tdg(qubit : Qubit) : Unit is Adj + Ctl {
146 Adjoint Std.Intrinsic.T(qubit);
147}
148
149operation sx(qubit : Qubit) : Unit is Adj + Ctl {
150 Std.Intrinsic.SX(qubit);
151}
152
153operation rx(theta : Angle, qubit : Qubit) : Unit is Adj + Ctl {
154 let theta = AngleAsDouble(theta);
155 Std.Intrinsic.Rx(theta, qubit);
156}
157
158operation ry(theta : Angle, qubit : Qubit) : Unit is Adj + Ctl {
159 let theta = AngleAsDouble(theta);
160 Std.Intrinsic.Ry(theta, qubit);
161}
162
163operation rz(theta : Angle, qubit : Qubit) : Unit is Adj + Ctl {
164 let theta = AngleAsDouble(theta);
165 Std.Intrinsic.Rz(theta, qubit);
166}
167
168operation cx(ctrl : Qubit, qubit : Qubit) : Unit is Adj + Ctl {
169 Std.Canon.CX(ctrl, qubit);
170}
171
172operation cy(ctrl : Qubit, qubit : Qubit) : Unit is Adj + Ctl {
173 Std.Canon.CY(ctrl, qubit);
174}
175
176operation cz(ctrl : Qubit, qubit : Qubit) : Unit is Adj + Ctl {
177 Std.Canon.CZ(ctrl, qubit);
178}
179
180operation cp(lambda : Angle, ctrl : Qubit, qubit : Qubit) : Unit is Adj + Ctl {
181 Controlled p([ctrl], (lambda, qubit));
182}
183
184operation crx(theta : Angle, ctrl : Qubit, qubit : Qubit) : Unit is Adj + Ctl {
185 let theta = AngleAsDouble(theta);
186 Controlled Std.Intrinsic.Rx([ctrl], (theta, qubit));
187}
188
189operation cry(theta : Angle, ctrl : Qubit, qubit : Qubit) : Unit is Adj + Ctl {
190 let theta = AngleAsDouble(theta);
191 Controlled Std.Intrinsic.Ry([ctrl], (theta, qubit));
192}
193
194operation crz(theta : Angle, ctrl : Qubit, qubit : Qubit) : Unit is Adj + Ctl {
195 let theta = AngleAsDouble(theta);
196 Controlled Std.Intrinsic.Rz([ctrl], (theta, qubit));
197}
198
199operation ch(ctrl : Qubit, qubit : Qubit) : Unit is Adj + Ctl {
200 Controlled Std.Intrinsic.H([ctrl], qubit);
201}
202
203operation swap(qubit1 : Qubit, qubit2 : Qubit) : Unit is Adj + Ctl {
204 Std.Intrinsic.SWAP(qubit1, qubit2);
205}
206
207operation ccx(ctrl1 : Qubit, ctrl2 : Qubit, target : Qubit) : Unit is Adj + Ctl {
208 Std.Intrinsic.CCNOT(ctrl1, ctrl2, target);
209}
210
211operation cswap(ctrl : Qubit, qubit1 : Qubit, qubit2 : Qubit) : Unit is Adj + Ctl {
212 Controlled Std.Intrinsic.SWAP([ctrl], (qubit1, qubit2));
213}
214
215operation cu(theta : Angle, phi : Angle, lambda : Angle, gamma : Angle, qubit1 : Qubit, qubit2 : Qubit) : Unit is Adj + Ctl {
216 p(SubtractAngles(gamma, DivideAngleByInt(theta, 2)), qubit1);
217 Controlled U([qubit1], (theta, phi, lambda, qubit2));
218}
219
220// Gates for OpenQASM 2 backwards compatibility
221operation phase(lambda : Angle, qubit : Qubit) : Unit is Adj + Ctl {
222 U(ZERO_ANGLE(), ZERO_ANGLE(), lambda, qubit);
223}
224
225operation cphase(lambda : Angle, ctrl : Qubit, qubit : Qubit) : Unit is Adj + Ctl {
226 Controlled phase([ctrl], (lambda, qubit));
227}
228
229operation id(qubit : Qubit) : Unit is Adj + Ctl {
230 Std.Intrinsic.I(qubit)
231}
232
233operation u1(lambda : Angle, qubit : Qubit) : Unit is Adj + Ctl {
234 U(ZERO_ANGLE(), ZERO_ANGLE(), lambda, qubit);
235}
236
237operation u2(phi : Angle, lambda : Angle, qubit : Qubit) : Unit is Adj + Ctl {
238 gphase(NegAngle(DivideAngleByInt(AddAngles(
239 phi,
240 AddAngles(
241 lambda,
242 PI_OVER_2()
243 )
244 ), 2)));
245
246 U(PI_OVER_2(), phi, lambda, qubit);
247}
248
249operation u3(theta : Angle, phi : Angle, lambda : Angle, qubit : Qubit) : Unit is Adj + Ctl {
250 gphase(NegAngle(DivideAngleByInt(AddAngles(
251 phi,
252 AddAngles(
253 lambda,
254 theta
255 )
256 ), 2)));
257
258 U(theta, phi, lambda, qubit);
259}
260
261/// Controlled-U1 gate.
262/// `ctrl @ u1(lambda) a, b` or:
263/// ```
264/// gate cu1(lambda) a,b {
265/// u1(lambda/2) a;
266/// cx a,b;
267/// u1(-lambda/2) b;
268/// cx a,b;
269/// u1(lambda/2) b;
270/// }
271/// ```
272operation cu1(lambda : Angle, ctrl : Qubit, target : Qubit) : Unit is Adj + Ctl {
273 Controlled u1([ctrl], (lambda, target));
274}
275
276/// Controlled-U3 gate (3-parameter two-qubit gate).
277/// `ctrl @ u3(theta, phi, lambda) a, b` or:
278/// ```
279/// gate cu3(theta,phi,lambda) c, t {
280/// u1((lambda+phi)/2) c;
281/// u1((lambda-phi)/2) t;
282/// cx c,t;
283/// u3(-theta/2,0,-(phi+lambda)/2) t;
284/// cx c,t;
285/// u3(theta/2,phi,0) t;
286/// }
287/// ```
288operation cu3(theta : Angle, phi : Angle, lambda : Angle, ctrl : Qubit, target : Qubit) : Unit is Adj + Ctl {
289 Controlled u3([ctrl], (theta, phi, lambda, target));
290}
291
292/// rxx: gate rxx(theta) a, b { h a; h b; cx a, b; rz(theta) b; cx a, b; h b; h a; }
293operation rxx(theta : Angle, qubit0 : Qubit, qubit1 : Qubit) : Unit is Adj + Ctl {
294 Std.Intrinsic.Rxx(AngleAsDouble(theta), qubit0, qubit1);
295}
296
297/// ryy: gate ryy(theta) a, b { rx(pi/2) a; rx(pi/2) b; cx a, b; rz(theta) b; cx a, b; rx(-pi/2) a; rx(-pi/2) b; }
298operation ryy(theta : Angle, qubit0 : Qubit, qubit1 : Qubit) : Unit is Adj + Ctl {
299 Std.Intrinsic.Ryy(AngleAsDouble(theta), qubit0, qubit1);
300}
301
302/// rzz: gate rzz(theta) a, b { cx a, b; u1(theta) b; cx a, b; }
303operation rzz(theta : Angle, qubit0 : Qubit, qubit1 : Qubit) : Unit is Adj + Ctl {
304 Std.Intrinsic.Rzz(AngleAsDouble(theta), qubit0, qubit1);
305}
306
307/// Double-CNOT gate.
308/// ```
309/// gate dcx a, b {
310/// cx a, b;
311/// cx b, a;
312/// }
313/// ```
314operation dcx(qubit0 : Qubit, qubit1 : Qubit) : Unit is Adj + Ctl {
315 cx(qubit0, qubit1);
316 cx(qubit1, qubit0);
317}
318
319/// An echoed cross-resonance gate.
320/// `gate ecr a, b { rzx(pi/4) a, b; x a; rzx(-pi/4) a, b; }`
321operation ecr(qubit0 : Qubit, qubit1 : Qubit) : Unit is Adj + Ctl {
322 rzx(PI_OVER_4(), qubit0, qubit1);
323 x(qubit0);
324 rzx(NEG_PI_OVER_4(), qubit0, qubit1);
325}
326
327/// Rotation θ around the cos(φ)x + sin(φ)y axis.
328/// `gate r(θ, φ) a {u3(θ, φ - π/2, -φ + π/2) a;}`
329operation r(theta : Angle, phi : Angle, qubit : Qubit) : Unit is Adj + Ctl {
330 u3(theta, AddAngles(
331 phi,
332 NEG_PI_OVER_2()
333 ), SubtractAngles(PI_OVER_2(), phi), qubit);
334}
335
336/// A parametric 2-qubit `Z ⊗ X` interaction (rotation about ZX).
337/// `gate rzx(theta) a, b { h b; cx a, b; u1(theta) b; cx a, b; h b; }`
338operation rzx(theta : Angle, qubit0 : Qubit, qubit1 : Qubit) : Unit is Adj + Ctl {
339 h(qubit1);
340 cx(qubit0, qubit1);
341 u1(theta, qubit1);
342 cx(qubit0, qubit1);
343 h(qubit1);
344}
345
346/// Controlled-S gate.
347/// `gate cs a,b { h b; cp(pi/2) a,b; h b; }`
348operation cs(qubit0 : Qubit, qubit1 : Qubit) : Unit is Adj + Ctl {
349 Controlled s([qubit1], qubit0);
350}
351
352/// Controlled-S† gate.
353/// csdg: gate csdg a,b { h b; cp(-pi/2) a,b; h b; }
354operation csdg(qubit0 : Qubit, qubit1 : Qubit) : Unit is Adj + Ctl {
355 Controlled Adjoint S([qubit1], qubit0);
356}
357
358/// The inverse single-qubit Sqrt(X) gate.
359/// `gate sxdg a { rz(pi/2) a; h a; rz(pi/2); }`
360operation sxdg(qubit : Qubit) : Unit is Adj + Ctl {
361 Adjoint sx(qubit);
362}
363
364// Controlled-√X gate.
365/// `gate csx a,b { h b; cu1(pi/2) a,b; h b; }`
366operation csx(qubit0 : Qubit, qubit1 : Qubit) : Unit is Adj + Ctl {
367 Controlled sx([qubit1], qubit0);
368}
369
370/// The simplified Toffoli gate, also referred to as Margolus gate.
371/// `gate rccx a,b,c { u2(0,pi) c; u1(pi/4) c; cx b, c; u1(-pi/4) c; cx a, c; u1(pi/4) c; cx b, c; u1(-pi/4) c; u2(0,pi) c; }`
372operation rccx(ctrl1 : Qubit, ctrl2 : Qubit, target : Qubit) : Unit is Adj + Ctl {
373 u2(ZERO_ANGLE(), PI_ANGLE(), target);
374 u1(PI_OVER_4(), target);
375 cx(ctrl2, target);
376 u1(NEG_PI_OVER_4(), target);
377 cx(ctrl1, target);
378 u1(PI_OVER_4(), target);
379 cx(ctrl2, target);
380 u1(NEG_PI_OVER_4(), target);
381 u2(ZERO_ANGLE(), PI_ANGLE(), target);
382}
383
384/// c3sx/c3sqrtx: The 3-qubit controlled sqrt-X gate.
385/// ```
386/// gate c3sqrtx a,b,c,d {
387/// h d;
388/// cu1(pi/8) a,d;
389/// h d; cx a,b;
390/// h d;
391/// cu1(-pi/8) b,d;
392/// h d; cx a,b; h d;
393/// cu1(pi/8) b,d;
394/// h d;
395/// cx b,c;
396/// h d;
397/// cu1(-pi/8) c,d;
398/// h d;
399/// cx a,c;
400/// h d;
401/// cu1(pi/8) c,d;
402/// h d;
403/// cx b,c;
404/// h d;
405/// cu1(-pi/8) c,d;
406/// h d;
407/// cx a,c;
408/// h d;
409/// cu1(pi/8) c,d;
410/// h d;
411/// }
412/// ```
413operation c3sqrtx(a : Qubit, b : Qubit, c : Qubit, target : Qubit) : Unit is Adj + Ctl {
414 h(target);
415 Controlled u1([a], (PI_OVER_8(), target));
416 h(target);
417 cx(a, b);
418 h(target);
419 Controlled u1([b], (NEG_PI_OVER_8(), target));
420 h(target);
421 cx(a, b);
422 h(target);
423 Controlled u1([b], (PI_OVER_8(), target));
424 h(target);
425 cx(b, c);
426 h(target);
427 Controlled u1([c], (NEG_PI_OVER_8(), target));
428 h(target);
429 cx(a, c);
430 h(target);
431 Controlled u1([c], (PI_OVER_8(), target));
432 h(target);
433 cx(b, c);
434 h(target);
435 Controlled u1([c], (NEG_PI_OVER_8(), target));
436 h(target);
437 cx(a, c);
438 h(target);
439 Controlled u1([c], (PI_OVER_8(), target));
440 h(target);
441}
442
443/// The X gate controlled on 3 qubits.
444/// ```
445/// gate c3x a,b,c,d
446/// {
447/// h d;
448/// p(pi/8) a;
449/// p(pi/8) b;
450/// p(pi/8) c;
451/// p(pi/8) d;
452/// cx a, b;
453/// p(-pi/8) b;
454/// cx a, b;
455/// cx b, c;
456/// p(-pi/8) c;
457/// cx a, c;
458/// p(pi/8) c;
459/// cx b, c;
460/// p(-pi/8) c;
461/// cx a, c;
462/// cx c, d;
463/// p(-pi/8) d;
464/// cx b, d;
465/// p(pi/8) d;
466/// cx c, d;
467/// p(-pi/8) d;
468/// cx a, d;
469/// p(pi/8) d;
470/// cx c, d;
471/// p(-pi/8) d;
472/// cx b, d;
473/// p(pi/8) d;
474/// cx c, d;
475/// p(-pi/8) d;
476/// cx a, d;
477/// h d;
478/// }
479/// ```
480operation c3x(a : Qubit, b : Qubit, c : Qubit, d : Qubit) : Unit is Adj + Ctl {
481 h(d);
482 p(PI_OVER_8(), a);
483 p(PI_OVER_8(), b);
484 p(PI_OVER_8(), c);
485 p(PI_OVER_8(), d);
486 cx(a, b);
487 p(NEG_PI_OVER_8(), b);
488 cx(a, b);
489 cx(b, c);
490 p(NEG_PI_OVER_8(), c);
491 cx(a, c);
492 p(PI_OVER_8(), c);
493 cx(b, c);
494 p(NEG_PI_OVER_8(), c);
495 cx(a, c);
496 cx(c, d);
497 p(NEG_PI_OVER_8(), d);
498 cx(b, d);
499 p(PI_OVER_8(), d);
500 cx(c, d);
501 p(NEG_PI_OVER_8(), d);
502 cx(a, d);
503 p(PI_OVER_8(), d);
504 cx(c, d);
505 p(NEG_PI_OVER_8(), d);
506 cx(b, d);
507 p(PI_OVER_8(), d);
508 cx(c, d);
509 p(NEG_PI_OVER_8(), d);
510 cx(a, d);
511 h(d);
512}
513
514/// Simplified 3-controlled Toffoli gate.
515/// ```
516/// gate rc3x a,b,c,d{
517/// u2(0,pi) d;
518/// u1(pi/4) d;
519/// cx c,d;
520/// u1(-pi/4) d;
521/// u2(0,pi) d;
522/// cx a,d;
523/// u1(pi/4) d;
524/// cx b,d;
525/// u1(-pi/4) d;
526/// cx a,d;
527/// u1(pi/4) d;
528/// cx b,d;
529/// u1(-pi/4) d;
530/// u2(0,pi) d;
531/// u1(pi/4) d;
532/// cx c,d;
533/// u1(-pi/4) d;
534/// u2(0,pi) d;
535/// }
536/// ```
537operation rc3x(a : Qubit, b : Qubit, c : Qubit, d : Qubit) : Unit is Adj + Ctl {
538 u2(ZERO_ANGLE(), PI_ANGLE(), d);
539 u1(PI_OVER_4(), d);
540 cx(c, d);
541 u1(NEG_PI_OVER_4(), d);
542 u2(ZERO_ANGLE(), PI_ANGLE(), d);
543 cx(a, d);
544 u1(PI_OVER_4(), d);
545 cx(b, d);
546 u1(NEG_PI_OVER_4(), d);
547 cx(a, d);
548 u1(PI_OVER_4(), d);
549 cx(b, d);
550 u1(NEG_PI_OVER_4(), d);
551 u2(ZERO_ANGLE(), PI_ANGLE(), d);
552 u1(PI_OVER_4(), d);
553 cx(c, d);
554 u1(NEG_PI_OVER_4(), d);
555 u2(ZERO_ANGLE(), PI_ANGLE(), d);
556}
557
558/// XX-YY gate.
559/// ```
560/// gate xx_minus_yy(theta, beta) a, b {
561/// rz(-beta) b;
562/// rz(-pi/2) a;
563/// sx a;
564/// rz(pi/2) a;
565/// s b;
566/// cx a, b;
567/// ry(theta/2) a;
568/// ry(-theta/2) b;
569/// cx a, b;
570/// sdg b;
571/// rz(-pi/2) a;
572/// sxdg a;
573/// rz(pi/2) a;
574/// rz(beta) b;
575/// }
576/// ```
577operation xx_minus_yy(theta : Angle, beta : Angle, qubit0 : Qubit, qubit1 : Qubit) : Unit is Adj + Ctl {
578 rz(NegAngle(beta), qubit1);
579 rz(NEG_PI_OVER_2(), qubit0);
580 sx(qubit0);
581 rz(PI_OVER_2(), qubit0);
582 s(qubit1);
583 cx(qubit0, qubit1);
584 ry(DivideAngleByInt(theta, 2), qubit0);
585 ry(NegAngle(DivideAngleByInt(theta, 2)), qubit1);
586 cx(qubit0, qubit1);
587 sdg(qubit1);
588 rz(NEG_PI_OVER_2(), qubit0);
589 sxdg(qubit0);
590 rz(PI_OVER_2(), qubit0);
591 rz(beta, qubit1);
592}
593
594/// XX+YY gate.
595/// ```
596/// gate xx_plus_yy(theta, beta) a, b {
597/// rz(beta) b;
598/// rz(-pi/2) a;
599/// sx a;
600/// rz(pi/2) a;
601/// s b;
602/// cx a, b;
603/// ry(theta/2) a;
604/// ry(theta/2) b;
605/// cx a, b;
606/// sdg b;
607/// rz(-pi/2) a;
608/// sxdg a;
609/// rz(pi/2) a;
610/// rz(-beta) b;
611/// }
612/// ```
613operation xx_plus_yy(theta : Angle, beta : Angle, qubit0 : Qubit, qubit1 : Qubit) : Unit is Adj + Ctl {
614 rz(beta, qubit1);
615 rz(NEG_PI_OVER_2(), qubit0);
616 sx(qubit0);
617 rz(PI_OVER_2(), qubit0);
618 s(qubit1);
619 cx(qubit0, qubit1);
620 ry(DivideAngleByInt(theta, 2), qubit0);
621 ry(DivideAngleByInt(theta, 2), qubit1);
622 cx(qubit0, qubit1);
623 sdg(qubit1);
624 rz(NEG_PI_OVER_2(), qubit0);
625 sxdg(qubit0);
626 rz(PI_OVER_2(), qubit0);
627 rz(NegAngle(beta), qubit1);
628}
629
630/// CCZ gate.
631/// `gate ccz a,b,c { h c; ccx a,b,c; h c; }`
632operation ccz(ctrl1 : Qubit, ctrl2 : Qubit, target : Qubit) : Unit is Adj + Ctl {
633 h(target);
634 ccx(ctrl1, ctrl2, target);
635 h(target);
636}
637
638/// A resetting measurement operation that checks for qubit loss.
639/// Returns 0 if the qubit measurement was `Zero`, 1 if it was `One`,
640/// and 2 if the measurement indicated qubit loss.
641operation mresetz_checked(q : Qubit) : Int {
642 let (r, b) = Std.Measurement.MResetZChecked(q);
643 if b {
644 2
645 } else {
646 Std.OpenQASM.Convert.ResultAsInt(r)
647 }
648}
649
650/// The ``BARRIER`` function is used to implement the `barrier` statement in QASM.
651/// The `@SimulatableIntrinsic` attribute is used to mark the operation for QIR
652/// generation.
653/// Q# doesn't support barriers, so this is a no-op. We need to figure out what
654/// barriers mean in the context of QIR in the future for better support.
655@SimulatableIntrinsic()
656operation __quantum__qis__barrier__body() : Unit {}
657