Add explicit decomposition testing infrastructure (#987)

This change adds an explicit decomposition test infrastructure based off of `AssertOperationsEqualReferenced` and wrappers around the native simulator intrinsics as references. This allows for verification tests of decompositions against the simulator written directly in Q#.
This commit is contained in:
Stefan J. Wernli 2022-04-13 15:31:06 -07:00 коммит произвёл GitHub
Родитель ad38c5ed4f
Коммит 8d305b9345
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 370 добавлений и 0 удалений

Просмотреть файл

@ -121,6 +121,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests.Microsoft.Quantum.Aut
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MicrosoftSimulatorExe", "src\Simulation\Simulators.Tests\TestProjects\MicrosoftSimulatorExe\MicrosoftSimulatorExe.csproj", "{9C317A71-702B-4C5D-9D19-D9A28CD483A5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests.TargetDefinitions", "src\Simulation\TargetDefinitions\Tests\Tests.TargetDefinitions.csproj", "{E5CB56D0-EDB1-4E07-A304-E17041F67642}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -821,6 +823,22 @@ Global
{9C317A71-702B-4C5D-9D19-D9A28CD483A5}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{9C317A71-702B-4C5D-9D19-D9A28CD483A5}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{9C317A71-702B-4C5D-9D19-D9A28CD483A5}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
{E5CB56D0-EDB1-4E07-A304-E17041F67642}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E5CB56D0-EDB1-4E07-A304-E17041F67642}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E5CB56D0-EDB1-4E07-A304-E17041F67642}.Debug|x64.ActiveCfg = Debug|Any CPU
{E5CB56D0-EDB1-4E07-A304-E17041F67642}.Debug|x64.Build.0 = Debug|Any CPU
{E5CB56D0-EDB1-4E07-A304-E17041F67642}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
{E5CB56D0-EDB1-4E07-A304-E17041F67642}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
{E5CB56D0-EDB1-4E07-A304-E17041F67642}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{E5CB56D0-EDB1-4E07-A304-E17041F67642}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{E5CB56D0-EDB1-4E07-A304-E17041F67642}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E5CB56D0-EDB1-4E07-A304-E17041F67642}.Release|Any CPU.Build.0 = Release|Any CPU
{E5CB56D0-EDB1-4E07-A304-E17041F67642}.Release|x64.ActiveCfg = Release|Any CPU
{E5CB56D0-EDB1-4E07-A304-E17041F67642}.Release|x64.Build.0 = Release|Any CPU
{E5CB56D0-EDB1-4E07-A304-E17041F67642}.RelWithDebInfo|Any CPU.ActiveCfg = Debug|Any CPU
{E5CB56D0-EDB1-4E07-A304-E17041F67642}.RelWithDebInfo|Any CPU.Build.0 = Debug|Any CPU
{E5CB56D0-EDB1-4E07-A304-E17041F67642}.RelWithDebInfo|x64.ActiveCfg = Debug|Any CPU
{E5CB56D0-EDB1-4E07-A304-E17041F67642}.RelWithDebInfo|x64.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -878,6 +896,7 @@ Global
{4EBC65DF-3B5E-419B-8E26-3EEF0B5CD300} = {34D419E9-CCF1-4E48-9FA4-3AD4B86BEEB4}
{D23480EE-88FC-4DF2-86BD-1C5BDD6CD98C} = {34D419E9-CCF1-4E48-9FA4-3AD4B86BEEB4}
{9C317A71-702B-4C5D-9D19-D9A28CD483A5} = {09C842CB-930C-4C7D-AD5F-E30DE4A55820}
{E5CB56D0-EDB1-4E07-A304-E17041F67642} = {93409CC3-8DF9-45FA-AE21-16A19FDEF650}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {929C0464-86D8-4F70-8835-0A5EAF930821}

Просмотреть файл

