From 2dc5c926c12d1524d8a00ef2059c3f4e65cd5c86 Mon Sep 17 00:00:00 2001 From: Bettina Heim Date: Thu, 20 Aug 2020 19:01:22 -0700 Subject: [PATCH] classical control tracer ... --- .../Circuits/ClassicalControl.qs | 72 ++--------------- .../QCTraceSimulator/Circuits/Interface.qs | 52 +++++++++++-- .../QCTraceSimulator.ClassicalControl.cs | 78 +++++++++++++++++-- 3 files changed, 122 insertions(+), 80 deletions(-) diff --git a/src/Simulation/Simulators/QCTraceSimulator/Circuits/ClassicalControl.qs b/src/Simulation/Simulators/QCTraceSimulator/Circuits/ClassicalControl.qs index 04b7b85ab33..5ea025c9b56 100644 --- a/src/Simulation/Simulators/QCTraceSimulator/Circuits/ClassicalControl.qs +++ b/src/Simulation/Simulators/QCTraceSimulator/Circuits/ClassicalControl.qs @@ -7,93 +7,37 @@ namespace Microsoft.Quantum.Simulation.Simulators.QCTraceSimulators.Circuits // Private helper operations. operation ApplyIfElseIntrinsic(measurementResult : Result, onResultZeroOp : (Unit => Unit) , onResultOneOp : (Unit => Unit)) : Unit { - body (...) { - Interface_ApplyIfElse(measurementResult, onResultZeroOp, onResultOneOp); - } + Interface_ApplyIfElse(measurementResult, onResultZeroOp, onResultOneOp); } operation ApplyIfElseIntrinsicA(measurementResult : Result, onResultZeroOp : (Unit => Unit is Adj) , onResultOneOp : (Unit => Unit is Adj)) : Unit is Adj { - body (...) { - Interface_ApplyIfElse(measurementResult, onResultZeroOp, onResultOneOp); - } - - adjoint (...) { - Interface_ApplyIfElseA(measurementResult, onResultZeroOp, onResultOneOp); - } + Interface_ApplyIfElseA(measurementResult, onResultZeroOp, onResultOneOp); } operation ApplyIfElseIntrinsicC(measurementResult : Result, onResultZeroOp : (Unit => Unit is Ctl) , onResultOneOp : (Unit => Unit is Ctl)) : Unit is Ctl { - body (...) { - Interface_ApplyIfElse(measurementResult, onResultZeroOp, onResultOneOp); - } - - controlled (ctrls, ...) { - Interface_ApplyIfElseC(ctrls, measurementResult, onResultZeroOp, onResultOneOp); - } + Interface_ApplyIfElseC(measurementResult, onResultZeroOp, onResultOneOp); } operation ApplyIfElseIntrinsicCA(measurementResult : Result, onResultZeroOp : (Unit => Unit is Ctl + Adj) , onResultOneOp : (Unit => Unit is Ctl + Adj)) : Unit is Ctl + Adj { - body (...) { - Interface_ApplyIfElse(measurementResult, onResultZeroOp, onResultOneOp); - } - - adjoint (...) { - Interface_ApplyIfElseA(measurementResult, onResultZeroOp, onResultOneOp); - } - - controlled (ctrls, ...) { - Interface_ApplyIfElseC(ctrls, measurementResult, onResultZeroOp, onResultOneOp); - } - - controlled adjoint (ctrls, ...) { - Interface_ApplyIfElseCA(ctrls, measurementResult, onResultZeroOp, onResultOneOp); - } + Interface_ApplyIfElseCA(measurementResult, onResultZeroOp, onResultOneOp); } // Private helper operations. operation ApplyConditionallyIntrinsic(measurementResults : Result[], resultsValues : Result[], onEqualOp : (Unit => Unit) , onNonEqualOp : (Unit => Unit)) : Unit { - body (...) { - Interface_ApplyConditionally(measurementResults, resultsValues, onEqualOp, onNonEqualOp); - } + Interface_ApplyConditionally(measurementResults, resultsValues, onEqualOp, onNonEqualOp); } operation ApplyConditionallyIntrinsicA(measurementResults : Result[], resultsValues : Result[], onEqualOp : (Unit => Unit is Adj) , onNonEqualOp : (Unit => Unit is Adj)) : Unit is Adj { - body (...) { - Interface_ApplyConditionally(measurementResults, resultsValues, onEqualOp, onNonEqualOp); - } - - adjoint (...) { - Interface_ApplyConditionallyA(measurementResults, resultsValues, onEqualOp, onNonEqualOp); - } + Interface_ApplyConditionallyA(measurementResults, resultsValues, onEqualOp, onNonEqualOp); } operation ApplyConditionallyIntrinsicC(measurementResults : Result[], resultsValues : Result[], onEqualOp : (Unit => Unit is Ctl) , onNonEqualOp : (Unit => Unit is Ctl)) : Unit is Ctl { - body (...) { - Interface_ApplyConditionally(measurementResults, resultsValues, onEqualOp, onNonEqualOp); - } - - controlled (ctrls, ...) { - Interface_ApplyConditionallyC(ctrls, measurementResults, resultsValues, onEqualOp, onNonEqualOp); - } + Interface_ApplyConditionallyC(measurementResults, resultsValues, onEqualOp, onNonEqualOp); } operation ApplyConditionallyIntrinsicCA(measurementResults : Result[], resultsValues : Result[], onEqualOp : (Unit => Unit is Ctl + Adj) , onNonEqualOp : (Unit => Unit is Ctl + Adj)) : Unit is Ctl + Adj { - body (...) { - Interface_ApplyConditionally(measurementResults, resultsValues, onEqualOp, onNonEqualOp); - } - - adjoint (...) { - Interface_ApplyConditionallyA(measurementResults, resultsValues, onEqualOp, onNonEqualOp); - } - - controlled (ctrls, ...) { - Interface_ApplyConditionallyC(ctrls, measurementResults, resultsValues, onEqualOp, onNonEqualOp); - } - - controlled adjoint (ctrls, ...) { - Interface_ApplyConditionallyCA(ctrls, measurementResults, resultsValues, onEqualOp, onNonEqualOp); - } + Interface_ApplyConditionallyCA(measurementResults, resultsValues, onEqualOp, onNonEqualOp); } } diff --git a/src/Simulation/Simulators/QCTraceSimulator/Circuits/Interface.qs b/src/Simulation/Simulators/QCTraceSimulator/Circuits/Interface.qs index b33effcbbe1..3f69a55bd11 100644 --- a/src/Simulation/Simulators/QCTraceSimulator/Circuits/Interface.qs +++ b/src/Simulation/Simulators/QCTraceSimulator/Circuits/Interface.qs @@ -81,7 +81,11 @@ namespace Microsoft.Quantum.Simulation.Simulators.QCTraceSimulators.Implementati /// /// Performs the onResultZeroOp when measurementResult is Zero, else performs the onResultOneOp. /// - operation Interface_ApplyIfElse (measurementResult : Result, onResultZeroOp : (Unit => Unit) , onResultOneOp : (Unit => Unit)) : Unit { + operation Interface_ApplyIfElse ( + measurementResult : Result, + onResultZeroOp : (Unit => Unit), + onResultOneOp : (Unit => Unit) + ) : Unit { body intrinsic; } @@ -89,7 +93,11 @@ namespace Microsoft.Quantum.Simulation.Simulators.QCTraceSimulators.Implementati /// Performs the onResultZeroOp when measurementResult is Zero, else performs the onResultOneOp. /// onReusltZeroOp and onResultOneOp must both be adjointable. /// - operation Interface_ApplyIfElseA (measurementResult : Result, onResultZeroOp : (Unit => Unit is Adj) , onResultOneOp : (Unit => Unit is Adj)) : Unit { + operation Interface_ApplyIfElseA ( + measurementResult : Result, + onResultZeroOp : (Unit => Unit is Adj), + onResultOneOp : (Unit => Unit is Adj) + ) : Unit is Adj { body intrinsic; } @@ -97,7 +105,11 @@ namespace Microsoft.Quantum.Simulation.Simulators.QCTraceSimulators.Implementati /// Performs the onResultZeroOp when measurementResult is Zero, else performs the onResultOneOp. /// onReusltZeroOp and onResultOneOp must both be controllable. /// - operation Interface_ApplyIfElseC (ctrls : Qubit[], measurementResult : Result, onResultZeroOp : (Unit => Unit is Ctl) , onResultOneOp : (Unit => Unit is Ctl)) : Unit { + operation Interface_ApplyIfElseC ( + measurementResult : Result, + onResultZeroOp : (Unit => Unit is Ctl), + onResultOneOp : (Unit => Unit is Ctl) + ) : Unit is Ctl { body intrinsic; } @@ -105,7 +117,11 @@ namespace Microsoft.Quantum.Simulation.Simulators.QCTraceSimulators.Implementati /// Performs the onResultZeroOp when measurementResult is Zero, else performs the onResultOneOp. /// onReusltZeroOp and onResultOneOp must both be controllable and adjointable. /// - operation Interface_ApplyIfElseCA (ctrls : Qubit[], measurementResult : Result, onResultZeroOp : (Unit => Unit is Ctl + Adj) , onResultOneOp : (Unit => Unit is Ctl + Adj)) : Unit { + operation Interface_ApplyIfElseCA ( + measurementResult : Result, + onResultZeroOp : (Unit => Unit is Ctl + Adj), + onResultOneOp : (Unit => Unit is Ctl + Adj) + ) : Unit is Adj + Ctl { body intrinsic; } @@ -113,7 +129,12 @@ namespace Microsoft.Quantum.Simulation.Simulators.QCTraceSimulators.Implementati /// Performs the onEqualOp when each element of measurementResults is equal to the corresponding /// element of resultsValues, else performs onNonEqualOp. /// - operation Interface_ApplyConditionally (measurementResults : Result[], resultsValues : Result[], onEqualOp : (Unit => Unit) , onNonEqualOp : (Unit => Unit)) : Unit { + operation Interface_ApplyConditionally ( + measurementResults : Result[], + resultsValues : Result[], + onEqualOp : (Unit => Unit), + onNonEqualOp : (Unit => Unit) + ) : Unit { body intrinsic; } @@ -122,7 +143,12 @@ namespace Microsoft.Quantum.Simulation.Simulators.QCTraceSimulators.Implementati /// element of resultsValues, else performs onNonEqualOp. /// onEqualOp and onNonEqualOp must both be adjointable. /// - operation Interface_ApplyConditionallyA (measurementResults : Result[], resultsValues : Result[], onEqualOp : (Unit => Unit is Adj) , onNonEqualOp : (Unit => Unit is Adj)) : Unit { + operation Interface_ApplyConditionallyA ( + measurementResults : Result[], + resultsValues : Result[], + onEqualOp : (Unit => Unit is Adj), + onNonEqualOp : (Unit => Unit is Adj) + ) : Unit is Adj { body intrinsic; } @@ -131,7 +157,12 @@ namespace Microsoft.Quantum.Simulation.Simulators.QCTraceSimulators.Implementati /// element of resultsValues, else performs onNonEqualOp. /// onEqualOp and onNonEqualOp must both be controllable. /// - operation Interface_ApplyConditionallyC (ctrls : Qubit[], measurementResults : Result[], resultsValues : Result[], onEqualOp : (Unit => Unit is Ctl) , onNonEqualOp : (Unit => Unit is Ctl)) : Unit { + operation Interface_ApplyConditionallyC ( + measurementResults : Result[], + resultsValues : Result[], + onEqualOp : (Unit => Unit is Ctl), + onNonEqualOp : (Unit => Unit is Ctl) + ) : Unit is Ctl { body intrinsic; } @@ -140,7 +171,12 @@ namespace Microsoft.Quantum.Simulation.Simulators.QCTraceSimulators.Implementati /// element of resultsValues, else performs onNonEqualOp. /// onEqualOp and onNonEqualOp must both be controllable and adjointable. /// - operation Interface_ApplyConditionallyCA (ctrls : Qubit[], measurementResults : Result[], resultsValues : Result[], onEqualOp : (Unit => Unit is Ctl + Adj) , onNonEqualOp : (Unit => Unit is Ctl + Adj)) : Unit { + operation Interface_ApplyConditionallyCA ( + measurementResults : Result[], + resultsValues : Result[], + onEqualOp : (Unit => Unit is Ctl + Adj), + onNonEqualOp : (Unit => Unit is Ctl + Adj) + ) : Unit is Adj + Ctl { body intrinsic; } diff --git a/src/Simulation/Simulators/QCTraceSimulator/QCTraceSimulator.ClassicalControl.cs b/src/Simulation/Simulators/QCTraceSimulator/QCTraceSimulator.ClassicalControl.cs index df7d799a8f1..c9b52f916e4 100644 --- a/src/Simulation/Simulators/QCTraceSimulator/QCTraceSimulator.ClassicalControl.cs +++ b/src/Simulation/Simulators/QCTraceSimulator/QCTraceSimulator.ClassicalControl.cs @@ -140,6 +140,12 @@ public TracerApplyIfElseA(QCTraceSimulatorImpl m) : base(m) } public override Func<(Result, IAdjointable, IAdjointable), QVoid> Body => (q) => + { + (Result measurementResult, ICallable onZero, ICallable onOne) = q; + return ExecuteConditionalStatement(measurementResult, onZero, onOne, OperationFunctor.Body, null); + }; + + public override Func<(Result, IAdjointable, IAdjointable), QVoid> AdjointBody => (q) => { (Result measurementResult, ICallable onZero, ICallable onOne) = q; return ExecuteConditionalStatement(measurementResult, onZero, onOne, OperationFunctor.Adjoint, null); @@ -155,9 +161,15 @@ public TracerApplyIfElseC(QCTraceSimulatorImpl m) : base(m) this.tracerCore = m; } - public override Func<(IQArray, Result, IControllable, IControllable), QVoid> Body => (q) => + public override Func<(Result, IControllable, IControllable), QVoid> Body => (q) => { - (IQArray ctrls, Result measurementResult, ICallable onZero, ICallable onOne) = q; + (Result measurementResult, ICallable onZero, ICallable onOne) = q; + return ExecuteConditionalStatement(measurementResult, onZero, onOne, OperationFunctor.Body, null); + }; + + public override Func<(IQArray, (Result, IControllable, IControllable)), QVoid> ControlledBody => (q) => + { + (IQArray ctrls, (Result measurementResult, ICallable onZero, ICallable onOne)) = q; OperationFunctor type = AdjustForNoControls(OperationFunctor.Controlled, ctrls); return ExecuteConditionalStatement(measurementResult, onZero, onOne, type, ctrls); }; @@ -172,9 +184,28 @@ public TracerApplyIfElseCA(QCTraceSimulatorImpl m) : base(m) this.tracerCore = m; } - public override Func<(IQArray, Result, IUnitary, IUnitary), QVoid> Body => (q) => + public override Func<(Result, IUnitary, IUnitary), QVoid> Body => (q) => + { + (Result measurementResult, ICallable onZero, ICallable onOne) = q; + return ExecuteConditionalStatement(measurementResult, onZero, onOne, OperationFunctor.Body, null); + }; + + public override Func<(Result, IUnitary, IUnitary), QVoid> AdjointBody => (q) => + { + (Result measurementResult, ICallable onZero, ICallable onOne) = q; + return ExecuteConditionalStatement(measurementResult, onZero, onOne, OperationFunctor.Adjoint, null); + }; + + public override Func<(IQArray, (Result, IUnitary, IUnitary)), QVoid> ControlledBody => (q) => + { + (IQArray ctrls, (Result measurementResult, ICallable onZero, ICallable onOne)) = q; + OperationFunctor type = AdjustForNoControls(OperationFunctor.Controlled, ctrls); + return ExecuteConditionalStatement(measurementResult, onZero, onOne, type, ctrls); + }; + + public override Func<(IQArray, (Result, IUnitary, IUnitary)), QVoid> ControlledAdjointBody => (q) => { - (IQArray ctrls, Result measurementResult, ICallable onZero, ICallable onOne) = q; + (IQArray ctrls, (Result measurementResult, ICallable onZero, ICallable onOne)) = q; OperationFunctor type = AdjustForNoControls(OperationFunctor.ControlledAdjoint, ctrls); return ExecuteConditionalStatement(measurementResult, onZero, onOne, type, ctrls); }; @@ -210,6 +241,12 @@ public TracerApplyConditionallyA(QCTraceSimulatorImpl m) : base(m) } public override Func<(IQArray, IQArray, IAdjointable, IAdjointable), QVoid> Body => (q) => + { + (IQArray measurementResults, IQArray comparisonResults, ICallable onEqualOp, ICallable onNonEqualOp) = q; + return ExecuteConditionalStatement(measurementResults, comparisonResults, onEqualOp, onNonEqualOp, OperationFunctor.Body, null); + }; + + public override Func<(IQArray, IQArray, IAdjointable, IAdjointable), QVoid> AdjointBody => (q) => { (IQArray measurementResults, IQArray comparisonResults, ICallable onEqualOp, ICallable onNonEqualOp) = q; return ExecuteConditionalStatement(measurementResults, comparisonResults, onEqualOp, onNonEqualOp, OperationFunctor.Adjoint, null); @@ -225,9 +262,15 @@ public TracerApplyConditionallyC(QCTraceSimulatorImpl m) : base(m) this.tracerCore = m; } - public override Func<(IQArray, IQArray, IQArray, IControllable, IControllable), QVoid> Body => (q) => + public override Func<(IQArray, IQArray, IControllable, IControllable), QVoid> Body => (q) => { - (IQArray ctrls, IQArray measurementResults, IQArray comparisonResults, ICallable onEqualOp, ICallable onNonEqualOp) = q; + (IQArray measurementResults, IQArray comparisonResults, ICallable onEqualOp, ICallable onNonEqualOp) = q; + return ExecuteConditionalStatement(measurementResults, comparisonResults, onEqualOp, onNonEqualOp, OperationFunctor.Body, null); + }; + + public override Func<(IQArray, (IQArray, IQArray, IControllable, IControllable)), QVoid> ControlledBody => (q) => + { + (IQArray ctrls, (IQArray measurementResults, IQArray comparisonResults, ICallable onEqualOp, ICallable onNonEqualOp)) = q; OperationFunctor type = AdjustForNoControls(OperationFunctor.Controlled, ctrls); return ExecuteConditionalStatement(measurementResults, comparisonResults, onEqualOp, onNonEqualOp, type, ctrls); }; @@ -242,12 +285,31 @@ public TracerApplyConditionallyCA(QCTraceSimulatorImpl m) : base(m) this.tracerCore = m; } - public override Func<(IQArray, IQArray, IQArray, IUnitary, IUnitary), QVoid> Body => (q) => + public override Func<(IQArray, IQArray, IUnitary, IUnitary), QVoid> Body => (q) => { - (IQArray ctrls, IQArray measurementResults, IQArray comparisonResults, ICallable onEqualOp, ICallable onNonEqualOp) = q; + (IQArray measurementResults, IQArray comparisonResults, ICallable onEqualOp, ICallable onNonEqualOp) = q; + return ExecuteConditionalStatement(measurementResults, comparisonResults, onEqualOp, onNonEqualOp, OperationFunctor.Body, null); + }; + + public override Func<(IQArray, IQArray, IUnitary, IUnitary), QVoid> AdjointBody => (q) => + { + (IQArray measurementResults, IQArray comparisonResults, ICallable onEqualOp, ICallable onNonEqualOp) = q; + return ExecuteConditionalStatement(measurementResults, comparisonResults, onEqualOp, onNonEqualOp, OperationFunctor.Adjoint, null); + }; + + public override Func<(IQArray, (IQArray, IQArray, IUnitary, IUnitary)), QVoid> ControlledBody => (q) => + { + (IQArray ctrls, (IQArray measurementResults, IQArray comparisonResults, ICallable onEqualOp, ICallable onNonEqualOp)) = q; OperationFunctor type = AdjustForNoControls(OperationFunctor.Controlled, ctrls); return ExecuteConditionalStatement(measurementResults, comparisonResults, onEqualOp, onNonEqualOp, type, ctrls); }; + + public override Func<(IQArray, (IQArray, IQArray, IUnitary, IUnitary)), QVoid> ControlledAdjointBody => (q) => + { + (IQArray ctrls, (IQArray measurementResults, IQArray comparisonResults, ICallable onEqualOp, ICallable onNonEqualOp)) = q; + OperationFunctor type = AdjustForNoControls(OperationFunctor.ControlledAdjoint, ctrls); + return ExecuteConditionalStatement(measurementResults, comparisonResults, onEqualOp, onNonEqualOp, type, ctrls); + }; } #endregion