diff --git a/src/Simulation/Core/TypeExtensions.cs b/src/Simulation/Core/TypeExtensions.cs index c47650b0b77..59cb0370b52 100644 --- a/src/Simulation/Core/TypeExtensions.cs +++ b/src/Simulation/Core/TypeExtensions.cs @@ -159,10 +159,16 @@ public static Type[] GetTupleFieldTypes(this Type arg) // If object is a Qubit, QVoid, or array of Qubits, ignore it (i.e. return null) if (o is Qubit || o is QVoid || o is IEnumerable) return null; + // If object is an ICallable, return its name + if (o is ICallable op) + { + return op.Name; + } + // If object is an IApplyData, recursively extract arguments if (o is IApplyData data) { - return data.Value.GetNonQubitArgumentsAsString(); + return data.Value?.GetNonQubitArgumentsAsString(); } // If object is a string, enclose it in quotations diff --git a/src/Simulation/Simulators.Tests/Circuits/RuntimeMetadataTest.qs b/src/Simulation/Simulators.Tests/Circuits/RuntimeMetadataTest.qs index 668f7ee5bf5..b75e70fb7d5 100644 --- a/src/Simulation/Simulators.Tests/Circuits/RuntimeMetadataTest.qs +++ b/src/Simulation/Simulators.Tests/Circuits/RuntimeMetadataTest.qs @@ -11,6 +11,11 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits { operation Empty () : Unit is Ctl + Adj { } + operation WrapperOp (op: (Qubit => Unit), q : Qubit) : Unit { + op(q); + Reset(q); + } + operation HOp (q : Qubit) : Unit { H(q); Reset(q); diff --git a/src/Simulation/Simulators.Tests/RuntimeMetadataTests.cs b/src/Simulation/Simulators.Tests/RuntimeMetadataTests.cs index 629417598b0..d41b15764fa 100644 --- a/src/Simulation/Simulators.Tests/RuntimeMetadataTests.cs +++ b/src/Simulation/Simulators.Tests/RuntimeMetadataTests.cs @@ -410,10 +410,32 @@ public void EmptyOperation() Assert.Equal(op.GetRuntimeMetadata(args), expected); } + [Fact] + public void OperationAsArgument() + { + var q = new FreeQubit(0); + var opArg = new QuantumSimulator().Get(); + var op = new QuantumSimulator().Get(); + var args = op.__dataIn((opArg, q)); + var expected = new RuntimeMetadata() + { + Label = "WrapperOp", + FormattedNonQubitArgs = "(HOp)", + IsAdjoint = false, + IsControlled = false, + IsMeasurement = false, + IsComposite = false, + Children = null, + Controls = new List() { }, + Targets = new List() { q }, + }; + + Assert.Equal(op.GetRuntimeMetadata(args), expected); + } + [Fact] public void NestedOperation() { - var measureQubit = new FreeQubit(0); var op = new QuantumSimulator().Get(); var args = op.__dataIn(QVoid.Instance); var expected = new RuntimeMetadata() diff --git a/src/Simulation/Simulators.Tests/TypeExtensionsTest.cs b/src/Simulation/Simulators.Tests/TypeExtensionsTest.cs index 5fa2f260610..a7942f7f110 100644 --- a/src/Simulation/Simulators.Tests/TypeExtensionsTest.cs +++ b/src/Simulation/Simulators.Tests/TypeExtensionsTest.cs @@ -33,6 +33,16 @@ public void BasicTypes() Assert.Equal("\"\"", "".GetNonQubitArgumentsAsString()); } + [Fact] + public void OperationTypes() + { + var op = new QuantumSimulator().Get(); + Assert.Equal("H", op.GetNonQubitArgumentsAsString()); + + var op2 = new QuantumSimulator().Get(); + Assert.Equal("CNOT", op2.GetNonQubitArgumentsAsString()); + } + [Fact] public void QubitTypes() { @@ -58,6 +68,10 @@ public void TupleTypes() Assert.Equal("(\"foo\", (\"bar\", \"car\"))", ("foo", ("bar", "car")).GetNonQubitArgumentsAsString()); Assert.Equal("((\"foo\"), (\"bar\", \"car\"))", (("foo", new FreeQubit(0)), ("bar", "car")).GetNonQubitArgumentsAsString()); + var op = new QuantumSimulator().Get(); + var opTuple = new QTuple<(ICallable, string)>((op, "foo")); + Assert.Equal("(H, \"foo\")", opTuple.GetNonQubitArgumentsAsString()); + var qtuple = new QTuple<(Qubit, string)>((new FreeQubit(0), "foo")); Assert.Equal("(\"foo\")", qtuple.GetNonQubitArgumentsAsString()); } @@ -68,11 +82,18 @@ public void ArrayTypes() Assert.Equal("[1, 2, 3]", new[] { 1, 2, 3 }.GetNonQubitArgumentsAsString()); Assert.Equal("[\"foo\", \"bar\"]", new[] { "foo", "bar" }.GetNonQubitArgumentsAsString()); - var arr = new[] { + var opArr = new ICallable[] { + new QuantumSimulator().Get(), + new QuantumSimulator().Get(), + new QuantumSimulator().Get(), + }; + Assert.Equal("[H, CNOT, Ry]", opArr.GetNonQubitArgumentsAsString()); + + var qTupleArr = new[] { (new FreeQubit(0), "foo"), (new FreeQubit(1), "bar"), }; - Assert.Equal("[(\"foo\"), (\"bar\")]", arr.GetNonQubitArgumentsAsString()); + Assert.Equal("[(\"foo\"), (\"bar\")]", qTupleArr.GetNonQubitArgumentsAsString()); } [Fact] @@ -88,6 +109,10 @@ public void IApplyDataTypes() data = new ApplyData("Foo"); Assert.Equal("\"Foo\"", data.GetNonQubitArgumentsAsString()); + var op = new QuantumSimulator().Get(); + data = new ApplyData(op); + Assert.Equal("H", data.GetNonQubitArgumentsAsString()); + data = new ApplyData>((1, "foo")); Assert.Equal("(1, \"foo\")", data.GetNonQubitArgumentsAsString());