@ -0,0 +1,202 @@
namespace DecompositionTests {
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Math;
open Microsoft.Quantum.Diagnostics;
// Note: These test cases run against only the sparse simulator for performance reasons. The
// highly entangled states are ideal for sparse state simulation, where full state simulation takes
// around 50x longer to run the same tests.
@Test("SparseSimulator")
operation VerifyH() : Unit {
VerifyUnitaryAndFunctors(H, Reference.H);
}
@Test("SparseSimulator")
operation VerifyS() : Unit {
VerifyUnitaryAndFunctors(S, Reference.S);
}
@Test("SparseSimulator")
operation VerifyT() : Unit {
VerifyUnitaryAndFunctors(T, Reference.T);
}
@Test("SparseSimulator")
operation VerifyX() : Unit {
VerifyUnitaryAndFunctors(X, Reference.X);
}
@Test("SparseSimulator")
operation VerifyY() : Unit {
VerifyUnitaryAndFunctors(Y, Reference.Y);
}
@Test("SparseSimulator")
operation VerifyZ() : Unit {
VerifyUnitaryAndFunctors(Z, Reference.Z);
}
@Test("SparseSimulator")
operation VerifyCNOT() : Unit {
VerifyUnitaryAndFunctors2(CNOT, (q0, q1) => Controlled Reference.X([q0], q1));
}
@Test("SparseSimulator")
operation VerifyCX() : Unit {
VerifyUnitaryAndFunctors2(CX, (q0, q1) => Controlled Reference.X([q0], q1));
}
@Test("SparseSimulator")
operation VerifyCY() : Unit {
VerifyUnitaryAndFunctors2(CY, (q0, q1) => Controlled Reference.Y([q0], q1));
}
@Test("SparseSimulator")
operation VerifyCZ() : Unit {
VerifyUnitaryAndFunctors2(CZ, (q0, q1) => Controlled Reference.Z([q0], q1));
}
@Test("SparseSimulator")
operation VerifyCCNOT() : Unit {
VerifyUnitaryAndFunctors3(CCNOT, (q0, q1, q2) => Controlled Reference.X([q0, q1], q2));
}
@Test("SparseSimulator")
operation VerifyRx() : Unit {
// Use an angle that doesn't have any symmetries as a stand-in for broader validation.
let angle = PI() / 7.0;
VerifyUnitaryAndFunctors(q => Rx(angle, q), q => Reference.R(PauliX, angle, q));
}
@Test("SparseSimulator")
operation VerifyRy() : Unit {
// Use an angle that doesn't have any symmetries as a stand-in for broader validation.
let angle = PI() / 7.0;
VerifyUnitaryAndFunctors(q => Ry(angle, q), q => Reference.R(PauliY, angle, q));
}
@Test("SparseSimulator")
operation VerifyRz() : Unit {
// Use an angle that doesn't have any symmetries as a stand-in for broader validation.
let angle = PI() / 7.0;
VerifyUnitaryAndFunctors(q => Rz(angle, q), q => Reference.R(PauliZ, angle, q));
}
@Test("SparseSimulator")
operation VerifyR() : Unit {
// Use an angle that doesn't have any symmetries as a stand-in for broader validation.
let angle = PI() / 7.0;
VerifyUnitaryAndFunctors(q => R(PauliX, angle, q), q => Reference.R(PauliX, angle, q));
VerifyUnitaryAndFunctors(q => R(PauliY, angle, q), q => Reference.R(PauliY, angle, q));
VerifyUnitaryAndFunctors(q => R(PauliZ, angle, q), q => Reference.R(PauliZ, angle, q));
VerifyUnitaryAndFunctors(q => R(PauliI, angle, q), q => Reference.R(PauliI, angle, q));
}
@Test("SparseSimulator")
operation VerifySWAP() : Unit {
VerifyUnitaryAndFunctors2(SWAP, Reference.SWAP);
}
internal operation VerifyUnitaryAndFunctors(unitary : Qubit => Unit is Adj + Ctl, reference : Qubit => Unit is Adj + Ctl) : Unit {
VerifyUnitary(unitary, reference);
VerifyUnitary(Adjoint unitary, Adjoint reference);
VerifyUnitary2((q0, q1) => Controlled unitary([q0], q1), (q0, q1) => Controlled reference([q0], q1));
VerifyUnitary2((q0, q1) => Controlled Adjoint unitary([q0], q1), (q0, q1) => Controlled Adjoint reference([q0], q1));
}
internal operation VerifyUnitaryAndFunctors2(unitary : (Qubit, Qubit) => Unit is Adj + Ctl, reference : (Qubit, Qubit) => Unit is Adj + Ctl) : Unit {
VerifyUnitary2(unitary, reference);
VerifyUnitary2(Adjoint unitary, Adjoint reference);
VerifyUnitary3((q0, q1, q2) => Controlled unitary([q0], (q1, q2)), (q0, q1, q2) => Controlled reference([q0], (q1, q2)));
VerifyUnitary3((q0, q1, q2) => Controlled Adjoint unitary([q0], (q1, q2)), (q0, q1, q2) => Controlled Adjoint reference([q0], (q1, q2)));
}
internal operation VerifyUnitaryAndFunctors3(unitary : (Qubit, Qubit, Qubit) => Unit is Adj + Ctl, reference : (Qubit, Qubit, Qubit) => Unit is Adj + Ctl) : Unit {
VerifyUnitary3(unitary, reference);
VerifyUnitary3(Adjoint unitary, Adjoint reference);
VerifyUnitary4((q0, q1, q2, q3) => Controlled unitary([q0], (q1, q2, q3)), (q0, q1, q2, q3) => Controlled reference([q0], (q1, q2, q3)));
VerifyUnitary4((q0, q1, q2, q3) => Controlled Adjoint unitary([q0], (q1, q2, q3)), (q0, q1, q2, q3) => Controlled Adjoint reference([q0], (q1, q2, q3)));
}
internal operation VerifyUnitary(unitary : Qubit => Unit is Adj + Ctl, reference : Qubit => Unit is Adj + Ctl) : Unit {
// Verify equality up to 8 controls.
Reference.AssertOperationsEqualReferenced(1, qs => unitary(qs[0]),
qs => reference(qs[0]));
Reference.AssertOperationsEqualReferenced(2, qs => Controlled unitary([qs[0]], qs[1]),
qs => Controlled reference([qs[0]], qs[1]));
Reference.AssertOperationsEqualReferenced(3, (qs => Controlled unitary([qs[0], qs[1]], qs[2])),
qs => Controlled reference([qs[0], qs[1]], qs[2]));
Reference.AssertOperationsEqualReferenced(4, qs => Controlled unitary([qs[0], qs[1], qs[2]], qs[3]),
qs => Controlled reference([qs[0], qs[1], qs[2]], qs[3]));
Reference.AssertOperationsEqualReferenced(5, qs => Controlled unitary([qs[0], qs[1], qs[2], qs[3]], qs[4]),
qs => Controlled reference([qs[0], qs[1], qs[2], qs[3]], qs[4]));
Reference.AssertOperationsEqualReferenced(6, qs => Controlled unitary([qs[0], qs[1], qs[2], qs[3], qs[4]], qs[5]),
qs => Controlled reference([qs[0], qs[1], qs[2], qs[3], qs[4]], qs[5]));
Reference.AssertOperationsEqualReferenced(7, qs => Controlled unitary([qs[0], qs[1], qs[2], qs[3], qs[4], qs[5]], qs[6]),
qs => Controlled reference([qs[0], qs[1], qs[2], qs[3], qs[4], qs[5]], qs[6]));
Reference.AssertOperationsEqualReferenced(8, qs => Controlled unitary([qs[0], qs[1], qs[2], qs[3], qs[4], qs[5], qs[6]], qs[7]),
qs => Controlled reference([qs[0], qs[1], qs[2], qs[3], qs[4], qs[5], qs[6]], qs[7]));
}
internal operation VerifyUnitary2(unitary : (Qubit, Qubit) => Unit is Adj + Ctl, reference : (Qubit, Qubit) => Unit is Adj + Ctl) : Unit {
// Verify equality up to 8 controls.
Reference.AssertOperationsEqualReferenced(2, qs => unitary(qs[0], qs[1]),
qs => reference(qs[0], qs[1]));
Reference.AssertOperationsEqualReferenced(3, qs => Controlled unitary([qs[0]], (qs[1], qs[2])),
qs => Controlled reference([qs[0]], (qs[1], qs[2])));
Reference.AssertOperationsEqualReferenced(4, qs => Controlled unitary([qs[0], qs[1]], (qs[2], qs[3])),
qs => Controlled reference([qs[0], qs[1]], (qs[2], qs[3])));
Reference.AssertOperationsEqualReferenced(5, qs => Controlled unitary([qs[0], qs[1], qs[2]], (qs[3], qs[4])),
qs => Controlled reference([qs[0], qs[1], qs[2]], (qs[3], qs[4])));
Reference.AssertOperationsEqualReferenced(6, qs => Controlled unitary([qs[0], qs[1], qs[2], qs[3]], (qs[4], qs[5])),
qs => Controlled reference([qs[0], qs[1], qs[2], qs[3]], (qs[4], qs[5])));
Reference.AssertOperationsEqualReferenced(7, qs => Controlled unitary([qs[0], qs[1], qs[2], qs[3], qs[4]], (qs[5], qs[6])),
qs => Controlled reference([qs[0], qs[1], qs[2], qs[3], qs[4]], (qs[5], qs[6])));
Reference.AssertOperationsEqualReferenced(8, qs => Controlled unitary([qs[0], qs[1], qs[2], qs[3], qs[4], qs[5]], (qs[6], qs[7])),
qs => Controlled reference([qs[0], qs[1], qs[2], qs[3], qs[4], qs[5]], (qs[6], qs[7])));
Reference.AssertOperationsEqualReferenced(9, qs => Controlled unitary([qs[0], qs[1], qs[2], qs[3], qs[4], qs[5], qs[6]], (qs[7], qs[8])),
qs => Controlled reference([qs[0], qs[1], qs[2], qs[3], qs[4], qs[5], qs[6]], (qs[7], qs[8])));
}
internal operation VerifyUnitary3(unitary : (Qubit, Qubit, Qubit) => Unit is Adj + Ctl, reference : (Qubit, Qubit, Qubit) => Unit is Adj + Ctl) : Unit {
// Verify equality up to 8 controls.
Reference.AssertOperationsEqualReferenced(3, qs => unitary(qs[0], qs[1], qs[2]),
qs => reference(qs[0], qs[1], qs[2]));
Reference.AssertOperationsEqualReferenced(4, qs => Controlled unitary([qs[0]], (qs[1], qs[2], qs[3])),
qs => Controlled reference([qs[0]], (qs[1], qs[2], qs[3])));
Reference.AssertOperationsEqualReferenced(5, qs => Controlled unitary([qs[0], qs[1]], (qs[2], qs[3], qs[4])),
qs => Controlled reference([qs[0], qs[1]], (qs[2], qs[3], qs[4])));
Reference.AssertOperationsEqualReferenced(6, qs => Controlled unitary([qs[0], qs[1], qs[2]], (qs[3], qs[4], qs[5])),
qs => Controlled reference([qs[0], qs[1], qs[2]], (qs[3], qs[4], qs[5])));
Reference.AssertOperationsEqualReferenced(7, qs => Controlled unitary([qs[0], qs[1], qs[2], qs[3]], (qs[4], qs[5], qs[6])),
qs => Controlled reference([qs[0], qs[1], qs[2], qs[3]], (qs[4], qs[5], qs[6])));
Reference.AssertOperationsEqualReferenced(8, qs => Controlled unitary([qs[0], qs[1], qs[2], qs[3], qs[4]], (qs[5], qs[6], qs[7])),
qs => Controlled reference([qs[0], qs[1], qs[2], qs[3], qs[4]], (qs[5], qs[6], qs[7])));
Reference.AssertOperationsEqualReferenced(9, qs => Controlled unitary([qs[0], qs[1], qs[2], qs[3], qs[4], qs[5]], (qs[6], qs[7], qs[8])),
qs => Controlled reference([qs[0], qs[1], qs[2], qs[3], qs[4], qs[5]], (qs[6], qs[7], qs[8])));
Reference.AssertOperationsEqualReferenced(10, qs => Controlled unitary([qs[0], qs[1], qs[2], qs[3], qs[4], qs[5], qs[6]], (qs[7], qs[8], qs[9])),
qs => Controlled reference([qs[0], qs[1], qs[2], qs[3], qs[4], qs[5], qs[6]], (qs[7], qs[8], qs[9])));
}
internal operation VerifyUnitary4(unitary : (Qubit, Qubit, Qubit, Qubit) => Unit is Adj + Ctl, reference : (Qubit, Qubit, Qubit, Qubit) => Unit is Adj + Ctl) : Unit {
// Verify equality up to 8 controls.
Reference.AssertOperationsEqualReferenced(4, qs => unitary(qs[0], qs[1], qs[2], qs[3]),
qs => reference(qs[0], qs[1], qs[2], qs[3]));
Reference.AssertOperationsEqualReferenced(5, qs => Controlled unitary([qs[0]], (qs[1], qs[2], qs[3], qs[4])),
qs => Controlled reference([qs[0]], (qs[1], qs[2], qs[3], qs[4])));
Reference.AssertOperationsEqualReferenced(6, qs => Controlled unitary([qs[0], qs[1]], (qs[2], qs[3], qs[4], qs[5])),
qs => Controlled reference([qs[0], qs[1]], (qs[2], qs[3], qs[4], qs[5])));
Reference.AssertOperationsEqualReferenced(7, qs => Controlled unitary([qs[0], qs[1], qs[2]], (qs[3], qs[4], qs[5], qs[6])),
qs => Controlled reference([qs[0], qs[1], qs[2]], (qs[3], qs[4], qs[5], qs[6])));
Reference.AssertOperationsEqualReferenced(8, qs => Controlled unitary([qs[0], qs[1], qs[2], qs[3]], (qs[4], qs[5], qs[6], qs[7])),
qs => Controlled reference([qs[0], qs[1], qs[2], qs[3]], (qs[4], qs[5], qs[6], qs[7])));
Reference.AssertOperationsEqualReferenced(9, qs => Controlled unitary([qs[0], qs[1], qs[2], qs[3], qs[4]], (qs[5], qs[6], qs[7], qs[8])),
qs => Controlled reference([qs[0], qs[1], qs[2], qs[3], qs[4]], (qs[5], qs[6], qs[7], qs[8])));
Reference.AssertOperationsEqualReferenced(10, qs => Controlled unitary([qs[0], qs[1], qs[2], qs[3], qs[4], qs[5]], (qs[6], qs[7], qs[8], qs[9])),
qs => Controlled reference([qs[0], qs[1], qs[2], qs[3], qs[4], qs[5]], (qs[6], qs[7], qs[8], qs[9])));
Reference.AssertOperationsEqualReferenced(11, qs => Controlled unitary([qs[0], qs[1], qs[2], qs[3], qs[4], qs[5], qs[6]], (qs[7], qs[8], qs[9], qs[10])),
qs => Controlled reference([qs[0], qs[1], qs[2], qs[3], qs[4], qs[5], qs[6]], (qs[7], qs[8], qs[9], qs[10])));
}
}

