qsharp-lang 1.12.2-dev → 1.12.4-dev
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/compiler/compiler.d.ts +6 -4
- package/dist/compiler/compiler.js +7 -2
- package/dist/katas-content.generated.js +92 -1
- package/dist/katas-content.generated.md.js +92 -1
- package/dist/samples.generated.js +1 -1
- package/dist/workers/browser.js +1 -1
- package/docs/Microsoft.Quantum.Core/Length.md +1 -1
- package/docs/Microsoft.Quantum.Core/Repeated.md +1 -1
- package/docs/Microsoft.Quantum.Core/index.md +1 -1
- package/docs/Std.Arithmetic/AddLE.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfEqualL.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfEqualLE.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfGreaterL.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfGreaterLE.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfGreaterOrEqualL.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfGreaterOrEqualLE.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfLessL.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfLessLE.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfLessOrEqualL.md +1 -1
- package/docs/Std.Arithmetic/ApplyIfLessOrEqualLE.md +1 -1
- package/docs/Std.Arithmetic/FourierTDIncByLE.md +1 -1
- package/docs/Std.Arithmetic/IncByI.md +1 -1
- package/docs/Std.Arithmetic/IncByIUsingIncByLE.md +1 -1
- package/docs/Std.Arithmetic/IncByL.md +1 -1
- package/docs/Std.Arithmetic/IncByLE.md +1 -1
- package/docs/Std.Arithmetic/IncByLEUsingAddLE.md +1 -1
- package/docs/Std.Arithmetic/IncByLUsingIncByLE.md +1 -1
- package/docs/Std.Arithmetic/LookAheadDKRSAddLE.md +1 -1
- package/docs/Std.Arithmetic/MAJ.md +1 -1
- package/docs/Std.Arithmetic/ReflectAboutInteger.md +1 -1
- package/docs/Std.Arithmetic/RippleCarryCGAddLE.md +1 -1
- package/docs/Std.Arithmetic/RippleCarryCGIncByLE.md +1 -1
- package/docs/Std.Arithmetic/RippleCarryTTKIncByLE.md +1 -1
- package/docs/Std.Arithmetic/index.md +1 -1
- package/docs/Std.Arrays/All.md +1 -1
- package/docs/Std.Arrays/Any.md +1 -1
- package/docs/Std.Arrays/Chunks.md +1 -1
- package/docs/Std.Arrays/CircularlyShifted.md +1 -1
- package/docs/Std.Arrays/ColumnAt.md +1 -1
- package/docs/Std.Arrays/Count.md +1 -1
- package/docs/Std.Arrays/Diagonal.md +1 -1
- package/docs/Std.Arrays/DrawMany.md +1 -1
- package/docs/Std.Arrays/Enumerated.md +1 -1
- package/docs/Std.Arrays/Excluding.md +1 -1
- package/docs/Std.Arrays/Filtered.md +1 -1
- package/docs/Std.Arrays/FlatMapped.md +1 -1
- package/docs/Std.Arrays/Flattened.md +1 -1
- package/docs/Std.Arrays/Fold.md +1 -1
- package/docs/Std.Arrays/ForEach.md +1 -1
- package/docs/Std.Arrays/Head.md +1 -1
- package/docs/Std.Arrays/HeadAndRest.md +1 -1
- package/docs/Std.Arrays/IndexOf.md +1 -1
- package/docs/Std.Arrays/IndexRange.md +1 -1
- package/docs/Std.Arrays/Interleaved.md +1 -1
- package/docs/Std.Arrays/IsEmpty.md +1 -1
- package/docs/Std.Arrays/IsRectangularArray.md +1 -1
- package/docs/Std.Arrays/IsSorted.md +1 -1
- package/docs/Std.Arrays/IsSquareArray.md +1 -1
- package/docs/Std.Arrays/Mapped.md +1 -1
- package/docs/Std.Arrays/MappedByIndex.md +1 -1
- package/docs/Std.Arrays/MappedOverRange.md +1 -1
- package/docs/Std.Arrays/Most.md +1 -1
- package/docs/Std.Arrays/MostAndTail.md +1 -1
- package/docs/Std.Arrays/Padded.md +1 -1
- package/docs/Std.Arrays/Partitioned.md +1 -1
- package/docs/Std.Arrays/Rest.md +1 -1
- package/docs/Std.Arrays/Reversed.md +1 -1
- package/docs/Std.Arrays/SequenceI.md +1 -1
- package/docs/Std.Arrays/SequenceL.md +1 -1
- package/docs/Std.Arrays/Sorted.md +1 -1
- package/docs/Std.Arrays/Subarray.md +1 -1
- package/docs/Std.Arrays/Swapped.md +1 -1
- package/docs/Std.Arrays/Tail.md +1 -1
- package/docs/Std.Arrays/Transposed.md +1 -1
- package/docs/Std.Arrays/Unzipped.md +1 -1
- package/docs/Std.Arrays/Where.md +1 -1
- package/docs/Std.Arrays/Windows.md +1 -1
- package/docs/Std.Arrays/Zipped.md +1 -1
- package/docs/Std.Arrays/index.md +1 -1
- package/docs/Std.Canon/ApplyCNOTChain.md +1 -1
- package/docs/Std.Canon/ApplyControlledOnBitString.md +1 -1
- package/docs/Std.Canon/ApplyControlledOnInt.md +1 -1
- package/docs/Std.Canon/ApplyP.md +1 -1
- package/docs/Std.Canon/ApplyPauli.md +1 -1
- package/docs/Std.Canon/ApplyPauliFromBitString.md +1 -1
- package/docs/Std.Canon/ApplyPauliFromInt.md +1 -1
- package/docs/Std.Canon/ApplyQFT.md +1 -1
- package/docs/Std.Canon/ApplyToEach.md +1 -1
- package/docs/Std.Canon/ApplyToEachA.md +1 -1
- package/docs/Std.Canon/ApplyToEachC.md +1 -1
- package/docs/Std.Canon/ApplyToEachCA.md +1 -1
- package/docs/Std.Canon/ApplyXorInPlace.md +1 -1
- package/docs/Std.Canon/ApplyXorInPlaceL.md +1 -1
- package/docs/Std.Canon/CX.md +1 -1
- package/docs/Std.Canon/CY.md +1 -1
- package/docs/Std.Canon/CZ.md +1 -1
- package/docs/Std.Canon/Fst.md +1 -1
- package/docs/Std.Canon/Relabel.md +1 -1
- package/docs/Std.Canon/Snd.md +1 -1
- package/docs/Std.Canon/SwapReverseRegister.md +1 -1
- package/docs/Std.Canon/index.md +1 -1
- package/docs/Std.Convert/BigIntAsBoolArray.md +1 -1
- package/docs/Std.Convert/BoolArrayAsBigInt.md +1 -1
- package/docs/Std.Convert/BoolArrayAsInt.md +1 -1
- package/docs/Std.Convert/BoolArrayAsResultArray.md +1 -1
- package/docs/Std.Convert/BoolAsResult.md +1 -1
- package/docs/Std.Convert/ComplexAsComplexPolar.md +1 -1
- package/docs/Std.Convert/ComplexPolarAsComplex.md +1 -1
- package/docs/Std.Convert/DoubleAsStringWithPrecision.md +1 -1
- package/docs/Std.Convert/IntAsBigInt.md +1 -1
- package/docs/Std.Convert/IntAsBoolArray.md +1 -1
- package/docs/Std.Convert/IntAsDouble.md +1 -1
- package/docs/Std.Convert/ResultArrayAsBoolArray.md +1 -1
- package/docs/Std.Convert/ResultArrayAsInt.md +1 -1
- package/docs/Std.Convert/ResultAsBool.md +1 -1
- package/docs/Std.Convert/index.md +1 -1
- package/docs/Std.Core/Length.md +1 -1
- package/docs/Std.Core/Repeated.md +1 -1
- package/docs/Std.Core/index.md +1 -1
- package/docs/Std.Diagnostics/ApplyIdleNoise.md +1 -1
- package/docs/Std.Diagnostics/BitFlipNoise.md +1 -1
- package/docs/Std.Diagnostics/CheckAllZero.md +1 -1
- package/docs/Std.Diagnostics/CheckOperationsAreEqual.md +1 -1
- package/docs/Std.Diagnostics/CheckZero.md +1 -1
- package/docs/Std.Diagnostics/ConfigurePauliNoise.md +1 -1
- package/docs/Std.Diagnostics/DepolarizingNoise.md +1 -1
- package/docs/Std.Diagnostics/DumpMachine.md +1 -1
- package/docs/Std.Diagnostics/DumpOperation.md +1 -1
- package/docs/Std.Diagnostics/DumpRegister.md +1 -1
- package/docs/Std.Diagnostics/Fact.md +1 -1
- package/docs/Std.Diagnostics/NoNoise.md +1 -1
- package/docs/Std.Diagnostics/PhaseFlipNoise.md +1 -1
- package/docs/Std.Diagnostics/StartCountingFunction.md +1 -1
- package/docs/Std.Diagnostics/StartCountingOperation.md +1 -1
- package/docs/Std.Diagnostics/StartCountingQubits.md +1 -1
- package/docs/Std.Diagnostics/StopCountingFunction.md +1 -1
- package/docs/Std.Diagnostics/StopCountingOperation.md +1 -1
- package/docs/Std.Diagnostics/StopCountingQubits.md +1 -1
- package/docs/Std.Diagnostics/index.md +1 -1
- package/docs/Std.Intrinsic/AND.md +1 -1
- package/docs/Std.Intrinsic/ApplyUnitary.md +1 -1
- package/docs/Std.Intrinsic/CCNOT.md +1 -1
- package/docs/Std.Intrinsic/CNOT.md +1 -1
- package/docs/Std.Intrinsic/Exp.md +1 -1
- package/docs/Std.Intrinsic/H.md +1 -1
- package/docs/Std.Intrinsic/I.md +1 -1
- package/docs/Std.Intrinsic/M.md +1 -1
- package/docs/Std.Intrinsic/Measure.md +1 -1
- package/docs/Std.Intrinsic/Message.md +1 -1
- package/docs/Std.Intrinsic/R.md +1 -1
- package/docs/Std.Intrinsic/R1.md +1 -1
- package/docs/Std.Intrinsic/R1Frac.md +1 -1
- package/docs/Std.Intrinsic/RFrac.md +1 -1
- package/docs/Std.Intrinsic/Reset.md +1 -1
- package/docs/Std.Intrinsic/ResetAll.md +1 -1
- package/docs/Std.Intrinsic/Rx.md +1 -1
- package/docs/Std.Intrinsic/Rxx.md +1 -1
- package/docs/Std.Intrinsic/Ry.md +1 -1
- package/docs/Std.Intrinsic/Ryy.md +1 -1
- package/docs/Std.Intrinsic/Rz.md +1 -1
- package/docs/Std.Intrinsic/Rzz.md +1 -1
- package/docs/Std.Intrinsic/S.md +1 -1
- package/docs/Std.Intrinsic/SWAP.md +1 -1
- package/docs/Std.Intrinsic/T.md +1 -1
- package/docs/Std.Intrinsic/X.md +1 -1
- package/docs/Std.Intrinsic/Y.md +1 -1
- package/docs/Std.Intrinsic/Z.md +1 -1
- package/docs/Std.Intrinsic/index.md +1 -1
- package/docs/Std.Logical/Xor.md +1 -1
- package/docs/Std.Logical/index.md +1 -1
- package/docs/Std.Math/AbsComplex.md +1 -1
- package/docs/Std.Math/AbsComplexPolar.md +1 -1
- package/docs/Std.Math/AbsD.md +1 -1
- package/docs/Std.Math/AbsI.md +1 -1
- package/docs/Std.Math/AbsL.md +1 -1
- package/docs/Std.Math/AbsSquaredComplex.md +1 -1
- package/docs/Std.Math/AbsSquaredComplexPolar.md +1 -1
- package/docs/Std.Math/ApproximateFactorial.md +1 -1
- package/docs/Std.Math/ArcCos.md +1 -1
- package/docs/Std.Math/ArcCosh.md +1 -1
- package/docs/Std.Math/ArcSin.md +1 -1
- package/docs/Std.Math/ArcSinh.md +1 -1
- package/docs/Std.Math/ArcTan.md +1 -1
- package/docs/Std.Math/ArcTan2.md +1 -1
- package/docs/Std.Math/ArcTanh.md +1 -1
- package/docs/Std.Math/ArgComplex.md +1 -1
- package/docs/Std.Math/ArgComplexPolar.md +1 -1
- package/docs/Std.Math/Binom.md +1 -1
- package/docs/Std.Math/BitSizeI.md +1 -1
- package/docs/Std.Math/BitSizeL.md +1 -1
- package/docs/Std.Math/Ceiling.md +1 -1
- package/docs/Std.Math/Complex.md +1 -1
- package/docs/Std.Math/ComplexPolar.md +1 -1
- package/docs/Std.Math/ContinuedFractionConvergentI.md +1 -1
- package/docs/Std.Math/ContinuedFractionConvergentL.md +1 -1
- package/docs/Std.Math/Cos.md +1 -1
- package/docs/Std.Math/Cosh.md +1 -1
- package/docs/Std.Math/DivRemI.md +1 -1
- package/docs/Std.Math/DivRemL.md +1 -1
- package/docs/Std.Math/DividedByC.md +1 -1
- package/docs/Std.Math/DividedByCP.md +1 -1
- package/docs/Std.Math/E.md +1 -1
- package/docs/Std.Math/ExpModI.md +1 -1
- package/docs/Std.Math/ExpModL.md +1 -1
- package/docs/Std.Math/ExtendedGreatestCommonDivisorI.md +1 -1
- package/docs/Std.Math/ExtendedGreatestCommonDivisorL.md +1 -1
- package/docs/Std.Math/FactorialI.md +1 -1
- package/docs/Std.Math/FactorialL.md +1 -1
- package/docs/Std.Math/Floor.md +1 -1
- package/docs/Std.Math/GreatestCommonDivisorI.md +1 -1
- package/docs/Std.Math/GreatestCommonDivisorL.md +1 -1
- package/docs/Std.Math/HammingWeightI.md +1 -1
- package/docs/Std.Math/InverseModI.md +1 -1
- package/docs/Std.Math/InverseModL.md +1 -1
- package/docs/Std.Math/IsCoprimeI.md +1 -1
- package/docs/Std.Math/IsCoprimeL.md +1 -1
- package/docs/Std.Math/IsInfinite.md +1 -1
- package/docs/Std.Math/IsNaN.md +1 -1
- package/docs/Std.Math/LargestFixedPoint.md +1 -1
- package/docs/Std.Math/Lg.md +1 -1
- package/docs/Std.Math/Log.md +1 -1
- package/docs/Std.Math/Log10.md +1 -1
- package/docs/Std.Math/LogFactorialD.md +1 -1
- package/docs/Std.Math/LogGammaD.md +1 -1
- package/docs/Std.Math/LogOf2.md +1 -1
- package/docs/Std.Math/Max.md +1 -1
- package/docs/Std.Math/MaxD.md +1 -1
- package/docs/Std.Math/MaxI.md +1 -1
- package/docs/Std.Math/MaxL.md +1 -1
- package/docs/Std.Math/Min.md +1 -1
- package/docs/Std.Math/MinD.md +1 -1
- package/docs/Std.Math/MinI.md +1 -1
- package/docs/Std.Math/MinL.md +1 -1
- package/docs/Std.Math/MinusC.md +1 -1
- package/docs/Std.Math/MinusCP.md +1 -1
- package/docs/Std.Math/ModulusI.md +1 -1
- package/docs/Std.Math/ModulusL.md +1 -1
- package/docs/Std.Math/NegationC.md +1 -1
- package/docs/Std.Math/NegationCP.md +1 -1
- package/docs/Std.Math/PI.md +1 -1
- package/docs/Std.Math/PNorm.md +1 -1
- package/docs/Std.Math/PNormalized.md +1 -1
- package/docs/Std.Math/PlusC.md +1 -1
- package/docs/Std.Math/PlusCP.md +1 -1
- package/docs/Std.Math/PowC.md +1 -1
- package/docs/Std.Math/PowCP.md +1 -1
- package/docs/Std.Math/RealMod.md +1 -1
- package/docs/Std.Math/Round.md +1 -1
- package/docs/Std.Math/SignD.md +1 -1
- package/docs/Std.Math/SignI.md +1 -1
- package/docs/Std.Math/SignL.md +1 -1
- package/docs/Std.Math/Sin.md +1 -1
- package/docs/Std.Math/Sinh.md +1 -1
- package/docs/Std.Math/SmallestFixedPoint.md +1 -1
- package/docs/Std.Math/Sqrt.md +1 -1
- package/docs/Std.Math/SquaredNorm.md +1 -1
- package/docs/Std.Math/Tan.md +1 -1
- package/docs/Std.Math/Tanh.md +1 -1
- package/docs/Std.Math/TimesC.md +1 -1
- package/docs/Std.Math/TimesCP.md +1 -1
- package/docs/Std.Math/TrailingZeroCountI.md +1 -1
- package/docs/Std.Math/TrailingZeroCountL.md +1 -1
- package/docs/Std.Math/Truncate.md +1 -1
- package/docs/Std.Math/index.md +1 -1
- package/docs/Std.Measurement/MResetEachZ.md +1 -1
- package/docs/Std.Measurement/MResetX.md +1 -1
- package/docs/Std.Measurement/MResetY.md +1 -1
- package/docs/Std.Measurement/MResetZ.md +1 -1
- package/docs/Std.Measurement/MeasureAllZ.md +1 -1
- package/docs/Std.Measurement/MeasureEachZ.md +1 -1
- package/docs/Std.Measurement/MeasureInteger.md +1 -1
- package/docs/Std.Measurement/index.md +1 -1
- package/docs/Std.Random/DrawRandomBool.md +1 -1
- package/docs/Std.Random/DrawRandomDouble.md +1 -1
- package/docs/Std.Random/DrawRandomInt.md +1 -1
- package/docs/Std.Random/index.md +1 -1
- package/docs/Std.Range/IsRangeEmpty.md +1 -1
- package/docs/Std.Range/RangeEnd.md +1 -1
- package/docs/Std.Range/RangeReverse.md +1 -1
- package/docs/Std.Range/RangeStart.md +1 -1
- package/docs/Std.Range/RangeStep.md +1 -1
- package/docs/Std.Range/index.md +1 -1
- package/docs/Std.ResourceEstimation/AccountForEstimates.md +1 -1
- package/docs/Std.ResourceEstimation/AuxQubitCount.md +1 -1
- package/docs/Std.ResourceEstimation/BeginEstimateCaching.md +1 -1
- package/docs/Std.ResourceEstimation/BeginRepeatEstimates.md +1 -1
- package/docs/Std.ResourceEstimation/CczCount.md +1 -1
- package/docs/Std.ResourceEstimation/EndEstimateCaching.md +1 -1
- package/docs/Std.ResourceEstimation/EndRepeatEstimates.md +1 -1
- package/docs/Std.ResourceEstimation/MeasurementCount.md +1 -1
- package/docs/Std.ResourceEstimation/PSSPCLayout.md +1 -1
- package/docs/Std.ResourceEstimation/RepeatEstimates.md +1 -1
- package/docs/Std.ResourceEstimation/RotationCount.md +1 -1
- package/docs/Std.ResourceEstimation/RotationDepth.md +1 -1
- package/docs/Std.ResourceEstimation/SingleVariant.md +1 -1
- package/docs/Std.ResourceEstimation/TCount.md +1 -1
- package/docs/Std.ResourceEstimation/index.md +1 -1
- package/docs/Std.StatePreparation/ApproximatelyPreparePureStateCP.md +1 -1
- package/docs/Std.StatePreparation/PreparePureStateD.md +1 -1
- package/docs/Std.StatePreparation/index.md +1 -1
- package/docs/Std.TableLookup/Select.md +1 -1
- package/docs/Std.TableLookup/index.md +1 -1
- package/docs/index.md +1 -1
- package/lib/node/qsc_wasm.cjs +559 -536
- package/lib/node/qsc_wasm.d.cts +16 -215
- package/lib/node/qsc_wasm_bg.wasm +0 -0
- package/lib/web/qsc_wasm.d.ts +20 -218
- package/lib/web/qsc_wasm.js +561 -532
- package/lib/web/qsc_wasm_bg.wasm +0 -0
- package/package.json +1 -1
- package/ux/circuit.tsx +4 -2
- package/ux/qsharp-ux.css +8 -5
|
@@ -5,8 +5,9 @@ import { IQscEventTarget, QscEventData } from "./events.js";
|
|
|
5
5
|
type Wasm = typeof import("../../lib/web/qsc_wasm.js");
|
|
6
6
|
export interface ICompiler {
|
|
7
7
|
checkCode(code: string): Promise<VSDiagnostic[]>;
|
|
8
|
-
getAst(code: string, languageFeatures
|
|
9
|
-
getHir(code: string, languageFeatures
|
|
8
|
+
getAst(code: string, languageFeatures: string[], profile: TargetProfile): Promise<string>;
|
|
9
|
+
getHir(code: string, languageFeatures: string[], profile: TargetProfile): Promise<string>;
|
|
10
|
+
getRir(program: ProgramConfig): Promise<string[]>;
|
|
10
11
|
run(program: ProgramConfig, expr: string, shots: number, eventHandler: IQscEventTarget): Promise<void>;
|
|
11
12
|
runWithPauliNoise(program: ProgramConfig, expr: string, shots: number, pauliNoise: number[], eventHandler: IQscEventTarget): Promise<void>;
|
|
12
13
|
getQir(program: ProgramConfig): Promise<string>;
|
|
@@ -23,7 +24,7 @@ export type ProgramConfig = ({
|
|
|
23
24
|
/** An array of source objects, each containing a name and contents. */
|
|
24
25
|
sources: [string, string][];
|
|
25
26
|
/** An array of language features to be opted in to in this compilation. */
|
|
26
|
-
languageFeatures
|
|
27
|
+
languageFeatures: string[];
|
|
27
28
|
} | {
|
|
28
29
|
/** Sources from all resolved dependencies, along with their languageFeatures configuration */
|
|
29
30
|
packageGraphSources: IPackageGraphSources;
|
|
@@ -37,8 +38,9 @@ export declare class Compiler implements ICompiler {
|
|
|
37
38
|
private wasm;
|
|
38
39
|
constructor(wasm: Wasm);
|
|
39
40
|
checkCode(code: string): Promise<VSDiagnostic[]>;
|
|
40
|
-
getAst(code: string, languageFeatures
|
|
41
|
+
getAst(code: string, languageFeatures: string[], profile: TargetProfile): Promise<string>;
|
|
41
42
|
getHir(code: string, languageFeatures: string[], profile: TargetProfile): Promise<string>;
|
|
43
|
+
getRir(program: ProgramConfig): Promise<string[]>;
|
|
42
44
|
run(program: ProgramConfig, expr: string, shots: number, eventHandler: IQscEventTarget): Promise<void>;
|
|
43
45
|
runWithPauliNoise(program: ProgramConfig, expr: string, shots: number, pauliNoise: number[], eventHandler: IQscEventTarget): Promise<void>;
|
|
44
46
|
getQir(program: ProgramConfig): Promise<string>;
|
|
@@ -32,10 +32,14 @@ export class Compiler {
|
|
|
32
32
|
return diags;
|
|
33
33
|
}
|
|
34
34
|
async getAst(code, languageFeatures, profile) {
|
|
35
|
-
return this.wasm.get_ast(code, languageFeatures
|
|
35
|
+
return this.wasm.get_ast(code, languageFeatures, profile);
|
|
36
36
|
}
|
|
37
37
|
async getHir(code, languageFeatures, profile) {
|
|
38
|
-
return this.wasm.get_hir(code, languageFeatures
|
|
38
|
+
return this.wasm.get_hir(code, languageFeatures, profile);
|
|
39
|
+
}
|
|
40
|
+
async getRir(program) {
|
|
41
|
+
const config = toWasmProgramConfig(program, program.profile || "adaptive_ri");
|
|
42
|
+
return this.wasm.get_rir(config);
|
|
39
43
|
}
|
|
40
44
|
async run(program, expr, shots, eventHandler) {
|
|
41
45
|
// All results are communicated as events, but if there is a compiler error (e.g. an invalid
|
|
@@ -133,6 +137,7 @@ export const compilerProtocol = {
|
|
|
133
137
|
checkCode: "request",
|
|
134
138
|
getAst: "request",
|
|
135
139
|
getHir: "request",
|
|
140
|
+
getRir: "request",
|
|
136
141
|
getQir: "request",
|
|
137
142
|
getEstimates: "request",
|
|
138
143
|
getCircuit: "request",
|
|
@@ -8721,7 +8721,7 @@ export default {
|
|
|
8721
8721
|
},
|
|
8722
8722
|
{
|
|
8723
8723
|
"type": "lesson",
|
|
8724
|
-
"id": "
|
|
8724
|
+
"id": "nonlocal_games__chsh_discussion",
|
|
8725
8725
|
"title": "Discussion: Probability of Victory for Quantum Strategy",
|
|
8726
8726
|
"items": [
|
|
8727
8727
|
{
|
|
@@ -8841,6 +8841,89 @@ export default {
|
|
|
8841
8841
|
]
|
|
8842
8842
|
}
|
|
8843
8843
|
},
|
|
8844
|
+
{
|
|
8845
|
+
"type": "exercise",
|
|
8846
|
+
"id": "nonlocal_games__ghz_create_entangled_state",
|
|
8847
|
+
"title": "Create Entangled Triple",
|
|
8848
|
+
"description": {
|
|
8849
|
+
"type": "text-content",
|
|
8850
|
+
"content": "<p>In the quantum version of the game, the players still can not communicate during the game, but they are allowed to share\nqubits from an entangled triple before the start of the game.</p>\n<p><strong>Input:</strong>\nAn array of three qubits in the $\\ket{000}$ state.</p>\n<p><strong>Goal:</strong>\nCreate the entangled state $\\ket{\\Phi} = \\frac{1}{2} \\big(\\ket{000} - \\ket{011} - \\ket{101} - \\ket{110} \\big)$ on these qubits.</p>\n<blockquote>\n<p>This state is equivalent to the three-qubit <a href=\"https://en.wikipedia.org/wiki/Greenberger%E2%80%93Horne%E2%80%93Zeilinger_state\">GHZ state</a>\n$$\\frac{1}{\\sqrt{2}} \\big(\\ket{000} + \\ket{111} \\big)$$\nup to local unitary operations. Please refer to the follow-up GHZ Quantum Strategy discussion for details.</p>\n</blockquote>\n"
|
|
8851
|
+
},
|
|
8852
|
+
"sourceIds": [
|
|
8853
|
+
"nonlocal_games__ghz_create_entangled_triple__Verification.qs",
|
|
8854
|
+
"KatasLibrary.qs"
|
|
8855
|
+
],
|
|
8856
|
+
"placeholderCode": "namespace Kata {\n operation CreateEntangledTriple (qs : Qubit[]) : Unit {\n // Implement your solution here...\n }\n}\n",
|
|
8857
|
+
"explainedSolution": {
|
|
8858
|
+
"type": "explained-solution",
|
|
8859
|
+
"items": [
|
|
8860
|
+
{
|
|
8861
|
+
"type": "text-content",
|
|
8862
|
+
"content": "<ol>\n<li>Apply an X gate to the first and the second qubits to get the $\\ket{110}$ state.</li>\n<li>Appy an H gate to the first and the second qubits to get the following state:\n$$\\frac12 \\big( \\ket{000} - \\ket{010} - \\ket{100} + \\ket{110} \\big)$$</li>\n<li>Flip the sign of the last term using a controlled Z gate with the first qubit as control and the second qubit as target (or vice versa):\n$$\\frac12 \\big( \\ket{000} - \\ket{010} - \\ket{100} -{\\color{blue}\\ket{110}} \\big)$$</li>\n<li>Now we have the right signs for each term, and the first and the last terms match those of the state we're preparing, so we just need to adjust the two middle terms.\nTo do this, we can use <a href=\"https://learn.microsoft.com/qsharp/api/qsharp-lang/microsoft.quantum.canon/applycontrolledonbitstring\">ControlledOnBitString</a> operation to flip the state of the last qubit if the first two qubits are in $\\ket{01}$ or in $\\ket{10}$ states, which gives us:\n$$\\frac{1}{2} \\big(\\ket{000} - {\\color{blue}\\ket{011}} - {\\color{blue}\\ket{101}} - \\ket{110} \\big)$$</li>\n</ol>\n"
|
|
8863
|
+
},
|
|
8864
|
+
{
|
|
8865
|
+
"type": "solution",
|
|
8866
|
+
"id": "nonlocal_games__ghz_create_entangled_triple_solution",
|
|
8867
|
+
"code": "namespace Kata {\n operation CreateEntangledTriple (qs : Qubit[]) : Unit is Adj {\n X(qs[0]);\n X(qs[1]);\n H(qs[0]);\n H(qs[1]);\n Controlled Z([qs[0]], qs[1]);\n ApplyControlledOnBitString([false, true], X, [qs[0], qs[1]], qs[2]);\n ApplyControlledOnBitString([true, false], X, [qs[0], qs[1]], qs[2]);\n }\n}\n"
|
|
8868
|
+
}
|
|
8869
|
+
]
|
|
8870
|
+
}
|
|
8871
|
+
},
|
|
8872
|
+
{
|
|
8873
|
+
"type": "exercise",
|
|
8874
|
+
"id": "nonlocal_games__ghz_quantum_strategy",
|
|
8875
|
+
"title": "Quantum Strategy",
|
|
8876
|
+
"description": {
|
|
8877
|
+
"type": "text-content",
|
|
8878
|
+
"content": "<p>In this task, you should implement three functions, one for each player's quantum strategy.\nNote that they are covered by one test, so you must implement all of them to pass the test.</p>\n<p><strong>Inputs:</strong></p>\n<ol>\n<li>The input bit for one of each of the players (R, S and T respectively),</li>\n<li>That player's qubit of the entangled triple shared between the players.</li>\n</ol>\n<p><strong>Goal:</strong>\nMeasure the qubit in the Z basis if the bit is 0 (FALSE), or the X basis if the bit is 1 (TRUE), and return the result.\nThe state of the qubit after the operation does not matter.</p>\n"
|
|
8879
|
+
},
|
|
8880
|
+
"sourceIds": [
|
|
8881
|
+
"nonlocal_games__ghz_quantum_strategy__Verification.qs",
|
|
8882
|
+
"KatasLibrary.qs"
|
|
8883
|
+
],
|
|
8884
|
+
"placeholderCode": "namespace Kata {\n operation AliceQuantum (bit : Bool, qubit : Qubit) : Bool {\n // Implement your solution here...\n\n return false;\n }\n\n operation BobQuantum (bit : Bool, qubit : Qubit) : Bool {\n // Implement your solution here...\n\n return false;\n }\n\n operation CharlieQuantum (bit : Bool, qubit : Qubit) : Bool {\n // Implement your solution here...\n\n return false;\n }\n}\n",
|
|
8885
|
+
"explainedSolution": {
|
|
8886
|
+
"type": "explained-solution",
|
|
8887
|
+
"items": [
|
|
8888
|
+
{
|
|
8889
|
+
"type": "text-content",
|
|
8890
|
+
"content": "<p>In Q#, you can perform measurements in a specific basis using either the\n<a href=\"https://learn.microsoft.com/qsharp/api/qsharp-lang/microsoft.quantum.intrinsic/measure\">Measure operation</a>\nor convenient shorthands for measure-and-reset-to-$\\ket{0}$ sequence of operations\n<a href=\"https://learn.microsoft.com/qsharp/api/qsharp-lang/microsoft.quantum.measurement/mresetz\">MResetZ</a> and\n<a href=\"https://learn.microsoft.com/qsharp/api/qsharp-lang/microsoft.quantum.measurement/mresetx\">MResetX</a>.</p>\n<p>Alternatively, you can recall that measuring the qubit in the X basis is equivalent to applying an H gate to it and measuring it in the Z basis.</p>\n"
|
|
8891
|
+
},
|
|
8892
|
+
{
|
|
8893
|
+
"type": "solution",
|
|
8894
|
+
"id": "nonlocal_games__ghz_quantum_strategy_solution",
|
|
8895
|
+
"code": "namespace Kata {\n operation AliceQuantum (bit : Bool, qubit : Qubit) : Bool {\n if bit {\n return MResetX(qubit) == One;\n }\n return MResetZ(qubit) == One;\n }\n\n operation BobQuantum (bit : Bool, qubit : Qubit) : Bool {\n if bit {\n return MResetX(qubit) == One;\n }\n return MResetZ(qubit) == One;\n }\n\n // alternative implementation\n operation CharlieQuantum (bit : Bool, qubit : Qubit) : Bool {\n if bit {\n H(qubit);\n } \n return M(qubit) == One;\n }\n}\n"
|
|
8896
|
+
}
|
|
8897
|
+
]
|
|
8898
|
+
}
|
|
8899
|
+
},
|
|
8900
|
+
{
|
|
8901
|
+
"type": "lesson",
|
|
8902
|
+
"id": "nonlocal_games__ghz_discussion",
|
|
8903
|
+
"title": "Discussion: Why the GHZ Quantum Strategy has a 100% Win Rate",
|
|
8904
|
+
"items": [
|
|
8905
|
+
{
|
|
8906
|
+
"type": "text-content",
|
|
8907
|
+
"content": "<hr />\n<p>Recall the formula for the win condition:</p>\n<ol>\n<li>The sum of the answer bits must be even if the question bits are (0,0,0)</li>\n<li>The sum of the answer bits must be odd if the question bits are (1,1,0), (1,0,1) or (0,1,1).</li>\n</ol>\n<blockquote>\n<p>As a reminder, the probability "wavefunction" for three qubits is given by the following vector of length 8:\n$$\\begin{bmatrix}\n\\psi_{000}\\\\\n\\psi_{001}\\\\\n\\psi_{010}\\\\\n\\psi_{011}\\\\\n\\psi_{100}\\\\\n\\psi_{101}\\\\\n\\psi_{110}\\\\\n\\psi_{111}\n\\end{bmatrix}$$\n$|\\psi_{ijk}|^2$ gives the probability of observing the corresponding basis state $\\ket{ijk}$ upon measuring the qubit trio.</p>\n</blockquote>\n<p>Now, the entangled state $\\ket{\\Phi}$ that Alice, Bob and Charlie have agreed to use is represented as</p>\n<p>$$\\begin{bmatrix}\n+1/2\\\\\n 0\\\\\n 0\\\\\n-1/2\\\\\n 0\\\\\n-1/2\\\\\n-1/2\\\\\n 0\n\\end{bmatrix}$$</p>\n<p>Let's first consider the case in which <strong>all three players got the 0 bit</strong>.</p>\n<p>When the players make their measurements, they will collectively get one of the basis states of the original state - 000, 011, 101 or 110.\nThis means they'll report back zero "1" bits between them (with $25\\%$ probability) or two "1" bits between them (with $75\\%$ probability),\neither way satisfying the win condition for the team.</p>\n<p>Now, suppose <strong>Alice gets a 0 bit and the others get 1</strong>.</p>\n<p>Alice, looking at the 0, takes a Z basis measurement as before, while Bob and Charlie each take X basis measurements.\n(An X basis measurement is also equivalent to performing a Hadamard transform followed by a standard Z basis measurement,\nas the X basis is the $\\ket{+}$ / $\\ket{-}$, and a Hadamard transform rotates the $\\ket{0}$ / $\\ket{1}$ basis to $\\ket{+}$ / $\\ket{-}$.)\nSo Bob and Charlie apply a Hadamard transform to their qubits, which corresponds to the following transformation applied to the whole system state:</p>\n<p>$$I \\otimes H \\otimes H = \\begin{bmatrix}\n1/2 & 1/2 & 1/2 & 1/2 & 0 & 0 & 0 & 0\\\\\n1/2 & -1/2 & 1/2 & -1/2 & 0 & 0 & 0 & 0\\\\\n1/2 & 1/2 & -1/2 & -1/2 & 0 & 0 & 0 & 0\\\\\n1/2 & -1/2 & -1/2 & 1/2 & 0 & 0 & 0 & 0\\\\\n0 & 0 & 0 & 0 & 1/2 & 1/2 & 1/2 & 1/2\\\\\n0 & 0 & 0 & 0 & 1/2 & -1/2 & 1/2 & -1/2\\\\\n0 & 0 & 0 & 0 & 1/2 & 1/2 & -1/2 & -1/2\\\\\n0 & 0 & 0 & 0 & 1/2 & -1/2 & -1/2 & 1/2\n\\end{bmatrix}$$</p>\n<p>When applied to the original entangled state, all the amplitude shifts to the states corresponding to $\\ket{001}$, $\\ket{010}$, $\\ket{100}$, and $\\ket{111}$.\nThe precise configuration of the new entangled state is</p>\n<p>$$\\begin{bmatrix}\n 0\\\\\n 1/2\\\\\n 1/2\\\\\n 0\\\\\n-1/2\\\\\n 0\\\\\n 0\\\\\n 1/2\n\\end{bmatrix}$$</p>\n<p>Now the players perform their measurements, and an odd number of them will see "1" (thanks to the new entangled state), again satisfying the win condition.\nSimilarly, if <strong>Alice and Charlie get "1" bits and Bob a "0"</strong>, Alice and Charlie will apply Hadamard transforms to their qubits to give the tensor product</p>\n<p>$$ H \\otimes I \\otimes H = \\begin{bmatrix}\n1/2 & 1/2 & 0 & 0 & 1/2 & 1/2 & 0 & 0\\\\\n1/2 & -1/2 & 0 & 0 & 1/2 & -1/2 & 0 & 0\\\\\n0 & 0 & 1/2 & 1/2 & 0 & 0 & 1/2 & 1/2\\\\\n0 & 0 & 1/2 & -1/2 & 0 & 0 & 1/2 & -1/2\\\\\n1/2 & 1/2 & 0 & 0 & -1/2 & -1/2 & 0 & 0\\\\\n1/2 & -1/2 & 0 & 0 & -1/2 & 1/2 & 0 & 0\\\\\n0 & 0 & 1/2 & 1/2 & 0 & 0 & -1/2 & -1/2\\\\\n0 & 0 & 1/2 & -1/2 & 0 & 0 & -1/2 & 1/2\n\\end{bmatrix}$$</p>\n<p>The resulting state vector before the measurement will be the same as in the previous case, except that the $\\ket{010}$ state\nends up with the negative amplitude instead of $\\ket{100}$. Again the players report back an odd number of true bits between them and the team wins.</p>\n<p>Finally if Charlie got the "0" bit and Alice and Bob both got "1", the latter two will apply Hadamard transform for the tensor product</p>\n<p>$$ H \\otimes H \\otimes I = \\begin{bmatrix}\n1/2 & 0 & 1/2 & 0 & 1/2 & 0 & 1/2 & 0\\\\\n0 & 1/2 & 0 & 1/2 & 0 & 1/2 & 0 & 1/2\\\\\n1/2 & 0 & -1/2 & 0 & 1/2 & 0 & -1/2 & 0\\\\\n0 & 1/2 & 0 & -1/2 & 0 & 1/2 & 0 & -1/2\\\\\n1/2 & 0 & 1/2 & 0 & -1/2 & 0 & -1/2 & 0\\\\\n0 & 1/2 & 0 & 1/2 & 0 & -1/2 & 0 & -1/2\\\\\n1/2 & 0 & -1/2 & 0 & -1/2 & 0 & 1/2 & 0\\\\\n0 & 1/2 & 0 & -1/2 & 0 & -1/2 & 0 & 1/2\n\\end{bmatrix}$$</p>\n<p>Operating with this on the original entangled state yields $(\\ket{100} + \\ket{010} - \\ket{001} + \\ket{111})/2$ and\nonce more the team will report back an odd number of true bits between them and win.</p>\n"
|
|
8908
|
+
}
|
|
8909
|
+
]
|
|
8910
|
+
},
|
|
8911
|
+
{
|
|
8912
|
+
"type": "lesson",
|
|
8913
|
+
"id": "nonlocal_games__ghz_e2e",
|
|
8914
|
+
"title": "Running GHZ Game End to End",
|
|
8915
|
+
"items": [
|
|
8916
|
+
{
|
|
8917
|
+
"type": "text-content",
|
|
8918
|
+
"content": "<p>Putting together the building blocks we've implemented into a strategy is very simple:</p>\n<ol>\n<li>Allocate three qubits and prepare our entangled state on them (using <code>CreateEntangledTriple</code>).</li>\n<li>Send one of the qubits to each of the players (this step is "virtual", not directly reflected in Q# code, other than making sure that the strategies each act on their qubit only).</li>\n<li>Have the players perform their measurements on their respective qubits using corresponding elements of the <code>strategies</code> array.</li>\n<li>Reset qubits to $\\ket{0}$ before they are released.</li>\n<li>Return their measurement results.</li>\n</ol>\n<p>In the example below you can compare winning percentage of classical and quantum games.</p>\n<blockquote>\n<p>You may play with the code and check if there is a difference in results when</p>\n<ol>\n<li>The referee picks non-random bits. How can the referee minimize player's win probability?</li>\n<li>Players get the <a href=\"https://en.wikipedia.org/wiki/Greenberger%E2%80%93Horne%E2%80%93Zeilinger_state\">GHZ state</a>.\nHow to change the quantum strategies to get $100\\%$ win rate?</li>\n</ol>\n</blockquote>\n"
|
|
8919
|
+
},
|
|
8920
|
+
{
|
|
8921
|
+
"type": "example",
|
|
8922
|
+
"id": "nonlocal_games__ghz_e2edemo",
|
|
8923
|
+
"code": "namespace Quantum.Kata.GHZGame {\n open Microsoft.Quantum.Random;\n open Microsoft.Quantum.Convert;\n\n function WinCondition (rst : Bool[], abc : Bool[]) : Bool {\n return (rst[0] or rst[1] or rst[2]) == (abc[0] != abc[1] != abc[2]);\n }\n\n function AliceClassical (r : Bool) : Bool {\n return true;\n }\n\n function BobClassical (s : Bool) : Bool {\n return true;\n }\n\n function CharlieClassical (t : Bool) : Bool {\n return true;\n }\n\n operation CreateEntangledTriple (qs : Qubit[]) : Unit is Adj {\n X(qs[0]);\n X(qs[1]);\n H(qs[0]);\n H(qs[1]);\n Controlled Z([qs[0]], qs[1]);\n ApplyControlledOnBitString([false, true], X, [qs[0], qs[1]], qs[2]);\n ApplyControlledOnBitString([true, false], X, [qs[0], qs[1]], qs[2]);\n }\n\n operation AliceQuantum (bit : Bool, qubit : Qubit) : Bool {\n if bit {\n return MResetX(qubit) == One;\n }\n return MResetZ(qubit) == One;\n }\n\n operation BobQuantum (bit : Bool, qubit : Qubit) : Bool {\n if bit {\n return MResetX(qubit) == One;\n }\n return MResetZ(qubit) == One;\n }\n\n operation CharlieQuantum (bit : Bool, qubit : Qubit) : Bool {\n if bit {\n return MResetX(qubit) == One;\n }\n return MResetZ(qubit) == One;\n }\n\n operation getRandomRefereeBits () : Bool[] {\n let bits = [[false, false, false],\n [true, true, false],\n [false, true, true],\n [true, false, true]];\n return bits[DrawRandomInt(0, 3)];\n }\n\n @EntryPoint()\n operation GHZ_GameDemo () : Unit {\n use (aliceQubit, bobQubit, charlieQubit) = (Qubit(), Qubit(), Qubit());\n mutable classicalWins = 0;\n mutable quantumWins = 0;\n let iterations = 1000;\n for _ in 1 .. iterations {\n CreateEntangledTriple([aliceQubit, bobQubit, charlieQubit]);\n let inputs = getRandomRefereeBits();\n let coutputs = [AliceClassical(inputs[0]), BobClassical(inputs[1]), CharlieClassical(inputs[2])];\n if WinCondition(inputs, coutputs) {\n set classicalWins += 1;\n }\n let qoutputs = [AliceQuantum(inputs[0], aliceQubit), BobQuantum(inputs[1], bobQubit), CharlieQuantum(inputs[2], charlieQubit)];\n if WinCondition(inputs, qoutputs) {\n set quantumWins += 1;\n }\n ResetAll([aliceQubit, bobQubit, charlieQubit]);\n }\n Message($\"Percentage of classical wins is {100.0*IntAsDouble(classicalWins)/IntAsDouble(iterations)}%\");\n Message($\"Percentage of quantum wins is {100.0*IntAsDouble(quantumWins)/IntAsDouble(iterations)}%\");\n }\n}\n"
|
|
8924
|
+
}
|
|
8925
|
+
]
|
|
8926
|
+
},
|
|
8844
8927
|
{
|
|
8845
8928
|
"type": "lesson",
|
|
8846
8929
|
"id": "nonlocal_games__conclusion",
|
|
@@ -9808,6 +9891,14 @@ export default {
|
|
|
9808
9891
|
{
|
|
9809
9892
|
"id": "nonlocal_games__ghz_classical_game__Verification.qs",
|
|
9810
9893
|
"code": "namespace Kata.Verification {\n\n // All possible starting bits (r, s and t) that the referee can give\n // to Alice, Bob and Charlie.\n function RefereeBits () : Bool[][] {\n return [[false, false, false],\n [true, true, false],\n [false, true, true],\n [true, false, true]];\n }\n\n operation TestStrategy (input : Bool, mode : Int) : Bool {\n return mode == 0 ? false | mode == 1 ? true | mode == 2 ? input | not input;\n }\n\n operation PlayClassicalGHZ_Reference (strategies : (Bool => Bool)[], inputs : Bool[]) : Bool[] {\n let r = inputs[0];\n let s = inputs[1];\n let t = inputs[2];\n let a = strategies[0](r);\n let b = strategies[1](s);\n let c = strategies[2](t);\n return [a, b, c];\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n let inputs = RefereeBits();\n for rst in inputs {\n // To test the interaction, run it on deterministic strategies (not necessarily good ones)\n // This logic helps to detect errors in user PlayClassicalGHZ implementation like\n // using the wrong sequence of output bits or not using the strategies at all. \n for mode_1 in 0 .. 3 {\n for mode_2 in 0 .. 3 {\n for mode_3 in 0 .. 3 {\n let strategies = [TestStrategy(_, mode_1), TestStrategy(_, mode_2), TestStrategy(_, mode_3)];\n let actual = Kata.PlayClassicalGHZ(strategies, rst);\n let expected = PlayClassicalGHZ_Reference(strategies, rst);\n if actual != expected {\n Message($\"Expected {expected}, got {actual} for {rst}\");\n return false;\n }\n }\n }\n }\n }\n Message(\"Correct!\");\n true\n }\n}\n"
|
|
9894
|
+
},
|
|
9895
|
+
{
|
|
9896
|
+
"id": "nonlocal_games__ghz_create_entangled_triple__Verification.qs",
|
|
9897
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Katas;\n\n operation CreateEntangledTriple_Reference (qs : Qubit[]) : Unit is Adj {\n X(qs[0]);\n X(qs[1]);\n H(qs[0]);\n H(qs[1]);\n Controlled Z([qs[0]], qs[1]);\n ApplyControlledOnBitString([false, true], X, [qs[0], qs[1]], qs[2]);\n ApplyControlledOnBitString([true, false], X, [qs[0], qs[1]], qs[2]);\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n CheckOperationsEquivalenceOnZeroStateWithFeedback(Kata.CreateEntangledTriple, CreateEntangledTriple_Reference, 3)\n }\n}\n"
|
|
9898
|
+
},
|
|
9899
|
+
{
|
|
9900
|
+
"id": "nonlocal_games__ghz_quantum_strategy__Verification.qs",
|
|
9901
|
+
"code": "namespace Kata.Verification {\n\n function WinCondition_Reference (rst : Bool[], abc : Bool[]) : Bool {\n return (rst[0] or rst[1] or rst[2]) == (abc[0] != abc[1] != abc[2]);\n }\n\n function RefereeBits () : Bool[][] {\n return [[false, false, false],\n [true, true, false],\n [false, true, true],\n [true, false, true]];\n }\n\n operation CreateEntangledTriple_Reference (qs : Qubit[]) : Unit is Adj {\n X(qs[0]);\n X(qs[1]);\n H(qs[0]);\n H(qs[1]);\n Controlled Z([qs[0]], qs[1]);\n ApplyControlledOnBitString([false, true], X, [qs[0], qs[1]], qs[2]);\n ApplyControlledOnBitString([true, false], X, [qs[0], qs[1]], qs[2]);\n }\n\n operation PlayQuantumGHZ_Reference (strategies : ((Bool, Qubit) => Bool)[], inputs : Bool[], qubits : Qubit[]) : Bool[] {\n let r = inputs[0];\n let s = inputs[1];\n let t = inputs[2];\n let a = strategies[0](r, qubits[0]);\n let b = strategies[1](s, qubits[1]);\n let c = strategies[2](t, qubits[2]);\n return [a, b, c];\n }\n\n @EntryPoint()\n operation CheckSolution () : Bool {\n use qs = Qubit[3];\n let inputs = RefereeBits();\n let strategies = [Kata.AliceQuantum, Kata.BobQuantum, Kata.CharlieQuantum];\n\n let iterations = 1000;\n mutable wins = 0;\n for _ in 1 .. iterations {\n for bits in inputs {\n CreateEntangledTriple_Reference(qs);\n let abc = PlayQuantumGHZ_Reference(strategies, bits, qs);\n if WinCondition_Reference(bits, abc) {\n set wins = wins + 1;\n }\n\t\tResetAll(qs);\n }\n }\n if wins < iterations*Length(inputs) {\n Message($\"Players' quantum strategies get {wins} wins out of {iterations*Length(inputs)} runs, which is not optimal\");\n return false;\n }\n Message(\"Correct!\");\n true\n }\n}\n"
|
|
9811
9902
|
}
|
|
9812
9903
|
]
|
|
9813
9904
|
};
|
|
@@ -8721,7 +8721,7 @@ export default {
|
|
|
8721
8721
|
},
|
|
8722
8722
|
{
|
|
8723
8723
|
"type": "lesson",
|
|
8724
|
-
"id": "
|
|
8724
|
+
"id": "nonlocal_games__chsh_discussion",
|
|
8725
8725
|
"title": "Discussion: Probability of Victory for Quantum Strategy",
|
|
8726
8726
|
"items": [
|
|
8727
8727
|
{
|
|
@@ -8841,6 +8841,89 @@ export default {
|
|
|
8841
8841
|
]
|
|
8842
8842
|
}
|
|
8843
8843
|
},
|
|
8844
|
+
{
|
|
8845
|
+
"type": "exercise",
|
|
8846
|
+
"id": "nonlocal_games__ghz_create_entangled_state",
|
|
8847
|
+
"title": "Create Entangled Triple",
|
|
8848
|
+
"description": {
|
|
8849
|
+
"type": "text-content",
|
|
8850
|
+
"content": "In the quantum version of the game, the players still can not communicate during the game, but they are allowed to share\nqubits from an entangled triple before the start of the game.\n\n**Input:**\nAn array of three qubits in the $\\ket{000}$ state.\n\n**Goal:**\nCreate the entangled state $\\ket{\\Phi} = \\frac{1}{2} \\big(\\ket{000} - \\ket{011} - \\ket{101} - \\ket{110} \\big)$ on these qubits.\n\n>This state is equivalent to the three-qubit [GHZ state](https://en.wikipedia.org/wiki/Greenberger%E2%80%93Horne%E2%80%93Zeilinger_state)\n>$$\\frac{1}{\\sqrt{2}} \\big(\\ket{000} + \\ket{111} \\big)$$\n>up to local unitary operations. Please refer to the follow-up GHZ Quantum Strategy discussion for details.\n"
|
|
8851
|
+
},
|
|
8852
|
+
"sourceIds": [
|
|
8853
|
+
"nonlocal_games__ghz_create_entangled_triple__Verification.qs",
|
|
8854
|
+
"KatasLibrary.qs"
|
|
8855
|
+
],
|
|
8856
|
+
"placeholderCode": "namespace Kata {\n operation CreateEntangledTriple (qs : Qubit[]) : Unit {\n // Implement your solution here...\n }\n}\n",
|
|
8857
|
+
"explainedSolution": {
|
|
8858
|
+
"type": "explained-solution",
|
|
8859
|
+
"items": [
|
|
8860
|
+
{
|
|
8861
|
+
"type": "text-content",
|
|
8862
|
+
"content": "\n1. Apply an X gate to the first and the second qubits to get the $\\ket{110}$ state.\n2. Appy an H gate to the first and the second qubits to get the following state:\n$$\\frac12 \\big( \\ket{000} - \\ket{010} - \\ket{100} + \\ket{110} \\big)$$\n3. Flip the sign of the last term using a controlled Z gate with the first qubit as control and the second qubit as target (or vice versa):\n$$\\frac12 \\big( \\ket{000} - \\ket{010} - \\ket{100} -{\\color{blue}\\ket{110}} \\big)$$\n4. Now we have the right signs for each term, and the first and the last terms match those of the state we're preparing, so we just need to adjust the two middle terms.\nTo do this, we can use [ControlledOnBitString](https://learn.microsoft.com/qsharp/api/qsharp-lang/microsoft.quantum.canon/applycontrolledonbitstring) operation to flip the state of the last qubit if the first two qubits are in $\\ket{01}$ or in $\\ket{10}$ states, which gives us:\n$$\\frac{1}{2} \\big(\\ket{000} - {\\color{blue}\\ket{011}} - {\\color{blue}\\ket{101}} - \\ket{110} \\big)$$"
|
|
8863
|
+
},
|
|
8864
|
+
{
|
|
8865
|
+
"type": "solution",
|
|
8866
|
+
"id": "nonlocal_games__ghz_create_entangled_triple_solution",
|
|
8867
|
+
"code": "namespace Kata {\n operation CreateEntangledTriple (qs : Qubit[]) : Unit is Adj {\n X(qs[0]);\n X(qs[1]);\n H(qs[0]);\n H(qs[1]);\n Controlled Z([qs[0]], qs[1]);\n ApplyControlledOnBitString([false, true], X, [qs[0], qs[1]], qs[2]);\n ApplyControlledOnBitString([true, false], X, [qs[0], qs[1]], qs[2]);\n }\n}\n"
|
|
8868
|
+
}
|
|
8869
|
+
]
|
|
8870
|
+
}
|
|
8871
|
+
},
|
|
8872
|
+
{
|
|
8873
|
+
"type": "exercise",
|
|
8874
|
+
"id": "nonlocal_games__ghz_quantum_strategy",
|
|
8875
|
+
"title": "Quantum Strategy",
|
|
8876
|
+
"description": {
|
|
8877
|
+
"type": "text-content",
|
|
8878
|
+
"content": "In this task, you should implement three functions, one for each player's quantum strategy.\nNote that they are covered by one test, so you must implement all of them to pass the test.\n\n**Inputs:**\n\n1. The input bit for one of each of the players (R, S and T respectively),\n2. That player's qubit of the entangled triple shared between the players.\n\n**Goal:**\nMeasure the qubit in the Z basis if the bit is 0 (FALSE), or the X basis if the bit is 1 (TRUE), and return the result.\nThe state of the qubit after the operation does not matter.\n"
|
|
8879
|
+
},
|
|
8880
|
+
"sourceIds": [
|
|
8881
|
+
"nonlocal_games__ghz_quantum_strategy__Verification.qs",
|
|
8882
|
+
"KatasLibrary.qs"
|
|
8883
|
+
],
|
|
8884
|
+
"placeholderCode": "namespace Kata {\n operation AliceQuantum (bit : Bool, qubit : Qubit) : Bool {\n // Implement your solution here...\n\n return false;\n }\n\n operation BobQuantum (bit : Bool, qubit : Qubit) : Bool {\n // Implement your solution here...\n\n return false;\n }\n\n operation CharlieQuantum (bit : Bool, qubit : Qubit) : Bool {\n // Implement your solution here...\n\n return false;\n }\n}\n",
|
|
8885
|
+
"explainedSolution": {
|
|
8886
|
+
"type": "explained-solution",
|
|
8887
|
+
"items": [
|
|
8888
|
+
{
|
|
8889
|
+
"type": "text-content",
|
|
8890
|
+
"content": "\nIn Q#, you can perform measurements in a specific basis using either the\n[Measure operation](https://learn.microsoft.com/qsharp/api/qsharp-lang/microsoft.quantum.intrinsic/measure)\nor convenient shorthands for measure-and-reset-to-$\\ket{0}$ sequence of operations\n[MResetZ](https://learn.microsoft.com/qsharp/api/qsharp-lang/microsoft.quantum.measurement/mresetz) and\n[MResetX](https://learn.microsoft.com/qsharp/api/qsharp-lang/microsoft.quantum.measurement/mresetx).\n\nAlternatively, you can recall that measuring the qubit in the X basis is equivalent to applying an H gate to it and measuring it in the Z basis."
|
|
8891
|
+
},
|
|
8892
|
+
{
|
|
8893
|
+
"type": "solution",
|
|
8894
|
+
"id": "nonlocal_games__ghz_quantum_strategy_solution",
|
|
8895
|
+
"code": "namespace Kata {\n operation AliceQuantum (bit : Bool, qubit : Qubit) : Bool {\n if bit {\n return MResetX(qubit) == One;\n }\n return MResetZ(qubit) == One;\n }\n\n operation BobQuantum (bit : Bool, qubit : Qubit) : Bool {\n if bit {\n return MResetX(qubit) == One;\n }\n return MResetZ(qubit) == One;\n }\n\n // alternative implementation\n operation CharlieQuantum (bit : Bool, qubit : Qubit) : Bool {\n if bit {\n H(qubit);\n } \n return M(qubit) == One;\n }\n}\n"
|
|
8896
|
+
}
|
|
8897
|
+
]
|
|
8898
|
+
}
|
|
8899
|
+
},
|
|
8900
|
+
{
|
|
8901
|
+
"type": "lesson",
|
|
8902
|
+
"id": "nonlocal_games__ghz_discussion",
|
|
8903
|
+
"title": "Discussion: Why the GHZ Quantum Strategy has a 100% Win Rate",
|
|
8904
|
+
"items": [
|
|
8905
|
+
{
|
|
8906
|
+
"type": "text-content",
|
|
8907
|
+
"content": "\n---------------------------------------------------------------\nRecall the formula for the win condition:\n1. The sum of the answer bits must be even if the question bits are (0,0,0)\n2. The sum of the answer bits must be odd if the question bits are (1,1,0), (1,0,1) or (0,1,1).\n\n> As a reminder, the probability \"wavefunction\" for three qubits is given by the following vector of length 8:\n> $$\\begin{bmatrix}\n\\psi_{000}\\\\\n\\psi_{001}\\\\\n\\psi_{010}\\\\\n\\psi_{011}\\\\\n\\psi_{100}\\\\\n\\psi_{101}\\\\\n\\psi_{110}\\\\\n\\psi_{111}\n\\end{bmatrix}$$\n> $|\\psi_{ijk}|^2$ gives the probability of observing the corresponding basis state $\\ket{ijk}$ upon measuring the qubit trio.\n\nNow, the entangled state $\\ket{\\Phi}$ that Alice, Bob and Charlie have agreed to use is represented as\n\n$$\\begin{bmatrix}\n+1/2\\\\\n 0\\\\\n 0\\\\\n-1/2\\\\\n 0\\\\\n-1/2\\\\\n-1/2\\\\\n 0\n\\end{bmatrix}$$\n\nLet's first consider the case in which **all three players got the 0 bit**.\n\nWhen the players make their measurements, they will collectively get one of the basis states of the original state - 000, 011, 101 or 110.\nThis means they'll report back zero \\\"1\\\" bits between them (with $25\\%$ probability) or two \\\"1\\\" bits between them (with $75\\%$ probability),\neither way satisfying the win condition for the team.\n\nNow, suppose **Alice gets a 0 bit and the others get 1**.\n\nAlice, looking at the 0, takes a Z basis measurement as before, while Bob and Charlie each take X basis measurements.\n(An X basis measurement is also equivalent to performing a Hadamard transform followed by a standard Z basis measurement,\nas the X basis is the $\\ket{+}$ / $\\ket{-}$, and a Hadamard transform rotates the $\\ket{0}$ / $\\ket{1}$ basis to $\\ket{+}$ / $\\ket{-}$.)\nSo Bob and Charlie apply a Hadamard transform to their qubits, which corresponds to the following transformation applied to the whole system state:\n\n$$I \\otimes H \\otimes H = \\begin{bmatrix}\n1/2 & 1/2 & 1/2 & 1/2 & 0 & 0 & 0 & 0\\\\\n1/2 & -1/2 & 1/2 & -1/2 & 0 & 0 & 0 & 0\\\\\n1/2 & 1/2 & -1/2 & -1/2 & 0 & 0 & 0 & 0\\\\\n1/2 & -1/2 & -1/2 & 1/2 & 0 & 0 & 0 & 0\\\\\n0 & 0 & 0 & 0 & 1/2 & 1/2 & 1/2 & 1/2\\\\\n0 & 0 & 0 & 0 & 1/2 & -1/2 & 1/2 & -1/2\\\\\n0 & 0 & 0 & 0 & 1/2 & 1/2 & -1/2 & -1/2\\\\\n0 & 0 & 0 & 0 & 1/2 & -1/2 & -1/2 & 1/2\n\\end{bmatrix}$$\n\nWhen applied to the original entangled state, all the amplitude shifts to the states corresponding to $\\ket{001}$, $\\ket{010}$, $\\ket{100}$, and $\\ket{111}$.\nThe precise configuration of the new entangled state is\n\n$$\\begin{bmatrix}\n 0\\\\\n 1/2\\\\\n 1/2\\\\\n 0\\\\\n-1/2\\\\\n 0\\\\\n 0\\\\\n 1/2\n\\end{bmatrix}$$\n\nNow the players perform their measurements, and an odd number of them will see \\\"1\\\" (thanks to the new entangled state), again satisfying the win condition.\nSimilarly, if **Alice and Charlie get \\\"1\\\" bits and Bob a \\\"0\\\"**, Alice and Charlie will apply Hadamard transforms to their qubits to give the tensor product\n\n$$ H \\otimes I \\otimes H = \\begin{bmatrix}\n1/2 & 1/2 & 0 & 0 & 1/2 & 1/2 & 0 & 0\\\\\n1/2 & -1/2 & 0 & 0 & 1/2 & -1/2 & 0 & 0\\\\\n0 & 0 & 1/2 & 1/2 & 0 & 0 & 1/2 & 1/2\\\\\n0 & 0 & 1/2 & -1/2 & 0 & 0 & 1/2 & -1/2\\\\\n1/2 & 1/2 & 0 & 0 & -1/2 & -1/2 & 0 & 0\\\\\n1/2 & -1/2 & 0 & 0 & -1/2 & 1/2 & 0 & 0\\\\\n0 & 0 & 1/2 & 1/2 & 0 & 0 & -1/2 & -1/2\\\\\n0 & 0 & 1/2 & -1/2 & 0 & 0 & -1/2 & 1/2\n\\end{bmatrix}$$\n\nThe resulting state vector before the measurement will be the same as in the previous case, except that the $\\ket{010}$ state\nends up with the negative amplitude instead of $\\ket{100}$. Again the players report back an odd number of true bits between them and the team wins.\n\nFinally if Charlie got the \\\"0\\\" bit and Alice and Bob both got \\\"1\\\", the latter two will apply Hadamard transform for the tensor product\n\n$$ H \\otimes H \\otimes I = \\begin{bmatrix}\n1/2 & 0 & 1/2 & 0 & 1/2 & 0 & 1/2 & 0\\\\\n0 & 1/2 & 0 & 1/2 & 0 & 1/2 & 0 & 1/2\\\\\n1/2 & 0 & -1/2 & 0 & 1/2 & 0 & -1/2 & 0\\\\\n0 & 1/2 & 0 & -1/2 & 0 & 1/2 & 0 & -1/2\\\\\n1/2 & 0 & 1/2 & 0 & -1/2 & 0 & -1/2 & 0\\\\\n0 & 1/2 & 0 & 1/2 & 0 & -1/2 & 0 & -1/2\\\\\n1/2 & 0 & -1/2 & 0 & -1/2 & 0 & 1/2 & 0\\\\\n0 & 1/2 & 0 & -1/2 & 0 & -1/2 & 0 & 1/2\n\\end{bmatrix}$$\n\nOperating with this on the original entangled state yields $(\\ket{100} + \\ket{010} - \\ket{001} + \\ket{111})/2$ and \nonce more the team will report back an odd number of true bits between them and win."
|
|
8908
|
+
}
|
|
8909
|
+
]
|
|
8910
|
+
},
|
|
8911
|
+
{
|
|
8912
|
+
"type": "lesson",
|
|
8913
|
+
"id": "nonlocal_games__ghz_e2e",
|
|
8914
|
+
"title": "Running GHZ Game End to End",
|
|
8915
|
+
"items": [
|
|
8916
|
+
{
|
|
8917
|
+
"type": "text-content",
|
|
8918
|
+
"content": "\nPutting together the building blocks we've implemented into a strategy is very simple:\n\n1. Allocate three qubits and prepare our entangled state on them (using `CreateEntangledTriple`).\n2. Send one of the qubits to each of the players (this step is \\\"virtual\\\", not directly reflected in Q# code, other than making sure that the strategies each act on their qubit only).\n3. Have the players perform their measurements on their respective qubits using corresponding elements of the `strategies` array.\n4. Reset qubits to $\\ket{0}$ before they are released.\n5. Return their measurement results.\n\nIn the example below you can compare winning percentage of classical and quantum games.\n\n>You may play with the code and check if there is a difference in results when\n>1. The referee picks non-random bits. How can the referee minimize player's win probability?\n>2. Players get the [GHZ state](https://en.wikipedia.org/wiki/Greenberger%E2%80%93Horne%E2%80%93Zeilinger_state).\n> How to change the quantum strategies to get $100\\%$ win rate?"
|
|
8919
|
+
},
|
|
8920
|
+
{
|
|
8921
|
+
"type": "example",
|
|
8922
|
+
"id": "nonlocal_games__ghz_e2edemo",
|
|
8923
|
+
"code": "namespace Quantum.Kata.GHZGame {\n open Microsoft.Quantum.Random;\n open Microsoft.Quantum.Convert;\n\n function WinCondition (rst : Bool[], abc : Bool[]) : Bool {\n return (rst[0] or rst[1] or rst[2]) == (abc[0] != abc[1] != abc[2]);\n }\n\n function AliceClassical (r : Bool) : Bool {\n return true;\n }\n\n function BobClassical (s : Bool) : Bool {\n return true;\n }\n\n function CharlieClassical (t : Bool) : Bool {\n return true;\n }\n\n operation CreateEntangledTriple (qs : Qubit[]) : Unit is Adj {\n X(qs[0]);\n X(qs[1]);\n H(qs[0]);\n H(qs[1]);\n Controlled Z([qs[0]], qs[1]);\n ApplyControlledOnBitString([false, true], X, [qs[0], qs[1]], qs[2]);\n ApplyControlledOnBitString([true, false], X, [qs[0], qs[1]], qs[2]);\n }\n\n operation AliceQuantum (bit : Bool, qubit : Qubit) : Bool {\n if bit {\n return MResetX(qubit) == One;\n }\n return MResetZ(qubit) == One;\n }\n\n operation BobQuantum (bit : Bool, qubit : Qubit) : Bool {\n if bit {\n return MResetX(qubit) == One;\n }\n return MResetZ(qubit) == One;\n }\n\n operation CharlieQuantum (bit : Bool, qubit : Qubit) : Bool {\n if bit {\n return MResetX(qubit) == One;\n }\n return MResetZ(qubit) == One;\n }\n\n operation getRandomRefereeBits () : Bool[] {\n let bits = [[false, false, false],\n [true, true, false],\n [false, true, true],\n [true, false, true]];\n return bits[DrawRandomInt(0, 3)];\n }\n\n @EntryPoint()\n operation GHZ_GameDemo () : Unit {\n use (aliceQubit, bobQubit, charlieQubit) = (Qubit(), Qubit(), Qubit());\n mutable classicalWins = 0;\n mutable quantumWins = 0;\n let iterations = 1000;\n for _ in 1 .. iterations {\n CreateEntangledTriple([aliceQubit, bobQubit, charlieQubit]);\n let inputs = getRandomRefereeBits();\n let coutputs = [AliceClassical(inputs[0]), BobClassical(inputs[1]), CharlieClassical(inputs[2])];\n if WinCondition(inputs, coutputs) {\n set classicalWins += 1;\n }\n let qoutputs = [AliceQuantum(inputs[0], aliceQubit), BobQuantum(inputs[1], bobQubit), CharlieQuantum(inputs[2], charlieQubit)];\n if WinCondition(inputs, qoutputs) {\n set quantumWins += 1;\n }\n ResetAll([aliceQubit, bobQubit, charlieQubit]);\n }\n Message($\"Percentage of classical wins is {100.0*IntAsDouble(classicalWins)/IntAsDouble(iterations)}%\");\n Message($\"Percentage of quantum wins is {100.0*IntAsDouble(quantumWins)/IntAsDouble(iterations)}%\");\n }\n}\n"
|
|
8924
|
+
}
|
|
8925
|
+
]
|
|
8926
|
+
},
|
|
8844
8927
|
{
|
|
8845
8928
|
"type": "lesson",
|
|
8846
8929
|
"id": "nonlocal_games__conclusion",
|
|
@@ -9808,6 +9891,14 @@ export default {
|
|
|
9808
9891
|
{
|
|
9809
9892
|
"id": "nonlocal_games__ghz_classical_game__Verification.qs",
|
|
9810
9893
|
"code": "namespace Kata.Verification {\n\n // All possible starting bits (r, s and t) that the referee can give\n // to Alice, Bob and Charlie.\n function RefereeBits () : Bool[][] {\n return [[false, false, false],\n [true, true, false],\n [false, true, true],\n [true, false, true]];\n }\n\n operation TestStrategy (input : Bool, mode : Int) : Bool {\n return mode == 0 ? false | mode == 1 ? true | mode == 2 ? input | not input;\n }\n\n operation PlayClassicalGHZ_Reference (strategies : (Bool => Bool)[], inputs : Bool[]) : Bool[] {\n let r = inputs[0];\n let s = inputs[1];\n let t = inputs[2];\n let a = strategies[0](r);\n let b = strategies[1](s);\n let c = strategies[2](t);\n return [a, b, c];\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n let inputs = RefereeBits();\n for rst in inputs {\n // To test the interaction, run it on deterministic strategies (not necessarily good ones)\n // This logic helps to detect errors in user PlayClassicalGHZ implementation like\n // using the wrong sequence of output bits or not using the strategies at all. \n for mode_1 in 0 .. 3 {\n for mode_2 in 0 .. 3 {\n for mode_3 in 0 .. 3 {\n let strategies = [TestStrategy(_, mode_1), TestStrategy(_, mode_2), TestStrategy(_, mode_3)];\n let actual = Kata.PlayClassicalGHZ(strategies, rst);\n let expected = PlayClassicalGHZ_Reference(strategies, rst);\n if actual != expected {\n Message($\"Expected {expected}, got {actual} for {rst}\");\n return false;\n }\n }\n }\n }\n }\n Message(\"Correct!\");\n true\n }\n}\n"
|
|
9894
|
+
},
|
|
9895
|
+
{
|
|
9896
|
+
"id": "nonlocal_games__ghz_create_entangled_triple__Verification.qs",
|
|
9897
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Katas;\n\n operation CreateEntangledTriple_Reference (qs : Qubit[]) : Unit is Adj {\n X(qs[0]);\n X(qs[1]);\n H(qs[0]);\n H(qs[1]);\n Controlled Z([qs[0]], qs[1]);\n ApplyControlledOnBitString([false, true], X, [qs[0], qs[1]], qs[2]);\n ApplyControlledOnBitString([true, false], X, [qs[0], qs[1]], qs[2]);\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n CheckOperationsEquivalenceOnZeroStateWithFeedback(Kata.CreateEntangledTriple, CreateEntangledTriple_Reference, 3)\n }\n}\n"
|
|
9898
|
+
},
|
|
9899
|
+
{
|
|
9900
|
+
"id": "nonlocal_games__ghz_quantum_strategy__Verification.qs",
|
|
9901
|
+
"code": "namespace Kata.Verification {\n\n function WinCondition_Reference (rst : Bool[], abc : Bool[]) : Bool {\n return (rst[0] or rst[1] or rst[2]) == (abc[0] != abc[1] != abc[2]);\n }\n\n function RefereeBits () : Bool[][] {\n return [[false, false, false],\n [true, true, false],\n [false, true, true],\n [true, false, true]];\n }\n\n operation CreateEntangledTriple_Reference (qs : Qubit[]) : Unit is Adj {\n X(qs[0]);\n X(qs[1]);\n H(qs[0]);\n H(qs[1]);\n Controlled Z([qs[0]], qs[1]);\n ApplyControlledOnBitString([false, true], X, [qs[0], qs[1]], qs[2]);\n ApplyControlledOnBitString([true, false], X, [qs[0], qs[1]], qs[2]);\n }\n\n operation PlayQuantumGHZ_Reference (strategies : ((Bool, Qubit) => Bool)[], inputs : Bool[], qubits : Qubit[]) : Bool[] {\n let r = inputs[0];\n let s = inputs[1];\n let t = inputs[2];\n let a = strategies[0](r, qubits[0]);\n let b = strategies[1](s, qubits[1]);\n let c = strategies[2](t, qubits[2]);\n return [a, b, c];\n }\n\n @EntryPoint()\n operation CheckSolution () : Bool {\n use qs = Qubit[3];\n let inputs = RefereeBits();\n let strategies = [Kata.AliceQuantum, Kata.BobQuantum, Kata.CharlieQuantum];\n\n let iterations = 1000;\n mutable wins = 0;\n for _ in 1 .. iterations {\n for bits in inputs {\n CreateEntangledTriple_Reference(qs);\n let abc = PlayQuantumGHZ_Reference(strategies, bits, qs);\n if WinCondition_Reference(bits, abc) {\n set wins = wins + 1;\n }\n\t\tResetAll(qs);\n }\n }\n if wins < iterations*Length(inputs) {\n Message($\"Players' quantum strategies get {wins} wins out of {iterations*Length(inputs)} runs, which is not optimal\");\n return false;\n }\n Message(\"Correct!\");\n true\n }\n}\n"
|
|
9811
9902
|
}
|
|
9812
9903
|
]
|
|
9813
9904
|
};
|
|
@@ -77,7 +77,7 @@ export default [
|
|
|
77
77
|
{
|
|
78
78
|
"title": "Shor",
|
|
79
79
|
"shots": 1,
|
|
80
|
-
"code": "/// # Sample\n/// Shor's Algorithm\n///\n/// # Description\n/// Shor's algorithm is a quantum algorithm for finding the prime factors of an\n/// integer.\n///\n/// This Q# program implements Shor's algorithm.\nimport Std.Convert.*;\nimport Std.Diagnostics.*;\nimport Std.Random.*;\nimport Std.Math.*;\nimport Std.Arithmetic.*;\nimport Std.Arrays.*;\n\noperation Main() : (Int, Int) {\n let n = 143; // 11*13;\n // You can try these other examples for a lengthier computation.\n // let n = 16837; // = 113*149\n // let n = 22499; // = 149*151\n\n // Use Shor's algorithm to factor a semiprime integer.\n let (a, b) = FactorSemiprimeInteger(n);\n Message($\"Found factorization {n} = {a} * {b}\");\n return (a, b);\n}\n\n/// # Summary\n/// Uses Shor's algorithm to factor an input number.\n///\n/// # Input\n/// ## number\n/// A semiprime integer to be factored.\n///\n/// # Output\n/// Pair of numbers p > 1 and q > 1 such that p⋅q = `number`\noperation FactorSemiprimeInteger(number : Int) : (Int, Int) {\n // First check the most trivial case (the provided number is even).\n if number % 2 == 0 {\n Message(\"An even number has been given; 2 is a factor.\");\n return (number / 2, 2);\n }\n // These mutables will keep track of whether we found the factors, and\n // if so, what they are. The default value for the factors is (1,1).\n mutable foundFactors = false;\n mutable factors = (1, 1);\n mutable attempt = 1;\n repeat {\n Message($\"*** Factorizing {number}, attempt {attempt}.\");\n // Try to guess a number co-prime to `number` by getting a random\n // integer in the interval [1, number-1]\n let generator = DrawRandomInt(1, number - 1);\n\n // Check if the random integer is indeed co-prime.\n // If true use Quantum algorithm for Period finding.\n if GreatestCommonDivisorI(generator, number) == 1 {\n Message($\"Estimating period of {generator}.\");\n\n // Call Quantum Period finding algorithm for\n // `generator` mod `number`.\n let period = EstimatePeriod(generator, number);\n\n // Set the flag and factors values if the continued\n // fractions classical algorithm succeeds.\n set (foundFactors, factors) = MaybeFactorsFromPeriod(number, generator, period);\n }\n // In this case, we guessed a divisor by accident.\n else {\n // Find divisor.\n let gcd = GreatestCommonDivisorI(number, generator);\n Message($\"We have guessed a divisor {gcd} by accident. \" + \"No quantum computation was done.\");\n\n // Set the flag `foundFactors` to true, indicating that we\n // succeeded in finding factors.\n set foundFactors = true;\n set factors = (gcd, number / gcd);\n }\n set attempt = attempt + 1;\n if (attempt > 100) {\n fail \"Failed to find factors: too many attempts!\";\n }\n } until foundFactors\n fixup {\n Message(\"The estimated period did not yield a valid factor. \" + \"Trying again.\");\n }\n\n // Return the factorization\n return factors;\n}\n\n/// # Summary\n/// Tries to find the factors of `modulus` given a `period` and `generator`.\n///\n/// # Input\n/// ## modulus\n/// The modulus which defines the residue ring Z mod `modulus` in which the\n/// multiplicative order of `generator` is being estimated.\n/// ## generator\n/// The unsigned integer multiplicative order (period) of which is being\n/// estimated. Must be co-prime to `modulus`.\n/// ## period\n/// The estimated period (multiplicative order) of the generator mod\n/// `modulus`.\n///\n/// # Output\n/// A tuple of a flag indicating whether factors were found successfully,\n/// and a pair of integers representing the factors that were found.\n/// Note that the second output is only meaningful when the first output is\n/// `true`.\nfunction MaybeFactorsFromPeriod(\n modulus : Int,\n generator : Int,\n period : Int\n) : (Bool, (Int, Int)) {\n\n // Period finding reduces to factoring only if period is even\n if period % 2 == 0 {\n // Compute `generator` ^ `period/2` mod `number`.\n let halfPower = ExpModI(generator, period / 2, modulus);\n\n // If we are unlucky, halfPower is just -1 mod N, which is a trivial\n // case and not useful for factoring.\n if halfPower != modulus - 1 {\n // When the halfPower is not -1 mod N, halfPower-1 or\n // halfPower+1 share non-trivial divisor with `number`. Find it.\n let factor = MaxI(\n GreatestCommonDivisorI(halfPower - 1, modulus),\n GreatestCommonDivisorI(halfPower + 1, modulus)\n );\n\n // Add a flag that we found the factors, and return only if computed\n // non-trivial factors (not like 1:n or n:1)\n if (factor != 1) and (factor != modulus) {\n Message($\"Found factor={factor}\");\n return (true, (factor, modulus / factor));\n }\n }\n // Return a flag indicating we hit a trivial case and didn't get\n // any factors.\n Message($\"Found trivial factors.\");\n return (false, (1, 1));\n } else {\n // When period is odd we have to pick another generator to estimate\n // period of and start over.\n Message($\"Estimated period {period} was odd, trying again.\");\n return (false, (1, 1));\n }\n}\n\n/// # Summary\n/// Find the period of a number from an input frequency.\n///\n/// # Input\n/// ## modulus\n/// The modulus which defines the residue ring Z mod `modulus` in which the\n/// multiplicative order of `generator` is being estimated.\n/// ## frequencyEstimate\n/// The frequency that we want to convert to a period.\n/// ## bitsPrecision\n/// Number of bits of precision with which we need to estimate s/r to\n/// recover period r using continued fractions algorithm.\n/// ## currentDivisor\n/// The divisor of the generator period found so far.\n///\n/// # Output\n/// The period as calculated from the estimated frequency via the continued\n/// fractions algorithm.\nfunction PeriodFromFrequency(\n modulus : Int,\n frequencyEstimate : Int,\n bitsPrecision : Int,\n currentDivisor : Int\n) : Int {\n // Now we use the ContinuedFractionConvergentI function to recover s/r\n // from dyadic fraction k/2^bitsPrecision.\n let (numerator, period) = ContinuedFractionConvergentI(\n (frequencyEstimate, 2^bitsPrecision),\n modulus\n );\n\n // ContinuedFractionConvergentI does not guarantee the signs of the\n // numerator and denominator. Here we make sure that both are positive\n // using AbsI.\n let (numeratorAbs, periodAbs) = (AbsI(numerator), AbsI(period));\n\n // Compute and return the newly found divisor.\n let period = (periodAbs * currentDivisor) / GreatestCommonDivisorI(currentDivisor, periodAbs);\n Message($\"Found period={period}\");\n return period;\n}\n\n/// # Summary\n/// Finds a multiplicative order of the generator in the residue ring Z mod\n/// `modulus`.\n///\n/// # Input\n/// ## generator\n/// The unsigned integer multiplicative order (period) of which is being\n/// estimated. Must be co-prime to `modulus`.\n/// ## modulus\n/// The modulus which defines the residue ring Z mod `modulus` in which the\n/// multiplicative order of `generator` is being estimated.\n///\n/// # Output\n/// The period (multiplicative order) of the generator mod `modulus`\noperation EstimatePeriod(generator : Int, modulus : Int) : Int {\n // Here we check that the inputs to the EstimatePeriod operation are\n // valid.\n Fact(\n GreatestCommonDivisorI(generator, modulus) == 1,\n \"`generator` and `modulus` must be co-prime\"\n );\n\n // Number of bits in the modulus with respect to which we are estimating\n // the period.\n let bitsize = BitSizeI(modulus);\n\n // The EstimatePeriod operation estimates the period r by finding an\n // approximation k/2^(bits precision) to a fraction s/r, where s is some\n // integer. Note that if s and r have common divisors we will end up\n // recovering a divisor of r and not r itself.\n\n // Number of bits of precision with which we need to estimate s/r to\n // recover period r, using continued fractions algorithm.\n let bitsPrecision = 2 * bitsize + 1;\n\n // Current estimate for the frequency of the form s/r.\n let frequencyEstimate = EstimateFrequency(generator, modulus, bitsize);\n if frequencyEstimate != 0 {\n return PeriodFromFrequency(\n modulus,\n frequencyEstimate,\n bitsPrecision,\n 1\n );\n } else {\n Message(\"The estimated frequency was 0, trying again.\");\n return 1;\n }\n}\n\n/// # Summary\n/// Estimates the frequency of a generator in the residue ring Z mod\n/// `modulus`.\n///\n/// # Input\n/// ## generator\n/// The unsigned integer multiplicative order (period) of which is being\n/// estimated. Must be co-prime to `modulus`.\n/// ## modulus\n/// The modulus which defines the residue ring Z mod `modulus` in which the\n/// multiplicative order of `generator` is being estimated.\n/// ## bitsize\n/// Number of bits needed to represent the modulus.\n///\n/// # Output\n/// The numerator k of dyadic fraction k/2^bitsPrecision approximating s/r.\noperation EstimateFrequency(generator : Int, modulus : Int, bitsize : Int) : Int {\n mutable frequencyEstimate = 0;\n let bitsPrecision = 2 * bitsize + 1;\n Message($\"Estimating frequency with bitsPrecision={bitsPrecision}.\");\n\n // Allocate qubits for the superposition of eigenstates of the oracle\n // that is used in period finding.\n use eigenstateRegister = Qubit[bitsize];\n\n // Initialize eigenstateRegister to 1, which is a superposition of the\n // eigenstates we are estimating the phases of.\n // We are interpreting the register as encoding an unsigned integer in\n // little-endian format.\n ApplyXorInPlace(1, eigenstateRegister);\n\n // Use phase estimation with a semiclassical Fourier transform to\n // estimate the frequency.\n use c = Qubit();\n for idx in bitsPrecision - 1..-1..0 {\n H(c);\n Controlled ApplyOrderFindingOracle(\n [c],\n (generator, modulus, 1 <<< idx, eigenstateRegister)\n );\n R1Frac(frequencyEstimate, bitsPrecision - 1 - idx, c);\n H(c);\n if M(c) == One {\n X(c); // Reset\n set frequencyEstimate += 1 <<< (bitsPrecision - 1 - idx);\n }\n }\n\n // Return all the qubits used for oracle's eigenstate back to 0 state\n // using ResetAll.\n ResetAll(eigenstateRegister);\n Message($\"Estimated frequency={frequencyEstimate}\");\n return frequencyEstimate;\n}\n\n/// # Summary\n/// Interprets `target` as encoding unsigned little-endian integer k\n/// and performs transformation |k⟩ ↦ |gᵖ⋅k mod N ⟩ where\n/// p is `power`, g is `generator` and N is `modulus`.\n///\n/// # Input\n/// ## generator\n/// The unsigned integer multiplicative order (period)\n/// of which is being estimated. Must be co-prime to `modulus`.\n/// ## modulus\n/// The modulus which defines the residue ring Z mod `modulus`\n/// in which the multiplicative order of `generator` is being estimated.\n/// ## power\n/// Power of `generator` by which `target` is multiplied.\n/// ## target\n/// Register interpreted as little-endian which is multiplied by\n/// given power of the generator. The multiplication is performed modulo\n/// `modulus`.\ninternal operation ApplyOrderFindingOracle(\n generator : Int,\n modulus : Int,\n power : Int,\n target : Qubit[]\n) : Unit is Adj + Ctl {\n // The oracle we use for order finding implements |x⟩ ↦ |x⋅a mod N⟩. We\n // also use `ExpModI` to compute a by which x must be multiplied. Also\n // note that we interpret target as unsigned integer in little-endian\n // format.\n ModularMultiplyByConstant(\n modulus,\n ExpModI(generator, power, modulus),\n target\n );\n}\n\n/// # Summary\n/// Performs modular in-place multiplication by a classical constant.\n///\n/// # Description\n/// Given the classical constants `c` and `modulus`, and an input quantum\n/// register |𝑦⟩ in little-endian format, this operation computes\n/// `(c*x) % modulus` into |𝑦⟩.\n///\n/// # Input\n/// ## modulus\n/// Modulus to use for modular multiplication\n/// ## c\n/// Constant by which to multiply |𝑦⟩\n/// ## y\n/// Quantum register of target\ninternal operation ModularMultiplyByConstant(modulus : Int, c : Int, y : Qubit[]) : Unit is Adj + Ctl {\n use qs = Qubit[Length(y)];\n for idx in IndexRange(y) {\n let shiftedC = (c <<< idx) % modulus;\n Controlled ModularAddConstant(\n [y[idx]],\n (modulus, shiftedC, qs)\n );\n }\n for idx in IndexRange(y) {\n SWAP(y[idx], qs[idx]);\n }\n let invC = InverseModI(c, modulus);\n for idx in IndexRange(y) {\n let shiftedC = (invC <<< idx) % modulus;\n Controlled ModularAddConstant(\n [y[idx]],\n (modulus, modulus - shiftedC, qs)\n );\n }\n}\n\n/// # Summary\n/// Performs modular in-place addition of a classical constant into a\n/// quantum register.\n///\n/// Given the classical constants `c` and `modulus`, and an input quantum\n/// register |𝑦⟩ in little-endian format, this operation computes\n/// `(x+c) % modulus` into |𝑦⟩.\n///\n/// # Input\n/// ## modulus\n/// Modulus to use for modular addition\n/// ## c\n/// Constant to add to |𝑦⟩\n/// ## y\n/// Quantum register of target\ninternal operation ModularAddConstant(modulus : Int, c : Int, y : Qubit[]) : Unit is Adj + Ctl {\n body (...) {\n Controlled ModularAddConstant([], (modulus, c, y));\n }\n controlled (ctrls, ...) {\n // We apply a custom strategy to control this operation instead of\n // letting the compiler create the controlled variant for us in\n // which the `Controlled` functor would be distributed over each\n // operation in the body.\n //\n // Here we can use some scratch memory to save ensure that at most\n // one control qubit is used for costly operations such as\n // `AddConstant` and `CompareGreaterThenOrEqualConstant`.\n if Length(ctrls) >= 2 {\n use control = Qubit();\n within {\n Controlled X(ctrls, control);\n } apply {\n Controlled ModularAddConstant([control], (modulus, c, y));\n }\n } else {\n use carry = Qubit();\n Controlled IncByI(ctrls, (c, y + [carry]));\n Controlled Adjoint IncByI(ctrls, (modulus, y + [carry]));\n Controlled IncByI([carry], (modulus, y));\n Controlled ApplyIfLessOrEqualL(ctrls, (X, IntAsBigInt(c), y, carry));\n }\n }\n}\n"
|
|
80
|
+
"code": "/// # Sample\n/// Shor's Algorithm\n///\n/// # Description\n/// Shor's algorithm is a quantum algorithm for finding the prime factors of an\n/// integer.\n///\n/// This Q# program implements Shor's algorithm.\nimport Std.Convert.*;\nimport Std.Diagnostics.*;\nimport Std.Random.*;\nimport Std.Math.*;\nimport Std.Arithmetic.*;\nimport Std.Arrays.*;\n\noperation Main() : (Int, Int) {\n let n = 187; // 11*17;\n // You can try these other examples for a lengthier computation.\n // let n = 16837; // = 113*149\n // let n = 22499; // = 149*151\n\n // Use Shor's algorithm to factor a semiprime integer.\n let (a, b) = FactorSemiprimeInteger(n);\n Message($\"Found factorization {n} = {a} * {b}\");\n return (a, b);\n}\n\n/// # Summary\n/// Uses Shor's algorithm to factor an input number.\n///\n/// # Input\n/// ## number\n/// A semiprime integer to be factored.\n///\n/// # Output\n/// Pair of numbers p > 1 and q > 1 such that p⋅q = `number`\noperation FactorSemiprimeInteger(number : Int) : (Int, Int) {\n // First check the most trivial case (the provided number is even).\n if number % 2 == 0 {\n Message(\"An even number has been given; 2 is a factor.\");\n return (number / 2, 2);\n }\n // These mutables will keep track of whether we found the factors, and\n // if so, what they are. The default value for the factors is (1,1).\n mutable foundFactors = false;\n mutable factors = (1, 1);\n mutable attempt = 1;\n repeat {\n Message($\"*** Factorizing {number}, attempt {attempt}.\");\n // Try to guess a number co-prime to `number` by getting a random\n // integer in the interval [1, number-1]\n let generator = DrawRandomInt(1, number - 1);\n\n // Check if the random integer is indeed co-prime.\n // If true use Quantum algorithm for Period finding.\n if GreatestCommonDivisorI(generator, number) == 1 {\n Message($\"Estimating period of {generator}.\");\n\n // Call Quantum Period finding algorithm for\n // `generator` mod `number`.\n let period = EstimatePeriod(generator, number);\n\n // Set the flag and factors values if the continued\n // fractions classical algorithm succeeds.\n set (foundFactors, factors) = MaybeFactorsFromPeriod(number, generator, period);\n }\n // In this case, we guessed a divisor by accident.\n else {\n // Find divisor.\n let gcd = GreatestCommonDivisorI(number, generator);\n Message($\"We have guessed a divisor {gcd} by accident. \" + \"No quantum computation was done.\");\n\n // Set the flag `foundFactors` to true, indicating that we\n // succeeded in finding factors.\n set foundFactors = true;\n set factors = (gcd, number / gcd);\n }\n set attempt = attempt + 1;\n if (attempt > 100) {\n fail \"Failed to find factors: too many attempts!\";\n }\n } until foundFactors\n fixup {\n Message(\"The estimated period did not yield a valid factor. \" + \"Trying again.\");\n }\n\n // Return the factorization\n return factors;\n}\n\n/// # Summary\n/// Tries to find the factors of `modulus` given a `period` and `generator`.\n///\n/// # Input\n/// ## modulus\n/// The modulus which defines the residue ring Z mod `modulus` in which the\n/// multiplicative order of `generator` is being estimated.\n/// ## generator\n/// The unsigned integer multiplicative order (period) of which is being\n/// estimated. Must be co-prime to `modulus`.\n/// ## period\n/// The estimated period (multiplicative order) of the generator mod\n/// `modulus`.\n///\n/// # Output\n/// A tuple of a flag indicating whether factors were found successfully,\n/// and a pair of integers representing the factors that were found.\n/// Note that the second output is only meaningful when the first output is\n/// `true`.\nfunction MaybeFactorsFromPeriod(\n modulus : Int,\n generator : Int,\n period : Int\n) : (Bool, (Int, Int)) {\n\n // Period finding reduces to factoring only if period is even\n if period % 2 == 0 {\n // Compute `generator` ^ `period/2` mod `number`.\n let halfPower = ExpModI(generator, period / 2, modulus);\n\n // If we are unlucky, halfPower is just -1 mod N, which is a trivial\n // case and not useful for factoring.\n if halfPower != modulus - 1 {\n // When the halfPower is not -1 mod N, halfPower-1 or\n // halfPower+1 share non-trivial divisor with `number`. Find it.\n let factor = MaxI(\n GreatestCommonDivisorI(halfPower - 1, modulus),\n GreatestCommonDivisorI(halfPower + 1, modulus)\n );\n\n // Add a flag that we found the factors, and return only if computed\n // non-trivial factors (not like 1:n or n:1)\n if (factor != 1) and (factor != modulus) {\n Message($\"Found factor={factor}\");\n return (true, (factor, modulus / factor));\n }\n }\n // Return a flag indicating we hit a trivial case and didn't get\n // any factors.\n Message($\"Found trivial factors.\");\n return (false, (1, 1));\n } else {\n // When period is odd we have to pick another generator to estimate\n // period of and start over.\n Message($\"Estimated period {period} was odd, trying again.\");\n return (false, (1, 1));\n }\n}\n\n/// # Summary\n/// Find the period of a number from an input frequency.\n///\n/// # Input\n/// ## modulus\n/// The modulus which defines the residue ring Z mod `modulus` in which the\n/// multiplicative order of `generator` is being estimated.\n/// ## frequencyEstimate\n/// The frequency that we want to convert to a period.\n/// ## bitsPrecision\n/// Number of bits of precision with which we need to estimate s/r to\n/// recover period r using continued fractions algorithm.\n/// ## currentDivisor\n/// The divisor of the generator period found so far.\n///\n/// # Output\n/// The period as calculated from the estimated frequency via the continued\n/// fractions algorithm.\nfunction PeriodFromFrequency(\n modulus : Int,\n frequencyEstimate : Int,\n bitsPrecision : Int,\n currentDivisor : Int\n) : Int {\n // Now we use the ContinuedFractionConvergentI function to recover s/r\n // from dyadic fraction k/2^bitsPrecision.\n let (numerator, period) = ContinuedFractionConvergentI(\n (frequencyEstimate, 2^bitsPrecision),\n modulus\n );\n\n // ContinuedFractionConvergentI does not guarantee the signs of the\n // numerator and denominator. Here we make sure that both are positive\n // using AbsI.\n let (numeratorAbs, periodAbs) = (AbsI(numerator), AbsI(period));\n\n // Compute and return the newly found divisor.\n let period = (periodAbs * currentDivisor) / GreatestCommonDivisorI(currentDivisor, periodAbs);\n Message($\"Found period={period}\");\n return period;\n}\n\n/// # Summary\n/// Finds a multiplicative order of the generator in the residue ring Z mod\n/// `modulus`.\n///\n/// # Input\n/// ## generator\n/// The unsigned integer multiplicative order (period) of which is being\n/// estimated. Must be co-prime to `modulus`.\n/// ## modulus\n/// The modulus which defines the residue ring Z mod `modulus` in which the\n/// multiplicative order of `generator` is being estimated.\n///\n/// # Output\n/// The period (multiplicative order) of the generator mod `modulus`\noperation EstimatePeriod(generator : Int, modulus : Int) : Int {\n // Here we check that the inputs to the EstimatePeriod operation are\n // valid.\n Fact(\n GreatestCommonDivisorI(generator, modulus) == 1,\n \"`generator` and `modulus` must be co-prime\"\n );\n\n // Number of bits in the modulus with respect to which we are estimating\n // the period.\n let bitsize = BitSizeI(modulus);\n\n // The EstimatePeriod operation estimates the period r by finding an\n // approximation k/2^(bits precision) to a fraction s/r, where s is some\n // integer. Note that if s and r have common divisors we will end up\n // recovering a divisor of r and not r itself.\n\n // Number of bits of precision with which we need to estimate s/r to\n // recover period r, using continued fractions algorithm.\n let bitsPrecision = 2 * bitsize + 1;\n\n // Current estimate for the frequency of the form s/r.\n let frequencyEstimate = EstimateFrequency(generator, modulus, bitsize);\n if frequencyEstimate != 0 {\n return PeriodFromFrequency(\n modulus,\n frequencyEstimate,\n bitsPrecision,\n 1\n );\n } else {\n Message(\"The estimated frequency was 0, trying again.\");\n return 1;\n }\n}\n\n/// # Summary\n/// Estimates the frequency of a generator in the residue ring Z mod\n/// `modulus`.\n///\n/// # Input\n/// ## generator\n/// The unsigned integer multiplicative order (period) of which is being\n/// estimated. Must be co-prime to `modulus`.\n/// ## modulus\n/// The modulus which defines the residue ring Z mod `modulus` in which the\n/// multiplicative order of `generator` is being estimated.\n/// ## bitsize\n/// Number of bits needed to represent the modulus.\n///\n/// # Output\n/// The numerator k of dyadic fraction k/2^bitsPrecision approximating s/r.\noperation EstimateFrequency(generator : Int, modulus : Int, bitsize : Int) : Int {\n mutable frequencyEstimate = 0;\n let bitsPrecision = 2 * bitsize + 1;\n Message($\"Estimating frequency with bitsPrecision={bitsPrecision}.\");\n\n // Allocate qubits for the superposition of eigenstates of the oracle\n // that is used in period finding.\n use eigenstateRegister = Qubit[bitsize];\n\n // Initialize eigenstateRegister to 1, which is a superposition of the\n // eigenstates we are estimating the phases of.\n // We are interpreting the register as encoding an unsigned integer in\n // little-endian format.\n ApplyXorInPlace(1, eigenstateRegister);\n\n // Use phase estimation with a semiclassical Fourier transform to\n // estimate the frequency.\n use c = Qubit();\n for idx in bitsPrecision - 1..-1..0 {\n H(c);\n Controlled ApplyOrderFindingOracle(\n [c],\n (generator, modulus, 1 <<< idx, eigenstateRegister)\n );\n R1Frac(frequencyEstimate, bitsPrecision - 1 - idx, c);\n H(c);\n if M(c) == One {\n X(c); // Reset\n set frequencyEstimate += 1 <<< (bitsPrecision - 1 - idx);\n }\n }\n\n // Return all the qubits used for oracle's eigenstate back to 0 state\n // using ResetAll.\n ResetAll(eigenstateRegister);\n Message($\"Estimated frequency={frequencyEstimate}\");\n return frequencyEstimate;\n}\n\n/// # Summary\n/// Interprets `target` as encoding unsigned little-endian integer k\n/// and performs transformation |k⟩ ↦ |gᵖ⋅k mod N ⟩ where\n/// p is `power`, g is `generator` and N is `modulus`.\n///\n/// # Input\n/// ## generator\n/// The unsigned integer multiplicative order (period)\n/// of which is being estimated. Must be co-prime to `modulus`.\n/// ## modulus\n/// The modulus which defines the residue ring Z mod `modulus`\n/// in which the multiplicative order of `generator` is being estimated.\n/// ## power\n/// Power of `generator` by which `target` is multiplied.\n/// ## target\n/// Register interpreted as little-endian which is multiplied by\n/// given power of the generator. The multiplication is performed modulo\n/// `modulus`.\ninternal operation ApplyOrderFindingOracle(\n generator : Int,\n modulus : Int,\n power : Int,\n target : Qubit[]\n) : Unit is Adj + Ctl {\n // The oracle we use for order finding implements |x⟩ ↦ |x⋅a mod N⟩. We\n // also use `ExpModI` to compute a by which x must be multiplied. Also\n // note that we interpret target as unsigned integer in little-endian\n // format.\n ModularMultiplyByConstant(\n modulus,\n ExpModI(generator, power, modulus),\n target\n );\n}\n\n/// # Summary\n/// Performs modular in-place multiplication by a classical constant.\n///\n/// # Description\n/// Given the classical constants `c` and `modulus`, and an input quantum\n/// register |𝑦⟩ in little-endian format, this operation computes\n/// `(c*x) % modulus` into |𝑦⟩.\n///\n/// # Input\n/// ## modulus\n/// Modulus to use for modular multiplication\n/// ## c\n/// Constant by which to multiply |𝑦⟩\n/// ## y\n/// Quantum register of target\ninternal operation ModularMultiplyByConstant(modulus : Int, c : Int, y : Qubit[]) : Unit is Adj + Ctl {\n use qs = Qubit[Length(y)];\n for idx in IndexRange(y) {\n let shiftedC = (c <<< idx) % modulus;\n Controlled ModularAddConstant(\n [y[idx]],\n (modulus, shiftedC, qs)\n );\n }\n for idx in IndexRange(y) {\n SWAP(y[idx], qs[idx]);\n }\n let invC = InverseModI(c, modulus);\n for idx in IndexRange(y) {\n let shiftedC = (invC <<< idx) % modulus;\n Controlled ModularAddConstant(\n [y[idx]],\n (modulus, modulus - shiftedC, qs)\n );\n }\n}\n\n/// # Summary\n/// Performs modular in-place addition of a classical constant into a\n/// quantum register.\n///\n/// Given the classical constants `c` and `modulus`, and an input quantum\n/// register |𝑦⟩ in little-endian format, this operation computes\n/// `(x+c) % modulus` into |𝑦⟩.\n///\n/// # Input\n/// ## modulus\n/// Modulus to use for modular addition\n/// ## c\n/// Constant to add to |𝑦⟩\n/// ## y\n/// Quantum register of target\ninternal operation ModularAddConstant(modulus : Int, c : Int, y : Qubit[]) : Unit is Adj + Ctl {\n body (...) {\n Controlled ModularAddConstant([], (modulus, c, y));\n }\n controlled (ctrls, ...) {\n // We apply a custom strategy to control this operation instead of\n // letting the compiler create the controlled variant for us in\n // which the `Controlled` functor would be distributed over each\n // operation in the body.\n //\n // Here we can use some scratch memory to save ensure that at most\n // one control qubit is used for costly operations such as\n // `AddConstant` and `CompareGreaterThenOrEqualConstant`.\n if Length(ctrls) >= 2 {\n use control = Qubit();\n within {\n Controlled X(ctrls, control);\n } apply {\n Controlled ModularAddConstant([control], (modulus, c, y));\n }\n } else {\n use carry = Qubit();\n Controlled IncByI(ctrls, (c, y + [carry]));\n Controlled Adjoint IncByI(ctrls, (modulus, y + [carry]));\n Controlled IncByI([carry], (modulus, y));\n Controlled ApplyIfLessOrEqualL(ctrls, (X, IntAsBigInt(c), y, carry));\n }\n }\n}\n"
|
|
81
81
|
},
|
|
82
82
|
{
|
|
83
83
|
"title": "Three Qubit Repetition Code",
|
package/dist/workers/browser.js
CHANGED
|
@@ -22,7 +22,7 @@ export function createWorker(serviceProtocol) {
|
|
|
22
22
|
switch (data.type) {
|
|
23
23
|
case "init":
|
|
24
24
|
{
|
|
25
|
-
wasm.initSync(data.wasmModule);
|
|
25
|
+
wasm.initSync({ module: data.wasmModule });
|
|
26
26
|
invokeService = initService(self.postMessage.bind(self), serviceProtocol, wasm, data.qscLogLevel);
|
|
27
27
|
}
|
|
28
28
|
break;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
uid: Qdk.Microsoft.Quantum.Core.Length
|
|
3
3
|
title: Length exported item
|
|
4
4
|
description: "Q# Length exported item: This is an exported item. The actual definition is found here: [Std.Core.Length](xref:Qdk.Std.Core.Length)"
|
|
5
|
-
ms.date:
|
|
5
|
+
ms.date: 01/25/2025
|
|
6
6
|
ms.topic: managed-reference
|
|
7
7
|
qsharp.kind: export
|
|
8
8
|
qsharp.package: __Std__
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
uid: Qdk.Microsoft.Quantum.Core.Repeated
|
|
3
3
|
title: Repeated exported item
|
|
4
4
|
description: "Q# Repeated exported item: This is an exported item. The actual definition is found here: [Std.Core.Repeated](xref:Qdk.Std.Core.Repeated)"
|
|
5
|
-
ms.date:
|
|
5
|
+
ms.date: 01/25/2025
|
|
6
6
|
ms.topic: managed-reference
|
|
7
7
|
qsharp.kind: export
|
|
8
8
|
qsharp.package: __Std__
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
uid: Qdk.Std.Arithmetic.AddLE
|
|
3
3
|
title: AddLE operation
|
|
4
4
|
description: "Q# AddLE operation: Sets a zero-initialized little-endian register zs to the sum of little-endian registers xs and ys"
|
|
5
|
-
ms.date:
|
|
5
|
+
ms.date: 01/25/2025
|
|
6
6
|
ms.topic: managed-reference
|
|
7
7
|
qsharp.kind: operation
|
|
8
8
|
qsharp.package: __Std__
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
uid: Qdk.Std.Arithmetic.ApplyIfEqualL
|
|
3
3
|
title: ApplyIfEqualL operation
|
|
4
4
|
description: "Q# ApplyIfEqualL operation: Computes `if (c == x) { action(target) }`, that is, applies `action` to `target` if a BigInt value `c` is equal to the little-endian qubit register `x`"
|
|
5
|
-
ms.date:
|
|
5
|
+
ms.date: 01/25/2025
|
|
6
6
|
ms.topic: managed-reference
|
|
7
7
|
qsharp.kind: operation
|
|
8
8
|
qsharp.package: __Std__
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
uid: Qdk.Std.Arithmetic.ApplyIfEqualLE
|
|
3
3
|
title: ApplyIfEqualLE operation
|
|
4
4
|
description: "Q# ApplyIfEqualLE operation: Computes `if x == y { action(target) }`, that is, applies `action` to `target` if register `x` is equal to the register `y`. Both qubit registers should be in a little-endian format."
|
|
5
|
-
ms.date:
|
|
5
|
+
ms.date: 01/25/2025
|
|
6
6
|
ms.topic: managed-reference
|
|
7
7
|
qsharp.kind: operation
|
|
8
8
|
qsharp.package: __Std__
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
uid: Qdk.Std.Arithmetic.ApplyIfGreaterL
|
|
3
3
|
title: ApplyIfGreaterL operation
|
|
4
4
|
description: "Q# ApplyIfGreaterL operation: Computes `if (c > x) { action(target) }`, that is, applies `action` to `target` if a BigInt value `c` is greater than the little-endian qubit register `x`"
|
|
5
|
-
ms.date:
|
|
5
|
+
ms.date: 01/25/2025
|
|
6
6
|
ms.topic: managed-reference
|
|
7
7
|
qsharp.kind: operation
|
|
8
8
|
qsharp.package: __Std__
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
uid: Qdk.Std.Arithmetic.ApplyIfGreaterLE
|
|
3
3
|
title: ApplyIfGreaterLE operation
|
|
4
4
|
description: "Q# ApplyIfGreaterLE operation: Computes `if x > y { action(target) }`, that is, applies `action` to `target` if register `x` is greater than the register `y`. Both qubit registers should be in a little-endian format."
|
|
5
|
-
ms.date:
|
|
5
|
+
ms.date: 01/25/2025
|
|
6
6
|
ms.topic: managed-reference
|
|
7
7
|
qsharp.kind: operation
|
|
8
8
|
qsharp.package: __Std__
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
uid: Qdk.Std.Arithmetic.ApplyIfGreaterOrEqualL
|
|
3
3
|
title: ApplyIfGreaterOrEqualL operation
|
|
4
4
|
description: "Q# ApplyIfGreaterOrEqualL operation: Computes `if (c >= x) { action(target) }`, that is, applies `action` to `target` if a BigInt value `c` is greater or equal to the little-endian qubit register `x`"
|
|
5
|
-
ms.date:
|
|
5
|
+
ms.date: 01/25/2025
|
|
6
6
|
ms.topic: managed-reference
|
|
7
7
|
qsharp.kind: operation
|
|
8
8
|
qsharp.package: __Std__
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
uid: Qdk.Std.Arithmetic.ApplyIfGreaterOrEqualLE
|
|
3
3
|
title: ApplyIfGreaterOrEqualLE operation
|
|
4
4
|
description: "Q# ApplyIfGreaterOrEqualLE operation: Computes `if x >= y { action(target) }`, that is, applies `action` to `target` if register `x` is greater or equal to the register `y`. Both qubit registers should be in a little-endian format."
|
|
5
|
-
ms.date:
|
|
5
|
+
ms.date: 01/25/2025
|
|
6
6
|
ms.topic: managed-reference
|
|
7
7
|
qsharp.kind: operation
|
|
8
8
|
qsharp.package: __Std__
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
uid: Qdk.Std.Arithmetic.ApplyIfLessL
|
|
3
3
|
title: ApplyIfLessL operation
|
|
4
4
|
description: "Q# ApplyIfLessL operation: Computes `if (c < x) { action(target) }`, that is, applies `action` to `target` if a BigInt value `c` is less than the little-endian qubit register `x`"
|
|
5
|
-
ms.date:
|
|
5
|
+
ms.date: 01/25/2025
|
|
6
6
|
ms.topic: managed-reference
|
|
7
7
|
qsharp.kind: operation
|
|
8
8
|
qsharp.package: __Std__
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
uid: Qdk.Std.Arithmetic.ApplyIfLessLE
|
|
3
3
|
title: ApplyIfLessLE operation
|
|
4
4
|
description: "Q# ApplyIfLessLE operation: Computes `if x < y { action(target) }`, that is, applies `action` to `target` if register `x` is less than the register `y`. Both qubit registers should be in a little-endian format."
|
|
5
|
-
ms.date:
|
|
5
|
+
ms.date: 01/25/2025
|
|
6
6
|
ms.topic: managed-reference
|
|
7
7
|
qsharp.kind: operation
|
|
8
8
|
qsharp.package: __Std__
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
uid: Qdk.Std.Arithmetic.ApplyIfLessOrEqualL
|
|
3
3
|
title: ApplyIfLessOrEqualL operation
|
|
4
4
|
description: "Q# ApplyIfLessOrEqualL operation: Computes `if (c <= x) { action(target) }`, that is, applies `action` to `target` if a BigInt value `c` is less or equal to the little-endian qubit register `x`"
|
|
5
|
-
ms.date:
|
|
5
|
+
ms.date: 01/25/2025
|
|
6
6
|
ms.topic: managed-reference
|
|
7
7
|
qsharp.kind: operation
|
|
8
8
|
qsharp.package: __Std__
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
uid: Qdk.Std.Arithmetic.ApplyIfLessOrEqualLE
|
|
3
3
|
title: ApplyIfLessOrEqualLE operation
|
|
4
4
|
description: "Q# ApplyIfLessOrEqualLE operation: Computes `if x <= y { action(target) }`, that is, applies `action` to `target` if register `x` is less or equal to the register `y`. Both qubit registers should be in a little-endian format."
|
|
5
|
-
ms.date:
|
|
5
|
+
ms.date: 01/25/2025
|
|
6
6
|
ms.topic: managed-reference
|
|
7
7
|
qsharp.kind: operation
|
|
8
8
|
qsharp.package: __Std__
|