diff --git a/src/Simulation/QsharpCore/Intrinsic.qs b/src/Simulation/QsharpCore/Intrinsic.qs
deleted file mode 100644
index b546a5e7d1f..00000000000
--- a/src/Simulation/QsharpCore/Intrinsic.qs
+++ /dev/null
@@ -1,661 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-namespace Microsoft.Quantum.Intrinsic {
- open Microsoft.Quantum.Math;
- open Microsoft.Quantum.Convert;
-
- //-------------------------------------------------
- // Clifford and related operations
- //-------------------------------------------------
-
- /// # Summary
- /// Performs the identity operation (no-op) on a single qubit.
- ///
- /// # Remarks
- /// This is a no-op. It is provided for completeness and because
- /// sometimes it is useful to call the identity in an algorithm or to pass it as a parameter.
- operation I (target : Qubit) : Unit
- is Adj + Ctl {
- body (...) { }
- adjoint self;
- }
-
-
- /// # Summary
- /// Applies the Pauli $X$ gate.
- ///
- /// \begin{align}
- /// \sigma_x \mathrel{:=}
- /// \begin{bmatrix}
- /// 0 & 1 \\\\
- /// 1 & 0
- /// \end{bmatrix}.
- /// \end{align}
- ///
- /// # Input
- /// ## qubit
- /// Qubit to which the gate should be applied.
- operation X (qubit : Qubit) : Unit
- is Adj + Ctl {
- body intrinsic;
- adjoint self;
- }
-
- /// # Summary
- /// Applies the Pauli $Y$ gate.
- ///
- /// \begin{align}
- /// \sigma_y \mathrel{:=}
- /// \begin{bmatrix}
- /// 0 & -i \\\\
- /// i & 0
- /// \end{bmatrix}.
- /// \end{align}
- ///
- /// # Input
- /// ## qubit
- /// Qubit to which the gate should be applied.
- operation Y (qubit : Qubit) : Unit
- is Adj + Ctl {
- body intrinsic;
- adjoint self;
- }
-
-
- /// # Summary
- /// Applies the Pauli $Z$ gate.
- ///
- /// \begin{align}
- /// \sigma_z \mathrel{:=}
- /// \begin{bmatrix}
- /// 1 & 0 \\\\
- /// 0 & -1
- /// \end{bmatrix}.
- /// \end{align}
- ///
- /// # Input
- /// ## qubit
- /// Qubit to which the gate should be applied.
- operation Z (qubit : Qubit) : Unit
- is Adj + Ctl {
- body intrinsic;
- adjoint self;
- }
-
-
- /// # Summary
- /// Applies the Hadamard transformation to a single qubit.
- ///
- /// \begin{align}
- /// H \mathrel{:=}
- /// \frac{1}{\sqrt{2}}
- /// \begin{bmatrix}
- /// 1 & 1 \\\\
- /// 1 & -1
- /// \end{bmatrix}.
- /// \end{align}
- ///
- /// # Input
- /// ## qubit
- /// Qubit to which the gate should be applied.
- operation H (qubit : Qubit) : Unit
- is Adj + Ctl {
- body intrinsic;
- adjoint self;
- }
-
-
- /// # Summary
- /// Applies the S gate to a single qubit.
- ///
- /// # Description
- /// This operation can be simulated by the unitary matrix
- /// \begin{align}
- /// S \mathrel{:=}
- /// \begin{bmatrix}
- /// 1 & 0 \\\\
- /// 0 & i
- /// \end{bmatrix}.
- /// \end{align}
- ///
- /// # Input
- /// ## qubit
- /// Qubit to which the gate should be applied.
- operation S(qubit : Qubit) : Unit
- is Adj + Ctl {
- body intrinsic;
- }
-
-
- /// # Summary
- /// Applies the T gate to a single qubit.
- ///
- /// # Description
- /// This operation can be simulated by the unitary matrix
- /// \begin{align}
- /// T \mathrel{:=}
- /// \begin{bmatrix}
- /// 1 & 0 \\\\
- /// 0 & e^{i \pi / 4}
- /// \end{bmatrix}.
- /// \end{align}
- ///
- /// # Input
- /// ## qubit
- /// Qubit to which the gate should be applied.
- operation T(qubit : Qubit) : Unit
- is Adj + Ctl {
- body intrinsic;
- }
-
-
- /// # Summary
- /// Applies the controlled-NOT (CNOT) gate to a pair of qubits.
- ///
- /// \begin{align}
- /// \operatorname{CNOT} \mathrel{:=}
- /// \begin{bmatrix}
- /// 1 & 0 & 0 & 0 \\\\
- /// 0 & 1 & 0 & 0 \\\\
- /// 0 & 0 & 0 & 1 \\\\
- /// 0 & 0 & 1 & 0
- /// \end{bmatrix},
- /// \end{align}
- ///
- /// where rows and columns are ordered as in the quantum concepts guide.
- ///
- /// # Input
- /// ## control
- /// Control qubit for the CNOT gate.
- /// ## target
- /// Target qubit for the CNOT gate.
- ///
- /// # Remarks
- /// Equivalent to:
- /// ```qsharp
- /// Controlled X([control], target);
- /// ```
- operation CNOT (control : Qubit, target : Qubit) : Unit
- is Adj + Ctl {
-
- body (...) {
- Controlled X([control], target);
- }
-
- adjoint self;
- }
-
-
- /// # Summary
- /// Applies the doubly controlled–NOT (CCNOT) gate to three qubits.
- ///
- /// # Input
- /// ## control1
- /// First control qubit for the CCNOT gate.
- /// ## control2
- /// Second control qubit for the CCNOT gate.
- /// ## target
- /// Target qubit for the CCNOT gate.
- ///
- /// # Remarks
- /// Equivalent to:
- /// ```qsharp
- /// Controlled X([control1, control2], target);
- /// ```
- operation CCNOT (control1 : Qubit, control2 : Qubit, target : Qubit) : Unit
- is Adj + Ctl {
- body (...) {
- Controlled X([control1, control2], target);
- }
-
- adjoint self;
- }
-
-
- /// # Summary
- /// Applies the SWAP gate to a pair of qubits.
- ///
- /// \begin{align}
- /// \operatorname{SWAP} \mathrel{:=}
- /// \begin{bmatrix}
- /// 1 & 0 & 0 & 0 \\\\
- /// 0 & 0 & 1 & 0 \\\\
- /// 0 & 1 & 0 & 0 \\\\
- /// 0 & 0 & 0 & 1
- /// \end{bmatrix},
- /// \end{align}
- ///
- /// where rows and columns are ordered as in the quantum concepts guide.
- ///
- /// # Input
- /// ## qubit1
- /// First qubit to be swapped.
- /// ## qubit2
- /// Second qubit to be swapped.
- ///
- /// # Remarks
- /// Equivalent to:
- /// ```qsharp
- /// CNOT(qubit1, qubit2);
- /// CNOT(qubit2, qubit1);
- /// CNOT(qubit1, qubit2);
- /// ```
- operation SWAP (qubit1 : Qubit, qubit2 : Qubit) : Unit
- is Adj + Ctl {
- body (...)
- {
- CNOT(qubit1, qubit2);
- CNOT(qubit2, qubit1);
- CNOT(qubit1, qubit2);
- }
-
- adjoint self;
- }
-
- //-------------------------------------------------
- // Rotations
- //-------------------------------------------------
-
- /// # Summary
- /// Applies a rotation about the given Pauli axis.
- ///
- /// \begin{align}
- /// R_{\mu}(\theta) \mathrel{:=}
- /// e^{-i \theta \sigma_{\mu} / 2},
- /// \end{align}
- /// where $\mu \in \{I, X, Y, Z\}$.
- ///
- /// # Input
- /// ## pauli
- /// Pauli operator ($\mu$) to be exponentiated to form the rotation.
- /// ## theta
- /// Angle about which the qubit is to be rotated.
- /// ## qubit
- /// Qubit to which the gate should be applied.
- ///
- /// # Remarks
- /// When called with `pauli = PauliI`, this operation applies
- /// a *global phase*. This phase can be significant
- /// when used with the `Controlled` functor.
- operation R (pauli : Pauli, theta : Double, qubit : Qubit) : Unit
- is Adj + Ctl {
- body intrinsic;
- }
-
-
- /// # Summary
- /// Applies a rotation about the given Pauli axis by an angle specified
- /// as a dyadic fraction.
- ///
- /// \begin{align}
- /// R_{\mu}(n, k) \mathrel{:=}
- /// e^{i \pi n \sigma_{\mu} / 2^k},
- /// \end{align}
- /// where $\mu \in \{I, X, Y, Z\}$.
- ///
- /// > [!WARNING]
- /// > This operation uses the **opposite** sign convention from
- /// > @"microsoft.quantum.intrinsic.r".
- ///
- /// # Input
- /// ## pauli
- /// Pauli operator to be exponentiated to form the rotation.
- /// ## numerator
- /// Numerator in the dyadic fraction representation of the angle
- /// by which the qubit is to be rotated.
- /// ## power
- /// Power of two specifying the denominator of the angle by which
- /// the qubit is to be rotated.
- /// ## qubit
- /// Qubit to which the gate should be applied.
- ///
- /// # Remarks
- /// Equivalent to:
- /// ```qsharp
- /// // PI() is a Q# function that returns an approximation of π.
- /// R(pauli, -PI() * IntAsDouble(numerator) / IntAsDouble(2 ^ (power - 1)), qubit);
- /// ```
- operation RFrac (pauli : Pauli, numerator : Int, power : Int, qubit : Qubit) : Unit
- is Adj + Ctl {
-
- let angle = ((-2.0 * PI()) * IntAsDouble(numerator)) / IntAsDouble(2 ^ power);
- R(pauli, angle, qubit);
- }
-
-
- /// # Summary
- /// Applies a rotation about the $x$-axis by a given angle.
- ///
- /// \begin{align}
- /// R_x(\theta) \mathrel{:=}
- /// e^{-i \theta \sigma_x / 2} =
- /// \begin{bmatrix}
- /// \cos \frac{\theta}{2} & -i\sin \frac{\theta}{2} \\\\
- /// -i\sin \frac{\theta}{2} & \cos \frac{\theta}{2}
- /// \end{bmatrix}.
- /// \end{align}
- ///
- /// # Input
- /// ## theta
- /// Angle about which the qubit is to be rotated.
- /// ## qubit
- /// Qubit to which the gate should be applied.
- ///
- /// # Remarks
- /// Equivalent to:
- /// ```qsharp
- /// R(PauliX, theta, qubit);
- /// ```
- operation Rx (theta : Double, qubit : Qubit) : Unit
- is Adj + Ctl {
- body (...)
- {
- R(PauliX, theta, qubit);
- }
-
- adjoint (...)
- {
- R(PauliX, -theta, qubit);
- }
- }
-
-
- /// # Summary
- /// Applies a rotation about the $y$-axis by a given angle.
- ///
- /// \begin{align}
- /// R_y(\theta) \mathrel{:=}
- /// e^{-i \theta \sigma_y / 2} =
- /// \begin{bmatrix}
- /// \cos \frac{\theta}{2} & -\sin \frac{\theta}{2} \\\\
- /// \sin \frac{\theta}{2} & \cos \frac{\theta}{2}
- /// \end{bmatrix}.
- /// \end{align}
- ///
- /// # Input
- /// ## theta
- /// Angle about which the qubit is to be rotated.
- /// ## qubit
- /// Qubit to which the gate should be applied.
- ///
- /// # Remarks
- /// Equivalent to:
- /// ```qsharp
- /// R(PauliY, theta, qubit);
- /// ```
- operation Ry (theta : Double, qubit : Qubit) : Unit
- is Adj + Ctl {
- body (...)
- {
- R(PauliY, theta, qubit);
- }
-
- adjoint (...)
- {
- R(PauliY, -theta, qubit);
- }
- }
-
-
- /// # Summary
- /// Applies a rotation about the $z$-axis by a given angle.
- ///
- /// \begin{align}
- /// R_z(\theta) \mathrel{:=}
- /// e^{-i \theta \sigma_z / 2} =
- /// \begin{bmatrix}
- /// e^{-i \theta / 2} & 0 \\\\
- /// 0 & e^{i \theta / 2}
- /// \end{bmatrix}.
- /// \end{align}
- ///
- /// # Input
- /// ## theta
- /// Angle about which the qubit is to be rotated.
- /// ## qubit
- /// Qubit to which the gate should be applied.
- ///
- /// # Remarks
- /// Equivalent to:
- /// ```qsharp
- /// R(PauliZ, theta, qubit);
- /// ```
- operation Rz (theta : Double, qubit : Qubit) : Unit
- is Adj + Ctl {
- body (...)
- {
- R(PauliZ, theta, qubit);
- }
-
- adjoint (...)
- {
- R(PauliZ, -theta, qubit);
- }
- }
-
-
- /// # Summary
- /// Applies a rotation about the $\ket{1}$ state by a given angle.
- ///
- /// \begin{align}
- /// R_1(\theta) \mathrel{:=}
- /// \operatorname{diag}(1, e^{i\theta}).
- /// \end{align}
- ///
- /// # Input
- /// ## theta
- /// Angle about which the qubit is to be rotated.
- /// ## qubit
- /// Qubit to which the gate should be applied.
- ///
- /// # Remarks
- /// Equivalent to:
- /// ```qsharp
- /// R(PauliZ, theta, qubit);
- /// R(PauliI, -theta, qubit);
- /// ```
- operation R1 (theta : Double, qubit : Qubit) : Unit
- is Adj + Ctl {
-
- R(PauliZ, theta, qubit);
- R(PauliI, -theta, qubit);
- }
-
-
- /// # Summary
- /// Applies a rotation about the $\ket{1}$ state by an angle specified
- /// as a dyadic fraction.
- ///
- /// \begin{align}
- /// R_1(n, k) \mathrel{:=}
- /// \operatorname{diag}(1, e^{i \pi k / 2^n}).
- /// \end{align}
- ///
- /// > [!WARNING]
- /// > This operation uses the **opposite** sign convention from
- /// > @"microsoft.quantum.intrinsic.r", and does not include the
- /// > factor of $1/ 2$ included by @"microsoft.quantum.intrinsic.r1".
- ///
- /// # Input
- /// ## numerator
- /// Numerator in the dyadic fraction representation of the angle
- /// by which the qubit is to be rotated.
- /// ## power
- /// Power of two specifying the denominator of the angle by which
- /// the qubit is to be rotated.
- /// ## qubit
- /// Qubit to which the gate should be applied.
- ///
- /// # Remarks
- /// Equivalent to:
- /// ```qsharp
- /// RFrac(PauliZ, -numerator, denominator + 1, qubit);
- /// RFrac(PauliI, numerator, denominator + 1, qubit);
- /// ```
- operation R1Frac (numerator : Int, power : Int, qubit : Qubit) : Unit
- is Adj + Ctl {
-
- RFrac(PauliZ, -numerator, power + 1, qubit);
- RFrac(PauliI, numerator, power + 1, qubit);
- }
-
-
- /// # Summary
- /// Applies the exponential of a multi-qubit Pauli operator.
- ///
- /// \begin{align}
- /// e^{i \theta [P_0 \otimes P_1 \cdots P_{N-1}]},
- /// \end{align}
- /// where $P_i$ is the $i$th element of `paulis`, and where
- /// $N = $`Length(paulis)`.
- ///
- /// # Input
- /// ## paulis
- /// Array of single-qubit Pauli values indicating the tensor product
- /// factors on each qubit.
- /// ## theta
- /// Angle about the given multi-qubit Pauli operator by which the
- /// target register is to be rotated.
- /// ## qubits
- /// Register to apply the given rotation to.
- operation Exp (paulis : Pauli[], theta : Double, qubits : Qubit[]) : Unit
- is Adj + Ctl {
- body intrinsic;
- }
-
-
- /// # Summary
- /// Applies the exponential of a multi-qubit Pauli operator
- /// with an argument given by a dyadic fraction.
- ///
- /// \begin{align}
- /// e^{i \pi k [P_0 \otimes P_1 \cdots P_{N-1}] / 2^n},
- /// \end{align}
- /// where $P_i$ is the $i$th element of `paulis`, and where
- /// $N = $`Length(paulis)`.
- ///
- /// # Input
- /// ## paulis
- /// Array of single-qubit Pauli values indicating the tensor product
- /// factors on each qubit.
- /// ## numerator
- /// Numerator ($k$) in the dyadic fraction representation of the angle
- /// by which the qubit register is to be rotated.
- /// ## power
- /// Power of two ($n$) specifying the denominator of the angle by which
- /// the qubit register is to be rotated.
- /// ## qubits
- /// Register to apply the given rotation to.
- operation ExpFrac (paulis : Pauli[], numerator : Int, power : Int, qubits : Qubit[]) : Unit
- is Adj + Ctl {
- let angle = (PI() * IntAsDouble(numerator)) / IntAsDouble(2 ^ power);
- Exp(paulis, angle, qubits);
- }
-
-
- //-------------------------------------------------
- // Measurements
- //-------------------------------------------------
-
- /// # Summary
- /// Performs a joint measurement of one or more qubits in the
- /// specified Pauli bases.
- ///
- /// The output result is given by the distribution:
- /// \begin{align}
- /// \Pr(\texttt{Zero} | \ket{\psi}) =
- /// \frac12 \braket{
- /// \psi \mid|
- /// \left(
- /// \boldone + P_0 \otimes P_1 \otimes \cdots \otimes P_{N-1}
- /// \right) \mid|
- /// \psi
- /// },
- /// \end{align}
- /// where $P_i$ is the $i$th element of `bases`, and where
- /// $N = \texttt{Length}(\texttt{bases})$.
- /// That is, measurement returns a `Result` $d$ such that the eigenvalue of the
- /// observed measurement effect is $(-1)^d$.
- ///
- /// # Input
- /// ## bases
- /// Array of single-qubit Pauli values indicating the tensor product
- /// factors on each qubit.
- /// ## qubits
- /// Register of qubits to be measured.
- ///
- /// # Output
- /// `Zero` if the $+1$ eigenvalue is observed, and `One` if
- /// the $-1$ eigenvalue is observed.
- ///
- /// # Remarks
- /// If the basis array and qubit array are different lengths, then the
- /// operation will fail.
- operation Measure (bases : Pauli[], qubits : Qubit[]) : Result {
- body intrinsic;
- }
-
-
- /// # Summary
- /// Performs a measurement of a single qubit in the
- /// Pauli $Z$ basis.
- ///
- /// The output result is given by
- /// the distribution
- /// \begin{align}
- /// \Pr(\texttt{Zero} | \ket{\psi}) =
- /// \braket{\psi | 0} \braket{0 | \psi}.
- /// \end{align}
- ///
- /// # Input
- /// ## qubit
- /// Qubit to be measured.
- ///
- /// # Output
- /// `Zero` if the $+1$ eigenvalue is observed, and `One` if
- /// the $-1$ eigenvalue is observed.
- ///
- /// # Remarks
- /// Equivalent to:
- /// ```qsharp
- /// Measure([PauliZ], [qubit]);
- /// ```
- operation M (qubit : Qubit) : Result {
- return Measure([PauliZ], [qubit]);
- }
-
-
- /// # Summary
- /// Given a single qubit, measures it and ensures it is in the |0⟩ state
- /// such that it can be safely released.
- ///
- /// # Input
- /// ## qubit
- /// The qubit whose state is to be reset to $\ket{0}$.
- operation Reset (target : Qubit) : Unit {
-
- if (M(target) == One)
- {
- X(target);
- }
- }
-
-
- /// # Summary
- /// Given an array of qubits, measure them and ensure they are in the |0⟩ state
- /// such that they can be safely released.
- ///
- /// # Input
- /// ## qubits
- /// An array of qubits whose states are to be reset to $\ket{0}$.
- operation ResetAll (qubits : Qubit[]) : Unit {
-
- for (qubit in qubits) {
- Reset(qubit);
- }
- }
-
-}
-
-
diff --git a/src/Simulation/QsharpCore/Microsoft.Quantum.QSharp.Core.csproj b/src/Simulation/QsharpCore/Microsoft.Quantum.QSharp.Core.csproj
index 519f0b31367..3b0fe3f8c55 100644
--- a/src/Simulation/QsharpCore/Microsoft.Quantum.QSharp.Core.csproj
+++ b/src/Simulation/QsharpCore/Microsoft.Quantum.QSharp.Core.csproj
@@ -3,6 +3,8 @@
+
+
netstandard2.1
true
diff --git a/src/Simulation/QsharpCore/Reset.qs b/src/Simulation/QsharpCore/Reset.qs
deleted file mode 100644
index b62e4b114e5..00000000000
--- a/src/Simulation/QsharpCore/Reset.qs
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-namespace Microsoft.Quantum.Measurement {
- open Microsoft.Quantum.Intrinsic;
-
- internal operation BasisChangeZtoY(target : Qubit) : Unit is Adj + Ctl {
- H(target);
- S(target);
- }
-
-
- /// # Summary
- /// Sets a qubit to a given computational basis state by measuring the
- /// qubit and applying a bit flip if needed.
- ///
- /// # Input
- /// ## desired
- /// The basis state that the qubit should be set to.
- /// ## target
- /// The qubit whose state is to be set.
- ///
- /// # Remarks
- /// As an invariant of this operation, calling `M(q)` immediately
- /// after `SetToBasisState(result, q)` will return `result`.
- operation SetToBasisState(desired : Result, target : Qubit) : Unit {
- if (desired != M(target)) {
- X(target);
- }
- }
-
- /// # Summary
- /// Measures a single qubit in the Z basis,
- /// and resets it to a fixed initial state
- /// following the measurement.
- ///
- /// # Description
- /// Performs a single-qubit measurement in the $Z$-basis,
- /// and ensures that the qubit is returned to $\ket{0}$
- /// following the measurement.
- ///
- /// # Input
- /// ## target
- /// A single qubit to be measured.
- ///
- /// # Output
- /// The result of measuring `target` in the Pauli $Z$ basis.
- operation MResetZ (target : Qubit) : Result {
- let result = M(target);
-
- if (result == One) {
- // Recall that the +1 eigenspace of a measurement operator corresponds to
- // the Result case Zero. Thus, if we see a One case, we must reset the state
- // have +1 eigenvalue.
- X(target);
- }
-
- return result;
- }
-
-
- /// # Summary
- /// Measures a single qubit in the X basis,
- /// and resets it to a fixed initial state
- /// following the measurement.
- ///
- /// # Description
- /// Performs a single-qubit measurement in the $X$-basis,
- /// and ensures that the qubit is returned to $\ket{0}$
- /// following the measurement.
- ///
- /// # Input
- /// ## target
- /// A single qubit to be measured.
- ///
- /// # Output
- /// The result of measuring `target` in the Pauli $X$ basis.
- operation MResetX (target : Qubit) : Result {
- let result = Measure([PauliX], [target]);
-
- // We must return the qubit to the Z basis as well.
- H(target);
-
- if (result == One) {
- // Recall that the +1 eigenspace of a measurement operator corresponds to
- // the Result case Zero. Thus, if we see a One case, we must reset the state
- // have +1 eigenvalue.
- X(target);
- }
-
- return result;
- }
-
-
- /// # Summary
- /// Measures a single qubit in the Y basis,
- /// and resets it to a fixed initial state
- /// following the measurement.
- ///
- /// # Description
- /// Performs a single-qubit measurement in the $Y$-basis,
- /// and ensures that the qubit is returned to $\ket{0}$
- /// following the measurement.
- ///
- /// # Input
- /// ## target
- /// A single qubit to be measured.
- ///
- /// # Output
- /// The result of measuring `target` in the Pauli $Y$ basis.
- operation MResetY (target : Qubit) : Result {
- let result = Measure([PauliY], [target]);
-
- // We must return the qubit to the Z basis as well.
- Adjoint BasisChangeZtoY(target);
-
- if (result == One) {
- // Recall that the +1 eigenspace of a measurement operator corresponds to
- // the Result case Zero. Thus, if we see a One case, we must reset the state
- // have +1 eigenvalue.
- X(target);
- }
-
- return result;
- }
-
-}
diff --git a/src/Simulation/QsharpCore/Arrays/Enumeration.qs b/src/Simulation/QsharpFoundation/Arrays/Enumeration.qs
similarity index 91%
rename from src/Simulation/QsharpCore/Arrays/Enumeration.qs
rename to src/Simulation/QsharpFoundation/Arrays/Enumeration.qs
index a90383b1ab5..2a4634681a7 100644
--- a/src/Simulation/QsharpCore/Arrays/Enumeration.qs
+++ b/src/Simulation/QsharpFoundation/Arrays/Enumeration.qs
@@ -2,9 +2,6 @@
// Licensed under the MIT License.
namespace Microsoft.Quantum.Arrays {
- open Microsoft.Quantum.Intrinsic;
- open Microsoft.Quantum.Canon;
-
/// # Summary
/// Given an array, returns a range over the indices of that array, suitable
/// for use in a for loop.
@@ -29,5 +26,4 @@ namespace Microsoft.Quantum.Arrays {
function IndexRange<'TElement>(array : 'TElement[]) : Range {
return 0..(Length(array) - 1);
}
-
}
diff --git a/src/Simulation/QsharpCore/Canon/NoOp.qs b/src/Simulation/QsharpFoundation/Canon/NoOp.qs
similarity index 100%
rename from src/Simulation/QsharpCore/Canon/NoOp.qs
rename to src/Simulation/QsharpFoundation/Canon/NoOp.qs
diff --git a/src/Simulation/QsharpCore/Diagnostics/AssertAllZero.qs b/src/Simulation/QsharpFoundation/Diagnostics/AssertAllZero.qs
similarity index 100%
rename from src/Simulation/QsharpCore/Diagnostics/AssertAllZero.qs
rename to src/Simulation/QsharpFoundation/Diagnostics/AssertAllZero.qs
diff --git a/src/Simulation/QsharpCore/Diagnostics/AssertQubit.qs b/src/Simulation/QsharpFoundation/Diagnostics/AssertQubit.qs
similarity index 87%
rename from src/Simulation/QsharpCore/Diagnostics/AssertQubit.qs
rename to src/Simulation/QsharpFoundation/Diagnostics/AssertQubit.qs
index 973c07e8f7a..9c74954cd08 100644
--- a/src/Simulation/QsharpCore/Diagnostics/AssertQubit.qs
+++ b/src/Simulation/QsharpFoundation/Diagnostics/AssertQubit.qs
@@ -22,7 +22,7 @@ namespace Microsoft.Quantum.Diagnostics {
/// allows for asserting
/// arbitrary qubit states rather than only $Z$ eigenstates.
operation AssertQubit (expected : Result, q : Qubit) : Unit {
- Assert([PauliZ], [q], expected, $"Qubit in invalid state. Expecting: {expected}");
+ AssertMeasurement([PauliZ], [q], expected, $"Qubit in invalid state. Expecting: {expected}");
}
/// # Summary
@@ -47,7 +47,7 @@ namespace Microsoft.Quantum.Diagnostics {
/// allows for asserting
/// arbitrary qubit states rather than only $Z$ eigenstates.
operation AssertQubitWithinTolerance(expected : Result, q : Qubit, tolerance : Double) : Unit {
- AssertProb([PauliZ], [q], expected, 1.0, $"Qubit in invalid state. Expecting: {expected} with tolerance {tolerance}", tolerance);
+ AssertMeasurementProbability([PauliZ], [q], expected, 1.0, $"Qubit in invalid state. Expecting: {expected} with tolerance {tolerance}", tolerance);
}
/// # Summary
@@ -126,10 +126,10 @@ namespace Microsoft.Quantum.Diagnostics {
// Probability of getting outcome One in measuring PauliZ is Tr(M(I-Z)/2) = (mi-mz)/2.0
// similarly, we find the probabilities for measuring PauliX,PauliY
let tol = tolerance / 2.0;
- AssertProb([PauliX], [register], Zero, (mi + mx) / 2.0, $"Qubit Zero probability on X basis failed", tol);
- AssertProb([PauliY], [register], Zero, (mi + my) / 2.0, $"Qubit Zero probability on Y basis failed", tol);
- AssertProb([PauliZ], [register], Zero, (mi + mz) / 2.0, $"Qubit Zero probability on Z basis failed", tol);
- AssertProb([PauliZ], [register], One, (mi - mz) / 2.0, $"Qubit One probability on Z basis failed", tol);
+ AssertMeasurementProbability([PauliX], [register], Zero, (mi + mx) / 2.0, $"Qubit Zero probability on X basis failed", tol);
+ AssertMeasurementProbability([PauliY], [register], Zero, (mi + my) / 2.0, $"Qubit Zero probability on Y basis failed", tol);
+ AssertMeasurementProbability([PauliZ], [register], Zero, (mi + mz) / 2.0, $"Qubit Zero probability on Z basis failed", tol);
+ AssertMeasurementProbability([PauliZ], [register], One, (mi - mz) / 2.0, $"Qubit One probability on Z basis failed", tol);
}
}
diff --git a/src/Simulation/QsharpCore/Diagnostics/Dump.qs b/src/Simulation/QsharpFoundation/Diagnostics/Dump.qs
similarity index 100%
rename from src/Simulation/QsharpCore/Diagnostics/Dump.qs
rename to src/Simulation/QsharpFoundation/Diagnostics/Dump.qs
diff --git a/src/Simulation/QsharpCore/Diagnostics/UnitTests.qs b/src/Simulation/QsharpFoundation/Diagnostics/UnitTests.qs
similarity index 100%
rename from src/Simulation/QsharpCore/Diagnostics/UnitTests.qs
rename to src/Simulation/QsharpFoundation/Diagnostics/UnitTests.qs
diff --git a/src/Simulation/Simulators.Tests/QuantumTestSuite/AssertProbMultiQubit.qs b/src/Simulation/Simulators.Tests/QuantumTestSuite/AssertProbMultiQubit.qs
index 49392e3aa0c..61619fdc008 100644
--- a/src/Simulation/Simulators.Tests/QuantumTestSuite/AssertProbMultiQubit.qs
+++ b/src/Simulation/Simulators.Tests/QuantumTestSuite/AssertProbMultiQubit.qs
@@ -8,6 +8,41 @@ namespace Microsoft.Quantum.Simulation.TestSuite {
open Microsoft.Quantum.Simulation.TestSuite.Math;
+ internal operation flipToBasis (basis : Int[], qubits : Qubit[]) : Unit is Adj + Ctl {
+ if (Length(qubits) != Length(basis))
+ {
+ fail $"qubits and stateIds must have the same length";
+ }
+
+ for (i in 0 .. Length(qubits) - 1)
+ {
+ let id = basis[i];
+ let qubit = qubits[i];
+
+ if (id < 0 or id > 3) {
+ fail $"Invalid basis. Must be between 0 and 3, it was {basis}";
+ }
+
+ if (id == 0)
+ {
+ I(qubit);
+ }
+ elif (id == 1)
+ {
+ X(qubit);
+ }
+ elif (id == 2)
+ {
+ H(qubit);
+ }
+ else
+ {
+ H(qubit);
+ S(qubit);
+ }
+ }
+ }
+
operation AssertProbMultiQubitTest () : Unit {
@@ -51,12 +86,12 @@ namespace Microsoft.Quantum.Simulation.TestSuite {
}
using (qubits = Qubit[l]) {
- _flipToBasis(stateId, qubits);
+ flipToBasis(stateId, qubits);
let expectedZeroProbability = 0.5 + 0.5 * ExpectedValueForMultiPauliByStateId(observable, stateId);
let expectedOneProbability = 1.0 - expectedZeroProbability;
- AssertProb(observable, qubits, Zero, expectedZeroProbability, $"", Accuracy());
- AssertProb(observable, qubits, One, expectedOneProbability, $"", Accuracy());
- Adjoint _flipToBasis(stateId, qubits);
+ AssertMeasurementProbability(observable, qubits, Zero, expectedZeroProbability, $"", Accuracy());
+ AssertMeasurementProbability(observable, qubits, One, expectedOneProbability, $"", Accuracy());
+ Adjoint flipToBasis(stateId, qubits);
}
}
diff --git a/src/Simulation/Simulators.Tests/QuantumTestSuite/AssertQubitUnitary.qs b/src/Simulation/Simulators.Tests/QuantumTestSuite/AssertQubitUnitary.qs
index 82f4009c77b..642003c7f61 100644
--- a/src/Simulation/Simulators.Tests/QuantumTestSuite/AssertQubitUnitary.qs
+++ b/src/Simulation/Simulators.Tests/QuantumTestSuite/AssertQubitUnitary.qs
@@ -15,7 +15,7 @@ namespace Microsoft.Quantum.Simulation.TestSuite {
for (stateId in 0 .. maxId) {
let expectedState = ApplyMatrix(unitaryMatrix, StateIdToVector(stateId));
- _flipToBasis([stateId], [qubit]);
+ flipToBasis([stateId], [qubit]);
unitaryOp(qubit);
let alpha = Microsoft.Quantum.Math.Complex((expectedState![0])!);
let beta = Microsoft.Quantum.Math.Complex((expectedState![1])!);
diff --git a/src/Simulation/Simulators.Tests/QuantumTestSuite/AssertUnitary.qs b/src/Simulation/Simulators.Tests/QuantumTestSuite/AssertUnitary.qs
index 22a38acbe2b..e808fdb532c 100644
--- a/src/Simulation/Simulators.Tests/QuantumTestSuite/AssertUnitary.qs
+++ b/src/Simulation/Simulators.Tests/QuantumTestSuite/AssertUnitary.qs
@@ -10,7 +10,7 @@ namespace Microsoft.Quantum.Simulation.TestSuite {
operation AssertUnitaryHelper (stateIds : Int[], unitaryMatrix : RowMajorMatrix, unitaryOp : (Qubit[] => Unit), qubits : Qubit[]) : Unit {
let expectedState = ApplyMatrix(unitaryMatrix, StateById(stateIds));
- _flipToBasis(stateIds, qubits);
+ flipToBasis(stateIds, qubits);
unitaryOp(qubits);
AssertState(expectedState, qubits);
ResetAll(qubits);
diff --git a/src/Simulation/Simulators.Tests/QuantumTestSuite/JointOneQubitTests.qs b/src/Simulation/Simulators.Tests/QuantumTestSuite/JointOneQubitTests.qs
index 137ea806f31..937b84b7099 100644
--- a/src/Simulation/Simulators.Tests/QuantumTestSuite/JointOneQubitTests.qs
+++ b/src/Simulation/Simulators.Tests/QuantumTestSuite/JointOneQubitTests.qs
@@ -23,7 +23,7 @@ namespace Microsoft.Quantum.Simulation.TestSuite {
}
mutable states = new Vector[numQubits];
- _flipToBasis(inputStateId, qubits);
+ flipToBasis(inputStateId, qubits);
for (i in 0 .. numQubits - 1) {
let (op, matrix) = operationsToTest[i]!;
diff --git a/src/Simulation/QsharpCore/Diagnostics/AssertOperationsEqualInPlace.qs b/src/Simulation/TargetDefinitions/Decompositions/AssertOperationsEqualInPlace.qs
similarity index 88%
rename from src/Simulation/QsharpCore/Diagnostics/AssertOperationsEqualInPlace.qs
rename to src/Simulation/TargetDefinitions/Decompositions/AssertOperationsEqualInPlace.qs
index 33bfdd67896..aa1c0cedc93 100644
--- a/src/Simulation/QsharpCore/Diagnostics/AssertOperationsEqualInPlace.qs
+++ b/src/Simulation/TargetDefinitions/Decompositions/AssertOperationsEqualInPlace.qs
@@ -9,7 +9,7 @@ namespace Microsoft.Quantum.Diagnostics {
/// Iterates a variable through a Cartesian product
/// [ 0, bounds[0]-1 ] × [ 0, bounds[1]-1 ] × [ 0, bounds[Length(bounds)-1]-1 ]
/// and calls op(arr) for every element of the Cartesian product
- operation _iterateThroughCartesianPower (length : Int, value : Int, op : (Int[] => Unit)) : Unit {
+ internal operation iterateThroughCartesianPower (length : Int, value : Int, op : (Int[] => Unit)) : Unit {
mutable bounds = new Int[length];
for (i in 0 .. length - 1)
@@ -67,9 +67,7 @@ namespace Microsoft.Quantum.Diagnostics {
/// ## basis
/// Array of single-qubit basis state IDs (0 <= id <= 3), one for each element of
/// qubits.
- operation _flipToBasis (basis : Int[], qubits : Qubit[]) : Unit
- is Adj + Ctl {
-
+ internal operation flipToBasis (basis : Int[], qubits : Qubit[]) : Unit is Adj + Ctl {
if (Length(qubits) != Length(basis))
{
fail $"qubits and stateIds must have the same length";
@@ -119,15 +117,15 @@ namespace Microsoft.Quantum.Diagnostics {
/// Operation on $n$ qubits to be checked.
/// ## expectedU
/// Reference operation on $n$ qubits that givenU is to be compared against.
- operation _assertEqualOnBasisVector (basis : Int[], givenU : (Qubit[] => Unit), expectedU : (Qubit[] => Unit is Adj)) : Unit {
+ internal operation assertEqualOnBasisVector (basis : Int[], givenU : (Qubit[] => Unit), expectedU : (Qubit[] => Unit is Adj)) : Unit {
let tolerance = 1e-5;
using (qubits = Qubit[Length(basis)]) {
AssertAllZeroWithinTolerance(qubits, tolerance);
- _flipToBasis(basis, qubits);
+ flipToBasis(basis, qubits);
givenU(qubits);
Adjoint expectedU(qubits);
- Adjoint _flipToBasis(basis, qubits);
+ Adjoint flipToBasis(basis, qubits);
AssertAllZeroWithinTolerance(qubits, tolerance);
}
}
@@ -157,8 +155,8 @@ namespace Microsoft.Quantum.Diagnostics {
/// described in [ *I. L. Chuang, M. A. Nielsen* ](https://arxiv.org/abs/quant-ph/9610001).
operation AssertOperationsEqualInPlace(nQubits : Int, givenU : (Qubit[] => Unit), expectedU : (Qubit[] => Unit is Adj)) : Unit
{
- let checkOperation = _assertEqualOnBasisVector(_, givenU, expectedU);
- _iterateThroughCartesianPower(nQubits, 4, checkOperation);
+ let checkOperation = assertEqualOnBasisVector(_, givenU, expectedU);
+ iterateThroughCartesianPower(nQubits, 4, checkOperation);
}
/// # Summary
@@ -177,8 +175,8 @@ namespace Microsoft.Quantum.Diagnostics {
/// Reference operation on $n$ qubits that `givenU` is to be compared against.
operation AssertOperationsEqualInPlaceCompBasis (nQubits : Int, givenU : (Qubit[] => Unit), expectedU : (Qubit[] => Unit is Adj)) : Unit
{
- let checkOperation = _assertEqualOnBasisVector(_, givenU, expectedU);
- _iterateThroughCartesianPower(nQubits, 2, checkOperation);
+ let checkOperation = assertEqualOnBasisVector(_, givenU, expectedU);
+ iterateThroughCartesianPower(nQubits, 2, checkOperation);
}
}
diff --git a/src/Simulation/QsharpCore/Diagnostics/AssertOperationsEqualReferenced.qs b/src/Simulation/TargetDefinitions/Decompositions/AssertOperationsEqualReferenced.qs
similarity index 93%
rename from src/Simulation/QsharpCore/Diagnostics/AssertOperationsEqualReferenced.qs
rename to src/Simulation/TargetDefinitions/Decompositions/AssertOperationsEqualReferenced.qs
index d29eecf85db..90399286af2 100644
--- a/src/Simulation/QsharpCore/Diagnostics/AssertOperationsEqualReferenced.qs
+++ b/src/Simulation/TargetDefinitions/Decompositions/AssertOperationsEqualReferenced.qs
@@ -17,7 +17,7 @@ namespace Microsoft.Quantum.Diagnostics {
/// A qubit array in the $\ket{0\cdots 0}$ state
/// ## right
/// A qubit array in the $\ket{0\cdots 0}$ state
- operation _prepareEntangledState (left : Qubit[], right : Qubit[]) : Unit
+ internal operation prepareEntangledState (left : Qubit[], right : Qubit[]) : Unit
is Adj + Ctl {
for (idxQubit in 0 .. Length(left) - 1)
@@ -56,10 +56,10 @@ namespace Microsoft.Quantum.Diagnostics {
operation AssertOperationsEqualReferenced (nQubits : Int, actual : (Qubit[] => Unit), expected : (Qubit[] => Unit is Adj)) : Unit {
// Prepare a reference register entangled with the target register.
using ((reference, target) = (Qubit[nQubits], Qubit[nQubits])) {
- _prepareEntangledState(reference, target);
+ prepareEntangledState(reference, target);
actual(target);
Adjoint expected(target);
- Adjoint _prepareEntangledState(reference, target);
+ Adjoint prepareEntangledState(reference, target);
AssertAllZero(reference + target);
ResetAll(target);
ResetAll(reference);
diff --git a/src/Simulation/TargetDefinitions/Decompositions/CCNOT.qs b/src/Simulation/TargetDefinitions/Decompositions/CCNOT.qs
new file mode 100644
index 00000000000..430ab0e4c9f
--- /dev/null
+++ b/src/Simulation/TargetDefinitions/Decompositions/CCNOT.qs
@@ -0,0 +1,27 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.Quantum.Intrinsic {
+ /// # Summary
+ /// Applies the doubly controlled–NOT (CCNOT) gate to three qubits.
+ ///
+ /// # Input
+ /// ## control1
+ /// First control qubit for the CCNOT gate.
+ /// ## control2
+ /// Second control qubit for the CCNOT gate.
+ /// ## target
+ /// Target qubit for the CCNOT gate.
+ ///
+ /// # Remarks
+ /// Equivalent to:
+ /// ```qsharp
+ /// Controlled X([control1, control2], target);
+ /// ```
+ operation CCNOT (control1 : Qubit, control2 : Qubit, target : Qubit) : Unit is Adj + Ctl {
+ body (...) {
+ Controlled X([control1, control2], target);
+ }
+ adjoint self;
+ }
+}
\ No newline at end of file
diff --git a/src/Simulation/TargetDefinitions/Decompositions/CNOT.qs b/src/Simulation/TargetDefinitions/Decompositions/CNOT.qs
new file mode 100644
index 00000000000..f6403a74e5f
--- /dev/null
+++ b/src/Simulation/TargetDefinitions/Decompositions/CNOT.qs
@@ -0,0 +1,38 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.Quantum.Intrinsic {
+ /// # Summary
+ /// Applies the controlled-NOT (CNOT) gate to a pair of qubits.
+ ///
+ /// # Description
+ /// \begin{align}
+ /// \operatorname{CNOT} \mathrel{:=}
+ /// \begin{bmatrix}
+ /// 1 & 0 & 0 & 0 \\\\
+ /// 0 & 1 & 0 & 0 \\\\
+ /// 0 & 0 & 0 & 1 \\\\
+ /// 0 & 0 & 1 & 0
+ /// \end{bmatrix},
+ /// \end{align}
+ ///
+ /// where rows and columns are ordered as in the quantum concepts guide.
+ ///
+ /// # Input
+ /// ## control
+ /// Control qubit for the CNOT gate.
+ /// ## target
+ /// Target qubit for the CNOT gate.
+ ///
+ /// # Remarks
+ /// Equivalent to:
+ /// ```qsharp
+ /// Controlled X([control], target);
+ /// ```
+ operation CNOT (control : Qubit, target : Qubit) : Unit is Adj + Ctl {
+ body (...) {
+ Controlled X([control], target);
+ }
+ adjoint self;
+ }
+}
\ No newline at end of file
diff --git a/src/Simulation/TargetDefinitions/Decompositions/ExpFrac.qs b/src/Simulation/TargetDefinitions/Decompositions/ExpFrac.qs
new file mode 100644
index 00000000000..e18d4e98e0d
--- /dev/null
+++ b/src/Simulation/TargetDefinitions/Decompositions/ExpFrac.qs
@@ -0,0 +1,35 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.Quantum.Intrinsic {
+ open Microsoft.Quantum.Math;
+ open Microsoft.Quantum.Convert;
+
+ /// # Summary
+ /// Applies the exponential of a multi-qubit Pauli operator
+ /// with an argument given by a dyadic fraction.
+ ///
+ /// # Description
+ /// \begin{align}
+ /// e^{i \pi k [P_0 \otimes P_1 \cdots P_{N-1}] / 2^n},
+ /// \end{align}
+ /// where $P_i$ is the $i$th element of `paulis`, and where
+ /// $N = $`Length(paulis)`.
+ ///
+ /// # Input
+ /// ## paulis
+ /// Array of single-qubit Pauli values indicating the tensor product
+ /// factors on each qubit.
+ /// ## numerator
+ /// Numerator ($k$) in the dyadic fraction representation of the angle
+ /// by which the qubit register is to be rotated.
+ /// ## power
+ /// Power of two ($n$) specifying the denominator of the angle by which
+ /// the qubit register is to be rotated.
+ /// ## qubits
+ /// Register to apply the given rotation to.
+ operation ExpFrac (paulis : Pauli[], numerator : Int, power : Int, qubits : Qubit[]) : Unit is Adj + Ctl {
+ let angle = (PI() * IntAsDouble(numerator)) / IntAsDouble(2 ^ power);
+ Exp(paulis, angle, qubits);
+ }
+}
\ No newline at end of file
diff --git a/src/Simulation/TargetDefinitions/Decompositions/M.qs b/src/Simulation/TargetDefinitions/Decompositions/M.qs
new file mode 100644
index 00000000000..c5066f9ee6c
--- /dev/null
+++ b/src/Simulation/TargetDefinitions/Decompositions/M.qs
@@ -0,0 +1,33 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.Quantum.Intrinsic {
+ /// # Summary
+ /// Performs a measurement of a single qubit in the
+ /// Pauli $Z$ basis.
+ ///
+ /// # Description
+ /// The output result is given by
+ /// the distribution
+ /// \begin{align}
+ /// \Pr(\texttt{Zero} | \ket{\psi}) =
+ /// \braket{\psi | 0} \braket{0 | \psi}.
+ /// \end{align}
+ ///
+ /// # Input
+ /// ## qubit
+ /// Qubit to be measured.
+ ///
+ /// # Output
+ /// `Zero` if the $+1$ eigenvalue is observed, and `One` if
+ /// the $-1$ eigenvalue is observed.
+ ///
+ /// # Remarks
+ /// Equivalent to:
+ /// ```qsharp
+ /// Measure([PauliZ], [qubit]);
+ /// ```
+ operation M (qubit : Qubit) : Result {
+ return Measure([PauliZ], [qubit]);
+ }
+}
\ No newline at end of file
diff --git a/src/Simulation/TargetDefinitions/Decompositions/MResetX.qs b/src/Simulation/TargetDefinitions/Decompositions/MResetX.qs
new file mode 100644
index 00000000000..ae845f9b788
--- /dev/null
+++ b/src/Simulation/TargetDefinitions/Decompositions/MResetX.qs
@@ -0,0 +1,38 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.Quantum.Measurement {
+ open Microsoft.Quantum.Intrinsic;
+
+ /// # Summary
+ /// Measures a single qubit in the X basis,
+ /// and resets it to a fixed initial state
+ /// following the measurement.
+ ///
+ /// # Description
+ /// Performs a single-qubit measurement in the $X$-basis,
+ /// and ensures that the qubit is returned to $\ket{0}$
+ /// following the measurement.
+ ///
+ /// # Input
+ /// ## target
+ /// A single qubit to be measured.
+ ///
+ /// # Output
+ /// The result of measuring `target` in the Pauli $X$ basis.
+ operation MResetX (target : Qubit) : Result {
+ let result = Measure([PauliX], [target]);
+
+ // We must return the qubit to the Z basis as well.
+ H(target);
+
+ if (result == One) {
+ // Recall that the +1 eigenspace of a measurement operator corresponds to
+ // the Result case Zero. Thus, if we see a One case, we must reset the state
+ // have +1 eigenvalue.
+ X(target);
+ }
+
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/src/Simulation/TargetDefinitions/Decompositions/MResetY.qs b/src/Simulation/TargetDefinitions/Decompositions/MResetY.qs
new file mode 100644
index 00000000000..41271901ab9
--- /dev/null
+++ b/src/Simulation/TargetDefinitions/Decompositions/MResetY.qs
@@ -0,0 +1,43 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.Quantum.Measurement {
+ open Microsoft.Quantum.Intrinsic;
+
+ internal operation BasisChangeZtoY(target : Qubit) : Unit is Adj + Ctl {
+ H(target);
+ S(target);
+ }
+
+ /// # Summary
+ /// Measures a single qubit in the Y basis,
+ /// and resets it to a fixed initial state
+ /// following the measurement.
+ ///
+ /// # Description
+ /// Performs a single-qubit measurement in the $Y$-basis,
+ /// and ensures that the qubit is returned to $\ket{0}$
+ /// following the measurement.
+ ///
+ /// # Input
+ /// ## target
+ /// A single qubit to be measured.
+ ///
+ /// # Output
+ /// The result of measuring `target` in the Pauli $Y$ basis.
+ operation MResetY (target : Qubit) : Result {
+ let result = Measure([PauliY], [target]);
+
+ // We must return the qubit to the Z basis as well.
+ Adjoint BasisChangeZtoY(target);
+
+ if (result == One) {
+ // Recall that the +1 eigenspace of a measurement operator corresponds to
+ // the Result case Zero. Thus, if we see a One case, we must reset the state
+ // have +1 eigenvalue.
+ X(target);
+ }
+
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/src/Simulation/TargetDefinitions/Decompositions/MResetZ.qs b/src/Simulation/TargetDefinitions/Decompositions/MResetZ.qs
new file mode 100644
index 00000000000..64c04237af6
--- /dev/null
+++ b/src/Simulation/TargetDefinitions/Decompositions/MResetZ.qs
@@ -0,0 +1,35 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.Quantum.Measurement {
+ open Microsoft.Quantum.Intrinsic;
+
+ /// # Summary
+ /// Measures a single qubit in the Z basis,
+ /// and resets it to a fixed initial state
+ /// following the measurement.
+ ///
+ /// # Description
+ /// Performs a single-qubit measurement in the $Z$-basis,
+ /// and ensures that the qubit is returned to $\ket{0}$
+ /// following the measurement.
+ ///
+ /// # Input
+ /// ## target
+ /// A single qubit to be measured.
+ ///
+ /// # Output
+ /// The result of measuring `target` in the Pauli $Z$ basis.
+ operation MResetZ (target : Qubit) : Result {
+ let result = M(target);
+
+ if (result == One) {
+ // Recall that the +1 eigenspace of a measurement operator corresponds to
+ // the Result case Zero. Thus, if we see a One case, we must reset the state
+ // have +1 eigenvalue.
+ X(target);
+ }
+
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/src/Simulation/TargetDefinitions/Decompositions/R1.qs b/src/Simulation/TargetDefinitions/Decompositions/R1.qs
new file mode 100644
index 00000000000..06678d7f707
--- /dev/null
+++ b/src/Simulation/TargetDefinitions/Decompositions/R1.qs
@@ -0,0 +1,30 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.Quantum.Intrinsic {
+ /// # Summary
+ /// Applies a rotation about the $\ket{1}$ state by a given angle.
+ ///
+ /// # Description
+ /// \begin{align}
+ /// R_1(\theta) \mathrel{:=}
+ /// \operatorname{diag}(1, e^{i\theta}).
+ /// \end{align}
+ ///
+ /// # Input
+ /// ## theta
+ /// Angle about which the qubit is to be rotated.
+ /// ## qubit
+ /// Qubit to which the gate should be applied.
+ ///
+ /// # Remarks
+ /// Equivalent to:
+ /// ```qsharp
+ /// R(PauliZ, theta, qubit);
+ /// R(PauliI, -theta, qubit);
+ /// ```
+ operation R1 (theta : Double, qubit : Qubit) : Unit is Adj + Ctl {
+ R(PauliZ, theta, qubit);
+ R(PauliI, -theta, qubit);
+ }
+}
\ No newline at end of file
diff --git a/src/Simulation/TargetDefinitions/Decompositions/R1Frac.qs b/src/Simulation/TargetDefinitions/Decompositions/R1Frac.qs
new file mode 100644
index 00000000000..338f32c8ff1
--- /dev/null
+++ b/src/Simulation/TargetDefinitions/Decompositions/R1Frac.qs
@@ -0,0 +1,40 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.Quantum.Intrinsic {
+ /// # Summary
+ /// Applies a rotation about the $\ket{1}$ state by an angle specified
+ /// as a dyadic fraction.
+ ///
+ /// # Description
+ /// \begin{align}
+ /// R_1(n, k) \mathrel{:=}
+ /// \operatorname{diag}(1, e^{i \pi k / 2^n}).
+ /// \end{align}
+ ///
+ /// > [!WARNING]
+ /// > This operation uses the **opposite** sign convention from
+ /// > @"microsoft.quantum.intrinsic.r", and does not include the
+ /// > factor of $1/ 2$ included by @"microsoft.quantum.intrinsic.r1".
+ ///
+ /// # Input
+ /// ## numerator
+ /// Numerator in the dyadic fraction representation of the angle
+ /// by which the qubit is to be rotated.
+ /// ## power
+ /// Power of two specifying the denominator of the angle by which
+ /// the qubit is to be rotated.
+ /// ## qubit
+ /// Qubit to which the gate should be applied.
+ ///
+ /// # Remarks
+ /// Equivalent to:
+ /// ```qsharp
+ /// RFrac(PauliZ, -numerator, denominator + 1, qubit);
+ /// RFrac(PauliI, numerator, denominator + 1, qubit);
+ /// ```
+ operation R1Frac (numerator : Int, power : Int, qubit : Qubit) : Unit is Adj + Ctl {
+ RFrac(PauliZ, -numerator, power + 1, qubit);
+ RFrac(PauliI, numerator, power + 1, qubit);
+ }
+}
\ No newline at end of file
diff --git a/src/Simulation/TargetDefinitions/Decompositions/RFrac.qs b/src/Simulation/TargetDefinitions/Decompositions/RFrac.qs
new file mode 100644
index 00000000000..a0f632c7e03
--- /dev/null
+++ b/src/Simulation/TargetDefinitions/Decompositions/RFrac.qs
@@ -0,0 +1,45 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.Quantum.Intrinsic {
+ open Microsoft.Quantum.Math;
+ open Microsoft.Quantum.Convert;
+
+ /// # Summary
+ /// Applies a rotation about the given Pauli axis by an angle specified
+ /// as a dyadic fraction.
+ ///
+ /// # Description
+ /// \begin{align}
+ /// R_{\mu}(n, k) \mathrel{:=}
+ /// e^{i \pi n \sigma_{\mu} / 2^k},
+ /// \end{align}
+ /// where $\mu \in \{I, X, Y, Z\}$.
+ ///
+ /// > [!WARNING]
+ /// > This operation uses the **opposite** sign convention from
+ /// > @"microsoft.quantum.intrinsic.r".
+ ///
+ /// # Input
+ /// ## pauli
+ /// Pauli operator to be exponentiated to form the rotation.
+ /// ## numerator
+ /// Numerator in the dyadic fraction representation of the angle
+ /// by which the qubit is to be rotated.
+ /// ## power
+ /// Power of two specifying the denominator of the angle by which
+ /// the qubit is to be rotated.
+ /// ## qubit
+ /// Qubit to which the gate should be applied.
+ ///
+ /// # Remarks
+ /// Equivalent to:
+ /// ```qsharp
+ /// // PI() is a Q# function that returns an approximation of π.
+ /// R(pauli, -PI() * IntAsDouble(numerator) / IntAsDouble(2 ^ (power - 1)), qubit);
+ /// ```
+ operation RFrac (pauli : Pauli, numerator : Int, power : Int, qubit : Qubit) : Unit is Adj + Ctl {
+ let angle = ((-2.0 * PI()) * IntAsDouble(numerator)) / IntAsDouble(2 ^ power);
+ R(pauli, angle, qubit);
+ }
+}
\ No newline at end of file
diff --git a/src/Simulation/TargetDefinitions/Decompositions/Reset.qs b/src/Simulation/TargetDefinitions/Decompositions/Reset.qs
new file mode 100644
index 00000000000..a5bb975894d
--- /dev/null
+++ b/src/Simulation/TargetDefinitions/Decompositions/Reset.qs
@@ -0,0 +1,17 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.Quantum.Intrinsic {
+ /// # Summary
+ /// Given a single qubit, measures it and ensures it is in the |0⟩ state
+ /// such that it can be safely released.
+ ///
+ /// # Input
+ /// ## qubit
+ /// The qubit whose state is to be reset to $\ket{0}$.
+ operation Reset (target : Qubit) : Unit {
+ if (M(target) == One) {
+ X(target);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Simulation/TargetDefinitions/Decompositions/ResetAll.qs b/src/Simulation/TargetDefinitions/Decompositions/ResetAll.qs
new file mode 100644
index 00000000000..cd76adc599e
--- /dev/null
+++ b/src/Simulation/TargetDefinitions/Decompositions/ResetAll.qs
@@ -0,0 +1,17 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.Quantum.Intrinsic {
+ /// # Summary
+ /// Given an array of qubits, measure them and ensure they are in the |0⟩ state
+ /// such that they can be safely released.
+ ///
+ /// # Input
+ /// ## qubits
+ /// An array of qubits whose states are to be reset to $\ket{0}$.
+ operation ResetAll (qubits : Qubit[]) : Unit {
+ for (qubit in qubits) {
+ Reset(qubit);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Simulation/TargetDefinitions/Decompositions/Rx.qs b/src/Simulation/TargetDefinitions/Decompositions/Rx.qs
new file mode 100644
index 00000000000..d4c999a83b2
--- /dev/null
+++ b/src/Simulation/TargetDefinitions/Decompositions/Rx.qs
@@ -0,0 +1,37 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.Quantum.Intrinsic {
+ /// # Summary
+ /// Applies a rotation about the $x$-axis by a given angle.
+ ///
+ /// # Description
+ /// \begin{align}
+ /// R_x(\theta) \mathrel{:=}
+ /// e^{-i \theta \sigma_x / 2} =
+ /// \begin{bmatrix}
+ /// \cos \frac{\theta}{2} & -i\sin \frac{\theta}{2} \\\\
+ /// -i\sin \frac{\theta}{2} & \cos \frac{\theta}{2}
+ /// \end{bmatrix}.
+ /// \end{align}
+ ///
+ /// # Input
+ /// ## theta
+ /// Angle about which the qubit is to be rotated.
+ /// ## qubit
+ /// Qubit to which the gate should be applied.
+ ///
+ /// # Remarks
+ /// Equivalent to:
+ /// ```qsharp
+ /// R(PauliX, theta, qubit);
+ /// ```
+ operation Rx (theta : Double, qubit : Qubit) : Unit is Adj + Ctl {
+ body (...) {
+ R(PauliX, theta, qubit);
+ }
+ adjoint (...) {
+ R(PauliX, -theta, qubit);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Simulation/TargetDefinitions/Decompositions/Ry.qs b/src/Simulation/TargetDefinitions/Decompositions/Ry.qs
new file mode 100644
index 00000000000..e68732523b6
--- /dev/null
+++ b/src/Simulation/TargetDefinitions/Decompositions/Ry.qs
@@ -0,0 +1,37 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.Quantum.Intrinsic {
+ /// # Summary
+ /// Applies a rotation about the $y$-axis by a given angle.
+ ///
+ /// # Description
+ /// \begin{align}
+ /// R_y(\theta) \mathrel{:=}
+ /// e^{-i \theta \sigma_y / 2} =
+ /// \begin{bmatrix}
+ /// \cos \frac{\theta}{2} & -\sin \frac{\theta}{2} \\\\
+ /// \sin \frac{\theta}{2} & \cos \frac{\theta}{2}
+ /// \end{bmatrix}.
+ /// \end{align}
+ ///
+ /// # Input
+ /// ## theta
+ /// Angle about which the qubit is to be rotated.
+ /// ## qubit
+ /// Qubit to which the gate should be applied.
+ ///
+ /// # Remarks
+ /// Equivalent to:
+ /// ```qsharp
+ /// R(PauliY, theta, qubit);
+ /// ```
+ operation Ry (theta : Double, qubit : Qubit) : Unit is Adj + Ctl {
+ body (...) {
+ R(PauliY, theta, qubit);
+ }
+ adjoint (...) {
+ R(PauliY, -theta, qubit);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Simulation/TargetDefinitions/Decompositions/Rz.qs b/src/Simulation/TargetDefinitions/Decompositions/Rz.qs
new file mode 100644
index 00000000000..30956ac6640
--- /dev/null
+++ b/src/Simulation/TargetDefinitions/Decompositions/Rz.qs
@@ -0,0 +1,37 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.Quantum.Intrinsic {
+ /// # Summary
+ /// Applies a rotation about the $z$-axis by a given angle.
+ ///
+ /// # Description
+ /// \begin{align}
+ /// R_z(\theta) \mathrel{:=}
+ /// e^{-i \theta \sigma_z / 2} =
+ /// \begin{bmatrix}
+ /// e^{-i \theta / 2} & 0 \\\\
+ /// 0 & e^{i \theta / 2}
+ /// \end{bmatrix}.
+ /// \end{align}
+ ///
+ /// # Input
+ /// ## theta
+ /// Angle about which the qubit is to be rotated.
+ /// ## qubit
+ /// Qubit to which the gate should be applied.
+ ///
+ /// # Remarks
+ /// Equivalent to:
+ /// ```qsharp
+ /// R(PauliZ, theta, qubit);
+ /// ```
+ operation Rz (theta : Double, qubit : Qubit) : Unit is Adj + Ctl {
+ body (...) {
+ R(PauliZ, theta, qubit);
+ }
+ adjoint (...) {
+ R(PauliZ, -theta, qubit);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Simulation/TargetDefinitions/Decompositions/SWAP.qs b/src/Simulation/TargetDefinitions/Decompositions/SWAP.qs
new file mode 100644
index 00000000000..19cc13a1634
--- /dev/null
+++ b/src/Simulation/TargetDefinitions/Decompositions/SWAP.qs
@@ -0,0 +1,42 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.Quantum.Intrinsic {
+ /// # Summary
+ /// Applies the SWAP gate to a pair of qubits.
+ ///
+ /// # Description
+ /// \begin{align}
+ /// \operatorname{SWAP} \mathrel{:=}
+ /// \begin{bmatrix}
+ /// 1 & 0 & 0 & 0 \\\\
+ /// 0 & 0 & 1 & 0 \\\\
+ /// 0 & 1 & 0 & 0 \\\\
+ /// 0 & 0 & 0 & 1
+ /// \end{bmatrix},
+ /// \end{align}
+ ///
+ /// where rows and columns are ordered as in the quantum concepts guide.
+ ///
+ /// # Input
+ /// ## qubit1
+ /// First qubit to be swapped.
+ /// ## qubit2
+ /// Second qubit to be swapped.
+ ///
+ /// # Remarks
+ /// Equivalent to:
+ /// ```qsharp
+ /// CNOT(qubit1, qubit2);
+ /// CNOT(qubit2, qubit1);
+ /// CNOT(qubit1, qubit2);
+ /// ```
+ operation SWAP (qubit1 : Qubit, qubit2 : Qubit) : Unit is Adj + Ctl {
+ body (...) {
+ CNOT(qubit1, qubit2);
+ CNOT(qubit2, qubit1);
+ CNOT(qubit1, qubit2);
+ }
+ adjoint self;
+ }
+}
\ No newline at end of file
diff --git a/src/Simulation/TargetDefinitions/Decompositions/SetToBasisState.qs b/src/Simulation/TargetDefinitions/Decompositions/SetToBasisState.qs
new file mode 100644
index 00000000000..ff7ec846edf
--- /dev/null
+++ b/src/Simulation/TargetDefinitions/Decompositions/SetToBasisState.qs
@@ -0,0 +1,25 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.Quantum.Measurement {
+ open Microsoft.Quantum.Intrinsic;
+
+ /// # Summary
+ /// Sets a qubit to a given computational basis state by measuring the
+ /// qubit and applying a bit flip if needed.
+ ///
+ /// # Input
+ /// ## desired
+ /// The basis state that the qubit should be set to.
+ /// ## target
+ /// The qubit whose state is to be set.
+ ///
+ /// # Remarks
+ /// As an invariant of this operation, calling `M(q)` immediately
+ /// after `SetToBasisState(result, q)` will return `result`.
+ operation SetToBasisState(desired : Result, target : Qubit) : Unit {
+ if (desired != M(target)) {
+ X(target);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Simulation/TargetDefinitions/Intrinsic/Exp.qs b/src/Simulation/TargetDefinitions/Intrinsic/Exp.qs
new file mode 100644
index 00000000000..0d008f67b25
--- /dev/null
+++ b/src/Simulation/TargetDefinitions/Intrinsic/Exp.qs
@@ -0,0 +1,27 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.Quantum.Intrinsic {
+ /// # Summary
+ /// Applies the exponential of a multi-qubit Pauli operator.
+ ///
+ /// # Description
+ /// \begin{align}
+ /// e^{i \theta [P_0 \otimes P_1 \cdots P_{N-1}]},
+ /// \end{align}
+ /// where $P_i$ is the $i$th element of `paulis`, and where
+ /// $N = $`Length(paulis)`.
+ ///
+ /// # Input
+ /// ## paulis
+ /// Array of single-qubit Pauli values indicating the tensor product
+ /// factors on each qubit.
+ /// ## theta
+ /// Angle about the given multi-qubit Pauli operator by which the
+ /// target register is to be rotated.
+ /// ## qubits
+ /// Register to apply the given rotation to.
+ operation Exp (paulis : Pauli[], theta : Double, qubits : Qubit[]) : Unit is Adj + Ctl {
+ body intrinsic;
+ }
+}
\ No newline at end of file
diff --git a/src/Simulation/TargetDefinitions/Intrinsic/H.qs b/src/Simulation/TargetDefinitions/Intrinsic/H.qs
new file mode 100644
index 00000000000..25a12838d32
--- /dev/null
+++ b/src/Simulation/TargetDefinitions/Intrinsic/H.qs
@@ -0,0 +1,25 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.Quantum.Intrinsic {
+ /// # Summary
+ /// Applies the Hadamard transformation to a single qubit.
+ ///
+ /// # Description
+ /// \begin{align}
+ /// H \mathrel{:=}
+ /// \frac{1}{\sqrt{2}}
+ /// \begin{bmatrix}
+ /// 1 & 1 \\\\
+ /// 1 & -1
+ /// \end{bmatrix}.
+ /// \end{align}
+ ///
+ /// # Input
+ /// ## qubit
+ /// Qubit to which the gate should be applied.
+ operation H (qubit : Qubit) : Unit is Adj + Ctl {
+ body intrinsic;
+ adjoint self;
+ }
+}
\ No newline at end of file
diff --git a/src/Simulation/TargetDefinitions/Intrinsic/I.qs b/src/Simulation/TargetDefinitions/Intrinsic/I.qs
new file mode 100644
index 00000000000..57a0a1d3125
--- /dev/null
+++ b/src/Simulation/TargetDefinitions/Intrinsic/I.qs
@@ -0,0 +1,15 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.Quantum.Intrinsic {
+ /// # Summary
+ /// Performs the identity operation (no-op) on a single qubit.
+ ///
+ /// # Remarks
+ /// This is a no-op. It is provided for completeness and because
+ /// sometimes it is useful to call the identity in an algorithm or to pass it as a parameter.
+ operation I (target : Qubit) : Unit is Adj + Ctl {
+ body (...) { }
+ adjoint self;
+ }
+}
\ No newline at end of file
diff --git a/src/Simulation/TargetDefinitions/Intrinsic/Measure.qs b/src/Simulation/TargetDefinitions/Intrinsic/Measure.qs
new file mode 100644
index 00000000000..957726d85da
--- /dev/null
+++ b/src/Simulation/TargetDefinitions/Intrinsic/Measure.qs
@@ -0,0 +1,43 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.Quantum.Intrinsic {
+ /// # Summary
+ /// Performs a joint measurement of one or more qubits in the
+ /// specified Pauli bases.
+ ///
+ /// # Description
+ /// The output result is given by the distribution:
+ /// \begin{align}
+ /// \Pr(\texttt{Zero} | \ket{\psi}) =
+ /// \frac12 \braket{
+ /// \psi \mid|
+ /// \left(
+ /// \boldone + P_0 \otimes P_1 \otimes \cdots \otimes P_{N-1}
+ /// \right) \mid|
+ /// \psi
+ /// },
+ /// \end{align}
+ /// where $P_i$ is the $i$th element of `bases`, and where
+ /// $N = \texttt{Length}(\texttt{bases})$.
+ /// That is, measurement returns a `Result` $d$ such that the eigenvalue of the
+ /// observed measurement effect is $(-1)^d$.
+ ///
+ /// # Input
+ /// ## bases
+ /// Array of single-qubit Pauli values indicating the tensor product
+ /// factors on each qubit.
+ /// ## qubits
+ /// Register of qubits to be measured.
+ ///
+ /// # Output
+ /// `Zero` if the $+1$ eigenvalue is observed, and `One` if
+ /// the $-1$ eigenvalue is observed.
+ ///
+ /// # Remarks
+ /// If the basis array and qubit array are different lengths, then the
+ /// operation will fail.
+ operation Measure (bases : Pauli[], qubits : Qubit[]) : Result {
+ body intrinsic;
+ }
+}
\ No newline at end of file
diff --git a/src/Simulation/TargetDefinitions/Intrinsic/R.qs b/src/Simulation/TargetDefinitions/Intrinsic/R.qs
new file mode 100644
index 00000000000..ff64e63631b
--- /dev/null
+++ b/src/Simulation/TargetDefinitions/Intrinsic/R.qs
@@ -0,0 +1,30 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.Quantum.Intrinsic {
+ /// # Summary
+ /// Applies a rotation about the given Pauli axis.
+ ///
+ /// # Description
+ /// \begin{align}
+ /// R_{\mu}(\theta) \mathrel{:=}
+ /// e^{-i \theta \sigma_{\mu} / 2},
+ /// \end{align}
+ /// where $\mu \in \{I, X, Y, Z\}$.
+ ///
+ /// # Input
+ /// ## pauli
+ /// Pauli operator ($\mu$) to be exponentiated to form the rotation.
+ /// ## theta
+ /// Angle about which the qubit is to be rotated.
+ /// ## qubit
+ /// Qubit to which the gate should be applied.
+ ///
+ /// # Remarks
+ /// When called with `pauli = PauliI`, this operation applies
+ /// a *global phase*. This phase can be significant
+ /// when used with the `Controlled` functor.
+ operation R (pauli : Pauli, theta : Double, qubit : Qubit) : Unit is Adj + Ctl {
+ body intrinsic;
+ }
+}
\ No newline at end of file
diff --git a/src/Simulation/TargetDefinitions/Intrinsic/S.qs b/src/Simulation/TargetDefinitions/Intrinsic/S.qs
new file mode 100644
index 00000000000..e30b637d086
--- /dev/null
+++ b/src/Simulation/TargetDefinitions/Intrinsic/S.qs
@@ -0,0 +1,23 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.Quantum.Intrinsic {
+ /// # Summary
+ /// Applies the π/4 phase gate to a single qubit.
+ ///
+ /// # Description
+ /// \begin{align}
+ /// S \mathrel{:=}
+ /// \begin{bmatrix}
+ /// 1 & 0 \\\\
+ /// 0 & i
+ /// \end{bmatrix}.
+ /// \end{align}
+ ///
+ /// # Input
+ /// ## qubit
+ /// Qubit to which the gate should be applied.
+ operation S (qubit : Qubit) : Unit is Adj + Ctl {
+ body intrinsic;
+ }
+}
\ No newline at end of file
diff --git a/src/Simulation/TargetDefinitions/Intrinsic/T.qs b/src/Simulation/TargetDefinitions/Intrinsic/T.qs
new file mode 100644
index 00000000000..287ec3087bc
--- /dev/null
+++ b/src/Simulation/TargetDefinitions/Intrinsic/T.qs
@@ -0,0 +1,23 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.Quantum.Intrinsic {
+ /// # Summary
+ /// Applies the π/8 gate to a single qubit.
+ ///
+ /// # Description
+ /// \begin{align}
+ /// T \mathrel{:=}
+ /// \begin{bmatrix}
+ /// 1 & 0 \\\\
+ /// 0 & e^{i \pi / 4}
+ /// \end{bmatrix}.
+ /// \end{align}
+ ///
+ /// # Input
+ /// ## qubit
+ /// Qubit to which the gate should be applied.
+ operation T (qubit : Qubit) : Unit is Adj + Ctl {
+ body intrinsic;
+ }
+}
\ No newline at end of file
diff --git a/src/Simulation/TargetDefinitions/Intrinsic/X.qs b/src/Simulation/TargetDefinitions/Intrinsic/X.qs
new file mode 100644
index 00000000000..522592f537a
--- /dev/null
+++ b/src/Simulation/TargetDefinitions/Intrinsic/X.qs
@@ -0,0 +1,24 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.Quantum.Intrinsic {
+ /// # Summary
+ /// Applies the Pauli $X$ gate.
+ ///
+ /// # Description
+ /// \begin{align}
+ /// \sigma_x \mathrel{:=}
+ /// \begin{bmatrix}
+ /// 0 & 1 \\\\
+ /// 1 & 0
+ /// \end{bmatrix}.
+ /// \end{align}
+ ///
+ /// # Input
+ /// ## qubit
+ /// Qubit to which the gate should be applied.
+ operation X (qubit : Qubit) : Unit is Adj + Ctl {
+ body intrinsic;
+ adjoint self;
+ }
+}
\ No newline at end of file
diff --git a/src/Simulation/TargetDefinitions/Intrinsic/Y.qs b/src/Simulation/TargetDefinitions/Intrinsic/Y.qs
new file mode 100644
index 00000000000..91769077adc
--- /dev/null
+++ b/src/Simulation/TargetDefinitions/Intrinsic/Y.qs
@@ -0,0 +1,24 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.Quantum.Intrinsic {
+ /// # Summary
+ /// Applies the Pauli $Y$ gate.
+ ///
+ /// # Description
+ /// \begin{align}
+ /// \sigma_y \mathrel{:=}
+ /// \begin{bmatrix}
+ /// 0 & -i \\\\
+ /// i & 0
+ /// \end{bmatrix}.
+ /// \end{align}
+ ///
+ /// # Input
+ /// ## qubit
+ /// Qubit to which the gate should be applied.
+ operation Y (qubit : Qubit) : Unit is Adj + Ctl {
+ body intrinsic;
+ adjoint self;
+ }
+}
\ No newline at end of file
diff --git a/src/Simulation/TargetDefinitions/Intrinsic/Z.qs b/src/Simulation/TargetDefinitions/Intrinsic/Z.qs
new file mode 100644
index 00000000000..9d505596f15
--- /dev/null
+++ b/src/Simulation/TargetDefinitions/Intrinsic/Z.qs
@@ -0,0 +1,24 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.Quantum.Intrinsic {
+ /// # Summary
+ /// Applies the Pauli $Z$ gate.
+ ///
+ /// # Description
+ /// \begin{align}
+ /// \sigma_z \mathrel{:=}
+ /// \begin{bmatrix}
+ /// 1 & 0 \\\\
+ /// 0 & -1
+ /// \end{bmatrix}.
+ /// \end{align}
+ ///
+ /// # Input
+ /// ## qubit
+ /// Qubit to which the gate should be applied.
+ operation Z (qubit : Qubit) : Unit is Adj + Ctl {
+ body intrinsic;
+ adjoint self;
+ }
+}
\ No newline at end of file
diff --git a/src/Simulation/TargetDefinitions/TargetPackages/QsharpCore.Package.props b/src/Simulation/TargetDefinitions/TargetPackages/QsharpCore.Package.props
new file mode 100644
index 00000000000..06d5e3117ea
--- /dev/null
+++ b/src/Simulation/TargetDefinitions/TargetPackages/QsharpCore.Package.props
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+