Просмотреть файл

@ -0,0 +1,84 @@
namespace Reference {
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Diagnostics;
// These intrinsic operations will get generated into concrete C# wrappers over the same
// interfaces as those implemented by the full state simulator, allowing them to be used
// as references for validating alternate decompositions.
operation H(qubit : Qubit) : Unit is Adj + Ctl {
body intrinsic;
adjoint self;
}
operation S(qubit : Qubit) : Unit is Adj + Ctl {
body intrinsic;
}
operation T(qubit : Qubit) : Unit is Adj + Ctl {
body intrinsic;
}
operation X(qubit : Qubit) : Unit is Adj + Ctl {
body intrinsic;
adjoint self;
}
operation Y(qubit : Qubit) : Unit is Adj + Ctl {
body intrinsic;
adjoint self;
}
operation Z(qubit : Qubit) : Unit is Adj + Ctl {
body intrinsic;
adjoint self;
}
operation R(pauli : Pauli, theta : Double, qubit : Qubit) : Unit is Adj + Ctl {
body intrinsic;
}
operation Reset(qubit : Qubit) : Unit {
body intrinsic;
}
// Use the trivial decomposition of SWAP to emulate an intrinsic SWAP on the simulator.
operation SWAP(qubit1 : Qubit, qubit2 : Qubit) : Unit is Adj + Ctl {
Controlled X([qubit1], qubit2);
Controlled X([qubit2], qubit1);
Controlled X([qubit1], qubit2);
}
// The following operations are reproduced here to ensure that `AssertOperationsEqualReferenced`
// uses these reference implementations for preparation and evaluation instead of the decompositions
// under test.
internal operation ResetAll (qubits : Qubit[]) : Unit {
for qubit in qubits {
Reset(qubit);
}
}
internal operation PrepareEntangledState (left : Qubit[], right : Qubit[]) : Unit
is Adj + Ctl {
for idxQubit in 0 .. Length(left) - 1
{
H(left[idxQubit]);
Controlled X([left[idxQubit]], right[idxQubit]);
}
}
operation AssertOperationsEqualReferenced (nQubits : Int, actual : (Qubit[] => Unit), expected : (Qubit[] => Unit is Adj)) : Unit {
// Prepare a reference register entangled with the target register.
use (reference, target) = (Qubit[nQubits], Qubit[nQubits]) {
PrepareEntangledState(reference, target);
actual(target);
Adjoint expected(target);
Adjoint PrepareEntangledState(reference, target);
AssertAllZero(reference + target);
ResetAll(target);
ResetAll(reference);
}
}
}

