From 20257a00ed71df0255c83f9a9d5d69b967503088 Mon Sep 17 00:00:00 2001 From: Scott Carda Date: Thu, 18 Jun 2020 17:54:08 -0700 Subject: [PATCH 1/7] Fixed an issue with the C# generation for UDT classes where tuple fields of the UDT where not being correctly parsed. --- .../CsharpGeneration/SimulationCode.fs | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/Simulation/CsharpGeneration/SimulationCode.fs b/src/Simulation/CsharpGeneration/SimulationCode.fs index 32cc584932b..66191f44bbe 100644 --- a/src/Simulation/CsharpGeneration/SimulationCode.fs +++ b/src/Simulation/CsharpGeneration/SimulationCode.fs @@ -1454,17 +1454,24 @@ module SimulationCode = [] ``}`` :> MemberDeclarationSyntax - - let buildNamedItemFields = - let items = getAllItems (``ident`` "Data") qsharpType - let rec buildProps = function - | QsTuple items -> items |> Seq.collect (fun i -> buildProps i) - | QsTupleItem (Anonymous _) -> items.Dequeue() |> ignore; Seq.empty - | QsTupleItem (Named decl) -> seq { yield - ``property-arrow_get`` (roslynTypeName context decl.Type) decl.VariableName.Value [ ``public`` ] - ``get`` (``=>`` (items.Dequeue())) - :> MemberDeclarationSyntax} - buildProps udt.TypeItems |> Seq.toList + let buildNamedItemFields = + let produceProperty (decl : LocalVariableDeclaration>) valueExpr = + ``property-arrow_get`` (roslynTypeName context decl.Type) decl.VariableName.Value [ ``public`` ] + ``get`` (``=>`` valueExpr) :> MemberDeclarationSyntax + let rec buildProps current = function + | QsTuple items -> items |> Seq.mapi (fun i x -> buildProps (current <|.|> ``ident`` ("Item" + (i+1).ToString())) x) |> Seq.collect id + | QsTupleItem (Anonymous _) -> Seq.empty + | QsTupleItem (Named decl) -> seq { yield produceProperty decl current } + // UDT types are packaged differently if there is one constituent type, or many. + // This function handles that difference in packaging. + let rec readType typeItem = + match typeItem with + | QsTuple items when items.IsEmpty -> Seq.empty + | QsTuple items when items.Length = 1 -> items |> Seq.head |> readType + | QsTuple _ -> buildProps (``ident`` "Data") typeItem + | QsTupleItem (Anonymous _) -> Seq.empty + | QsTupleItem (Named decl) -> seq { yield produceProperty decl (``ident`` "Data") } + readType udt.TypeItems |> Seq.toList let buildItemFields = let buildOne i t = ``property-arrow_get`` (roslynTypeName context t) (sprintf "Item%d" (i+1)) [ ``public`` ] From d8d9c57f2e18b938776ce5dae1800cbd11701514 Mon Sep 17 00:00:00 2001 From: Scott Carda Date: Fri, 19 Jun 2020 18:06:17 -0700 Subject: [PATCH 2/7] Added code gen test for the bug fix. --- .../Circuits/CodegenTests.qs | 2 ++ .../SimulationCodeTests.fs | 28 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/Simulation/CsharpGeneration.Tests/Circuits/CodegenTests.qs b/src/Simulation/CsharpGeneration.Tests/Circuits/CodegenTests.qs index 4761f2b4aaf..fc791dff352 100644 --- a/src/Simulation/CsharpGeneration.Tests/Circuits/CodegenTests.qs +++ b/src/Simulation/CsharpGeneration.Tests/Circuits/CodegenTests.qs @@ -1307,6 +1307,8 @@ namespace Microsoft.Quantum.Compiler.Generics { w/ i1 <- 1; } + newtype NamedTuple = (FirstItem: (Int, Double), SecondItem: Int); + // Access Modifiers internal function EmptyInternalFunction () : Unit { } diff --git a/src/Simulation/CsharpGeneration.Tests/SimulationCodeTests.fs b/src/Simulation/CsharpGeneration.Tests/SimulationCodeTests.fs index 6605b571cd2..ad64c0ce78f 100644 --- a/src/Simulation/CsharpGeneration.Tests/SimulationCodeTests.fs +++ b/src/Simulation/CsharpGeneration.Tests/SimulationCodeTests.fs @@ -212,6 +212,7 @@ namespace N1 let udt_Complex = findUdt @"udt_Complex" let udt_TwoDimArray = findUdt @"udt_TwoDimArray" let udt_InternalType = findUdt @"InternalType" + let udt_NamedTuple = findUdt @"NamedTuple" let createTestContext op = globalContext.setCallable op @@ -3139,6 +3140,33 @@ internal class InternalType : UDTBase, IApplyData """ |> testOneUdt udt_InternalType + [] + let ``buildUdtClass - named tuple`` () = + """ +public class NamedTuple : UDTBase<((Int64,Double),Int64)>, IApplyData +{ + public NamedTuple() : base(default(((Int64,Double),Int64))) + { + } + + public NamedTuple(((Int64,Double),Int64) data) : base(data) + { + } + + public (Int64,Double) FirstItem => Data.Item1; + public Int64 SecondItem => Data.Item2; + public (Int64,Double) Item1 => Data.Item1; + public Int64 Item2 => Data.Item2; + System.Collections.Generic.IEnumerable IApplyData.Qubits => null; + public void Deconstruct(out (Int64,Double) item1, out Int64 item2) + { + item1 = Data.Item1; + item2 = Data.Item2; + } +} +""" + |> testOneUdt udt_NamedTuple + [] let ``one file - EmptyElements`` () = From 570a9065aa4f4ec5b1e33c9520a6223e2ad57e17 Mon Sep 17 00:00:00 2001 From: Scott Carda Date: Fri, 19 Jun 2020 19:21:56 -0700 Subject: [PATCH 3/7] Added execution test for UDT Named Tuple Fields bug fix. --- .../Simulators.Tests/Circuits/UserDefinedTypes.qs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Simulation/Simulators.Tests/Circuits/UserDefinedTypes.qs b/src/Simulation/Simulators.Tests/Circuits/UserDefinedTypes.qs index 70473404b9d..63d345ee41c 100644 --- a/src/Simulation/Simulators.Tests/Circuits/UserDefinedTypes.qs +++ b/src/Simulation/Simulators.Tests/Circuits/UserDefinedTypes.qs @@ -7,6 +7,7 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits newtype P1 = (Int, Int); newtype P2 = ((Int, Int), Int); + newtype NamedTuple = (FirstItem: (Int, Double), SecondItem: Int); function TakesUdtPartial<'T, 'U> (build : ('T -> 'U), remainingArgs : 'T) : 'U { return build(remainingArgs); @@ -107,5 +108,13 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits AssertEqual(c, 3); } } + + function UdtNamedTupleFieldTest () : Unit { + let data = NamedTuple((1, 2.0), 3); + let ((a,b),c) = data; + AssertEqual(a, 1); + AssertEqual(b, 2.0); + AssertEqual(c, 3); + } } From 9862e049d47d716dd6c47055ebbfc695c49c4848 Mon Sep 17 00:00:00 2001 From: Scott Carda Date: Fri, 19 Jun 2020 19:54:56 -0700 Subject: [PATCH 4/7] Fixed udt test not deconstructing correctly. --- src/Simulation/Simulators.Tests/Circuits/UserDefinedTypes.qs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Simulation/Simulators.Tests/Circuits/UserDefinedTypes.qs b/src/Simulation/Simulators.Tests/Circuits/UserDefinedTypes.qs index 63d345ee41c..2d1720f2b21 100644 --- a/src/Simulation/Simulators.Tests/Circuits/UserDefinedTypes.qs +++ b/src/Simulation/Simulators.Tests/Circuits/UserDefinedTypes.qs @@ -111,7 +111,8 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits function UdtNamedTupleFieldTest () : Unit { let data = NamedTuple((1, 2.0), 3); - let ((a,b),c) = data; + let (a, b) = data::FirstItem; + let c = data::SecondItem; AssertEqual(a, 1); AssertEqual(b, 2.0); AssertEqual(c, 3); From 260a8c982c4432801db530aa36905e929a3fca98 Mon Sep 17 00:00:00 2001 From: Scott Carda Date: Fri, 19 Jun 2020 22:26:33 -0700 Subject: [PATCH 5/7] Fixed location data in expected outcome of tests to account for the new test. --- .../Circuits/CodegenTests.qs | 800 +++++++++--------- .../SimulationCodeTests.fs | 782 ++++++++--------- .../CsharpGeneration/SimulationCode.fs | 710 ++++++++-------- .../Circuits/UserDefinedTypes.qs | 12 +- 4 files changed, 1152 insertions(+), 1152 deletions(-) diff --git a/src/Simulation/CsharpGeneration.Tests/Circuits/CodegenTests.qs b/src/Simulation/CsharpGeneration.Tests/Circuits/CodegenTests.qs index fc791dff352..131e7899e01 100644 --- a/src/Simulation/CsharpGeneration.Tests/Circuits/CodegenTests.qs +++ b/src/Simulation/CsharpGeneration.Tests/Circuits/CodegenTests.qs @@ -2,58 +2,58 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.Overrides { - + newtype udt0 = (Result, Result); - - + + function emptyFunction () : Unit { body intrinsic; } - + } namespace Microsoft.Quantum.Testing { - + open Microsoft.Quantum.Intrinsic; - - + + // Nothing in it function emptyFunction () : Unit { body intrinsic; } - - + + operation emptyOperation () : Unit { body intrinsic; } - - + + //Function tests function intFunction () : Int { - + return 1; } - - + + // A duplicated H, just in case... operation H (q1 : Qubit) : Unit { - + } - - + + function powFunction (x : Int, y : Int) : Int { - + return x ^ y; } - - + + function bigPowFunction (x : BigInt, y : Int) : BigInt { - + return x ^ y; } - - + + operation zeroQubitOperation () : Unit { body { } @@ -61,339 +61,339 @@ namespace Microsoft.Quantum.Testing { controlled auto; adjoint controlled auto; } - + operation oneQubitAbstractOperation (q1 : Qubit) : Unit { body intrinsic; adjoint intrinsic; controlled intrinsic; controlled adjoint intrinsic; } - - + + operation oneQubitSelfAdjointAbstractOperation (q1 : Qubit) : Unit { body intrinsic; adjoint self; controlled intrinsic; controlled adjoint self; } - + newtype Basis = Pauli; - + newtype udt_Real = Double; - + newtype udt_Complex = (udt_Real, udt_Real); - + newtype udt_TwoDimArray = Result[][]; - + operation randomAbstractOperation (q1 : Qubit, b : Basis, t : (Pauli, Double[][], Bool), i : Int) : Unit { body intrinsic; adjoint intrinsic; controlled intrinsic; controlled adjoint intrinsic; } - - + + operation oneQubitSelfAdjointOperation (q1 : Qubit) : Unit { - + body (...) { Z(q1); } - + adjoint self; } - - + + operation oneQubitOperation (q1 : Qubit) : Unit { - + body (...) { // some comment in body. X(q1); } - + adjoint (...) { // some comment in adjoint. // second comment in adjoint. Adjoint X(q1); } - + controlled (c, ...) { Controlled X(c, q1); // some comment in controlled at the bottom. // Notice an empty statement (;) will be added to // make it easy to add this comment... } - + controlled adjoint (c, ...) { Adjoint Controlled X(c, q1); } } - - + + operation twoQubitOperation (q1 : Qubit, t1 : (Qubit, Double)) : Unit { - + body (...) { let (q2, r) = t1; CNOT(q1, q2); R(r, q1); } - + adjoint (...) { let (q2, r) = t1; - + // One Comment. Adjoint R(r, q1); - + // First comment. // Second comment. Adjoint CNOT(q1, q2); } } - - + + operation three_op1 (q1 : Qubit, q2 : Qubit) : Unit { body intrinsic; adjoint intrinsic; controlled intrinsic; controlled adjoint intrinsic; } - - + + operation threeQubitOperation (q1 : Qubit, q2 : Qubit, arr1 : Qubits) : Unit { - + body (...) { three_op1(q1, q2); three_op1(q2, q1); three_op1(q1, q2); } - + adjoint (...) { Adjoint three_op1(q1, q2); Adjoint three_op1(q2, q1); Adjoint three_op1(q1, q2); } - + controlled (c, ...) { Controlled three_op1(c, (q1, q2)); Controlled three_op1(c, (q2, q1)); Controlled three_op1(c, (q1, q2)); } - + controlled adjoint (c, ...) { Adjoint Controlled three_op1(c, (q1, q2)); Adjoint Controlled three_op1(c, (q2, q1)); Adjoint Controlled three_op1(c, (q1, q2)); } } - - + + operation nestedArgTuple1 ((a : Int, b : Int), (c : Double, d : Double)) : Unit { body intrinsic; } - - + + operation nestedArgTuple2 (a : (Int, Int), (c : Double, (b : Int, d : (Qubit, Qubit)), e : Double)) : Unit { body intrinsic; } - - + + operation nestedArgTupleGeneric<'A> (a : ('A, Int), (c : 'A, (b : Int, d : (Qubit, 'A)), e : Double)) : Unit { body intrinsic; } - - + + // calling function with the same name in different namespaces operation duplicatedDefinitionsCaller () : Unit { - + emptyFunction(); Microsoft.Quantum.Overrides.emptyFunction(); - + using (qubits = Qubit[1]) { H(qubits[0]); Microsoft.Quantum.Intrinsic.H(qubits[0]); } } - - + + operation da_op0 () : Unit { body intrinsic; } - - + + operation da_op1 (q1 : Qubit) : Unit { body intrinsic; adjoint intrinsic; controlled intrinsic; controlled adjoint intrinsic; } - - + + operation da_op2 (i : Int, q : Qubit) : Unit { body intrinsic; adjoint intrinsic; controlled intrinsic; controlled adjoint intrinsic; } - - + + operation da_op3 (d : Double, r : Result, i : Int) : Unit { body intrinsic; adjoint intrinsic; controlled intrinsic; controlled adjoint intrinsic; } - - + + operation differentArgsOperation (q1 : Qubit, q2 : Qubit, arr1 : Qubit[]) : Unit { - + da_op0(); Adjoint da_op1(q1); Controlled da_op2([q1], (1, q2)); Adjoint Controlled da_op3([q1, q2], (1.1, One, Length(arr1))); } - - + + function random_f0 () : Int { - + return 1; } - - + + function random_f1 (n1 : Int, n2 : Int) : Int { - + return n1 * n2 - random_f0(); } - - + + operation random_op0 (q1 : Qubit, i1 : Int) : Unit { - + } - - + + operation random_op1 (q1 : Qubit) : Result { body intrinsic; } - - + + operation random_op2 (q1 : Qubit) : Result { body intrinsic; } - - + + operation random_op3 (q1 : Qubit, r1 : Result, p1 : Pauli) : Unit { body intrinsic; } - - + + operation random_op4 (q1 : Qubit, p1 : Pauli) : Unit { body intrinsic; } - - + + operation random_op5 (q1 : Qubit, p1 : Pauli) : Unit { body intrinsic; adjoint intrinsic; } - - + + operation random_op6 (q1 : Qubit, p1 : Pauli) : Unit { body intrinsic; } - - + + operation random_op7 (q1 : Qubit, p1 : Pauli) : Unit { body intrinsic; adjoint intrinsic; controlled intrinsic; controlled adjoint intrinsic; } - - + + operation random_op8 (q1 : Qubit, p1 : Pauli) : Unit { body intrinsic; } - - + + operation random_op9 (q1 : Qubit, p1 : Pauli) : Unit { body intrinsic; adjoint intrinsic; controlled intrinsic; controlled adjoint intrinsic; } - - + + operation random_op10 (q1 : Qubit, i1 : Int) : Unit { body intrinsic; } - - + + operation randomOperation (q1 : Qubit, i1 : Int, r1 : Result, p1 : Pauli) : Unit { - + body (...) { let arr1 = [q1, q1]; - + using (qubits = Qubit[Length(arr1)]) { random_op0(q1, i1); let r = random_op1(q1); - + if (r == One) { - + borrowing (b = Qubit[Length(arr1) + i1]) { - + for (i in 0 .. 1 .. 5) { let m = random_op2(arr1[random_f1(1, 2)]); - + if (m == Zero) { random_op0(q1, i); } } - + random_op3(q1, r1, p1); } } } } - + adjoint (...) { random_op0(q1, i1); random_op6(q1, p1); Adjoint random_op5(q1, p1); } - + controlled (c, ...) { random_op0(q1, i1); random_op4(q1, p1); Controlled random_op7(c, (q1, p1)); } - + controlled adjoint (c, ...) { random_op10(q1, i1); random_op8(q1, p1); Adjoint Controlled random_op9(c, (q1, p1)); } } - - + + function if_f0 () : Int { - + return 0; } - - + + operation ifOperation (i : Int, r : Result, p : Pauli) : Int { - + mutable n = 0; - + if (r == One) { set n = if_f0() * i; } - + if (p == PauliX) { return n; } else { return 0; } - + if (p == PauliX) { return n; } @@ -404,32 +404,32 @@ namespace Microsoft.Quantum.Testing { return p == PauliI ? 3 | if_f0(); } } - - + + function foreach_f2 (n1 : Int, n2 : Int) : Int { - + return n1 * n2; } - - + + operation foreachOperation (i : Int, r1 : Result) : Result { - + mutable result = 0; - + for (n in 0 .. i) { set result = result + i; } - + for (n in i .. -1 .. 0) { set result = (result - i) * 2; } - + let range = 0 .. 10; - + for (n in range) { set result = RangeEnd(range) + result + n * -foreach_f2(n, 4); } - + if (result > 10) { return One; } @@ -437,35 +437,35 @@ namespace Microsoft.Quantum.Testing { return Zero; } } - + newtype udt_args0 = Qubit[]; - + newtype udt_args1 = (Int, Qubit[]); - + newtype udt_args2 = (udt_args0 => udt_args1); - + newtype udt_args3 = (udt_args0 => udt_args1 is Ctl); - + newtype udt_args4 = (udt_args0 => udt_args1 is Adj); - + newtype udt_args5 = (udt_args0 => udt_args1 is Adj + Ctl); - + newtype udt_args1_0 = (Int, udt_args0); - + newtype udt_args1_1 = (Int, udt_args1); - + newtype udt_args1_2 = (Int, udt_args2); - + newtype udt_args2_0 = (Int, Result, udt_args0[]); - + newtype udt_args2_1 = (Int, Result, udt_args1[]); - + newtype udt_args2_2 = (Int, Result, udt_args2[]); - - - operation udtsTest + + + operation udtsTest ( - qubits : Qubit[], + qubits : Qubit[], u0 : Microsoft.Quantum.Overrides.udt0, u1 : udt_args1, u2 : udt_args2, @@ -481,7 +481,7 @@ namespace Microsoft.Quantum.Testing { op2_1 : (udt_args2_1 => Unit), op2_2 : (udt_args2_2 => Unit is Adj + Ctl), op_o : (Microsoft.Quantum.Overrides.udt0 => Unit) ) : udt_args1 { - + let args0 = udt_args0(qubits); let args1 = udt_args1(1, args0!); let args1a = op2(args0); @@ -497,96 +497,96 @@ namespace Microsoft.Quantum.Testing { op1(udt_args1(4, (udt_args0(qubits))!)); return udt_args1(22, qubits); } - - - + + + newtype returnUdt0 = (Int, Int); - + newtype returnUdt1 = (Int, Int)[]; - + newtype returnUdt3 = returnUdt0[]; - + function returnTest1 () : Unit { - + return (); } - - + + function returnTest2 () : Int { - + return 5; } - - + + function returnTest3 () : (Int, Int) { - + return (5, 6); } - - + + function returnTest4 () : returnUdt0 { - + return returnUdt0(7, 8); } - - + + function returnTest5 () : Int[] { - + return [9, 10]; } - - + + function returnTest6 () : returnUdt1 { - + return returnUdt1([(1, 2), (3, 4)]); } - - + + function returnTest7 () : returnUdt0[] { - + return [returnUdt0(1, 2), returnUdt0(3, 4)]; } - - + + function returnTest8 () : returnUdt3 { - + return returnUdt3([returnUdt0(1, 2), returnUdt0(3, 4)]); } - - + + function returnTest9 () : (returnUdt0, returnUdt1) { - + return (returnUdt0(7, 8), returnUdt1([(1, 2), (3, 4)])); } - - + + function returnTest10 () : Microsoft.Quantum.Overrides.udt0 { - + return Microsoft.Quantum.Overrides.udt0(Zero, One); } - + newtype repeat_udt0 = (Int, Qubit[]); - - + + operation repeat_op0 (info : repeat_udt0) : Result { body intrinsic; } - - + + operation repeat_op1 (index : Int, qubits : Qubit[]) : Result { body intrinsic; } - - + + operation repeat_op2 (angle : Double, info : repeat_udt0) : Result { body intrinsic; } - - + + operation repeatOperation (i : Int) : Unit { - + using (qubits = Qubit[i]) { - + repeat { mutable res = repeat_op0(repeat_udt0(0, qubits)); } @@ -596,32 +596,32 @@ namespace Microsoft.Quantum.Testing { } } } - - + + newtype udtTuple_1 = (Int, Qubit); - + newtype udtTuple_2 = (Int, (Qubit, Qubit)); - + operation udtTuple (i : Int, t1 : udtTuple_1, t2 : udtTuple_2, q : Qubit) : Unit { body intrinsic; } - - + + operation selfInvokingOperation (q1 : Qubit) : Unit { - + body (...) { Z(q1); } - + adjoint (...) { Adjoint Z(q1); selfInvokingOperation(q1); } } - - + + function factorial (x : Int) : Int { - + if (x == 1) { return 1; } @@ -629,60 +629,60 @@ namespace Microsoft.Quantum.Testing { return x * factorial(x - 1); } } - - + + function let_f0 (n : Int) : Range { body intrinsic; } - + newtype let_udt_1 = (Int, Qubit[]); - + newtype let_udt_2 = (let_udt_1 => Range is Adj + Ctl); - + newtype let_udt_3 = (let_udt_1 => let_udt_2); - - + + operation letsOperations (q1 : Qubit, n : Int, udts : (Microsoft.Quantum.Overrides.udt0, let_udt_1, let_udt_2, let_udt_3, (Qubit => Unit))) : Range { - + // Assigning from identifier: let q2 = q1; - + // Assigning from op result: let r = M(q1); - + // Assigning from literal: let i = 1.1; let iZero = 0; let dZero = 0.0; - + // Assigning from ranges: let a = 0 .. 10; let b = 8 .. -1 .. 5; - + // Assigning from expressions // Simple and complex: let j = n + 1; let k = ((n - 1) * (n ^ 2) / 3) % 4; - + // Deconstructing tuples: let t = (2.2, (3, One)); let (l, (m, o)) = t; let (p, q) = t; let (u0, u1, u2, u3, call1) = udts; let u = u3!(u1); - + // Deconstructing inside inner blocks: if (true) { let (l2, (m2, o2)) = t; return (u3!(u1))!(u1); } - + // Interpolated string literal let s = $"n is {n} and u is {u3!(u1)}, {r}, {n}, {j}"; let str = $"Hello{true ? "quantum" | ""} world!"; - + //let str2 = "more complicated stuff { true ? $"{n}" | "" }"; // to be fixed in the compilation builder... - + // Discarding variables: let (l3, _) = t; let (_, (_, o3)) = t; @@ -691,10 +691,10 @@ namespace Microsoft.Quantum.Testing { let _ = t; return let_f0(n); } - - + + function bitOperations (a : Int, b : Int) : Bool { - + let andEx = a &&& b; let orEx = a ||| b; let xorEx = a ^^^ b; @@ -702,7 +702,7 @@ namespace Microsoft.Quantum.Testing { let right = a >>> b; let negation = ~~~a; let total = ((((andEx + orEx) + xorEx) + left) + right) + negation; - + if (total > 0) { return true; } @@ -710,15 +710,15 @@ namespace Microsoft.Quantum.Testing { return false; } } - + newtype arrays_T1 = Pauli[]; - + newtype arrays_T2 = (Pauli[], Int[]); - + newtype arrays_T3 = Result[][]; - + operation arraysOperations (qubits : Qubit[], register : Qubits, indices : Range[][], t : arrays_T3) : Result[][] { - + // Creating/Assigning arrays let q = qubits; let r1 = [Zero]; @@ -739,7 +739,7 @@ namespace Microsoft.Quantum.Testing { let r16 = qubits[1 .. -1]; let r18 = new Qubits[2]; let r19 = new Microsoft.Quantum.Overrides.udt0[7]; - + // Accessing array items: let i0 = ((r13!)[0])[1]; let i1 = r2[0 + Length(r1)]; @@ -749,7 +749,7 @@ namespace Microsoft.Quantum.Testing { let i5 = (indices[0])[1]; let i6 = (t!)[0]; let i7 = (register!)[3]; - + // Lengths: let l0 = Length(qubits); let l1 = Length(indices); @@ -761,16 +761,16 @@ namespace Microsoft.Quantum.Testing { return [[i0, One], [Zero]]; } - - + + function GetMeARange () : Range { - + return 0 .. 1; } - - + + operation sliceOperations (qubits : Qubit[], option : Int) : Qubit[] { - + let r2 = 10 .. -2 .. 0; let ranges = new Range[1]; let s1 = qubits[0 .. 10]; @@ -781,7 +781,7 @@ namespace Microsoft.Quantum.Testing { return qubits[10 .. -3 .. 0]; } - + operation rangeOperations (r: Range) : Int { return RangeStart(r) + RangeEnd(r) + RangeStep(r); @@ -789,32 +789,32 @@ namespace Microsoft.Quantum.Testing { function call_target1 ( - i : Int, - plain : (Qubit => Unit), - adj : (Qubit => Unit is Adj), - ctr : (Qubit => Unit is Ctl), + i : Int, + plain : (Qubit => Unit), + adj : (Qubit => Unit is Adj), + ctr : (Qubit => Unit is Ctl), uni : (Qubit => Unit is Adj + Ctl) ) : Unit { } - - - function call_target2 + + + function call_target2 ( - i : Int, plain : (Result, (Qubit => Unit)), - adj : (Result, (Qubit => Unit is Adj)), - ctr : (Result, (Qubit => Unit is Ctl)), + i : Int, plain : (Result, (Qubit => Unit)), + adj : (Result, (Qubit => Unit is Adj)), + ctr : (Result, (Qubit => Unit is Ctl)), uni : (Result, (Qubit => Unit is Adj + Ctl)) ) : Unit { } - + newtype call_plain = (Qubit => Unit); - + newtype call_adj = (Qubit => Unit is Adj); - + newtype call_ctr = (Qubit => Unit is Ctl); - + newtype call_uni = (Qubit => Unit is Adj + Ctl); - + operation callTests (qubits : Qubits) : Unit { - + let plain = call_plain(X); let adj = call_adj(X); let ctr = call_ctr(X); @@ -827,120 +827,120 @@ namespace Microsoft.Quantum.Testing { call_target2(1, (Zero, X), (Zero, X), (Zero, X), (Zero, X)); call_target2(2, (One, plain!), (One, adj!), (One, ctr!), (One, uni!)); } - - + + operation helloWorld (n : Int) : Int { - + let r = n + 1; return r; } - - + + operation alloc_op0 (q1 : Qubit) : Unit { body intrinsic; } - - + + operation allocOperation (n : Int) : Unit { - + body (...) { using (q = Qubit()) { let flag = true; (flag ? X | Z)(q); alloc_op0(q); } - + using (qs = Qubit[n]) { alloc_op0(qs[n - 1]); } - + using ((q1, (q2, (_, q3, _, q4))) = (Qubit(), ((Qubit(), Qubit[2]), (Qubit(), Qubit[n], Qubit[n - 1], Qubit[4])))) { alloc_op0(q1); alloc_op0(q3[1]); } } - + adjoint (...) { borrowing (b = Qubit[n]) { alloc_op0(b[n - 1]); } - + borrowing ((q1, (q2, (_, q3))) = (Qubit(), (Qubit[2], (Qubit(), (Qubit[n], Qubit[4]))))) { - + using (qt = (Qubit(), (Qubit[1], Qubit[2]))) { let (qt1, qt2) = qt; alloc_op0(qt1); } - + alloc_op0(q1); alloc_op0(q2[1]); } } } - - + + operation failedOperation (n : Int) : Int { - + fail "This operation should never be called."; return 1; } - - + + operation compareOps (n : Int) : Bool { - + let lt = n < 1; let lte = n <= 2; let gt = n > 3; let gte = n >= 4; return (lt == (lte and gt)) != gte or not lt; } - - + + operation partialGeneric1<'A, 'B> (a : 'A, b : 'B, c : ('A, 'B)) : Unit { body intrinsic; } - - + + operation partialGeneric2<'A, 'B, 'C, 'D> (a : 'A, b : 'B, c : ('C, 'D)) : Unit { body intrinsic; } - - + + operation partial1Args (a : Int) : Unit { body intrinsic; } - - + + operation partialInnerTuple (a : Int, b : (Double, Result)) : Unit { body intrinsic; } - - + + operation partial3Args (a : Int, b : Double, c : Result) : Unit { body intrinsic; } - - + + operation partialNestedArgsOp (a : (Int, Int, Int), b : ((Double, Double), (Result, Result, Result))) : Unit { body intrinsic; } - - + + function partialFunction (a : Int, b : Double, c : Pauli) : Result { return Zero; } - - + + // TODO: (partial1Args (_))(1); - operation partialApplicationTest + operation partialApplicationTest ( - i : Int, res : Result, - partialInput : ((Int, (Double, Double), (Result, Result, Result)) => Unit), + i : Int, res : Result, + partialInput : ((Int, (Double, Double), (Result, Result, Result)) => Unit), partialUnitary : ((Double, ((Int, Double) -> Result), Qubit[]) => Unit is Adj + Ctl) ) : (Qubit[] => Unit is Adj + Ctl) { - + (partial3Args(_, _, _))(1, 3.5, One); (partial3Args(1, _, Zero))(3.5); (partial3Args(_, 3.5, _))(1, Zero); @@ -964,37 +964,37 @@ namespace Microsoft.Quantum.Testing { (partialInput(1, (_, 1.1), (Zero, _, _)))(2.2, (One, One)); return partialUnitary(1.1, partialFunction(_, _, PauliX), _); } - + newtype Q = Qubit; - + newtype U = (Qubit => Unit is Adj + Ctl); - + newtype A = (Int -> Int[]); - + newtype B = (Int[] -> U); - + newtype C = (Int, A); - + newtype D = (Int[] -> U); - + newtype E = (Double -> C); - + newtype F = (D, E); - + newtype G = ((Double, F, Qubit[]) => Unit is Adj + Ctl); - + newtype AA = A; - + newtype QQ = Q; - - function partialFunctionTest + + function partialFunctionTest ( start : Double, t1 : (A, D), t2 : (B, E), op : G ) : (Qubit[] => Unit is Adj + Ctl) { - + let r1 = (partialFunction(_, _, _))(2, 2.2, PauliY); let r2 = ((partialFunction(1, _, _))(3.3, _))(PauliZ); let (a, d) = t1; @@ -1002,13 +1002,13 @@ namespace Microsoft.Quantum.Testing { let f = F(d, e); return op!(start, f, _); } - - + + operation OP_1 (q : Qubit) : Result { body intrinsic; } - - + + operation opParametersTest ( q1 : Qubit, @@ -1018,7 +1018,7 @@ namespace Microsoft.Quantum.Testing { t1 : (((Qubit[], (Qubit, Qubit)) => Unit is Ctl), ((Qubit[], (Qubit, Qubit)) => Unit is Adj + Ctl)), f1 : (Double -> Double) ) : (Qubit => Unit) { - + op1(OP_1); let v0 = op0; let r0 = v0(q1); @@ -1026,35 +1026,35 @@ namespace Microsoft.Quantum.Testing { op3([q1], (q1, q1)); return op2(q1, _); } - - + + operation With1C (outerOperation : (Qubit => Unit is Adj), innerOperation : (Qubit => Unit is Ctl), target : Qubit) : Unit { - + body (...) { outerOperation(target); innerOperation(target); Adjoint outerOperation(target); } - + controlled (controlRegister, ...) { outerOperation(target); Controlled innerOperation(controlRegister, target); Adjoint outerOperation(target); } } - - + + operation measureWithScratch (pauli : Pauli[], target : Qubit[]) : Result { - + mutable result = Zero; - + using (scratchRegister = Qubit[1]) { let scratch = scratchRegister[0]; - + for (idxPauli in 0 .. Length(pauli) - 1) { let P = pauli[idxPauli]; let src = [target[idxPauli]]; - + if (P == PauliX) { Controlled X(src, scratch); } @@ -1065,30 +1065,30 @@ namespace Microsoft.Quantum.Testing { Controlled (With1C(Microsoft.Quantum.Intrinsic.H, X, _))(src, scratch); } } - + set result = M(scratch); } - + return result; } - - + + operation noOpResult (r : Result) : Unit { - + body (...) { } - + adjoint invert; controlled distribute; controlled adjoint distribute; } - - + + operation noOpGeneric<'T> (r : 'T) : Unit { - + body (...) { } - + adjoint invert; controlled distribute; controlled adjoint distribute; @@ -1098,7 +1098,7 @@ namespace Microsoft.Quantum.Testing { { op(arg); } - + function iter<'T, 'U> (mapper : ('T -> 'U), source : 'T[]) : Unit { for (i in source) { let v = mapper(i); @@ -1122,16 +1122,16 @@ namespace Microsoft.Quantum.Intrinsic { namespace Microsoft.Quantum.Core { - function Length<'T> (a : 'T[]) : Int { - body intrinsic; + function Length<'T> (a : 'T[]) : Int { + body intrinsic; } - - function RangeStart (range : Range) : Int { + + function RangeStart (range : Range) : Int { body intrinsic; } - - + + function RangeEnd (range : Range) : Int { body intrinsic; } @@ -1145,92 +1145,92 @@ namespace Microsoft.Quantum.Core namespace Microsoft.Quantum.Compiler.Generics { - + open Microsoft.Quantum.Intrinsic; open Microsoft.Quantum.Testing; - - + + function genF1<'A> (arg : 'A) : Unit { body intrinsic; } - - + + operation genMapper<'T, 'U> (mapper : ('T => 'U), source : 'T[]) : 'U[] { - + mutable result = new 'U[Length(source)]; - + for (i in 0 .. Length(source) - 1) { let m = mapper(source[i]); - set result = result w/ i <- m; + set result = result w/ i <- m; } - + return result; } - - + + operation genIter<'T> (callback : ('T => Unit is Adj + Ctl), source : 'T[]) : Unit { - + body (...) { for (i in 0 .. Length(source) - 1) { callback(source[i]); } } - + adjoint invert; controlled distribute; controlled adjoint distribute; } - - + + operation genC1<'T> (a1 : 'T) : Unit { body intrinsic; } - - + + operation genC1a<'T> (a1 : 'T) : 'T { body intrinsic; } - - + + operation genC2<'T, 'U> (a1 : 'T) : 'T { body intrinsic; } - - + + operation genAdj1<'T> (a1 : 'T) : Unit { body intrinsic; adjoint self; } - - + + operation genU1<'T> (a1 : 'T) : Unit { - + body (...) { let x = genC2<'T, Unit>(a1); } - + adjoint (...) { } controlled (c, ...) { } controlled adjoint (c, ...) { } } - - + + operation genCtrl3<'X, 'Y, 'Z> (arg1 : 'X, arg2 : (Int, ('Y, 'Z), Result)) : Unit { body intrinsic; controlled intrinsic; } - - + + operation genU2<'A, 'B> (a1 : 'A, t1 : ('A, 'B), i : Int) : Unit { body intrinsic; adjoint intrinsic; controlled intrinsic; controlled adjoint intrinsic; } - - + + operation ResultToString (v : Result) : String { - + if (v == One) { return "uno"; } @@ -1238,14 +1238,14 @@ namespace Microsoft.Quantum.Compiler.Generics { return "zero"; } } - - + + operation usesGenerics () : Unit { - + let a = [One, Zero, Zero]; let s = [ResultToString(a[0]), ResultToString(a[1])]; noOpResult(a[0]); - + using (qubits = Qubit[3]) { let op = Hold(CNOT, (qubits[0], qubits[1]),_); @@ -1255,28 +1255,28 @@ namespace Microsoft.Quantum.Compiler.Generics { noOpGeneric(a[0]); genIter(X, qubits); } - + genIter(noOpResult, a); genIter(genU1, genMapper(ResultToString, a)); genIter(genU1, s); genIter(genU1, a); } - - + + operation composeImpl<'A, 'B> (second : ('A => Unit), first : ('B => 'A), arg : 'B) : Unit { - + second(first(arg)); } - - + + operation compose<'A, 'B> (second : ('A => Unit), first : ('B => 'A)) : ('B => Unit) { - + return composeImpl(second, first, _); } - - + + function genRecursion<'T> (x : 'T, cnt : Int) : 'T { - + if (cnt == 0) { return x; } @@ -1284,12 +1284,12 @@ namespace Microsoft.Quantum.Compiler.Generics { return genRecursion(x, cnt - 1); } } - - + + function MapDefaults<'C, 'B> (map : ('C -> 'C), l : Int) : Unit { - + mutable arr = new 'C[l]; - + for (i in 0 .. l - 1) { set arr = arr w/ i <- map(arr[i]); } @@ -1299,12 +1299,12 @@ namespace Microsoft.Quantum.Compiler.Generics { newtype MyType2 = (i1 : Int, i2 : MyType1, (i3 : Int[], i4 : String)); function UpdateUdtItems (udt : MyType2) : MyType2 { - + mutable arr = new Int[10]; return udt w/ i1 <- -5 - w/ i3 <- arr - w/ i1 <- 1; + w/ i3 <- arr + w/ i1 <- 1; } newtype NamedTuple = (FirstItem: (Int, Double), SecondItem: Int); diff --git a/src/Simulation/CsharpGeneration.Tests/SimulationCodeTests.fs b/src/Simulation/CsharpGeneration.Tests/SimulationCodeTests.fs index ad64c0ce78f..13c29cafd81 100644 --- a/src/Simulation/CsharpGeneration.Tests/SimulationCodeTests.fs +++ b/src/Simulation/CsharpGeneration.Tests/SimulationCodeTests.fs @@ -35,9 +35,9 @@ module SimulationCode = let ``Pure roslyn``() = let code = " namespace N1 - { + { enum E { A, b, C } - + public class C1 { public object P1 {get;set;} @@ -63,8 +63,8 @@ namespace N1 Assert.Equal(expected |> clearFormatting, actual |> clearFormatting) [] - let ``doubles in different locales`` () = - let cases = + let ``doubles in different locales`` () = + let cases = [ 1.1, "1.1D" 1000.001, "1000.001D" @@ -93,42 +93,42 @@ namespace N1 | DiagnosticSeverity.Error -> errors <- diag :: errors | _ -> () let addSourceFile (mgr:CompilationUnitManager) fileName = - let fileId = new Uri(Path.GetFullPath fileName) + let fileId = new Uri(Path.GetFullPath fileName) let file = CompilationUnitManager.InitializeFileManager(fileId, File.ReadAllText fileName) mgr.AddOrUpdateSourceFileAsync file |> ignore // TODO: catch compilation errors and fail let mgr = new CompilationUnitManager(null, fun ps -> ps.Diagnostics |> Array.iter addError) files |> List.iter (addSourceFile mgr) try let mutable compilation = mgr.Build().BuiltCompilation - if not errors.IsEmpty then - errors + if not errors.IsEmpty then + errors |> List.map (fun e -> sprintf "%s at %s, line %d" e.Message e.Source (e.Range.Start.Line + 1)) |> String.concat "\n" - |> failwith + |> failwith let functorGenSuccessful = CodeGeneration.GenerateFunctorSpecializations(compilation, &compilation) // todo: we might want to raise an error here if the functor generation fails (which will be the case for incorrect code) compilation.Namespaces with | e -> sprintf "compilation threw exception: \n%s" e.Message |> failwith // should never happen (all exceptions are caught by the compiler) - + let syntaxTree = parse [ (Path.Combine("Circuits", "Intrinsic.qs")); (Path.Combine("Circuits", "CodegenTests.qs")) ] let globalContext = CodegenContext.Create syntaxTree - let findCallable name = + let findCallable name = let key = NonNullable.New name - match globalContext.byName.TryGetValue key with + match globalContext.byName.TryGetValue key with | true, v -> v |> List.sort |> List.head - | false, _ -> sprintf "no callable with name %s has been successfully compiled" name |> failwith + | false, _ -> sprintf "no callable with name %s has been successfully compiled" name |> failwith let findUdt name = let key = globalContext.allUdts.Keys |> Seq.sort |> Seq.find (fun n -> n.Name.Value = name) - match globalContext.allUdts.TryGetValue key with - | true, v -> key.Namespace, v - | false, _ -> sprintf "no type with name %s has been successfully compiled" name |> failwith + match globalContext.allUdts.TryGetValue key with + | true, v -> key.Namespace, v + | false, _ -> sprintf "no type with name %s has been successfully compiled" name |> failwith //// // Create some operations for our tests... - //// + //// let emptyOperation = findCallable @"emptyOperation" let zeroQubitOperation = findCallable @"zeroQubitOperation" let oneQubitAbstractOperation = findCallable @"oneQubitAbstractOperation" @@ -153,7 +153,7 @@ namespace N1 let failedOperation = findCallable @"failedOperation" let compareOps = findCallable @"compareOps" let partialApplicationTest = findCallable @"partialApplicationTest" - let opParametersTest = findCallable @"opParametersTest" + let opParametersTest = findCallable @"opParametersTest" let measureWithScratch = findCallable @"measureWithScratch" let with1C = findCallable @"With1C" let genC1 = findCallable @"genC1" @@ -170,11 +170,11 @@ namespace N1 let nestedArgTuple1 = findCallable @"nestedArgTuple1" let nestedArgTuple2 = findCallable @"nestedArgTuple2" let nestedArgTupleGeneric = findCallable @"nestedArgTupleGeneric" - let udtsTest = findCallable @"udtsTest" - let compose = findCallable @"compose" - let composeImpl = findCallable @"composeImpl" - let callTests = findCallable @"callTests" - let udtTuple = findCallable @"udtTuple" + let udtsTest = findCallable @"udtsTest" + let compose = findCallable @"compose" + let composeImpl = findCallable @"composeImpl" + let callTests = findCallable @"callTests" + let udtTuple = findCallable @"udtTuple" let emptyFunction = findCallable @"emptyFunction" let intFunction = findCallable @"intFunction" let powFunction = findCallable @"powFunction" @@ -221,59 +221,59 @@ namespace N1 let expected = expected.Replace("%%%", (Uri(Path.GetFullPath fileName)).AbsolutePath) let expected = expected.Replace("%%", (Path.GetFullPath fileName).Replace("\\", "\\\\")) let tree = parse [(Path.Combine("Circuits","Intrinsic.qs")); fileName] - let actual = + let actual = CodegenContext.Create (tree, ImmutableDictionary.Empty) |> generate (Path.GetFullPath fileName |> NonNullable.New) Assert.Equal(expected |> clearFormatting, actual |> clearFormatting) let testOneBody (builder:SyntaxBuilder) (expected: string list) = - let actual = + let actual = builder.BuiltStatements |> List.map (fun s -> s.ToFullString()) Assert.Equal(expected.Length, actual.Length) List.zip (expected |> List.map clearFormatting) (actual |> List.map clearFormatting) |> List.iter Assert.Equal - + let testOneList op (build: CodegenContext -> 'X -> 'Y List) (arg: 'X) (clean: 'Y -> 'Z) (expected: 'Z list) = let context = createTestContext op - let actual = + let actual = arg |> build context |> List.map clean - List.zip expected actual + List.zip expected actual |> List.iter Assert.Equal<'Z> [] let ``tupleBaseClassName test`` () = let testOne (_, udt) expected = let context = (CodegenContext.Create syntaxTree).setUdt udt - let actual = tupleBaseClassName context udt.Type + let actual = tupleBaseClassName context udt.Type Assert.Equal (expected |> clearFormatting, actual |> clearFormatting) - + "QTuple>" |> testOne udt_args0 - + "QTuple<(Int64, IQArray)>" - |> testOne udt_args1 - + |> testOne udt_args1 + "QTuple" |> testOne udt_A - + "QTuple" |> testOne udt_AA "QTuple" |> testOne udt_U - + "QTuple" |> testOne udt_Q - + "QTuple" |> testOne udt_Real - + "QTuple<(udt_Real,udt_Real)>" |> testOne udt_Complex - + "QTuple>>" |> testOne udt_TwoDimArray @@ -288,14 +288,14 @@ namespace N1 let testOne (_,op) expected = let context = createTestContext op let sortByNames l = l |> List.sortBy (fun ((n,_),_) -> n) |> List.sortBy (fun ((_,ns),_) -> ns) - let actual = + let actual = op |> operationDependencies |> List.map (fun n -> ((n.Namespace.Value, n.Name.Value), (n |> roslynCallableTypeName context))) - + List.zip (expected |> sortByNames) (actual |> sortByNames) |> List.iter Assert.Equal - + [] |> testOne emptyOperation @@ -307,21 +307,21 @@ namespace N1 ((NS2, "R" ), "IAdjointable<(Double,Qubit)>") ] |> testOne twoQubitOperation - + [ ((NS1,"three_op1"), "IUnitary<(Qubit,Qubit)>") ] |> testOne threeQubitOperation - + [] |> testOne randomAbstractOperation - + [ ((NS2, "Z"), "IUnitary") ((NS1, "selfInvokingOperation"), "IAdjointable") ] |> testOne selfInvokingOperation - + [ ((NSG, "genRecursion"), "ICallable") ] @@ -332,7 +332,7 @@ namespace N1 ((NS1, "let_f0" ), "ICallable") ] |> testOne letsOperations - + [] |> testOne helloWorld @@ -349,7 +349,7 @@ namespace N1 [] |> testOne failedOperation - + [] |> testOne compareOps @@ -370,9 +370,9 @@ namespace N1 ((NS1, "repeat_op0"), "ICallable") ((NS1, "repeat_op1"), "ICallable<(Int64,IQArray), Result>") ((NS1, "repeat_op2"), "ICallable<(Double,repeat_udt0), Result>") - ((NS1, "repeat_udt0"), "ICallable<(Int64,IQArray), repeat_udt0>") + ((NS1, "repeat_udt0"), "ICallable<(Int64,IQArray), repeat_udt0>") ] - |> testOne repeatOperation + |> testOne repeatOperation [ ((NS1, "partial3Args"), "ICallable<(Int64,Double,Result), QVoid>") @@ -383,12 +383,12 @@ namespace N1 ((NS1, "partialNestedArgsOp"), "ICallable<((Int64,Int64,Int64),((Double,Double),(Result,Result,Result))), QVoid>") ] |> testOne partialApplicationTest - + [ ((NS1, "OP_1"), "ICallable") ] |> testOne opParametersTest - + [ ((NS2, "Allocate" ), "Allocate") ((NS2, "Borrow" ), "Borrow") @@ -408,9 +408,9 @@ namespace N1 ((NS1, "random_op8" ), "ICallable<(Qubit,Pauli), QVoid>") ((NS1, "random_op9" ), "IUnitary<(Qubit,Pauli)>") ] - |> testOne randomOperation - - [ + |> testOne randomOperation + + [ ((NS2, "Allocate" ), "Allocate") ((NS2, "H" ), "IUnitary") ((NSC, "Length" ), "ICallable") @@ -421,18 +421,18 @@ namespace N1 ((NS2, "X" ), "IUnitary") ] |> testOne measureWithScratch - + [] |> testOne genC1 - + [ ((NSG, "genC2" ), "ICallable") ] |> testOne genU1 - + [] |> testOne genCtrl3 - + [ ((NS2, "Allocate" ), "Allocate") ((NS2, "CNOT" ), "IAdjointable<(Qubit,Qubit)>") @@ -446,7 +446,7 @@ namespace N1 ((NS1, "noOpGeneric" ), "IUnitary") ((NS1, "noOpResult" ), "IUnitary") ] - |> testOne usesGenerics + |> testOne usesGenerics [ ((NS2, "Allocate" ), "Allocate") @@ -456,23 +456,23 @@ namespace N1 ((NS1, "emptyFunction" ), "ICallable") ((NSO, "emptyFunction" ), "ICallable") ] - |> testOne duplicatedDefinitionsCaller - + |> testOne duplicatedDefinitionsCaller + [ ((NS1, "iter"), "ICallable") ((NSC, "Length"), "ICallable") ] |> testOne testLengthDependency - + [] let ``flatArgumentsList test`` () = - let testOne (_, op: QsCallable) (expectedArgs: (string * string) list) = + let testOne (_, op: QsCallable) (expectedArgs: (string * string) list) = testOneList op flatArgumentsList op.ArgumentTuple id expectedArgs [] |> testOne emptyOperation - + [ ("n", "Int64") ] @@ -482,14 +482,14 @@ namespace N1 ("q1", "Qubit") ] |> testOne oneQubitAbstractOperation - + [ "q1", "Qubit" "t1", "(Qubit,Double)" ] |> testOne twoQubitOperation - - + + [ "q1", "Qubit" "q2", "Qubit" @@ -500,11 +500,11 @@ namespace N1 [ "q1", "Qubit" "b", "Basis" - "t", "(Pauli,IQArray>,Boolean)" + "t", "(Pauli,IQArray>,Boolean)" "i", "Int64" ] |> testOne randomAbstractOperation - + [ "a", "Int64" "b", "Int64" @@ -512,7 +512,7 @@ namespace N1 "d", "Double" ] |> testOne nestedArgTuple1 - + [ "a", "(Int64,Int64)" "c", "Double" @@ -521,7 +521,7 @@ namespace N1 "e", "Double" ] |> testOne nestedArgTuple2 - + [ "outerOperation", "IAdjointable" "innerOperation", "IControllable" @@ -533,33 +533,33 @@ namespace N1 "a1", "__T__" ] |> testOne genC1 - + [ "arg1", "__X__" "arg2", "(Int64,(__Y__,__Z__),Result)" ] |> testOne genCtrl3 - + [ "second", "ICallable" "first", "ICallable" "arg", "__B__" ] |> testOne composeImpl - + [ "mapper", "ICallable" "source", "IQArray<__T__>" ] |> testOne genMapper - + [] let ``findQubitFields test`` () = let testOne (_,op) = testOneList op findQubitFields op.Signature.ArgumentType (snd >> formatSyntaxTree) [] |> testOne emptyOperation - + [] |> testOne helloWorld @@ -567,28 +567,28 @@ namespace N1 "Data" ] |> testOne oneQubitAbstractOperation - + [ "Data.Item1" "Data.Item2.Item1" ] |> testOne twoQubitOperation - - + + [ "Data.Item1" "Data.Item2" "Data.Item3?.Data" ] |> testOne threeQubitOperation - + [ "Data.Item1" "Data.Item2" "Data.Item3" ] |> testOne differentArgsOperation - + [ "Data.Item1" ] @@ -598,7 +598,7 @@ namespace N1 "Data.Item1" ] |> testOne randomAbstractOperation - + [ ] |> testOne nestedArgTuple1 @@ -608,19 +608,19 @@ namespace N1 "Data.Item2.Item2.Item2.Item2" ] |> testOne nestedArgTuple2 - + [ "Data" ] |> testOne genU1 - + [ "Data.Item1" "Data.Item2.Item2.Item1" "Data.Item2.Item2.Item2" ] |> testOne genCtrl3 - + [ "Data.Item2?.Data.Item2" "Data.Item3?.Data.Item2.Item1" @@ -631,7 +631,7 @@ namespace N1 [] |> testOne emptyFunction - + [ "Data.Item2.Item1?.Data" "Data.Item2.Item2?.Data" @@ -640,7 +640,7 @@ namespace N1 "Data.Item4?.Data" ] |> testOne partialFunctionTest - + [] let ``buildQubitsField test`` () = let testOne (_,op) expected = testOneList op buildQubitsField op.Signature.ArgumentType (formatSyntaxTree >> clearFormatting) (expected |> List.map clearFormatting) @@ -649,7 +649,7 @@ namespace N1 "System.Collections.Generic.IEnumerable IApplyData.Qubits => null;" ] |> testOne emptyOperation - + [ "System.Collections.Generic.IEnumerable IApplyData.Qubits => null;" ] @@ -665,7 +665,7 @@ namespace N1 }" ] |> testOne oneQubitAbstractOperation - + [ "System.Collections.Generic.IEnumerable IApplyData.Qubits { @@ -677,38 +677,38 @@ namespace N1 }" ] |> testOne twoQubitOperation - - + + [ "System.Collections.Generic.IEnumerable IApplyData.Qubits { get { return Qubit.Concat( - ((IApplyData)Data.Item1)?.Qubits, - ((IApplyData)Data.Item2)?.Qubits, + ((IApplyData)Data.Item1)?.Qubits, + ((IApplyData)Data.Item2)?.Qubits, ((IApplyData)Data.Item3?.Data)?.Qubits ); } }" ] |> testOne threeQubitOperation - + [ "System.Collections.Generic.IEnumerable IApplyData.Qubits { get { return Qubit.Concat( - ((IApplyData)Data.Item1)?.Qubits, - ((IApplyData)Data.Item2)?.Qubits, + ((IApplyData)Data.Item1)?.Qubits, + ((IApplyData)Data.Item2)?.Qubits, ((IApplyData)Data.Item3)?.Qubits ); } }" ] |> testOne differentArgsOperation - + [ "System.Collections.Generic.IEnumerable IApplyData.Qubits { @@ -719,7 +719,7 @@ namespace N1 }" ] |> testOne randomOperation - + [ "System.Collections.Generic.IEnumerable IApplyData.Qubits => null;" ] @@ -736,7 +736,7 @@ namespace N1 }" ] |> testOne nestedArgTuple2 - + [ "System.Collections.Generic.IEnumerable IApplyData.Qubits @@ -751,14 +751,14 @@ namespace N1 }" ] |> testOne udtTuple - + [ - "System.Collections.Generic.IEnumerable IApplyData.Qubits + "System.Collections.Generic.IEnumerable IApplyData.Qubits { get { return Qubit.Concat( - ((IApplyData)Data.Item1)?.Qubits, + ((IApplyData)Data.Item1)?.Qubits, ((IApplyData)Data.Item3.Item2?.Data.Item2)?.Qubits, ((IApplyData)Data.Item3.Item3?.Data)?.Qubits, ((IApplyData)Data.Item3.Item4?.Data)?.Qubits, @@ -768,7 +768,7 @@ namespace N1 }" ] |> testOne letsOperations - + [ "System.Collections.Generic.IEnumerable IApplyData.Qubits { @@ -781,7 +781,7 @@ namespace N1 ] |> testOne genU1 - + [ "System.Collections.Generic.IEnumerable IApplyData.Qubits { @@ -791,8 +791,8 @@ namespace N1 var __temp2__ = Data.Item2.Item2.Item1; var __temp3__ = Data.Item2.Item2.Item2; return Qubit.Concat( - __temp1__?.GetQubits(), - __temp2__?.GetQubits(), + __temp1__?.GetQubits(), + __temp2__?.GetQubits(), __temp3__?.GetQubits() ); } @@ -804,43 +804,43 @@ namespace N1 let ``areAllQubitArgs test`` () = let testOne (_,op) expected = let context = createTestContext op - let actual = + let actual = op.Signature.ArgumentType |> findQubitFields context |> List.map fst |> areAllQubitArgs - Assert.Equal (expected, actual) + Assert.Equal (expected, actual) true |> testOne emptyOperation - + true |> testOne helloWorld true |> testOne oneQubitAbstractOperation - + true |> testOne twoQubitOperation - + false |> testOne threeQubitOperation - + false |> testOne differentArgsOperation - + true |> testOne randomOperation true |> testOne randomAbstractOperation - + true |> testOne nestedArgTuple1 true |> testOne nestedArgTuple2 - + let depsByName (l : QsQualifiedName list) = l |> List.sortBy (fun n -> n.Namespace.Value) |> List.sortBy (fun n -> n.Name.Value) @@ -857,11 +857,11 @@ namespace N1 [ ] |> testOne emptyOperation - + [ ] |> testOne oneQubitAbstractOperation - + [ ] |> testOne genU2 @@ -875,7 +875,7 @@ namespace N1 template "emptyFunction" "ICallable" "emptyFunction" ] |> testOne duplicatedDefinitionsCaller - + [ template "Allocate" "Allocate" "Microsoft.Quantum.Intrinsic.Allocate" template "CNOT" "IAdjointable<(Qubit, Qubit)>" "Microsoft.Quantum.Intrinsic.CNOT" @@ -890,28 +890,28 @@ namespace N1 template "MicrosoftQuantumTestingnoOpResult" "IUnitary" "Microsoft.Quantum.Testing.noOpResult" ] |> testOne usesGenerics - + [ template "Z" "IUnitary" "Microsoft.Quantum.Intrinsic.Z" "this.self = this;" ] |> testOne selfInvokingOperation - + [ template "self" "ICallable" "genRecursion<>" ] |> testOne genRecursion - + [] let ``getTypeOfOp test`` () = let testOne (_,op) = let dependendies context d = operationDependencies d |> List.map (getTypeOfOp context) - |> List.map formatSyntaxTree + |> List.map formatSyntaxTree |> List.sort testOneList op dependendies op id - + let template = sprintf "typeof(%s)" [ template "Microsoft.Quantum.Intrinsic.Allocate" @@ -928,12 +928,12 @@ namespace N1 ] |> List.sort |> testOne usesGenerics - + [ template "composeImpl<,>" ] |> testOne compose - + [ template "genRecursion<>" ] @@ -949,7 +949,7 @@ namespace N1 let ``buildOpsProperties test`` () = let testOne (_,op) expected = let context = createTestContext op - let actual = + let actual = op |> operationDependencies |> depsByName @@ -973,13 +973,13 @@ namespace N1 template "IUnitary" "MicrosoftQuantumTestingnoOpResult" ] |> testOne usesGenerics - + [ template "IUnitary" "Z" template "IAdjointable" "self" ] |> testOne selfInvokingOperation - + [ template "ICallable" "self" ] @@ -1027,19 +1027,19 @@ namespace N1 template "QVoid" "QVoid" "emptyFunction" |> testOne emptyFunction - let findBody op = + let findBody op = let isBody (sp:QsSpecialization) = match sp.Kind with | QsBody -> true | _ -> false (op.Specializations |> Seq.find isBody) - let findAdjoint op = + let findAdjoint op = let isAdjoint (sp:QsSpecialization) = match sp.Kind with | QsAdjoint -> true | _ -> false (op.Specializations |> Seq.find isAdjoint) - let findControlled op = + let findControlled op = let isControlled (sp:QsSpecialization) = match sp.Kind with | QsControlled -> true | _ -> false (op.Specializations |> Seq.find isControlled) - let findControlledAdjoint op = + let findControlledAdjoint op = let isControlledAdjoint (sp:QsSpecialization) = match sp.Kind with | QsControlledAdjoint -> true | _ -> false (op.Specializations |> Seq.find isControlledAdjoint) @@ -1047,7 +1047,7 @@ namespace N1 let context = createTestContext op let builder = new SyntaxBuilder(context) builder.Namespaces.OnSpecializationDeclaration sp |> ignore - builder + builder let applyVisitor (ns,op) = createVisitor (ns,op) (findBody op) @@ -1058,7 +1058,7 @@ namespace N1 let controlledVisitor (ns,op) = createVisitor (ns,op) (findControlled op) - + [] let ``basic body builder`` () = let testOne = testOneBody @@ -1071,7 +1071,7 @@ namespace N1 "X.Apply(q1);" ] |> testOne (applyVisitor oneQubitOperation) - + [ "X.Adjoint.Apply(q1);" ] @@ -1102,16 +1102,16 @@ namespace N1 "self.Apply(q1);" ] |> testOne (adjointVisitor selfInvokingOperation) - + [] let ``recursive functions body`` () = let testOne = testOneBody - + [ """ if ((cnt == 0L)) { - return x; + return x; } else { @@ -1125,7 +1125,7 @@ namespace N1 """ if ((x == 1L)) { - return 1L; + return 1L; } else { @@ -1134,30 +1134,30 @@ namespace N1 """ ] |> testOne (applyVisitor factorial) - + [] let ``generic functions body`` () = let testOne = testOneBody - + [ "X.Apply(q1);" ] |> testOne (applyVisitor oneQubitOperation) - + [] let ``composed generic body`` () = let testOne = testOneBody - + [ "second.Apply(first.Apply<__A__>(arg));" ] |> testOne (applyVisitor composeImpl) - + [ "return composeImpl.Partial((second, first, _));" ] |> testOne (applyVisitor compose) - + [] let ``usesGenerics body`` () = @@ -1165,7 +1165,7 @@ namespace N1 "var a = (IQArray)new QArray(Result.One, Result.Zero, Result.Zero);" "var s = (IQArray)new QArray(ResultToString.Apply(a[0L]), ResultToString.Apply(a[1L]));" "MicrosoftQuantumTestingnoOpResult.Apply(a[0L]);" - + """ { var qubits = Allocate.Apply(3L); @@ -1182,7 +1182,7 @@ namespace N1 } #line hidden catch - { + { __arg1__ = false; throw; } @@ -1220,7 +1220,7 @@ namespace N1 "call_target1.Apply((1L, X, X, X, X));" "call_target1.Apply((1L, plain.Data, adj.Data, ctr.Data, uni.Data));" - + "call_target2.Apply((1L, (Result.Zero, X), (Result.Zero, X), (Result.Zero, X), (Result.Zero, X)));" "call_target2.Apply((2L, (Result.One, plain.Data), (Result.One, adj.Data), (Result.One, ctr.Data), (Result.One, uni.Data)));" ] @@ -1268,7 +1268,7 @@ namespace N1 "return let_f0.Apply(n);" ] |> testOneBody (applyVisitor letsOperations) - + [] let ``bit operations`` () = [ @@ -1280,7 +1280,7 @@ namespace N1 "var negation = ~(a); " "var total = (((((andEx + orEx) + xorEx) + left) + right) + negation);" - """ + """ if ((total > 0L)) { return true; @@ -1292,7 +1292,7 @@ namespace N1 """ ] |> testOneBody (applyVisitor bitOperations) - + [] let ``helloWorld body`` () = [ @@ -1300,14 +1300,14 @@ namespace N1 "return r;" ] |> testOneBody (applyVisitor helloWorld) - + [] let ``if operations`` () = [ "var n = 0L;" """ - if ((r == Result.One)) - { + if ((r == Result.One)) + { n = (if_f0.Apply(QVoid.Instance) * i); } """ @@ -1329,7 +1329,7 @@ namespace N1 else if ((p == Pauli.PauliY)) { return 1L; - } + } else { return ((p==Pauli.PauliI)?3L:if_f0.Apply(QVoid.Instance)); @@ -1337,39 +1337,39 @@ namespace N1 """ ] |> testOneBody (applyVisitor ifOperation) - + [] let ``foreach operations`` () = [ "var result = 0L;" - @"foreach (var n in new QRange(0L, i)) + @"foreach (var n in new QRange(0L, i)) #line hidden - { - result = (result + i); + { + result = (result + i); }" - @"foreach (var n in new QRange(i, -(1L), 0L)) + @"foreach (var n in new QRange(i, -(1L), 0L)) #line hidden - { - result = ((result - i) * 2L); + { + result = ((result - i) * 2L); }" "var range = new QRange(0L, 10L);" - @"foreach (var n in range) + @"foreach (var n in range) #line hidden - { - result = ((range.End + result) + (n * -(foreach_f2.Apply((n, 4L))))); + { + result = ((range.End + result) + (n * -(foreach_f2.Apply((n, 4L))))); }" """ - if ((result > 10L)) - { + if ((result > 10L)) + { return Result.One; - } + } else { return Result.Zero; }""" ] |> testOneBody (applyVisitor foreachOperation) - + [] let ``udt operations`` () = [ @@ -1390,21 +1390,21 @@ namespace N1 "return new udt_args1((22L, qubits));" ] |> testOneBody (applyVisitor udtsTest) - + [] let ``test Length dependency`` () = [ "iter.Apply((Length, new QArray>(new QArray(Result.One), new QArray(Result.Zero, Result.One))));" ] |> testOneBody (applyVisitor testLengthDependency) - + [] let ``udt return values`` () = [ "return QVoid.Instance;" ] |> testOneBody (applyVisitor returnTest1) - + [ "return 5L;" ] @@ -1414,7 +1414,7 @@ namespace N1 "return (5L, 6L);" ] |> testOneBody (applyVisitor returnTest3) - + [ "return new returnUdt0((7L, 8L));" ] @@ -1424,32 +1424,32 @@ namespace N1 "return new QArray(9L, 10L);" ] |> testOneBody (applyVisitor returnTest5) - + [ "return new returnUdt1( new QArray<(Int64,Int64)>((1L, 2L), (3L, 4L)));" ] |> testOneBody (applyVisitor returnTest6) - + [ "return new QArray( new returnUdt0((1L, 2L)), new returnUdt0((3L, 4L)));" ] |> testOneBody (applyVisitor returnTest7) - + [ "return new returnUdt3(new QArray(new returnUdt0((1L, 2L)), new returnUdt0((3L, 4L))));" ] |> testOneBody (applyVisitor returnTest8) - + [ "return (new returnUdt0((7L, 8L)), new returnUdt1(new QArray<(Int64,Int64)>((1L, 2L), (3L, 4L))));" ] |> testOneBody (applyVisitor returnTest9) - + [ "return new Microsoft.Quantum.Overrides.udt0((Result.Zero, Result.One));" ] |> testOneBody (applyVisitor returnTest10) - + [] let ``repeat operation`` () = [ @@ -1457,7 +1457,7 @@ namespace N1 { var qubits = Allocate.Apply(i); #line hidden - bool __arg1__ = true; + bool __arg1__ = true; try { while (true) @@ -1476,15 +1476,15 @@ namespace N1 } #line hidden catch - { - __arg1__ = false; + { + __arg1__ = false; throw; } #line hidden finally { - if (__arg1__) - { + if (__arg1__) + { Release.Apply(qubits); } } @@ -1492,7 +1492,7 @@ namespace N1 """ ] |> testOneBody (applyVisitor repeatOperation) - + [] let ``allocate operations`` () = [ @@ -1500,7 +1500,7 @@ namespace N1 { var q = Allocate.Apply(); #line hidden - bool __arg1__ = true; + bool __arg1__ = true; try { var flag = true; @@ -1509,15 +1509,15 @@ namespace N1 } #line hidden catch - { - __arg1__ = false; + { + __arg1__ = false; throw; } #line hidden - finally + finally { if (__arg1__) - { + { Release.Apply(q); } } @@ -1526,22 +1526,22 @@ namespace N1 { var qs = Allocate.Apply(n); #line hidden - bool __arg2__ = true; + bool __arg2__ = true; try { alloc_op0.Apply(qs[(n-1L)]); } #line hidden catch - { - __arg2__ = false; + { + __arg2__ = false; throw; } #line hidden finally { if (__arg2__) - { + { Release.Apply(qs); } } @@ -1550,7 +1550,7 @@ namespace N1 { var (q1, (q2, (__arg3__, q3, __arg4__, q4))) = (Allocate.Apply(), ((Allocate.Apply(), Allocate.Apply(2L)), (Allocate.Apply(), Allocate.Apply(n), Allocate.Apply((n-1L)), Allocate.Apply(4L)))); #line hidden - bool __arg5__ = true; + bool __arg5__ = true; try { alloc_op0.Apply(q1); @@ -1558,15 +1558,15 @@ namespace N1 } #line hidden catch - { - __arg5__ = false; + { + __arg5__ = false; throw; } #line hidden finally { if (__arg5__) - { + { Release.Apply(q1); Release.Apply(q2.Item1); Release.Apply(q2.Item2); @@ -1585,22 +1585,22 @@ namespace N1 { var b = Borrow.Apply(n); #line hidden - bool __arg1__ = true; + bool __arg1__ = true; try { alloc_op0.Apply(b[(n-1L)]); } #line hidden catch - { - __arg1__ = false; + { + __arg1__ = false; throw; } #line hidden finally { - if (__arg1__) - { + if (__arg1__) + { Return.Apply(b); } } @@ -1609,29 +1609,29 @@ namespace N1 { var (q1, (q2, (__arg2__, q3))) = (Borrow.Apply(), (Borrow.Apply(2L), (Borrow.Apply(), (Borrow.Apply(n), Borrow.Apply(4L))))); #line hidden - bool __arg3__ = true; + bool __arg3__ = true; try { { var qt = (Allocate.Apply(), (Allocate.Apply(1L), Allocate.Apply(2L))); #line hidden - bool __arg4__ = true; + bool __arg4__ = true; try { var (qt1, qt2) = ((Qubit, (IQArray, IQArray)))qt; alloc_op0.Apply(qt1); - } + } #line hidden catch - { - __arg4__ = false; + { + __arg4__ = false; throw; - } + } #line hidden finally { if (__arg4__) - { + { Release.Apply(qt.Item1); Release.Apply(qt.Item2.Item1); Release.Apply(qt.Item2.Item2); @@ -1644,15 +1644,15 @@ namespace N1 } #line hidden catch - { - __arg3__ = false; + { + __arg3__ = false; throw; } #line hidden finally { if (__arg3__) - { + { Return.Apply(q1); Return.Apply(q2); Return.Apply(__arg2__); @@ -1663,7 +1663,7 @@ namespace N1 }""" ] |> testOneBody (adjointVisitor allocOperation) - + [] let ``failed operation`` () = [ @@ -1671,8 +1671,8 @@ namespace N1 @"return 1L;" ] |> testOneBody (applyVisitor failedOperation) - - + + [] let ``compare operations`` () = [ @@ -1683,7 +1683,7 @@ namespace N1 "return (((lt == (lte && gt)) != gte) || !(lt));" ] |> testOneBody (applyVisitor compareOps) - + let testOneSpecialization pick (_,op) expected = let context = createTestContext op let actual = op |> pick |> buildSpecialization context |> Option.map (fst >> formatSyntaxTree) @@ -1691,26 +1691,26 @@ namespace N1 [] let ``buildSpecialization - apply`` () = - let testOne = testOneSpecialization findBody + let testOne = testOneSpecialization findBody None |> testOne emptyOperation None |> testOne oneQubitAbstractOperation - + None |> testOne oneQubitSelfAdjointAbstractOperation - + None |> testOne randomAbstractOperation - + Some """ public override Func Body => (__in__) => { #line hidden return QVoid.Instance; - };""" + };""" |> testOne zeroQubitOperation Some """ @@ -1740,8 +1740,8 @@ namespace N1 }; """ |> testOne twoQubitOperation - - + + Some """ public override Func<(Qubit,Qubit,IQArray), QVoid> Body => (__in__) => { @@ -1757,11 +1757,11 @@ namespace N1 }; """ |> testOne differentArgsOperation - + [] let ``operation/function types`` () = let testOne = testOneSpecialization findBody - + let ret = "ICallable"; let op0 = "ICallable"; let op1 = "ICallable"; @@ -1778,7 +1778,7 @@ namespace N1 var r0 = v0.Apply(q1); var (op3, op4) = t1; op3.Apply((new QArray(q1), (q1, q1))); - + return op2.Partial(new Func((__arg1__) => (q1, __arg1__))); };""" op0 op1 op2 op3 op4 f1 ret) |> testOne opParametersTest @@ -1786,7 +1786,7 @@ namespace N1 [] let ``array operations`` () = [ - "var q = (IQArray)qubits;" + "var q = (IQArray)qubits;" "var r1 = (IQArray)new QArray(Result.Zero);" "var r2 = (IQArray)new QArray(0L, 1L);" "var r3 = (IQArray)new QArray(0D, 1.1D, 2.2D);" @@ -1795,7 +1795,7 @@ namespace N1 "var r6 = QArray.Create(r5.Length);" "var r7 = (IQArray)QArray.Add(r2, r4);" "var r8 = (IQArray)r7?.Slice(new QRange(1L, 5L, 10L));" - + "var r9 = new arrays_T1(new QArray(Pauli.PauliX, Pauli.PauliY));" "var r10 = (IQArray)QArray.Create(4L);" "var r11 = new arrays_T2((new QArray(Pauli.PauliZ), new QArray(4L)));" @@ -1805,7 +1805,7 @@ namespace N1 "var r15 = (IQArray)register.Data?.Slice(new QRange(0L, 2L));" "var r16 = (IQArray)qubits?.Slice(new QRange(1L, -(1L)));" "var r18 = (IQArray)QArray.Create(2L);" - "var r19 = (IQArray)QArray.Create(7L);" + "var r19 = (IQArray)QArray.Create(7L);" "var i0 = r13.Data[0L][1L];" "var i1 = r2[(0L + r1.Length)];" "var i2 = r3[(i1 * ((2L + 3L) - (8L % 1L)))];" @@ -1814,7 +1814,7 @@ namespace N1 "var i5 = indices[0L][1L];" "var i6 = (IQArray)t.Data[0L];" "var i7 = register.Data[3L];" - + "var l0 = qubits.Length;" "var l1 = indices.Length;" "var l2 = indices[0L].Length;" @@ -1822,12 +1822,12 @@ namespace N1 "var l4 = r8.Length;" "var l5 = r9.Data.Length;" "var l6 = register.Data.Length;" - + "return new QArray>(new QArray(i0, Result.One), new QArray(Result.Zero));" ] |> testOneBody (applyVisitor arraysOperations) - - + + [] let ``array slice`` () = [ @@ -1842,7 +1842,7 @@ namespace N1 "return qubits?.Slice(new QRange(10L,-(3L),0L));" ] |> testOneBody (applyVisitor sliceOperations) - + [] let ``range operations`` () = [ @@ -1853,10 +1853,10 @@ namespace N1 [] let ``generic parameter types`` () = let testOne (ns,op : QsCallable) (expected: string list) = - let actual = + let actual = op.Signature |> typeParametersNames - List.zip (expected |> List.map clearFormatting) (actual |> List.map clearFormatting) + List.zip (expected |> List.map clearFormatting) (actual |> List.map clearFormatting) |> List.iter Assert.Equal [] @@ -1864,28 +1864,28 @@ namespace N1 [] |> testOne oneQubitAbstractOperation - + [] |> testOne randomAbstractOperation - + [ "__T__" ] |> testOne genC1 - + [ "__T__" "__U__" ] |> testOne genC2 - + [ "__X__" "__Y__" "__Z__" ] |> testOne genCtrl3 - + [ "__T__" "__U__" @@ -1893,35 +1893,35 @@ namespace N1 |> testOne genMapper [] - let ``buildSpecialization - adjoint`` () = + let ``buildSpecialization - adjoint`` () = let testOne = testOneSpecialization findAdjoint None |> testOne oneQubitAbstractOperation - - Some "public override Func AdjointBody => Body;" + + Some "public override Func AdjointBody => Body;" |> testOne oneQubitSelfAdjointAbstractOperation None |> testOne randomAbstractOperation - - Some "public override Func AdjointBody => Body;" - |> testOne oneQubitSelfAdjointOperation - + + Some "public override Func AdjointBody => Body;" + |> testOne oneQubitSelfAdjointOperation + Some """ public override Func AdjointBody => (__in__) => { #line hidden return QVoid.Instance; - };""" + };""" |> testOne zeroQubitOperation - + Some """ public override Func AdjointBody => (__in__) => { var q1 = __in__; X.Adjoint.Apply(q1); - + #line hidden return QVoid.Instance; };""" @@ -1936,12 +1936,12 @@ namespace N1 R.Adjoint.Apply((r, q1)); CNOT.Adjoint.Apply((q1, q2)); - + #line hidden return QVoid.Instance; };""" - |> testOne twoQubitOperation - + |> testOne twoQubitOperation + Some """ public override Func<(Qubit,Qubit,Qubits), QVoid> AdjointBody => (__in__) => { @@ -1952,25 +1952,25 @@ namespace N1 #line hidden return QVoid.Instance; };""" - |> testOne threeQubitOperation - - + |> testOne threeQubitOperation + + Some "public override Func<__T__, QVoid> AdjointBody => Body;" |> testOne genAdj1 - + [] - let ``buildSpecialization - controlled`` () = + let ``buildSpecialization - controlled`` () = let testOne = testOneSpecialization findControlled - + None |> testOne oneQubitAbstractOperation - + None |> testOne oneQubitSelfAdjointAbstractOperation - + None |> testOne randomAbstractOperation - + Some """ public override Func<(IQArray,QVoid), QVoid> ControlledBody => (__in__) => { @@ -1978,7 +1978,7 @@ namespace N1 #line hidden return QVoid.Instance; - };""" + };""" |> testOne zeroQubitOperation Some """ @@ -1991,8 +1991,8 @@ namespace N1 #line hidden return QVoid.Instance; };""" - |> testOne oneQubitOperation - + |> testOne oneQubitOperation + Some """ public override Func<(IQArray,(Qubit,Qubit,Qubits)), QVoid> ControlledBody => (__in__) => { @@ -2001,25 +2001,25 @@ namespace N1 three_op1.Controlled.Apply((c, (q1, q2))); three_op1.Controlled.Apply((c, (q2, q1))); three_op1.Controlled.Apply((c, (q1, q2))); - + #line hidden return QVoid.Instance; };""" |> testOne threeQubitOperation - + [] - let ``buildSpecialization - controlled-adjoint`` () = + let ``buildSpecialization - controlled-adjoint`` () = let testOne = testOneSpecialization findControlledAdjoint None |> testOne oneQubitAbstractOperation - + Some "public override Func<(IQArray,Qubit), QVoid> ControlledAdjointBody => ControlledBody;" |> testOne oneQubitSelfAdjointAbstractOperation - + None |> testOne randomAbstractOperation - + Some """ public override Func<(IQArray,QVoid), QVoid> ControlledAdjointBody => (__in__) => { @@ -2027,11 +2027,11 @@ namespace N1 #line hidden return QVoid.Instance; - };""" + };""" |> testOne zeroQubitOperation Some """ - public override Func<(IQArray, Qubit), QVoid> ControlledAdjointBody => (__in__) => + public override Func<(IQArray, Qubit), QVoid> ControlledAdjointBody => (__in__) => { var (c,q1) = __in__; X.Controlled.Adjoint.Apply((c, q1)); @@ -2040,12 +2040,12 @@ namespace N1 };""" |> testOne oneQubitOperation - + Some """ public override Func<(IQArray,(Qubit,Qubit,Qubits)), QVoid> ControlledAdjointBody => (__in__) => { var (c,(q1,q2,arr1)) = __in__; - + three_op1.Controlled.Adjoint.Apply((c, (q1, q2))); three_op1.Controlled.Adjoint.Apply((c, (q2, q1))); three_op1.Controlled.Adjoint.Apply((c, (q1, q2))); @@ -2054,7 +2054,7 @@ namespace N1 return QVoid.Instance; };""" |> testOne threeQubitOperation - + [] let ``partial application`` () = [ @@ -2093,57 +2093,57 @@ namespace N1 .Partial(new Func((__arg11__) => (1L, (3.5D, __arg11__)))) .Apply(Result.One);" "partialNestedArgsOp - .Partial(new Func<((Int64,Int64,Int64),((Double,Double),(Result,Result,Result))), ((Int64,Int64,Int64),((Double,Double),(Result,Result,Result)))>((__arg12__) => + .Partial(new Func<((Int64,Int64,Int64),((Double,Double),(Result,Result,Result))), ((Int64,Int64,Int64),((Double,Double),(Result,Result,Result)))>((__arg12__) => ( - (__arg12__.Item1.Item1, __arg12__.Item1.Item2, __arg12__.Item1.Item3), + (__arg12__.Item1.Item1, __arg12__.Item1.Item2, __arg12__.Item1.Item3), ( - (__arg12__.Item2.Item1.Item1, __arg12__.Item2.Item1.Item2), + (__arg12__.Item2.Item1.Item1, __arg12__.Item2.Item1.Item2), (__arg12__.Item2.Item2.Item1, __arg12__.Item2.Item2.Item2, __arg12__.Item2.Item2.Item3) ) ) )) - .Partial(new Func<(Int64,((Double,Double),Result)), ((Int64,Int64,Int64),((Double,Double),(Result,Result,Result)))>((__arg13__) => + .Partial(new Func<(Int64,((Double,Double),Result)), ((Int64,Int64,Int64),((Double,Double),(Result,Result,Result)))>((__arg13__) => ( - (1L, i, __arg13__.Item1), + (1L, i, __arg13__.Item1), ( - (__arg13__.Item2.Item1.Item1, __arg13__.Item2.Item1.Item2), + (__arg13__.Item2.Item1.Item1, __arg13__.Item2.Item1.Item2), (res, __arg13__.Item2.Item2, res) ) ) )) .Apply((1L, ((3.3D, 2D), Result.Zero)));" "partialNestedArgsOp - .Partial(new Func<(Int64,((Double,Double),Result)), ((Int64,Int64,Int64),((Double,Double),(Result,Result,Result)))>((__arg14__) => + .Partial(new Func<(Int64,((Double,Double),Result)), ((Int64,Int64,Int64),((Double,Double),(Result,Result,Result)))>((__arg14__) => ( - (1L, i, __arg14__.Item1), + (1L, i, __arg14__.Item1), ( - (__arg14__.Item2.Item1.Item1, __arg14__.Item2.Item1.Item2), + (__arg14__.Item2.Item1.Item1, __arg14__.Item2.Item1.Item2), (res, __arg14__.Item2.Item2, res) ) ) )) - .Partial(new Func<(Double,Result), (Int64,((Double,Double),Result))>((__arg15__) => + .Partial(new Func<(Double,Result), (Int64,((Double,Double),Result))>((__arg15__) => ( - 2L, + 2L, ( - (2.2D, __arg15__.Item1), + (2.2D, __arg15__.Item1), __arg15__.Item2 ) ) )) .Apply((3.3D, Result.Zero));" "partialNestedArgsOp - .Partial(new Func<(Int64,(Double,Result)), ((Int64,Int64,Int64),((Double,Double),(Result,Result,Result)))>((__arg16__) => + .Partial(new Func<(Int64,(Double,Result)), ((Int64,Int64,Int64),((Double,Double),(Result,Result,Result)))>((__arg16__) => ( - (i, __arg16__.Item1, 1L), + (i, __arg16__.Item1, 1L), ( (__arg16__.Item2.Item1, 1D), (res, __arg16__.Item2.Item2, Result.Zero) ) ) )) - .Partial(new Func((__arg17__) => + .Partial(new Func((__arg17__) => ( - i, + i, (__arg17__, res) ) )) @@ -2163,26 +2163,26 @@ namespace N1 "partialGeneric2.Partial((_, _, (1L, Result.One))).Apply((0L, Result.Zero));" "partialGeneric2.Partial((0L, _, (1L, _))).Apply((Result.Zero, Result.One));" "partialInput - .Partial(new Func<(Double,(Result,Result)), (Int64,(Double,Double),(Result,Result,Result))>((__arg20__) => + .Partial(new Func<(Double,(Result,Result)), (Int64,(Double,Double),(Result,Result,Result))>((__arg20__) => ( - 1L, - (__arg20__.Item1, 1.1D), + 1L, + (__arg20__.Item1, 1.1D), (Result.Zero, __arg20__.Item2.Item1, __arg20__.Item2.Item2) ) )) .Apply((2.2D, (Result.One, Result.One)));" """ return partialUnitary - .Partial(new Func, (Double,ICallable,IQArray)>((__arg21__) => + .Partial(new Func, (Double,ICallable,IQArray)>((__arg21__) => ( - 1.1D, - partialFunction.Partial(new Func<(Int64,Double), (Int64,Double,Pauli)>((__arg22__) => + 1.1D, + partialFunction.Partial(new Func<(Int64,Double), (Int64,Double,Pauli)>((__arg22__) => ( - __arg22__.Item1, - __arg22__.Item2, + __arg22__.Item1, + __arg22__.Item2, Pauli.PauliX ) - )), + )), __arg21__) )); """ @@ -2203,10 +2203,10 @@ namespace N1 "return op.Data.Partial(new Func, (Double,F,IQArray)>((__arg4__) => (start, f, __arg4__)));" ] |> testOneBody (applyVisitor partialFunctionTest) - + [] let ``buildRun test`` () = - let testOne (_,op) expected = + let testOne (_,op) expected = let context = createTestContext op let (name, nonGenericName) = findClassName context op let actual = buildRun context nonGenericName op.ArgumentTuple op.Signature.ArgumentType op.Signature.ReturnType |> formatSyntaxTree @@ -2223,57 +2223,57 @@ namespace N1 return __m__.Run(q1); }" |> testOne oneQubitAbstractOperation - + "public static System.Threading.Tasks.Task Run(IOperationFactory __m__, Qubit q1) { return __m__.Run(q1); }" |> testOne oneQubitSelfAdjointAbstractOperation - - + + "public static System.Threading.Tasks.Task Run(IOperationFactory __m__, Qubit q1, Basis b, (Pauli, IQArray>, Boolean) t, Int64 i) { return __m__.Run>, Boolean), Int64), QVoid>((q1,b,t,i)); }" |> testOne randomAbstractOperation - - + + "public static System.Threading.Tasks.Task>> Run(IOperationFactory __m__, IQArray qubits, Qubits register, IQArray> indices, arrays_T3 t) { return __m__.Run, Qubits, IQArray>, arrays_T3), IQArray>>((qubits, register, indices, t)); - }" + }" |> testOne arraysOperations - - + + "public static System.Threading.Tasks.Task<__T__> Run(IOperationFactory __m__, __T__ a1) { return __m__.Run, __T__, __T__>(a1); - }" + }" |> testOne genC1a - - + + "public static System.Threading.Tasks.Task> Run(IOperationFactory __m__, ICallable mapper, IQArray<__T__> source) { return __m__.Run, (ICallable, IQArray<__T__>), IQArray<__U__>>((mapper, source)); - }" + }" |> testOne genMapper - + "public static System.Threading.Tasks.Task Run(IOperationFactory __m__, Int64 a, Int64 b, Double c, Double d) { return __m__.Run(((a,b),(c,d))); - }" + }" |> testOne nestedArgTuple1 "public static System.Threading.Tasks.Task Run(IOperationFactory __m__, (Int64, Int64) a, Double c, Int64 b, (Qubit, Qubit) d, Double e) { return __m__.Run((a,(c,(b,d),e))); - }" + }" |> testOne nestedArgTuple2 "public static System.Threading.Tasks.Task Run(IOperationFactory __m__, (__A__, Int64) a, __A__ c, Int64 b, (Qubit, __A__) d, Double e) { return __m__.Run, ((__A__,Int64),(__A__,(Int64,(Qubit,__A__)),Double)), QVoid>((a,(c,(b,d),e))); - }" + }" |> testOne nestedArgTupleGeneric "public static System.Threading.Tasks.Task Run(IOperationFactory __m__, ICallable second, ICallable first, __B__ arg) @@ -2281,35 +2281,35 @@ namespace N1 return __m__.Run, (ICallable, ICallable, __B__), QVoid>((second, first, arg)); }" |> testOne composeImpl - + "public static System.Threading.Tasks.Task Run(IOperationFactory __m__, ICallable second, ICallable first) { return __m__.Run, (ICallable, ICallable), ICallable>((second, first)); }" |> testOne compose - + [] let ``is abstract`` () = let testOne (_,op) expected = let actual = op |> isAbstract Assert.Equal(expected, actual) - true |> testOne emptyOperation + true |> testOne emptyOperation true |> testOne oneQubitAbstractOperation true |> testOne oneQubitSelfAdjointAbstractOperation true |> testOne randomAbstractOperation false |> testOne zeroQubitOperation - false |> testOne oneQubitSelfAdjointOperation + false |> testOne oneQubitSelfAdjointOperation false |> testOne oneQubitOperation false |> testOne twoQubitOperation - false |> testOne threeQubitOperation + false |> testOne threeQubitOperation false |> testOne differentArgsOperation false |> testOne randomOperation let testOneClass (_,op : QsCallable) executionTarget (expected : string) = let expected = expected.Replace("%%%", op.SourceFile.Value) - let assemblyConstants = - new System.Collections.Generic.KeyValuePair<_,_> (AssemblyConstants.ExecutionTarget, executionTarget) + let assemblyConstants = + new System.Collections.Generic.KeyValuePair<_,_> (AssemblyConstants.ExecutionTarget, executionTarget) |> Seq.singleton |> ImmutableDictionary.CreateRange let compilation = {Namespaces = syntaxTree; EntryPoints = ImmutableArray.Create op.FullName} @@ -2318,7 +2318,7 @@ namespace N1 Assert.Equal(expected |> clearFormatting, actual |> clearFormatting) [] - let ``buildOperationClass - concrete`` () = + let ``buildOperationClass - concrete`` () = """ public abstract partial class emptyOperation : Operation, ICallable { @@ -2332,7 +2332,7 @@ namespace N1 public static HoneywellEntryPointInfo Info => new HoneywellEntryPointInfo(typeof(emptyOperation)); public override void Init() { } - + public override IApplyData __dataIn(QVoid data) => data; public override IApplyData __dataOut(QVoid data) => data; public static System.Threading.Tasks.Task Run(IOperationFactory __m__) @@ -2436,12 +2436,12 @@ namespace N1 } ; - - public override void Init() - { + + public override void Init() + { this.X = this.Factory.Get>(typeof(Microsoft.Quantum.Intrinsic.X)); } - + public override IApplyData __dataIn(Qubit data) => data; public override IApplyData __dataOut(QVoid data) => data; public static System.Threading.Tasks.Task Run(IOperationFactory __m__, Qubit q1) @@ -2451,9 +2451,9 @@ namespace N1 } """ |> testOneClass oneQubitOperation AssemblyConstants.QCIProcessor - + [] - let ``buildOperationClass - generics`` () = + let ``buildOperationClass - generics`` () = """ public abstract partial class genCtrl3<__X__, __Y__, __Z__> : Controllable<(__X__,(Int64,(__Y__,__Z__),Result))>, ICallable { @@ -2467,7 +2467,7 @@ namespace N1 { } - System.Collections.Generic.IEnumerable IApplyData.Qubits + System.Collections.Generic.IEnumerable IApplyData.Qubits { get { @@ -2493,9 +2493,9 @@ namespace N1 return __m__.Run, (__X__,(Int64,(__Y__,__Z__),Result)), QVoid>((arg1, arg2)); } } -""" +""" |> testOneClass genCtrl3 AssemblyConstants.HoneywellProcessor - + """ [SourceLocation("%%%", OperationFunctor.Body, 1266, 1272)] public partial class composeImpl<__A__, __B__> : Operation<(ICallable,ICallable,__B__), QVoid>, ICallable @@ -2510,7 +2510,7 @@ namespace N1 { } - System.Collections.Generic.IEnumerable IApplyData.Qubits + System.Collections.Generic.IEnumerable IApplyData.Qubits { get { @@ -2542,11 +2542,11 @@ namespace N1 return __m__.Run, (ICallable,ICallable,__B__), QVoid>((second, first, arg)); } } -""" +""" |> testOneClass composeImpl AssemblyConstants.IonQProcessor - + [] - let ``buildOperationClass - abstract function`` () = + let ``buildOperationClass - abstract function`` () = """ public abstract partial class genF1<__A__> : Function<__A__, QVoid>, ICallable { @@ -2570,11 +2570,11 @@ namespace N1 } """ |> testOneClass genF1 AssemblyConstants.QCIProcessor - + [] let ``buildOperationClass - access modifiers`` () = """ -[SourceLocation("%%%", OperationFunctor.Body, 1312, 1314)] +[SourceLocation("%%%", OperationFunctor.Body, 1314, 1316)] internal partial class EmptyInternalFunction : Function, ICallable { public EmptyInternalFunction(IOperationFactory m) : base(m) @@ -2608,7 +2608,7 @@ internal partial class EmptyInternalFunction : Function, ICallable |> testOneClass emptyInternalFunction null """ -[SourceLocation("%%%", OperationFunctor.Body, 1314, 1316)] +[SourceLocation("%%%", OperationFunctor.Body, 1316, 1318)] internal partial class EmptyInternalOperation : Operation, ICallable { public EmptyInternalOperation(IOperationFactory m) : base(m) @@ -2652,22 +2652,22 @@ internal partial class EmptyInternalOperation : Operation, ICallab var qubits = Allocate.Apply(1L); #line hidden bool __arg1__ = true; - try + try { H.Apply(qubits[0L]); - MicrosoftQuantumIntrinsicH.Apply(qubits[0L]); + MicrosoftQuantumIntrinsicH.Apply(qubits[0L]); } #line hidden catch - { + { __arg1__ = false; throw; } #line hidden - finally + finally { if (__arg1__) - { + { Release.Apply(qubits); } } @@ -2675,7 +2675,7 @@ internal partial class EmptyInternalOperation : Operation, ICallab ] |> testOneBody (applyVisitor duplicatedDefinitionsCaller) - + [] let ``buildOpsProperties with duplicatedDefinitionsCaller`` () = let t = sprintf @"protected %s %s { get; set; }" @@ -2683,23 +2683,23 @@ internal partial class EmptyInternalOperation : Operation, ICallab let expected = [ - template "Allocate" "Allocate" - template "IUnitary" "MicrosoftQuantumIntrinsicH" - template "ICallable" "H" - template "Release" "Release" - template "ICallable" "MicrosoftQuantumOverridesemptyFunction" - template "ICallable" "emptyFunction" + template "Allocate" "Allocate" + template "IUnitary" "MicrosoftQuantumIntrinsicH" + template "ICallable" "H" + template "Release" "Release" + template "ICallable" "MicrosoftQuantumOverridesemptyFunction" + template "ICallable" "emptyFunction" ] let (_,op) = duplicatedDefinitionsCaller let context = createTestContext op - let actual = + let actual = op |> operationDependencies |> depsByName |> buildOpsProperties context |> List.map formatSyntaxTree - + List.zip (expected |> List.map clearFormatting) (actual |> List.map clearFormatting) |> List.iter Assert.Equal [] @@ -2723,28 +2723,28 @@ internal partial class EmptyInternalOperation : Operation, ICallab |> List.iter Assert.Equal [] - let ``buildOperationClass - concrete functions`` () = + let ``buildOperationClass - concrete functions`` () = """ - [SourceLocation("%%%", OperationFunctor.Body, 1301,1312)] + [SourceLocation("%%%", OperationFunctor.Body, 1301,1310)] public partial class UpdateUdtItems : Function, ICallable { public UpdateUdtItems(IOperationFactorym) : base(m) { } - + String ICallable.Name => "UpdateUdtItems"; String ICallable.FullName => "Microsoft.Quantum.Compiler.Generics.UpdateUdtItems"; public static EntryPointInfo Info => new EntryPointInfo(typeof(UpdateUdtItems)); - public override Func Body => (__in__) => + public override Func Body => (__in__) => { var udt = __in__; vararr=QArray.Create(10L); return new MyType2((1L,udt.Data.Item2,(arr?.Copy(),udt.Data.Item3.Item2))); }; - + public override void Init() { } - + public override IApplyData __dataIn(MyType2data) => data; public override IApplyData __dataOut(MyType2data) => data; public static System.Threading.Tasks.Task Run(IOperationFactory __m__, MyType2 udt) @@ -2905,8 +2905,8 @@ internal partial class EmptyInternalOperation : Operation, ICallab public U(IUnitary data) : base(data) { } - - System.Collections.Generic.IEnumerable IApplyData.Qubits + + System.Collections.Generic.IEnumerable IApplyData.Qubits { get { @@ -2920,7 +2920,7 @@ internal partial class EmptyInternalOperation : Operation, ICallab } """ |> testOneUdt udt_U - + """ public class AA : UDTBase, IApplyData { @@ -2931,8 +2931,8 @@ internal partial class EmptyInternalOperation : Operation, ICallab public AA(A data) : base(data) { } - - System.Collections.Generic.IEnumerable IApplyData.Qubits + + System.Collections.Generic.IEnumerable IApplyData.Qubits { get { @@ -2946,7 +2946,7 @@ internal partial class EmptyInternalOperation : Operation, ICallab } """ |> testOneUdt udt_AA - + """ public class Q : UDTBase, IApplyData { @@ -2957,7 +2957,7 @@ internal partial class EmptyInternalOperation : Operation, ICallab public Q(Qubit data) : base(data) { } - + System.Collections.Generic.IEnumerable IApplyData.Qubits { get @@ -2972,7 +2972,7 @@ internal partial class EmptyInternalOperation : Operation, ICallab } """ |> testOneUdt udt_Q - + """ public class QQ : UDTBase, IApplyData { @@ -2983,7 +2983,7 @@ internal partial class EmptyInternalOperation : Operation, ICallab public QQ(Q data) : base(data) { } - + System.Collections.Generic.IEnumerable IApplyData.Qubits { get @@ -3024,7 +3024,7 @@ internal partial class EmptyInternalOperation : Operation, ICallab } """ |> testOneUdt udt_Qubits - + """ public class udt_args1 : UDTBase<(Int64,IQArray)>, IApplyData { @@ -3054,7 +3054,7 @@ internal partial class EmptyInternalOperation : Operation, ICallab } """ |> testOneUdt udt_args1 - + """ public class udt_Real : UDTBase, IApplyData { @@ -3074,7 +3074,7 @@ internal partial class EmptyInternalOperation : Operation, ICallab } """ |> testOneUdt udt_Real - + """ public class udt_Complex : UDTBase<(udt_Real,udt_Real)>, IApplyData { @@ -3097,7 +3097,7 @@ internal partial class EmptyInternalOperation : Operation, ICallab } """ |> testOneUdt udt_Complex - + """ public class udt_TwoDimArray : UDTBase>>, IApplyData { @@ -3169,7 +3169,7 @@ public class NamedTuple : UDTBase<((Int64,Double),Int64)>, IApplyData [] - let ``one file - EmptyElements`` () = + let ``one file - EmptyElements`` () = """ //------------------------------------------------------------------------------ // @@ -3280,7 +3280,7 @@ namespace Microsoft.Quantum |> testOneFile (Path.Combine("Circuits","EmptyElements.qs")) [] - let ``one file - UserDefinedTypes`` () = + let ``one file - UserDefinedTypes`` () = """ //------------------------------------------------------------------------------ // @@ -3356,7 +3356,7 @@ namespace Microsoft.Quantum item2 = Data.Item2; } } -} +} """ |> testOneFile (Path.Combine("Circuits","Types.qs")) @@ -3368,7 +3368,7 @@ namespace Microsoft.Quantum Assert.Equal(1, local.Length) Assert.Equal("Microsoft.Quantum.Intrinsic", (fst local.[0]).Value) let actual = (snd local.[0]) |> List.map oneName |> List.sort - List.zip expected actual |> List.iter Assert.Equal + List.zip expected actual |> List.iter Assert.Equal [] let ``one file - HelloWorld`` () = @@ -3414,9 +3414,9 @@ namespace Microsoft.Quantum.Tests.Inline #line 11 "%%" return r; }; - + public override void Init() { } - + public override IApplyData __dataIn(Int64 data) => new QTuple(data); public override IApplyData __dataOut(Int64 data) => new QTuple(data); public static System.Threading.Tasks.Task Run(IOperationFactory __m__, Int64 n) @@ -3425,10 +3425,10 @@ namespace Microsoft.Quantum.Tests.Inline } } }""" - |> + |> testOneFile (Path.Combine("Circuits","HelloWorld.qs")) - + [] let ``one file - LineNumbers`` () = """ @@ -3492,7 +3492,7 @@ namespace Microsoft.Quantum.Tests.LineNumbers var (ctrls,q) = (Allocate.Apply(r), Allocate.Apply()); #line hidden bool __arg1__ = true; - try + try { #line 15 "%%" if ((n == 0L)) @@ -3513,7 +3513,7 @@ namespace Microsoft.Quantum.Tests.LineNumbers } #line hidden catch - { + { __arg1__ = false; throw; } @@ -3550,10 +3550,10 @@ namespace Microsoft.Quantum.Tests.LineNumbers } } }""" - |> + |> testOneFile (Path.Combine("Circuits","LineNumbers.qs")) - + [] let ``one file - UnitTests`` () = """ @@ -3784,7 +3784,7 @@ namespace Microsoft.Quantum.Tests.UnitTests } """ - |> + |> testOneFile (Path.Combine("Circuits","UnitTests.qs")) diff --git a/src/Simulation/CsharpGeneration/SimulationCode.fs b/src/Simulation/CsharpGeneration/SimulationCode.fs index 66191f44bbe..e0c6b0c0810 100644 --- a/src/Simulation/CsharpGeneration/SimulationCode.fs +++ b/src/Simulation/CsharpGeneration/SimulationCode.fs @@ -17,7 +17,7 @@ open Microsoft.Quantum.RoslynWrapper open Microsoft.Quantum.QsCompiler open Microsoft.Quantum.QsCompiler.DataTypes open Microsoft.Quantum.QsCompiler.ReservedKeywords -open Microsoft.Quantum.QsCompiler.SyntaxTokens +open Microsoft.Quantum.QsCompiler.SyntaxTokens open Microsoft.Quantum.QsCompiler.SyntaxTree open Microsoft.Quantum.QsCompiler.SyntaxExtensions open Microsoft.Quantum.QsCompiler.Transformations.Core @@ -31,17 +31,17 @@ open Microsoft.Quantum.QsCompiler.Transformations.BasicTransformations /// --------------------------------------------------------------------------- module SimulationCode = open System.Globalization - + type CodegenContext with member this.setCallable (op: QsCallable) = { this with current = (Some op.FullName); signature = (Some op.Signature) } member this.setUdt (udt: QsCustomType) = { this with current = (Some udt.FullName) } - let autoNamespaces = + let autoNamespaces = [ "System" "Microsoft.Quantum.Core" "Microsoft.Quantum.Intrinsic" - "Microsoft.Quantum.Simulation.Core" + "Microsoft.Quantum.Simulation.Core" ] let funcsAsProps = [ @@ -50,43 +50,43 @@ module SimulationCode = ("End", { Namespace = "Microsoft.Quantum.Core" |> NonNullable.New; Name = "RangeEnd" |> NonNullable.New } ) ("Step", { Namespace = "Microsoft.Quantum.Core" |> NonNullable.New; Name = "RangeStep" |> NonNullable.New } ) ] - + let isCurrentOp context n = match context.current with | None -> false | Some name -> name = n - let prependNamespaceString (name : QsQualifiedName) = + let prependNamespaceString (name : QsQualifiedName) = let pieces = name.Namespace.Value.Split([|'.'|]) |> String.Concat pieces + name.Name.Value - let needsFullPath context (op:QsQualifiedName) = + let needsFullPath context (op:QsQualifiedName) = let hasMultipleDefinitions() = if context.byName.ContainsKey op.Name then context.byName.[op.Name].Length > 1 else false let sameNamespace = match context.current with | None -> false | Some n -> n.Namespace = op.Namespace - if sameNamespace then + if sameNamespace then false elif hasMultipleDefinitions() then true else not (autoNamespaces |> List.contains op.Namespace.Value) - - let getTypeParameters types = - let findAll (t: ResolvedType) = t.ExtractAll (fun item -> item.Resolution |> function + + let getTypeParameters types = + let findAll (t: ResolvedType) = t.ExtractAll (fun item -> item.Resolution |> function | QsTypeKind.TypeParameter tp -> seq{ yield tp } | _ -> Enumerable.Empty()) - types - |> Seq.collect findAll + types + |> Seq.collect findAll |> Seq.distinctBy (fun tp -> tp.Origin, tp.TypeName) |> Seq.toList - let getAllItems itemBase t = - let rec getItems (acc : Queue) current = function + let getAllItems itemBase t = + let rec getItems (acc : Queue) current = function | Tuple ts -> ts |> Seq.iteri (fun i x -> getItems acc (current <|.|> ``ident`` ("Item" + (i+1).ToString())) x) | _ -> acc.Enqueue current - let items = Queue() + let items = Queue() getItems items itemBase t items let hasTypeParameters types = not (getTypeParameters types).IsEmpty - + let justTheName context (n: QsQualifiedName) = if needsFullPath context n then n.Namespace.Value + "." + n.Name.Value else n.Name.Value @@ -108,14 +108,14 @@ module SimulationCode = | QsTypeKind.Operation ((tIn, tOut), _) -> (tIn, tOut) | QsTypeKind.Function (tIn, tOut) -> (tIn, tOut) // TODO: Diagnostics - | _ -> failwith "Invalid ResolvedType for callable definition" + | _ -> failwith "Invalid ResolvedType for callable definition" - let hasAdjointControlled functors = - let oneFunctor (adj,ctrl) f = - match f with - | QsFunctor.Adjoint -> (true, ctrl) + let hasAdjointControlled functors = + let oneFunctor (adj,ctrl) f = + match f with + | QsFunctor.Adjoint -> (true, ctrl) | QsFunctor.Controlled -> (adj, true) - match functors with + match functors with | Value fs -> fs |> Seq.fold oneFunctor (false,false) // TODO: Diagnostics | Null -> (true, true) @@ -139,11 +139,11 @@ module SimulationCode = | QsTypeKind.Operation (_,functors) -> roslynCallableInterfaceName functors.Characteristics | QsTypeKind.Function _ -> roslynCallableInterfaceName ResolvedCharacteristics.Empty | QsTypeKind.TypeParameter t -> t |> roslynTypeParameterName - | QsTypeKind.MissingType -> "object" + | QsTypeKind.MissingType -> "object" // TODO: diagnostics | QsTypeKind.InvalidType -> "" - - and roslynTupleTypeName context tupleTypes = + + and roslynTupleTypeName context tupleTypes = tupleTypes |> Seq.map (roslynTypeName context) |> String.concat "," @@ -152,13 +152,13 @@ module SimulationCode = and roslynTypeParameterName (t:QsTypeParameter) = sprintf "__%s__" t.TypeName.Value - and roslynCallableInterfaceName characteristics = - let (adj, ctrl) = characteristics.SupportedFunctors |> hasAdjointControlled - match (adj,ctrl) with - | (true, true) -> "IUnitary" - | (true, false) -> "IAdjointable" + and roslynCallableInterfaceName characteristics = + let (adj, ctrl) = characteristics.SupportedFunctors |> hasAdjointControlled + match (adj,ctrl) with + | (true, true) -> "IUnitary" + | (true, false) -> "IAdjointable" | (false, true) -> "IControllable" - | _ -> "ICallable" + | _ -> "ICallable" and roslynCallableTypeName context (name:QsQualifiedName) = if not (context.allCallables.ContainsKey name) then @@ -171,7 +171,7 @@ module SimulationCode = if isGeneric context name then baseInterface else - match baseInterface with + match baseInterface with | "ICallable" -> sprintf "%s<%s, %s>" baseInterface (roslynTypeName context tIn) (roslynTypeName context tOut) | _ -> @@ -186,11 +186,11 @@ module SimulationCode = | QsTypeKind.Operation _ | QsTypeKind.Function _ -> true | _ -> false - + let tupleBaseClassName context qsharpType = let baseType = (roslynTypeName context qsharpType) sprintf "QTuple<%s>" baseType - + let udtBaseClassName context qsharpType = let baseType = (roslynTypeName context qsharpType) sprintf "UDTBase<%s>" baseType @@ -204,20 +204,20 @@ module SimulationCode = count <- count + 1 sprintf "__arg%d__" count - type ExpressionSeeker(parent : SyntaxTreeTransformation>) = + type ExpressionSeeker(parent : SyntaxTreeTransformation>) = inherit ExpressionTransformation>(parent, TransformationOptions.NoRebuild) override this.OnTypedExpression ex = match ex.Expression with - | Identifier (id, _) -> + | Identifier (id, _) -> match id with | GlobalCallable name -> this.SharedState.Add name |> ignore | _ -> () | _ -> () - base.OnTypedExpression ex + base.OnTypedExpression ex /// Used to discover which operations are used by a certain code block. - type StatementKindSeeker(parent : SyntaxTreeTransformation>) = + type StatementKindSeeker(parent : SyntaxTreeTransformation>) = inherit StatementKindTransformation>(parent, TransformationOptions.NoRebuild) let ALLOCATE = { Name = "Allocate" |> NonNullable.New; Namespace = "Microsoft.Quantum.Intrinsic" |> NonNullable.New } @@ -225,22 +225,22 @@ module SimulationCode = let BORROW = { Name = "Borrow" |> NonNullable.New; Namespace = "Microsoft.Quantum.Intrinsic" |> NonNullable.New } let RETURN = { Name = "Return" |> NonNullable.New; Namespace = "Microsoft.Quantum.Intrinsic" |> NonNullable.New } - override this.OnAllocateQubits node = + override this.OnAllocateQubits node = this.SharedState.Add ALLOCATE |> ignore this.SharedState.Add RELEASE |> ignore - base.OnAllocateQubits node + base.OnAllocateQubits node - override this.OnBorrowQubits node = + override this.OnBorrowQubits node = this.SharedState.Add BORROW |> ignore this.SharedState.Add RETURN |> ignore - base.OnBorrowQubits node + base.OnBorrowQubits node /// Used to discover which operations are used by a certain code block. type OperationsSeeker private (_private_) = inherit SyntaxTreeTransformation>(new HashSet<_>(), TransformationOptions.NoRebuild) - new () as this = - new OperationsSeeker("_private_") then + new () as this = + new OperationsSeeker("_private_") then this.StatementKinds <- new StatementKindSeeker(this) this.Expressions <- new ExpressionSeeker(this) this.Types <- new TypeTransformation>(this, TransformationOptions.Disabled) @@ -257,8 +257,8 @@ module SimulationCode = member val StartLine = None with get, set member val LineNumber = None with get, set - new (context : CodegenContext) as this = - new SyntaxBuilder("_private_") then + new (context : CodegenContext) as this = + new SyntaxBuilder("_private_") then this.Namespaces <- new NamespaceBuilder(this) this.Statements <- new StatementBlockBuilder(this) this.StatementKinds <- new StatementBuilder(this, context) @@ -266,19 +266,19 @@ module SimulationCode = this.Types <- new TypeTransformation(this, TransformationOptions.Disabled) /// Used to generate the list of statements that implement a Q# operation specialization. - and StatementBlockBuilder(parent : SyntaxBuilder) = + and StatementBlockBuilder(parent : SyntaxBuilder) = inherit StatementTransformation(parent, TransformationOptions.NoRebuild) - override this.OnScope (scope : QsScope) = + override this.OnScope (scope : QsScope) = parent.DeclarationsInScope <- scope.KnownSymbols base.OnScope scope override this.OnStatement (node:QsStatement) = - match node.Location with - | Value loc -> + match node.Location with + | Value loc -> let (current, _) = loc.Offset parent.LineNumber <- parent.StartLine |> Option.map (fun start -> start + current + 1) // The Q# compiler reports 0-based line numbers. - | Null -> + | Null -> parent.LineNumber <- None // auto-generated statement; the line number will be set to the specialization declaration parent.DeclarationsInStatement <- node.SymbolDeclarations parent.DeclarationsInScope <- LocalDeclarations.Concat parent.DeclarationsInScope parent.DeclarationsInStatement // only fine because/if a new statement transformation is created for every block! @@ -287,20 +287,20 @@ module SimulationCode = /// Used to generate the statements that implement a Q# operation specialization. and StatementBuilder(parent : SyntaxBuilder, context) = inherit StatementKindTransformation(parent, TransformationOptions.NoRebuild) - + let withLineNumber s = // add a line directive if the operation specifies the source file and a line number match context.fileName, parent.LineNumber with | Some _, Some ln when ln = 0 -> ``#line hidden`` <| s - | Some n, Some ln -> + | Some n, Some ln -> ``#line`` ln n s - | Some n, None -> parent.StartLine |> function - | Some ln -> + | Some n, None -> parent.StartLine |> function + | Some ln -> ``#line`` (ln + 1) n s // we need 1-based line numbers here, and startLine is zero-based | None -> s | _ -> s - + let QArrayType = function | ArrayType b -> generic "QArray" ``<<`` [ roslynTypeName context b ] ``>>`` |> Some | _ -> None @@ -308,17 +308,17 @@ module SimulationCode = let (|Property|_|) = function | CallLikeExpression (op : TypedExpression, args) -> match op.Expression with - | Identifier (id, _) -> + | Identifier (id, _) -> match id with | GlobalCallable n -> funcsAsProps |> List.tryPick (fun (prop, f) -> if (n = f) then Some (args, prop) else None) | _ -> None | _ -> None | _ -> None - + let (|NewUdt|_|) = function | CallLikeExpression (op : TypedExpression, args) -> match op.Expression with - | Identifier (id, _) -> + | Identifier (id, _) -> match id with | GlobalCallable n when isUdt context n |> fst -> Some (n,args) | _ -> None @@ -327,7 +327,7 @@ module SimulationCode = let (|PartialApplication|_|) expression = match expression with - | CallLikeExpression (op,args) when TypedExpression.IsPartialApplication expression -> Some (op,args) + | CallLikeExpression (op,args) when TypedExpression.IsPartialApplication expression -> Some (op,args) | _ -> None // Builds Roslyn code for a Q# expression @@ -348,7 +348,7 @@ module SimulationCode = | RangeLiteral (r,e) -> buildRange r e | NEG n -> ``-`` (buildExpression n) | NOT r -> ! (buildExpression r) - | BNOT i -> ``~~~`` (buildExpression i) + | BNOT i -> ``~~~`` (buildExpression i) | ADD (l, r) -> buildAddExpr ex.ResolvedType l r // We use the Pow extension method from Microsoft.Quantum.Simulation.Core for all valid combinations of types. | POW (l, r) -> ``invoke`` ((buildExpression l) <|.|> (``ident`` "Pow")) ``(`` [ (buildExpression r) ] ``)`` @@ -369,7 +369,7 @@ module SimulationCode = | LTE (l, r) -> ``((`` ((buildExpression l) .<=. (buildExpression r)) ``))`` | GT (l, r) -> ``((`` ((buildExpression l) .>. (buildExpression r)) ``))`` | GTE (l, r) -> ``((`` ((buildExpression l) .>=. (buildExpression r)) ``))`` - | CONDITIONAL (c, t, f) -> ``((`` (buildConditional c t f) ``))`` + | CONDITIONAL (c, t, f) -> ``((`` (buildConditional c t f) ``))`` | CopyAndUpdate (l, i, r) -> buildCopyAndUpdateExpression (l, i, r) | UnwrapApplication e -> (buildExpression e) <|.|> (``ident`` "Data") | ValueTuple vs -> buildTuple vs @@ -383,7 +383,7 @@ module SimulationCode = | PartialApplication (op,args) -> buildPartial ex.ResolvedType ex.TypeParameterResolutions op args // needs to be before NewUdt! | NewUdt (udt,args) -> buildNewUdt udt args // needs to be before CallLikeExpression! | CallLikeExpression (op,args) -> buildApply ex.ResolvedType op args - | MissingExpr -> ``ident`` "_" :> ExpressionSyntax + | MissingExpr -> ``ident`` "_" :> ExpressionSyntax and captureExpression (ex : TypedExpression) = match ex.Expression with @@ -393,44 +393,44 @@ module SimulationCode = | _ -> buildExpression ex | _ -> buildExpression ex - and buildNamedItem ex acc = - match acc with + and buildNamedItem ex acc = + match acc with | LocalVariable name -> (buildExpression ex) <|.|> (``ident`` name.Value) // TODO: Diagnostics | _ -> failwith "Invalid identifier for named item" - and buildAddExpr (exType : ResolvedType) lhs rhs = - match exType.Resolution |> QArrayType with - | Some arrType -> arrType <.> (``ident`` "Add", [buildExpression lhs; buildExpression rhs]) + and buildAddExpr (exType : ResolvedType) lhs rhs = + match exType.Resolution |> QArrayType with + | Some arrType -> arrType <.> (``ident`` "Add", [buildExpression lhs; buildExpression rhs]) | _ -> ``((`` ((buildExpression lhs) <+> (buildExpression rhs)) ``))`` and buildInterpolatedString (s : string) (exs: ImmutableArray) = - if exs.Length <> 0 then + if exs.Length <> 0 then let exprs = exs |> Seq.map buildExpression |> Seq.toList ``invoke`` (``ident`` "String.Format" ) ``(`` (literal s :: exprs) ``)`` else literal s - - and buildId id : ExpressionSyntax = + + and buildId id : ExpressionSyntax = match id with | LocalVariable n-> n.Value |> ``ident`` :> ExpressionSyntax | GlobalCallable n -> - if isCurrentOp context n then + if isCurrentOp context n then Directives.Self |> ``ident`` :> ExpressionSyntax - elif needsFullPath context n then + elif needsFullPath context n then prependNamespaceString n |> ``ident`` :> ExpressionSyntax - else + else n.Name.Value |> ``ident`` :> ExpressionSyntax // TODO: Diagnostics - | InvalidIdentifier -> + | InvalidIdentifier -> failwith "Received InvalidIdentifier" - and buildCopyAndUpdateExpression (lhsEx : TypedExpression, accEx : TypedExpression, rhsEx) = + and buildCopyAndUpdateExpression (lhsEx : TypedExpression, accEx : TypedExpression, rhsEx) = match lhsEx.ResolvedType.Resolution |> QArrayType with - | Some arrayType -> - let lhsAsQArray = ``new`` arrayType ``(`` [buildExpression lhsEx] ``)`` + | Some arrayType -> + let lhsAsQArray = ``new`` arrayType ``(`` [buildExpression lhsEx] ``)`` lhsAsQArray <.> (``ident`` "Modify", [ buildExpression accEx; captureExpression rhsEx ]) // in-place modification | _ -> lhsEx.ResolvedType.Resolution |> function - | UserDefinedType udt -> + | UserDefinedType udt -> let name = QsQualifiedName.New (udt.Namespace, udt.Name) let decl = findUdt context name @@ -440,48 +440,48 @@ module SimulationCode = // TODO: Diagnostics | _ -> failwith "item access expression in copy-and-update expression for user defined type is not a suitable identifier" let updatedItems = new Dictionary() - let rec aggregate (lhs : TypedExpression) = - match lhs.Expression with - | CopyAndUpdate (l, i, r) when l.ResolvedType.Resolution |> isUserDefinedType -> + let rec aggregate (lhs : TypedExpression) = + match lhs.Expression with + | CopyAndUpdate (l, i, r) when l.ResolvedType.Resolution |> isUserDefinedType -> let lhs = aggregate l // need to recur first, or make sure key is not already in dictionary updatedItems.[getItemName i.Expression] <- captureExpression r lhs | _ -> lhs - let lhs = aggregate lhsEx |> buildExpression + let lhs = aggregate lhsEx |> buildExpression updatedItems.[getItemName accEx.Expression] <- captureExpression rhsEx // needs to be after aggregate let root = lhs <|.|> (``ident`` "Data") let items = getAllItems root decl.Type - let rec buildArg = function + let rec buildArg = function | QsTuple args -> args |> Seq.map buildArg |> Seq.toList |> ``tuple`` | QsTupleItem (Named item) -> updatedItems.TryGetValue item.VariableName.Value |> function - | true, rhs -> + | true, rhs -> items.Dequeue() |> ignore rhs | _ -> items.Dequeue() | QsTupleItem _ -> items.Dequeue() - ``new`` (``type`` [ justTheName context name ]) ``(`` [buildArg decl.TypeItems] ``)`` + ``new`` (``type`` [ justTheName context name ]) ``(`` [buildArg decl.TypeItems] ``)`` | _ -> failwith "copy-and-update expressions are currently only supported for arrays and user defined types" - and buildTuple many : ExpressionSyntax = - many |> Seq.map captureExpression |> Seq.toList |> ``tuple`` // captured since we rely on the native C# tuples + and buildTuple many : ExpressionSyntax = + many |> Seq.map captureExpression |> Seq.toList |> ``tuple`` // captured since we rely on the native C# tuples and buildPartial (partialType : ResolvedType) typeParamResolutions opEx args = let (pIn, pOut) = inAndOutputType partialType // The type of the operation constructed by partial application let (oIn, _) = inAndOutputType opEx.ResolvedType // The type of the operation accepting the partial tuples. - let buildPartialMapper () = // may only be executed if there are no more type parameters to be resolved + let buildPartialMapper () = // may only be executed if there are no more type parameters to be resolved let argName = nextArgName() let items = getAllItems (``ident`` argName) pIn let rec argMapping (expr : TypedExpression) = let rec buildMissing = function | Tuple ts -> ts |> Seq.toList |> List.map buildMissing |> ``tuple`` - | _ -> items.Dequeue() - - match expr with + | _ -> items.Dequeue() + + match expr with | Missing -> buildMissing expr.ResolvedType - | Tuple vt -> + | Tuple vt -> match expr.ResolvedType with | Tuple ts when ts.Length = vt.Length -> vt |> Seq.zip ts |> Seq.toList @@ -492,10 +492,10 @@ module SimulationCode = | Item ex -> captureExpression ex // TODO: Diagnostics. | _ -> failwith "partial application contains an error expression" - + let resolvedOrigInputT = ResolvedType.ResolveTypeParameters typeParamResolutions oIn let mapper = [ ``() =>`` [argName] (argMapping {args with ResolvedType = resolvedOrigInputT}) ] - ``new`` (generic "Func" ``<<`` [ (roslynTypeName context pIn); (roslynTypeName context resolvedOrigInputT) ] ``>>``) ``(`` mapper ``)`` + ``new`` (generic "Func" ``<<`` [ (roslynTypeName context pIn); (roslynTypeName context resolvedOrigInputT) ] ``>>``) ``(`` mapper ``)`` // Checks if the expression still has type parameters. // If it does, we can't create the PartialMapper at compile time @@ -507,32 +507,32 @@ module SimulationCode = op <.> (``ident`` "Partial", [ values ]) and buildNewUdt n args = - ``new`` (``type`` [ justTheName context n ]) ``(`` [args |> captureExpression] ``)`` + ``new`` (``type`` [ justTheName context n ]) ``(`` [args |> captureExpression] ``)`` - and buildApply returnType op args = + and buildApply returnType op args = // Checks if the expression points to a non-generic user-defined callable. // Because these have fully-resolved types in the runtime, // they don't need to have the return type explicitly in the apply. - let isNonGenericCallable() = + let isNonGenericCallable() = match op.Expression with | Identifier (_, Value tArgs) when tArgs.Length > 0 -> false - | Identifier (id, _) -> + | Identifier (id, _) -> match id with | GlobalCallable n -> let sameName = match context.current with | None -> false | Some name -> n = name if sameName then // when called recursively, we always need to specify the return type. false else - not (hasTypeParameters [op.ResolvedType]) - | _ -> + not (hasTypeParameters [op.ResolvedType]) + | _ -> false | _ -> false - let useReturnType = + let useReturnType = match returnType.Resolution with | QsTypeKind.UnitType -> false - | _ -> + | _ -> not (isNonGenericCallable()) let apply = if useReturnType then (``ident`` (sprintf "Apply<%s>" (roslynTypeName context returnType))) else (``ident`` "Apply") buildExpression op <.> (apply, [args |> captureExpression]) // we need to capture to guarantee that the result accurately reflects any indirect binding of arguments @@ -556,50 +556,50 @@ module SimulationCode = | Some arrayType -> ``new`` arrayType ``(`` (elems |> Seq.map captureExpression |> Seq.toList) ``)`` // TODO: diagnostics. | _ -> failwith "" - - and buildNewArray b count = - let arrayType = (ArrayType b |> QArrayType).Value + + and buildNewArray b count = + let arrayType = (ArrayType b |> QArrayType).Value arrayType <.> (``ident`` "Create", [count |> buildExpression]) - and buildArrayItem a i = + and buildArrayItem a i = match i.ResolvedType.Resolution with - | Range -> ``invoke`` ((buildExpression a) <|?.|> (``ident`` "Slice")) ``(`` [ (buildExpression i) ] ``)`` - | _ -> ``item`` (buildExpression a) [ (buildExpression i) ] - - let buildBlock (block : QsScope) = + | Range -> ``invoke`` ((buildExpression a) <|?.|> (``ident`` "Slice")) ``(`` [ (buildExpression i) ] ``)`` + | _ -> ``item`` (buildExpression a) [ (buildExpression i) ] + + let buildBlock (block : QsScope) = let builder = new SyntaxBuilder(context) builder.StartLine <- parent.StartLine builder.Statements.OnScope block |> ignore builder.BuiltStatements - let buildSymbolTuple buildTuple buildSymbol symbol = + let buildSymbolTuple buildTuple buildSymbol symbol = let rec buildOne = function // TODO: Diagnostics | InvalidItem -> failwith ("InvalidItem received") | VariableName one -> one.Value |> buildSymbol | VariableNameTuple many -> many |> Seq.map buildOne |> Seq.toList |> buildTuple | DiscardedItem -> "_" |> buildSymbol - // While _ inside C# tuple destructs will properly discard the assignment, + // While _ inside C# tuple destructs will properly discard the assignment, // _ can also be used as variable name in C# where a repeated usage will lead to a compilation error. // We hence auto-generate a name for discarded Q# bindings. match symbol with | DiscardedItem -> nextArgName() |> buildSymbol | _ -> buildOne symbol - let buildSymbolNames buildName = - buildSymbolTuple (String.concat "," >> sprintf "(%s)") buildName + let buildSymbolNames buildName = + buildSymbolTuple (String.concat "," >> sprintf "(%s)") buildName /// returns true if a value of this type contains any arrays /// -> in particular, this does not include the in- and output type of callables - let rec containsArrays (t : ResolvedType) = - match t.Resolution with + let rec containsArrays (t : ResolvedType) = + match t.Resolution with | TupleType ts -> ts |> Seq.exists containsArrays | ArrayType _ -> true | _ -> false // no need to check types within callables - + /// returns true if the given expression initializes a new QArray instance - let rec isArrayInit ex = - match ex.Expression with + let rec isArrayInit ex = + match ex.Expression with | CopyAndUpdate _ | NewArray _ | ADD _ | ValueArray _ -> true | CONDITIONAL (_, l, r) -> isArrayInit l && isArrayInit r | _ -> false @@ -619,23 +619,23 @@ module SimulationCode = |> this.AddStatement QsReturnStatement node - override this.OnVariableDeclaration (node:QsBinding) = + override this.OnVariableDeclaration (node:QsBinding) = let bindsArrays = node.Rhs.ResolvedType |> containsArrays - let rhs = node.Rhs |> captureExpression - let buildBinding buildName = + let rhs = node.Rhs |> captureExpression + let buildBinding buildName = let lhs = node.Lhs |> buildSymbolNames buildName if bindsArrays then // we need to cast to the correct type here (in particular to IQArray for arrays) let t = roslynTypeName context node.Rhs.ResolvedType - ``var`` lhs (``:=`` <| ``cast`` t rhs ) |> this.AddStatement + ``var`` lhs (``:=`` <| ``cast`` t rhs ) |> this.AddStatement else ``var`` lhs (``:=`` <| rhs ) |> this.AddStatement - match node.Kind with + match node.Kind with | MutableBinding -> - match node.Lhs with + match node.Lhs with // no need to insert a destructing statement first - | VariableName varName -> - match node.Rhs.ResolvedType.Resolution |> QArrayType with + | VariableName varName -> + match node.Rhs.ResolvedType.Resolution |> QArrayType with | Some _ when isArrayInit node.Rhs -> // avoid unnecessary copies on construction ``var`` varName.Value (``:=`` <| rhs ) |> this.AddStatement | Some arrType -> // we need to make sure to bind to a new QArray instance here @@ -644,27 +644,27 @@ module SimulationCode = | _ -> buildBinding id // we first need to destruct here, and then make sure all QArrays are built - | VariableNameTuple _ when bindsArrays -> + | VariableNameTuple _ when bindsArrays -> // insert a destructing statement let prefix = nextArgName() let imName = sprintf "%s%s__" prefix - buildBinding imName + buildBinding imName // build the actual binding, making sure all necessary QArrays instances are created - for localVar in parent.DeclarationsInStatement.Variables do + for localVar in parent.DeclarationsInStatement.Variables do let varName = localVar.VariableName.Value - match localVar.Type.Resolution |> QArrayType with - | Some arrType -> + match localVar.Type.Resolution |> QArrayType with + | Some arrType -> let qArray = ``new`` arrType ``(`` [``ident`` (imName varName)] ``)`` ``var`` varName (``:=`` <| qArray) |> this.AddStatement - | _ -> ``var`` varName (``:=`` <| ``ident`` (imName varName)) |> this.AddStatement - | _ -> buildBinding id + | _ -> ``var`` varName (``:=`` <| ``ident`` (imName varName)) |> this.AddStatement + | _ -> buildBinding id | _ -> buildBinding id QsVariableDeclaration node override this.OnValueUpdate (node:QsValueUpdate) = - let rec varNames onTuple onItem (ex : TypedExpression) = - match ex.Expression with + let rec varNames onTuple onItem (ex : TypedExpression) = + match ex.Expression with | MissingExpr -> onItem "_" | Identifier (LocalVariable id, Null) -> onItem id.Value | ValueTuple vs -> vs |> Seq.map (varNames onTuple onItem) |> onTuple @@ -672,67 +672,67 @@ module SimulationCode = | _ -> failwith "unexpected expression in lhs of value update" let lhs, rhs = buildExpression node.Lhs, captureExpression node.Rhs - match node.Lhs.Expression with - | MissingExpr -> ``var`` (nextArgName()) (``:=`` <| buildExpression node.Rhs) |> this.AddStatement + match node.Lhs.Expression with + | MissingExpr -> ``var`` (nextArgName()) (``:=`` <| buildExpression node.Rhs) |> this.AddStatement // no need to insert a destructing statement first - | Identifier (LocalVariable id, Null) -> - let matchesIdentifier (ex : TypedExpression) = - match ex.Expression with + | Identifier (LocalVariable id, Null) -> + let matchesIdentifier (ex : TypedExpression) = + match ex.Expression with | Identifier (LocalVariable rhsId, Null) when rhsId.Value = id.Value -> true | _ -> false let isArray = function | ArrayType _ -> true | _ -> false - match node.Rhs.Expression with + match node.Rhs.Expression with | CopyAndUpdate (l, a, r) when l |> matchesIdentifier && l.ResolvedType.Resolution |> isArray -> // we do an in-place modification in this case let access, rhs = buildExpression a, captureExpression r (buildExpression l) <.> (``ident`` "Modify", [ access; rhs ]) |> statement |> this.AddStatement - | _ when node.Rhs |> matchesIdentifier -> () // unnecessary statement + | _ when node.Rhs |> matchesIdentifier -> () // unnecessary statement | _ -> node.Rhs.ResolvedType.Resolution |> QArrayType |> function - | Some _ when isArrayInit node.Rhs -> // avoid unnecessary copies here - lhs <-- rhs |> statement |> this.AddStatement + | Some _ when isArrayInit node.Rhs -> // avoid unnecessary copies here + lhs <-- rhs |> statement |> this.AddStatement | Some arrType -> // we need to make sure to bind to a new QArray instance here let qArray = ``new`` arrType ``(`` [rhs] ``)`` lhs <-- qArray |> statement |> this.AddStatement | _ -> lhs <-- rhs |> statement |> this.AddStatement // we first need to destruct here, and then make sure all QArrays are built - | _ when containsArrays node.Rhs.ResolvedType -> + | _ when containsArrays node.Rhs.ResolvedType -> // insert a destructing statement let prefix = nextArgName() let imName name = if name = "_" then name else sprintf "%s%s__" prefix name let tempBinding = varNames (fun ids -> String.Join (",", ids) |> sprintf "(%s)") imName node.Lhs - ``var`` tempBinding (``:=`` <| rhs ) |> this.AddStatement + ``var`` tempBinding (``:=`` <| rhs ) |> this.AddStatement // build the actual binding, making sure all necessary QArrays instances are created let ids = varNames (Seq.collect id) (fun id -> seq{ if id <> "_" then yield id}) node.Lhs - for id in ids do + for id in ids do let decl = parent.DeclarationsInScope.Variables |> Seq.tryFind (fun d -> d.VariableName.Value = id) - match decl |> Option.map (fun d -> d.Type.Resolution |> QArrayType) |> Option.flatten with + match decl |> Option.map (fun d -> d.Type.Resolution |> QArrayType) |> Option.flatten with | Some arrType -> // we need to make sure to create a new QArray instance here let qArray = ``new`` arrType ``(`` [imName id |> ``ident``] ``)`` (``ident`` id) <-- qArray |> statement |> this.AddStatement - | _ -> (``ident`` id) <-- (imName id |> ``ident``) |> statement |> this.AddStatement + | _ -> (``ident`` id) <-- (imName id |> ``ident``) |> statement |> this.AddStatement | _ -> lhs <-- rhs |> statement |> this.AddStatement QsValueUpdate node - override this.OnConditionalStatement (node:QsConditionalStatement) = + override this.OnConditionalStatement (node:QsConditionalStatement) = let all = node.ConditionalBlocks let (cond, thenBlock) = all.[0] let cond = cond |> buildExpression let thenBlock = thenBlock.Body |> buildBlock - let others = [ - for i in 1 .. all.Length - 1 -> + let others = [ + for i in 1 .. all.Length - 1 -> let (cond, block) = all.[i] cond |> buildExpression, block.Body |> buildBlock ] - let elseBlock = - match node.Default with + let elseBlock = + match node.Default with | Null -> None | Value block -> ``else`` (buildBlock block.Body) |> Some ``if`` ``(`` cond ``)`` thenBlock (``elif`` others elseBlock) |> this.AddStatement QsConditionalStatement node - + override this.OnForStatement (node:QsForStatement) = let sym = node.LoopItem |> fst |> buildSymbolNames id let range = node.IterationValues |> captureExpression @@ -747,34 +747,34 @@ module SimulationCode = ``while`` ``(`` cond ``)`` body |> this.AddStatement QsWhileStatement node - - override this.OnRepeatStatement rs = + + override this.OnRepeatStatement rs = let buildTest test fixup = let condition = buildExpression test let thens = [``break``] let elses = buildBlock fixup ``if`` ``(`` condition ``)`` thens (Some (``else`` elses)) - ``while`` ``(`` ``true`` ``)`` + ``while`` ``(`` ``true`` ``)`` ((buildBlock rs.RepeatBlock.Body) @ [buildTest rs.SuccessCondition rs.FixupBlock.Body]) |> this.AddStatement QsRepeatStatement rs - override this.OnQubitScope (using:QsQubitScope) = - let (alloc, release) = - match using.Kind with + override this.OnQubitScope (using:QsQubitScope) = + let (alloc, release) = + match using.Kind with | Allocate -> ("Allocate", "Release") | Borrow -> ("Borrow", "Return") - let rec removeDiscarded sym = + let rec removeDiscarded sym = match sym with | VariableName _ -> sym | DiscardedItem -> nextArgName() |> NonNullable.New |> VariableName | VariableNameTuple many -> many |> Seq.map removeDiscarded |> ImmutableArray.CreateRange |> VariableNameTuple | InvalidItem -> failwith ("InvalidItem received") - let rec buildInitializeExpression (exp:ResolvedInitializer) = + let rec buildInitializeExpression (exp:ResolvedInitializer) = match exp.Resolution with - | SingleQubitAllocation -> ((``ident`` alloc) <.> (``ident`` "Apply", [])) - | QubitRegisterAllocation e -> ((``ident`` alloc) <.> (``ident`` "Apply", [ (buildExpression e) ])) + | SingleQubitAllocation -> ((``ident`` alloc) <.> (``ident`` "Apply", [])) + | QubitRegisterAllocation e -> ((``ident`` alloc) <.> (``ident`` "Apply", [ (buildExpression e) ])) | QubitTupleAllocation many -> many |> Seq.map buildInitializeExpression |> List.ofSeq |> ``tuple`` // todo: diagnostics | InvalidInitializer -> failwith ("InvalidInitializer received") @@ -793,12 +793,12 @@ module SimulationCode = match (symbol, expr.Resolution) with | VariableName one, SingleQubitAllocation -> [ buildOne one.Value ] | VariableName one, QubitRegisterAllocation _ -> [ buildOne one.Value ] - | VariableName one, QubitTupleAllocation _ -> (buildDeconstruct one.Value expr) + | VariableName one, QubitTupleAllocation _ -> (buildDeconstruct one.Value expr) | VariableNameTuple ss, QubitTupleAllocation aa -> Seq.zip ss aa |> Seq.map buildReleaseExpression |> Seq.toList |> List.concat | _ -> failwith ("InvalidItem received") parent.LineNumber <- currentLine - releases - + releases + let symbols = removeDiscarded using.Binding.Lhs let deallocationFlagName = nextArgName() let deallocationFlagIdentifier = ``ident`` deallocationFlagName @@ -810,12 +810,12 @@ module SimulationCode = let deallocation = buildReleaseExpression (symbols, using.Binding.Rhs) // To force that exceptions thrown during the execution of the allocation scope take precedence over the ones thrown upon release - // we catch all exceptions in a variable and throw after releaseing if necessary. + // we catch all exceptions in a variable and throw after releaseing if necessary. // Indicates if deallocation is needed. It is not needed when exception is thrown. let deallocationFlagDeclaration = ``typed var`` "bool" deallocationFlagName (``:=`` ``true`` |> Some) |> ``#line hidden`` :> StatementSyntax - - let catch = + + let catch = let setFlagToFalse = deallocationFlagIdentifier <-- ``false`` |> statement ``catch`` None [setFlagToFalse; ``throw`` None] // use standard mechanism to rethrow the exception by using "throw;" let finallyBlock = [``if`` ``(`` deallocationFlagIdentifier ``)`` deallocation None] @@ -830,27 +830,27 @@ module SimulationCode = parent.LineNumber <- currentLine QsQubitScope using - override this.OnFailStatement fs = + override this.OnFailStatement fs = let failException = ``new`` (``type`` ["ExecutionFailException"]) ``(`` [ (buildExpression fs) ] ``)`` this.AddStatement (``throw`` <| Some failException) QsFailStatement fs - and NamespaceBuilder (parent : SyntaxBuilder) = + and NamespaceBuilder (parent : SyntaxBuilder) = inherit NamespaceTransformation(parent, TransformationOptions.NoRebuild) - override this.OnSpecializationDeclaration (sp : QsSpecialization) = + override this.OnSpecializationDeclaration (sp : QsSpecialization) = count <- 0 - match sp.Location with + match sp.Location with | Value location -> parent.StartLine <- Some (location.Offset |> fst) | Null -> parent.StartLine <- None // TODO: we may need to have the means to know which original declaration the code came from base.OnSpecializationDeclaration sp - + let operationDependencies (od:QsCallable) = let seeker = new OperationsSeeker() seeker.Namespaces.OnCallableDeclaration od |> ignore seeker.SharedState |> Seq.toList - let getOpName context n = + let getOpName context n = if needsFullPath context n then prependNamespaceString n else if isCurrentOp context n then Directives.Self else n.Name.Value @@ -863,9 +863,9 @@ module SimulationCode = let signature = context.allCallables.[n].Signature let tIn = signature.ArgumentType let tOut = signature.ReturnType - let count = (getTypeParameters [tIn;tOut]).Length + let count = (getTypeParameters [tIn;tOut]).Length sprintf "%s<%s>" opName (String.replicate (count - 1) ",") - else + else opName ``invoke`` (``ident`` "typeof") ``(`` [``ident`` name] ``)`` @@ -876,8 +876,8 @@ module SimulationCode = let buildOne n = let name = getOpName context n let lhs = ``ident`` "this" <|.|> ``ident`` name - let rhs = - if (isCurrentOp context n) && not (isGeneric context n) then + let rhs = + if (isCurrentOp context n) && not (isGeneric context n) then "this" |> ``ident`` :> ExpressionSyntax else let signature = roslynCallableTypeName context n @@ -885,20 +885,20 @@ module SimulationCode = (``invoke`` factoryGet ``(`` [ (getTypeOfOp context n) ] ``)``) statement (lhs <-- rhs) operations - |> List.map buildOne - ``method`` "void" "Init" ``<<`` [] ``>>`` - ``(`` parameters ``)`` + |> List.map buildOne + ``method`` "void" "Init" ``<<`` [] ``>>`` + ``(`` parameters ``)`` [ ``public``; ``override`` ] ``{`` body ``}`` :> MemberDeclarationSyntax - + /// Returns the constructor for the given operation. let buildConstructor context name : MemberDeclarationSyntax = - ``constructor`` name ``(`` [ ("m", ``type`` "IOperationFactory") ] ``)`` + ``constructor`` name ``(`` [ ("m", ``type`` "IOperationFactory") ] ``)`` ``:`` [ "m" ] [ ``public`` ] ``{`` [] ``}`` - :> MemberDeclarationSyntax + :> MemberDeclarationSyntax /// For each Operation used in the given OperationDeclartion, returns /// a Property that returns an instance of the operation by calling the @@ -930,7 +930,7 @@ module SimulationCode = /// Returns a static property of type OperationInfo using the operation's input and output types. let buildOperationInfoProperty (globalContext:CodegenContext) operationInput operationOutput operationName = - let propertyType = + let propertyType = match globalContext.ExecutionTarget with | target when target = AssemblyConstants.HoneywellProcessor -> sprintf "HoneywellEntryPointInfo<%s, %s>" operationInput operationOutput | target when target = AssemblyConstants.IonQProcessor -> sprintf "IonQEntryPointInfo<%s, %s>" operationInput operationOutput @@ -946,7 +946,7 @@ module SimulationCode = let buildSpecializationBody context (sp:QsSpecialization) = match sp.Implementation with - | Provided (args, _) -> + | Provided (args, _) -> let returnType = sp.Signature.ReturnType let statements = let builder = new SyntaxBuilder(context) @@ -954,12 +954,12 @@ module SimulationCode = builder.BuiltStatements let inData = ``ident`` "__in__" - let ret = + let ret = match returnType.Resolution with | QsTypeKind.UnitType -> - [ - ``#line hidden`` <| - ``return`` ( Some ((``ident`` "QVoid") <|.|> (``ident`` "Instance")) ) + [ + ``#line hidden`` <| + ``return`` ( Some ((``ident`` "QVoid") <|.|> (``ident`` "Instance")) ) ] | _ -> [] @@ -972,79 +972,79 @@ module SimulationCode = match args with | QsTupleItem one -> (one.VariableName |> name, []) | QsTuple many -> - if many.Length = 0 then + if many.Length = 0 then ("__in__", []) - elif many.Length = 1 then + elif many.Length = 1 then ("__in__", [ ``var`` (buildVariableName many.[0]) (``:=`` <| inData) ]) - else + else ("__in__", [ ``var`` (buildVariableName args) (``:=`` <| inData) ]) Some (``() => {}`` [ argName ] (argsInit @ statements @ ret) :> ExpressionSyntax) - | Generated SelfInverse -> - let adjointedBodyName = - match sp.Kind with + | Generated SelfInverse -> + let adjointedBodyName = + match sp.Kind with | QsAdjoint -> "Body" | QsControlledAdjoint -> "ControlledBody" //TODO: diagnostics. | _ -> "Body" Some (``ident`` adjointedBodyName :> ExpressionSyntax) - | _ -> + | _ -> None - + let buildSpecialization context (sp:QsSpecialization) : (PropertyDeclarationSyntax * _) option = let inType = roslynTypeName context sp.Signature.ArgumentType let outType = roslynTypeName context sp.Signature.ReturnType let propertyType = "Func<" + inType + ", " + outType + ">" - let bodyName = - match sp.Kind with + let bodyName = + match sp.Kind with | QsBody -> "Body" | QsAdjoint -> "Adjoint" | QsControlled -> "Controlled" | QsControlledAdjoint -> "ControlledAdjoint" let body = buildSpecializationBody context sp let attributes = - match sp.Location with + match sp.Location with | Null -> [] | Value location -> [ // since the line numbers throughout the generated code are 1-based, let's also choose them 1-based here let startLine = fst location.Offset + 1 - let endLine = - match context.declarationPositions.TryGetValue sp.SourceFile with - | true, startPositions -> + let endLine = + match context.declarationPositions.TryGetValue sp.SourceFile with + | true, startPositions -> let index = startPositions.IndexOf location.Offset if index + 1 >= startPositions.Count then -1 else fst startPositions.[index + 1] + 1 //TODO: diagnostics. | false, _ -> startLine - ``attribute`` None (``ident`` "SourceLocation") [ - ``literal`` sp.SourceFile.Value - ``ident`` "OperationFunctor" <|.|> ``ident`` bodyName - ``literal`` startLine + ``attribute`` None (``ident`` "SourceLocation") [ + ``literal`` sp.SourceFile.Value + ``ident`` "OperationFunctor" <|.|> ``ident`` bodyName + ``literal`` startLine ``literal`` endLine ] ] - match body with + match body with | Some body -> let bodyName = if bodyName = "Body" then bodyName else bodyName + "Body" - let impl = + let impl = ``property-arrow_get`` propertyType bodyName [``public``; ``override``] ``get`` (``=>`` body) Some (impl, attributes) | None -> - None + None /// Returns a flat list (name, type) with all the named parameters of a DeconstructedTuple - let flatArgumentsList context args = + let flatArgumentsList context args = let rec flatOne found = function | QsTupleItem one -> match one.VariableName with | ValidName n -> found @ [n.Value, one.Type |> roslynTypeName context] | InvalidName -> found - | QsTuple many -> + | QsTuple many -> many |> Seq.fold flatOne found args - |> flatOne [] + |> flatOne [] /// Maps the name and type of each named item in the argument tuple. let internal mapArgumentTuple mapping context arguments (argumentType : ResolvedType) = @@ -1057,54 +1057,54 @@ module SimulationCode = many |> Seq.map buildTuple |> List.ofSeq |> ``tuple`` if isTuple argumentType.Resolution then buildTuple arguments - else match flatArgumentsList context arguments with + else match flatArgumentsList context arguments with | [] -> ``ident`` "QVoid" <|.|> ``ident`` "Instance" | [name, typeName] -> mapping (name, typeName) :> ExpressionSyntax | flatArgs -> flatArgs |> List.map mapping |> ``tuple`` let buildRun context className arguments argumentType returnType : MemberDeclarationSyntax = - let inType = roslynTypeName context argumentType + let inType = roslynTypeName context argumentType let outType = roslynTypeName context returnType let task = sprintf "System.Threading.Tasks.Task<%s>" outType let flatArgs = arguments |> flatArgumentsList context let opFactoryTypes = [ className; inType; outType ] - + let uniqueArgName = "__m__" let runArgs = mapArgumentTuple (fst >> ``ident``) context arguments argumentType - let body = - [ + let body = + [ ``return`` (Some ((``ident`` uniqueArgName) <.> (``generic`` "Run" ``<<`` opFactoryTypes ``>>``, [ runArgs ]))) ] - let args = - (``param`` uniqueArgName ``of`` (``type`` "IOperationFactory") ) - :: (flatArgs |> List.map (fun (name, roslynType) -> (``param`` name ``of`` (``type`` roslynType)) ) ) - ``method`` task "Run" ``<<`` [] ``>>`` - ``(`` args ``)`` + let args = + (``param`` uniqueArgName ``of`` (``type`` "IOperationFactory") ) + :: (flatArgs |> List.map (fun (name, roslynType) -> (``param`` name ``of`` (``type`` roslynType)) ) ) + ``method`` task "Run" ``<<`` [] ``>>`` + ``(`` args ``)`` [``public``; ``static``] ``{`` body ``}`` :> MemberDeclarationSyntax - + let findUdtBase context n = let udt = findUdt context n udt.Type - let rec canHaveQubits context (qsharpType:ResolvedType) = + let rec canHaveQubits context (qsharpType:ResolvedType) = match qsharpType.Resolution with | QsTypeKind.Qubit -> true | QsTypeKind.ArrayType at -> canHaveQubits context at - | QsTypeKind.TupleType tt -> tt |> Seq.fold (fun state m -> state || canHaveQubits context m) false + | QsTypeKind.TupleType tt -> tt |> Seq.fold (fun state m -> state || canHaveQubits context m) false | QsTypeKind.UserDefinedType n -> QsQualifiedName.New (n.Namespace, n.Name) - |> findUdtBase context + |> findUdtBase context |> canHaveQubits context | QsTypeKind.Operation _ | QsTypeKind.Function _ -> true | QsTypeKind.TypeParameter _ -> true | _ -> false - let findQubitFields context (qsharpType:ResolvedType) = + let findQubitFields context (qsharpType:ResolvedType) = let item_n n = ``ident`` (sprintf "Item%d" (n+1)) let rec buildSimpleTerm current nullable (t:ResolvedType) = @@ -1112,7 +1112,7 @@ module SimulationCode = | QsTypeKind.Qubit -> [ t, current ] | QsTypeKind.Operation _ - | QsTypeKind.Function _ + | QsTypeKind.Function _ | QsTypeKind.TypeParameter _ | QsTypeKind.ArrayType _ -> if canHaveQubits context t then @@ -1121,21 +1121,21 @@ module SimulationCode = [] | QsTypeKind.UserDefinedType n -> QsQualifiedName.New (n.Namespace, n.Name) - |> findUdtBase context + |> findUdtBase context |> buildSimpleTerm (current <|?.|> (``ident`` "Data")) false | QsTypeKind.TupleType tt -> let buildOne j t = - if nullable then + if nullable then buildSimpleTerm (current <|?.|> (item_n j)) false t - else + else buildSimpleTerm (current <|.|> (item_n j)) false t tt |> Seq.mapi buildOne |> List.concat | _ -> [] match qsharpType.Resolution with - | QsTypeKind.TupleType many -> + | QsTypeKind.TupleType many -> many |> Seq.mapi ( fun j -> buildSimpleTerm ( ``ident`` "Data" <|.|> item_n j ) false ) |> List.concat - | one -> + | one -> qsharpType |> buildSimpleTerm ( ``ident`` "Data" ) true let areAllQubitArgs (argsTypes:ResolvedType list) = @@ -1144,63 +1144,63 @@ module SimulationCode = | _ -> false argsTypes |> List.fold (fun st t -> st && isOne t.Resolution) true - let buildQubitsField context (qsharpType:ResolvedType) = - let fields = qsharpType |> findQubitFields context + let buildQubitsField context (qsharpType:ResolvedType) = + let fields = qsharpType |> findQubitFields context let (fieldTypes, fieldPaths) = fields |> List.unzip if areAllQubitArgs fieldTypes then let buildOne path = ``yield return`` path - match fieldPaths with - | [] -> - ``property-arrow_get`` "System.Collections.Generic.IEnumerable" "IApplyData.Qubits" [] + match fieldPaths with + | [] -> + ``property-arrow_get`` "System.Collections.Generic.IEnumerable" "IApplyData.Qubits" [] ``get`` (``=>`` ``null``) | _ -> - ``property-get`` "System.Collections.Generic.IEnumerable" "IApplyData.Qubits" [] + ``property-get`` "System.Collections.Generic.IEnumerable" "IApplyData.Qubits" [] ``get`` (fieldPaths |> List.map buildOne) else - // this implementation is a workaround for the .NET Core issue discussed here: + // this implementation is a workaround for the .NET Core issue discussed here: // https://github.com/microsoft/qsharp-runtime/issues/116 let mutable count = 0 let nextName() = count <- count + 1 sprintf "__temp%d__" count let mutable items = [] - for (t, token) in fields do + for (t, token) in fields do match t.Resolution with | QsTypeKind.Function _ | QsTypeKind.Operation _ | QsTypeKind.ArrayType _ | QsTypeKind.UserDefinedType _ - | QsTypeKind.Qubit -> + | QsTypeKind.Qubit -> let qs = ``((`` ( ``cast`` "IApplyData" token) ``))`` <|?.|> ``ident`` "Qubits" items <- (null, qs) :: items - | _ -> + | _ -> let id = nextName() let decl = ``var`` id (``:=`` token) let qs = (``ident`` id) ( ``ident`` "GetQubits", [] ) items <- (decl, qs) :: items items <- items |> List.rev - let statements = + let statements = match fields with | [] -> [``return`` (Some ``null``)] - | [_] -> + | [_] -> [ let (decl, qs) = items.Head; if decl <> null then yield decl yield ``return`` (snd items.Head |> Some) - ] + ] | _ -> [ for (decl, _) in items do if decl <> null then yield decl let qs = ( ``ident`` "Qubit" <.> (``ident`` "Concat", items |> List.map snd) ) yield ``return`` (Some qs) ] - ``property-get`` "System.Collections.Generic.IEnumerable" "IApplyData.Qubits" [] + ``property-get`` "System.Collections.Generic.IEnumerable" "IApplyData.Qubits" [] ``get`` statements :> MemberDeclarationSyntax |> List.singleton - + let buildName name = - ``property-arrow_get`` "String" "ICallable.Name" [ ] + ``property-arrow_get`` "String" "ICallable.Name" [ ] ``get`` (``=>`` (``literal`` name) ) :> MemberDeclarationSyntax @@ -1209,7 +1209,7 @@ module SimulationCode = let ns = name.Namespace.Value let n = name.Name.Value if ns = "" then n else ns + "." + n - ``property-arrow_get`` "String" "ICallable.FullName" [ ] + ``property-arrow_get`` "String" "ICallable.FullName" [ ] ``get`` (``=>`` (``literal`` fqn) ) :> MemberDeclarationSyntax @@ -1217,8 +1217,8 @@ module SimulationCode = let testOutputHandle = "Output" let buildOutput () = [ - ``propg`` outputHelperInterface testOutputHandle [ ``internal`` ] - :> MemberDeclarationSyntax + ``propg`` outputHelperInterface testOutputHandle [ ``internal`` ] + :> MemberDeclarationSyntax ] let buildUnitTest (targetName : QsQualifiedName) opName opStart opSourceFile = @@ -1257,7 +1257,7 @@ module SimulationCode = let buildDataClass = let buildValueTupleConstructor = let args = [ ("data", ``type`` (roslynTypeName context qsharpType)) ] - ``constructor`` name ``(`` args ``)`` + ``constructor`` name ``(`` args ``)`` ``:`` [ "data" ] [ ``public`` ] ``{`` @@ -1274,27 +1274,27 @@ module SimulationCode = (constructors @ qubitsField) ``}`` :> MemberDeclarationSyntax - let buildMethod t body = + let buildMethod t body = let baseType = (roslynTypeName context t) let args = [ (``param`` "data" ``of`` (``type`` (roslynTypeName context t)) ) ] - ``arrow_method`` "IApplyData" (sprintf "__data%s" name) ``<<`` [] ``>>`` - ``(`` args ``)`` + ``arrow_method`` "IApplyData" (sprintf "__data%s" name) ``<<`` [] ``>>`` + ``(`` args ``)`` [``public``; ``override``] ( Some ( ``=>`` body) ) :> MemberDeclarationSyntax match qsharpType.Resolution with - | QsTypeKind.UnitType - | QsTypeKind.Qubit + | QsTypeKind.UnitType + | QsTypeKind.Qubit | QsTypeKind.UserDefinedType _ - | QsTypeKind.ArrayType _ -> + | QsTypeKind.ArrayType _ -> (``ident`` "data") |> buildMethod qsharpType, None - | QsTypeKind.TupleType vt -> + | QsTypeKind.TupleType vt -> ( ``new`` (``type`` name) ``(`` [ ``ident`` "data" ] ``)`` ) |> buildMethod qsharpType , (Some buildDataClass) - | _ -> + | _ -> ( ``new`` (``generic`` "QTuple" ``<<`` [ roslynTypeName context qsharpType ] ``>>``) ``(`` [ ``ident`` "data" ] ``)`` ) |> buildMethod qsharpType, None - let typeParametersNames signature = + let typeParametersNames signature = // TODO Diagnostics let name = function | ValidName n -> sprintf "__%s__" n.Value | InvalidName -> "__" signature.TypeParameters |> Seq.map name |> Seq.sort |> Seq.toList @@ -1302,17 +1302,17 @@ module SimulationCode = let findClassName context (op: QsCallable) = let name = op.FullName.Name.Value let typeParameters = typeParametersNames op.Signature - let nonGeneric = if typeParameters.IsEmpty then name else sprintf "%s<%s>" name (String.Join(",", typeParameters)) + let nonGeneric = if typeParameters.IsEmpty then name else sprintf "%s<%s>" name (String.Join(",", typeParameters)) (name, nonGeneric) - let isAbstract op = + let isAbstract op = let isBody (sp:QsSpecialization) = match sp.Kind with | QsBody when sp.Implementation <> Intrinsic -> true | _ -> false not (op.Specializations |> Seq.exists isBody) let isFunction (op:QsCallable) = match op.Kind with | Function -> true | _ -> false let buildTestClass (testTargets : QsQualifiedName list) (targetName : QsQualifiedName) opName (op : QsCallable) = - let className = + let className = let requiresQualification = (testTargets |> List.filter (fun t -> t.Name.Value = targetName.Name.Value)).Length > 1 if requiresQualification then sprintf "%s_%s" (targetName.Namespace.Value.Replace('.', '_')) targetName.Name.Value else targetName.Name.Value @@ -1321,8 +1321,8 @@ module SimulationCode = ``constructor`` className ``(`` [ (testOutputHandle, ``type`` outputHelperInterface) ] ``)`` ``:`` [] [``public``] - ``{`` - [ + ``{`` + [ ``ident`` "this" <|.|> ``ident`` testOutputHandle <-- ``ident`` testOutputHandle |> statement ] ``}`` @@ -1331,16 +1331,16 @@ module SimulationCode = let properties = buildOutput () let methods = - match op.Location with + match op.Location with | Value location -> [ buildUnitTest targetName opName (fst location.Offset) op.SourceFile.Value ] // TODO: diagnostics | Null -> failwith "missing location for unit test" - + ``class`` className ``<<`` [] ``>>`` ``:`` None ``,`` [] [``public``] ``{`` - (constructors @ properties @ methods) + (constructors @ properties @ methods) ``}`` let private classAccessModifier = function @@ -1356,33 +1356,33 @@ module SimulationCode = let outType = op.Signature.ReturnType |> roslynTypeName context let constructors = [ (buildConstructor context name) ] - let properties = + let properties = let opProperties = buildOpsProperties context opNames - buildName name :: - buildFullName context.current.Value :: - if globalContext.entryPoints |> Seq.contains op.FullName then - buildOperationInfoProperty globalContext inType outType nonGenericName :: + buildName name :: + buildFullName context.current.Value :: + if globalContext.entryPoints |> Seq.contains op.FullName then + buildOperationInfoProperty globalContext inType outType nonGenericName :: opProperties else opProperties - + let baseOp = - if isFunction op then + if isFunction op then "Function" else let (adj, ctrl) = op.Signature.Information.Characteristics.SupportedFunctors |> hasAdjointControlled - match (adj, ctrl) with + match (adj, ctrl) with | (false , false) -> "Operation" | (true , false) -> "Adjointable" | (false , true ) -> "Controllable" | (true , true ) -> "Unitary" - + let typeArgsInterface = if (baseOp = "Operation" || baseOp = "Function") then [inType; outType] else [inType] let typeParameters = typeParametersNames op.Signature let baseClass = genericBase baseOp ``<<`` typeArgsInterface ``>>`` - let bodies, attr = - op.Specializations |> Seq.map (buildSpecialization context) |> Seq.choose id |> Seq.toList + let bodies, attr = + op.Specializations |> Seq.map (buildSpecialization context) |> Seq.choose id |> Seq.toList |> List.map (fun (x, y) -> (x :> MemberDeclarationSyntax, y)) |> List.unzip - let inData = (buildDataWrapper context "In" op.Signature.ArgumentType) + let inData = (buildDataWrapper context "In" op.Signature.ArgumentType) let outData = (buildDataWrapper context "Out" op.Signature.ReturnType) let defaultTargetNs = NonNullable<_>.New("Microsoft.Quantum.Simulation.Simulators") @@ -1407,7 +1407,7 @@ module SimulationCode = let innerClasses = ([ inData |> snd; outData |> snd ] |> List.choose id) @ unitTests let methods = [ opNames |> buildInit context; inData |> fst; outData |> fst; buildRun context nonGenericName op.ArgumentTuple op.Signature.ArgumentType op.Signature.ReturnType ] - + let modifiers = let access = classAccessModifier op.Modifiers.Access if isAbstract op then @@ -1419,7 +1419,7 @@ module SimulationCode = ``class`` name ``<<`` typeParameters ``>>`` ``:`` (Some baseClass) ``,`` [ ``simpleBase`` "ICallable" ] modifiers ``{`` - (constructors @ innerClasses @ properties @ bodies @ methods) + (constructors @ innerClasses @ properties @ bodies @ methods) ``}`` ) @@ -1429,15 +1429,15 @@ module SimulationCode = let buildUdtClass (globalContext:CodegenContext) (udt: QsCustomType) = let context = globalContext.setUdt udt let name = udt.FullName.Name.Value - let qsharpType = udt.Type - let buildEmtpyConstructor = - let baseTupleType = - match qsharpType.Resolution with + let qsharpType = udt.Type + let buildEmtpyConstructor = + let baseTupleType = + match qsharpType.Resolution with | ArrayType b -> roslynTypeName context b |> sprintf "QArray<%s>" | _ -> (roslynTypeName context qsharpType) let defaultValue = match qsharpType.Resolution with | ArrayType _ -> [ sprintf "new %s()" baseTupleType] | _ -> [ sprintf "default(%s)" baseTupleType ] let args = [] - ``constructor`` name ``(`` args ``)`` + ``constructor`` name ``(`` args ``)`` ``:`` defaultValue [ ``public`` ] ``{`` @@ -1447,7 +1447,7 @@ module SimulationCode = let buildBaseTupleConstructor = let baseTupleType = (roslynTypeName context qsharpType) let args = [ ("data", ``type`` baseTupleType) ] - ``constructor`` name ``(`` args ``)`` + ``constructor`` name ``(`` args ``)`` ``:`` [ "data" ] [ ``public`` ] ``{`` @@ -1456,7 +1456,7 @@ module SimulationCode = :> MemberDeclarationSyntax let buildNamedItemFields = let produceProperty (decl : LocalVariableDeclaration>) valueExpr = - ``property-arrow_get`` (roslynTypeName context decl.Type) decl.VariableName.Value [ ``public`` ] + ``property-arrow_get`` (roslynTypeName context decl.Type) decl.VariableName.Value [ ``public`` ] ``get`` (``=>`` valueExpr) :> MemberDeclarationSyntax let rec buildProps current = function | QsTuple items -> items |> Seq.mapi (fun i x -> buildProps (current <|.|> ``ident`` ("Item" + (i+1).ToString())) x) |> Seq.collect id @@ -1472,14 +1472,14 @@ module SimulationCode = | QsTupleItem (Anonymous _) -> Seq.empty | QsTupleItem (Named decl) -> seq { yield produceProperty decl (``ident`` "Data") } readType udt.TypeItems |> Seq.toList - let buildItemFields = + let buildItemFields = let buildOne i t = - ``property-arrow_get`` (roslynTypeName context t) (sprintf "Item%d" (i+1)) [ ``public`` ] + ``property-arrow_get`` (roslynTypeName context t) (sprintf "Item%d" (i+1)) [ ``public`` ] ``get`` (``=>`` (``ident`` "Data" <|.|> ``ident`` (sprintf "Item%d" (i+1)))) :> MemberDeclarationSyntax match qsharpType.Resolution with | QsTypeKind.TupleType many -> many |> Seq.mapi buildOne |> List.ofSeq - | _ -> [] + | _ -> [] let buildDeconstruct = let body = let buildOne i t = @@ -1489,48 +1489,48 @@ module SimulationCode = match qsharpType.Resolution with | QsTypeKind.TupleType many -> many |> Seq.mapi buildOne |> List.ofSeq | _ -> [] - let parameters = + let parameters = let buildOneParameter i t = - let paramType = t |> roslynTypeName context + let paramType = t |> roslynTypeName context ``out param`` (sprintf "item%d" (i+1)) ``of`` (``type`` paramType) match qsharpType.Resolution with | QsTypeKind.TupleType many -> many |> Seq.mapi buildOneParameter |> List.ofSeq | _ -> [] - ``method`` "void" "Deconstruct" ``<<`` [] ``>>`` - ``(`` parameters ``)`` + ``method`` "void" "Deconstruct" ``<<`` [] ``>>`` + ``(`` parameters ``)`` [ ``public`` ] ``{`` body ``}`` :> MemberDeclarationSyntax - + let baseClassName = udtBaseClassName context qsharpType let baseClass = ``simpleBase`` baseClassName let modifiers = [ classAccessModifier udt.Modifiers.Access ] - let interfaces = [ ``simpleBase`` "IApplyData" ] + let interfaces = [ ``simpleBase`` "IApplyData" ] let constructors = [ buildEmtpyConstructor; buildBaseTupleConstructor ] let qubitsField = buildQubitsField context qsharpType let itemFields = buildNamedItemFields @ buildItemFields let allFields = itemFields @ qubitsField let allMethods = [ buildDeconstruct ] - + ``class`` name ``<<`` [] ``>>`` ``:`` (Some baseClass) ``,`` interfaces modifiers ``{`` (constructors @ allFields @ allMethods) ``}`` :> MemberDeclarationSyntax - + // Generates the code for all the elements of the given namespace. - let buildNamespace globalContext (nsName : NonNullable, localElements : QsNamespaceElement list) = + let buildNamespace globalContext (nsName : NonNullable, localElements : QsNamespaceElement list) = let buildOne = function | QsCallable op when op.Kind = TypeConstructor -> None | QsCustomType udt -> udt |> buildUdtClass globalContext |> Some | QsCallable op -> op |> buildOperationClass globalContext |> Some - let members = + let members = localElements |> List.map buildOne |> List.choose id - ``#line hidden`` <| + ``#line hidden`` <| ``namespace`` nsName.Value ``{`` [] @@ -1538,7 +1538,7 @@ module SimulationCode = ``}`` :> MemberDeclarationSyntax - type AttributeGenerator () = + type AttributeGenerator () = inherit NamespaceTransformation(TransformationOptions.NoRebuild) let mutable attributes = [] @@ -1546,36 +1546,36 @@ module SimulationCode = let attr = ``attribute`` (Some ``assembly``) (``ident`` attrName) [ ``literal`` json ] attributes <- attr :: attributes - member internal this.Apply (elements : IEnumerable) = + member internal this.Apply (elements : IEnumerable) = attributes <- [] - for element in elements do + for element in elements do base.OnNamespaceElement element |> ignore attributes |> List.rev - override this.OnSpecializationDeclaration (spec : QsSpecialization) = + override this.OnSpecializationDeclaration (spec : QsSpecialization) = (SpecializationDeclarationHeader.New spec).ToJson() |> GenerateAndAdd "SpecializationDeclaration" spec - override this.OnCallableDeclaration (callable : QsCallable) = + override this.OnCallableDeclaration (callable : QsCallable) = (CallableDeclarationHeader.New callable).ToJson() |> GenerateAndAdd "CallableDeclaration" base.OnCallableDeclaration callable - override this.OnTypeDeclaration (qsType : QsCustomType) = + override this.OnTypeDeclaration (qsType : QsCustomType) = (TypeDeclarationHeader.New qsType).ToJson() |> GenerateAndAdd "TypeDeclaration" qsType - let buildDeclarationAttributes elements = + let buildDeclarationAttributes elements = let generator = new AttributeGenerator() - generator.Apply elements + generator.Apply elements // Returns only those namespaces and their elements that are defined for the given file. let findLocalElements selector fileName syntaxTree = - let path = - match CompilationBuilder.CompilationUnitManager.TryGetUri fileName with + let path = + match CompilationBuilder.CompilationUnitManager.TryGetUri fileName with | true, uri -> uri.AbsolutePath |> NonNullable.New | false, _ -> NonNullable.New "" syntaxTree @@ -1596,12 +1596,12 @@ module SimulationCode = ] // Builds the C# syntaxTree for the Q# elements defined in the given file. - let buildSyntaxTree localElements (context : CodegenContext) = + let buildSyntaxTree localElements (context : CodegenContext) = let usings = autoNamespaces |> List.map (fun ns -> ``using`` ns) let attributes = localElements |> List.map (snd >> buildDeclarationAttributes) |> List.concat let namespaces = localElements |> List.map (buildNamespace context) - ``compilation unit`` + ``compilation unit`` attributes usings namespaces @@ -1611,55 +1611,55 @@ module SimulationCode = |> ``pragmaDisableWarning`` 0436 // shadowing existing classes from references |> ``with leading comments`` autogenComment - // Helper method that takes a SyntaxTree, adds trivia (formatting) + // Helper method that takes a SyntaxTree, adds trivia (formatting) // and returns it as a string let formatSyntaxTree tree = - try + try let ws = new AdhocWorkspace() let formattedRoot = Formatter.Format(tree, ws) formattedRoot.ToFullString() - with + with | :? ReflectionTypeLoadException as l -> let msg = l.LoaderExceptions |> Array.fold (fun msg e -> msg + ";" + e.Message) "" failwith msg - - /// Builds the SyntaxTree for callables and types loaded via test names, + + /// Builds the SyntaxTree for callables and types loaded via test names, /// formats it and returns it as a string. - /// Returns null if no elements have been loaded via test name. - let loadedViaTestNames (dllName : NonNullable) globalContext = - let isLoadedViaTestName nsElement = + /// Returns null if no elements have been loaded via test name. + let loadedViaTestNames (dllName : NonNullable) globalContext = + let isLoadedViaTestName nsElement = let asOption = function | Value _ -> Some nsElement | _ -> None - match nsElement with - | QsCallable c as e -> SymbolResolution.TryGetTestName c.Attributes - | QsCustomType t as e -> SymbolResolution.TryGetTestName t.Attributes + match nsElement with + | QsCallable c as e -> SymbolResolution.TryGetTestName c.Attributes + | QsCustomType t as e -> SymbolResolution.TryGetTestName t.Attributes |> asOption - let context = {globalContext with fileName = Some dllName.Value} + let context = {globalContext with fileName = Some dllName.Value} let localElements = findLocalElements isLoadedViaTestName dllName context.allQsElements - let getNameCollisions (_, elems : QsNamespaceElement list) = - let tryGetCollision = function - | QsCustomType t -> - match SymbolResolution.TryGetOriginalName t.Attributes with - | Value origName -> - match context.allUdts.TryGetValue origName with - | true, collision -> + let getNameCollisions (_, elems : QsNamespaceElement list) = + let tryGetCollision = function + | QsCustomType t -> + match SymbolResolution.TryGetOriginalName t.Attributes with + | Value origName -> + match context.allUdts.TryGetValue origName with + | true, collision -> if context.GenerateCodeForSource collision.SourceFile then None else Some (origName.Namespace, QsCustomType collision) | _ -> None | Null -> None - | QsCallable c -> - match SymbolResolution.TryGetOriginalName c.Attributes with - | Value origName -> - match context.allCallables.TryGetValue origName with - | true, collision -> + | QsCallable c -> + match SymbolResolution.TryGetOriginalName c.Attributes with + | Value origName -> + match context.allCallables.TryGetValue origName with + | true, collision -> if context.GenerateCodeForSource collision.SourceFile then None else Some (origName.Namespace, QsCallable collision) | _ -> None | Null -> None elems |> List.choose tryGetCollision - if localElements.Any() then - let collisions = + if localElements.Any() then + let collisions = (localElements |> Seq.collect getNameCollisions).ToLookup(fst, snd) |> Seq.map (fun g -> g.Key, g |> Seq.toList) |> Seq.toList buildSyntaxTree (localElements @ collisions) context @@ -1668,14 +1668,14 @@ module SimulationCode = /// Main entry method for a CodeGenerator. /// Builds the SyntaxTree for the given Q# syntax tree, formats it and returns it as a string. - /// Omits code generation for intrinsic callables in references. - let generate (fileName : NonNullable) globalContext = + /// Omits code generation for intrinsic callables in references. + let generate (fileName : NonNullable) globalContext = let isIntrinsic = function | QsCallable c -> c.Signature.Information.InferredInformation.IsIntrinsic | QsCustomType _ -> false let filterIntrinsics (ns, elems) = ns, elems |> List.filter (not << isIntrinsic) - let context = {globalContext with fileName = Some fileName.Value} - let localElements = + let context = {globalContext with fileName = Some fileName.Value} + let localElements = let elements = findLocalElements Some fileName context.allQsElements if fileName.Value.EndsWith ".dll" then elements |> List.map filterIntrinsics else elements diff --git a/src/Simulation/Simulators.Tests/Circuits/UserDefinedTypes.qs b/src/Simulation/Simulators.Tests/Circuits/UserDefinedTypes.qs index 2d1720f2b21..b98956c5fb9 100644 --- a/src/Simulation/Simulators.Tests/Circuits/UserDefinedTypes.qs +++ b/src/Simulation/Simulators.Tests/Circuits/UserDefinedTypes.qs @@ -11,7 +11,7 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits function TakesUdtPartial<'T, 'U> (build : ('T -> 'U), remainingArgs : 'T) : 'U { return build(remainingArgs); - } + } operation PassingUDTConstructorTest() : Unit { @@ -21,7 +21,7 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits AssertEqual(c1, 3); let partial = P2((_,2), _); - let full = TakesUdtPartial(partial, (3,1)); + let full = TakesUdtPartial(partial, (3,1)); let ((a2, b2), c2) = full!; AssertEqual(a2, 3); AssertEqual(b2, 2); @@ -32,7 +32,7 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits { let partial = P2((_,2), _); let full = partial(3, 1); - + let ((a, b), c) = full!; AssertEqual(a, 3); AssertEqual(b, 2); @@ -43,10 +43,10 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits { let partial = P1(2, _); let full = partial(3); - + let (a, b) = full!; AssertEqual(5, a+b); - + let full2 = partial(10); let (x, y) = full2!; AssertEqual(12, x + y); @@ -76,7 +76,7 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits return P2((3,_),_); } - function CallReturnedUdtConstructorTest () : Unit + function CallReturnedUdtConstructorTest () : Unit { let udt1 = (returnUdtConstructor())((1,2),3); let ((a1,b1),c1) = udt1!; From 3fe1ac5c1ff1e12c110f634c419b450b67ce7543 Mon Sep 17 00:00:00 2001 From: Scott Carda Date: Mon, 22 Jun 2020 18:41:29 -0700 Subject: [PATCH 6/7] Added inner named tuple udt execution test. --- .../Simulators.Tests/Circuits/UserDefinedTypes.qs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Simulation/Simulators.Tests/Circuits/UserDefinedTypes.qs b/src/Simulation/Simulators.Tests/Circuits/UserDefinedTypes.qs index b98956c5fb9..5260290389f 100644 --- a/src/Simulation/Simulators.Tests/Circuits/UserDefinedTypes.qs +++ b/src/Simulation/Simulators.Tests/Circuits/UserDefinedTypes.qs @@ -8,6 +8,18 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits newtype P1 = (Int, Int); newtype P2 = ((Int, Int), Int); newtype NamedTuple = (FirstItem: (Int, Double), SecondItem: Int); + newtype InnerNamedTuple = ((Fst : Result, Snd : (Int, Int)), Trd : String); + + operation UdtInnerNamedTupleFieldTest () : Unit { + let t = InnerNamedTuple((Zero, (0,1)), ""); + AssertEqual(Zero, t::Fst); + let snd = t::Snd; + let (s1, s2) = snd; + AssertEqual(0, s1); + AssertEqual(1, s2); + AssertEqual("", t::Trd); + } + function TakesUdtPartial<'T, 'U> (build : ('T -> 'U), remainingArgs : 'T) : 'U { return build(remainingArgs); From 25c5aa2bf4d793a15918d6385bd52607abf48955 Mon Sep 17 00:00:00 2001 From: Scott Carda Date: Mon, 22 Jun 2020 18:50:54 -0700 Subject: [PATCH 7/7] Moved the new test to be near the other new test. --- .../Circuits/UserDefinedTypes.qs | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/Simulation/Simulators.Tests/Circuits/UserDefinedTypes.qs b/src/Simulation/Simulators.Tests/Circuits/UserDefinedTypes.qs index 5260290389f..fa8cbc07cff 100644 --- a/src/Simulation/Simulators.Tests/Circuits/UserDefinedTypes.qs +++ b/src/Simulation/Simulators.Tests/Circuits/UserDefinedTypes.qs @@ -9,17 +9,6 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits newtype P2 = ((Int, Int), Int); newtype NamedTuple = (FirstItem: (Int, Double), SecondItem: Int); newtype InnerNamedTuple = ((Fst : Result, Snd : (Int, Int)), Trd : String); - - operation UdtInnerNamedTupleFieldTest () : Unit { - let t = InnerNamedTuple((Zero, (0,1)), ""); - AssertEqual(Zero, t::Fst); - let snd = t::Snd; - let (s1, s2) = snd; - AssertEqual(0, s1); - AssertEqual(1, s2); - AssertEqual("", t::Trd); - } - function TakesUdtPartial<'T, 'U> (build : ('T -> 'U), remainingArgs : 'T) : 'U { return build(remainingArgs); @@ -129,5 +118,15 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits AssertEqual(b, 2.0); AssertEqual(c, 3); } + + function UdtInnerNamedTupleFieldTest () : Unit { + let t = InnerNamedTuple((Zero, (0,1)), ""); + AssertEqual(Zero, t::Fst); + let snd = t::Snd; + let (s1, s2) = snd; + AssertEqual(0, s1); + AssertEqual(1, s2); + AssertEqual("", t::Trd); + } }