Skip to content
This repository was archived by the owner on Jan 12, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/Simulation/CsharpGeneration.Tests/Circuits/CodegenTests.qs
Original file line number Diff line number Diff line change
Expand Up @@ -1294,7 +1294,18 @@ namespace Microsoft.Quantum.Compiler.Generics {
set arr = arr w/ i <- map(arr[i]);
}
}

newtype MyType1 = (i1 : Int[], i2 : Double);
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;
}
}


34 changes: 34 additions & 0 deletions src/Simulation/CsharpGeneration.Tests/SimulationCodeTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ namespace N1
let returnTest10 = findCallable @"returnTest10"
let bitOperations = findCallable @"bitOperations"
let testLengthDependency = findCallable @"testLengthDependency"
let UpdateUdtItems = findCallable @"UpdateUdtItems"

let udt_args0 = findUdt @"udt_args0"
let udt_args1 = findUdt @"udt_args1"
Expand Down Expand Up @@ -2621,6 +2622,39 @@ namespace N1

[<Fact>]
let ``buildOperationClass - concrete functions`` () =
"""
[SourceLocation("%%%", OperationFunctor.Body, 1301,-1)]
public partial class UpdateUdtItems : Function<MyType2, MyType2>, ICallable
{
public UpdateUdtItems(IOperationFactorym) : base(m)
{
}

String ICallable.Name => "UpdateUdtItems";
String ICallable.FullName => "Microsoft.Quantum.Compiler.Generics.UpdateUdtItems";

public static OperationInfo<MyType2, MyType2> Info => new OperationInfo<MyType2, MyType2>(typeof(UpdateUdtItems));

public override Func<MyType2, MyType2> Body => (__in__) =>
{
var udt = __in__;
vararr=QArray<Int64>.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<MyType2> Run(IOperationFactory __m__, MyType2 udt)
{
return __m__.Run<UpdateUdtItems,MyType2,MyType2>(udt);
}
}
"""
|> testOneClass UpdateUdtItems


"""
public abstract partial class emptyFunction : Function<QVoid, QVoid>, ICallable
{
Expand Down
31 changes: 23 additions & 8 deletions src/Simulation/CsharpGeneration/SimulationCode.fs
Original file line number Diff line number Diff line change
Expand Up @@ -423,19 +423,34 @@ module SimulationCode =
lhsAsQArray <.> (``ident`` "Modify", [ buildExpression accEx; captureExpression rhsEx ]) // in-place modification
| _ -> lhsEx.ResolvedType.Resolution |> function
| UserDefinedType udt ->
let itemName = accEx.Expression |> function
| Identifier (LocalVariable id, Null) -> id
// TODO: Diagnostics
| _ -> failwith "item access expression in copy-and-update expression for user defined type is not a suitable identifier"
let name = QsQualifiedName.New (udt.Namespace, udt.Name)
let decl = findUdt context name
let root = (buildExpression lhsEx) <|.|> (``ident`` "Data")

let isUserDefinedType = function | UserDefinedType _ -> true | _ -> false
let getItemName = function
| Identifier (LocalVariable id, Null) -> id.Value
// TODO: Diagnostics
| _ -> failwith "item access expression in copy-and-update expression for user defined type is not a suitable identifier"
let updatedItems = new Dictionary<string, ExpressionSyntax>()
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
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
| QsTuple args -> args |> Seq.map buildArg |> Seq.toList |> ``tuple``
| QsTupleItem (Named item) when item.VariableName.Value = itemName.Value ->
items.Dequeue() |> ignore
captureExpression rhsEx
| QsTupleItem (Named item) -> updatedItems.TryGetValue item.VariableName.Value |> function
| true, rhs ->
items.Dequeue() |> ignore
rhs
| _ -> items.Dequeue()
| QsTupleItem _ -> items.Dequeue()
``new`` (``type`` [ justTheName context name ]) ``(`` [buildArg decl.TypeItems] ``)``
| _ -> failwith "copy-and-update expressions are currently only supported for arrays and user defined types"
Expand Down