Просмотреть файл

@ -0,0 +1,65 @@
<Project Sdk="Microsoft.Quantum.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<IsPackable>false</IsPackable>
<!-- we will provide our own -->
<IncludeQSharpCorePackages>false</IncludeQSharpCorePackages>
<IncludeCSharpRuntime>false</IncludeCSharpRuntime>
<GenerateConcreteIntrinsic>true</GenerateConcreteIntrinsic>
</PropertyGroup>
<ItemGroup>
<QsharpCompile Include="..\Intrinsic\ApplyControlledX.qs" />
<QsharpCompile Include="..\Intrinsic\ApplyControlledZ.qs" />
<QsharpCompile Include="..\Intrinsic\ApplyUncontrolledH.qs" />
<QsharpCompile Include="..\Intrinsic\ApplyUncontrolledRx.qs" />
<QsharpCompile Include="..\Intrinsic\ApplyUncontrolledRy.qs" />
<QsharpCompile Include="..\Intrinsic\ApplyUncontrolledRz.qs" />
<QsharpCompile Include="..\Intrinsic\ApplyUncontrolledS.qs" />
<QsharpCompile Include="..\Intrinsic\ApplyUncontrolledSAdj.qs" />
<QsharpCompile Include="..\Intrinsic\ApplyUncontrolledSWAP.qs" />
<QsharpCompile Include="..\Intrinsic\ApplyUncontrolledT.qs" />
<QsharpCompile Include="..\Intrinsic\ApplyUncontrolledTAdj.qs" />
<QsharpCompile Include="..\Intrinsic\ApplyUncontrolledX.qs" />
<QsharpCompile Include="..\Intrinsic\ApplyUncontrolledY.qs" />
<QsharpCompile Include="..\Intrinsic\ApplyUncontrolledZ.qs" />
</ItemGroup>
<ItemGroup>
<QsharpCompile Include="..\Decompositions\CCNOTFromCCZ.qs" />
<QsharpCompile Include="..\Decompositions\CNOTFromSinglyControlled.qs" />
<QSharpCompile Include="..\Decompositions\CX.qs" />
<QSharpCompile Include="..\Decompositions\CYFromCNOT.qs" />
<QSharpCompile Include="..\Decompositions\CZFromSinglyControlled.qs" />
<QsharpCompile Include="..\Decompositions\HFromSinglyControlled.qs" />
<QsharpCompile Include="..\Decompositions\R.qs" />
<QsharpCompile Include="..\Decompositions\R1.qs" />
<QsharpCompile Include="..\Decompositions\R1Frac.qs" />
<QsharpCompile Include="..\Decompositions\RFrac.qs" />
<QsharpCompile Include="..\Decompositions\RxFromSinglyControlled.qs" />
<QsharpCompile Include="..\Decompositions\RyFromSinglyControlled.qs" />
<QsharpCompile Include="..\Decompositions\RzFromSinglyControlled.qs" />
<QsharpCompile Include="..\Decompositions\SFromSinglyControlled.qs" />
<QsharpCompile Include="..\Decompositions\SWAPFromSinglyControlled.qs" />
<QsharpCompile Include="..\Decompositions\TFromSinglyControlled.qs" />
<QsharpCompile Include="..\Decompositions\XFromSinglyControlled.qs" />
<QsharpCompile Include="..\Decompositions\YFromSinglyControlled.qs" />
<QsharpCompile Include="..\Decompositions\ZFromSinglyControlled.qs" />
<QsharpCompile Include="..\Decompositions\Utils.qs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Simulators\Microsoft.Quantum.Simulators.csproj" />
<ProjectReference Include="..\..\QSharpFoundation\Microsoft.Quantum.QSharp.Foundation.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
</ItemGroup>
</Project>