public override QsScope OnScope(QsScope scope) { var statements = ImmutableArray.CreateBuilder <QsStatement>(); foreach (var statement in scope.Statements) { if (statement.Statement is QsStatementKind.QsConjugation conj) { // since we are eliminating scopes, // we need to make sure that the variables defined within the inlined scopes do not clash with other defined variables. var outer = this.SharedState.ResolveNames(this.OnScope(conj.Item.OuterTransformation.Body)); var inner = this.SharedState.ResolveNames(this.OnScope(conj.Item.InnerTransformation.Body)); var adjOuter = outer.GenerateAdjoint(); // will add a unique name wrapper statements.AddRange(outer.Statements); statements.AddRange(inner.Statements); statements.AddRange(adjOuter.Statements); } else { statements.Add(this.OnStatement(statement)); } } return(new QsScope(statements.ToImmutableArray(), scope.KnownSymbols)); }
/// <summary> /// Get the exact function with given parameters names. /// by comparing the names and the length of parameters. /// </summary> /// <param name="scope"></param> /// <param name="parametersNames"></param> /// <returns></returns> public static QsFunction GetExactFunctionWithParameters( QsScope scope, string nameSpace, string functionName, params string[] parametersNames) { if (parametersNames == null) { return(GetDefaultFunction(scope, nameSpace, functionName, 0)); } else { var funcs = FindFunctionByParameters(scope, nameSpace, functionName, parametersNames.Length, parametersNames); foreach (var func in funcs) { //double check parameters and their length to get the exact function. if (func.Parameters.Length == parametersNames.Length) { if (func.ContainsParameters(parametersNames)) { return(func); } } } return(null); } }
/// <summary> /// Get the first declared function of this undecorated name. /// </summary> /// <param name="scope"></param> /// <param name="nameSpace"></param> /// <param name="functionName"></param> /// <returns></returns> public static QsFunction GetFirstDeclaredFunction( QsScope scope, string nameSpace, string functionName) { IEnumerable <KeyValuePair <string, object> > Items = null; if (!string.IsNullOrEmpty(nameSpace)) { var ns = QsNamespace.GetNamespace(scope, nameSpace); Items = ns.GetItems(); } else { Items = scope.GetItems(); } var func_Pass1 = from item in Items where item.Value is QsFunction select(QsFunction) item.Value; var qf = from fun in func_Pass1 where fun.FunctionName.Equals(functionName, StringComparison.OrdinalIgnoreCase) select fun; return(qf.ElementAtOrDefault(0)); }
/// <summary> /// /// </summary> /// <param name="scope"></param> /// <param name="nameSpace"></param> /// <param name="parametersCount">filter functions by number of parameters</param> /// <param name="parametersNames"></param> /// <returns></returns> public static QsFunction[] FindFunctionByParameters( QsScope scope, string qsNamespace, string functionName, int parametersCount, params string[] parametersNames) { IEnumerable <KeyValuePair <string, object> > Items = null; if (!string.IsNullOrEmpty(qsNamespace)) { var ns = QsNamespace.GetNamespace(scope, qsNamespace); Items = ns.GetItems(); } else { Items = scope.GetItems(); } var func_Pass1 = from item in Items where item.Value is QsFunction select(QsFunction) item.Value; var func_Pass2 = from func in func_Pass1 where func.ContainsParameters(parametersNames) && func.Parameters.Length == parametersCount select func; var func_Pass3 = from fc in func_Pass2 where fc.FunctionName.Equals(functionName, StringComparison.OrdinalIgnoreCase) select fc; return(func_Pass3.ToArray()); }
/// <summary> /// The primary function that gets the namespace from the scope. /// </summary> /// <param name="scope"></param> /// <param name="moduleNamespace"></param> /// <param name="forceCreation">force creation of namespace in scope if dosen't exist before.</param> /// <returns></returns> public static QsNamespace GetNamespace(QsScope scope, string moduleNamespace, bool forceCreation) { QsNamespace NameSpace = null; // try to get the namespace object from the scope // then see if it represent a custom namespace also or not. // then return the object that hold the whole thing. if (scope != null) { if (scope.HasValue(moduleNamespace)) { NameSpace = (QsNamespace)scope.GetValue(moduleNamespace); } if (NameSpace == null) { // no namespace in this scope NameSpace = new QsNamespace(moduleNamespace); // search if this namespace represent hardcoded namespace System.Type nst = GetQsNamespaceType(moduleNamespace); NameSpace._NamespaceType = nst; if (forceCreation | (nst != null)) { scope.SetValue(moduleNamespace, NameSpace); } } } return(NameSpace); }
/// <summary> /// Given the body of an operation, auto-generates the (content of the) adjoint specialization, /// under the assumption that operation calls may only ever occur within expression statements, /// and while-loops cannot occur within operations. /// </summary> public static QsScope GenerateAdjoint(this QsScope scope) { // Since we are pulling purely classical statements up, we are potentially changing the order of declarations. // We therefore need to generate unique variable names before reordering the statements. scope = new UniqueVariableNames().Transform(scope); scope = ApplyFunctorToOperationCalls.ApplyAdjoint(scope); scope = new ReverseOrderOfOperationCalls().Transform(scope); return(StripLocationInformation.Apply(scope)); }
/// <summary> /// Checks if the scope is valid for conversion to an operation call from the conditional control API. /// It is valid if there is exactly one statement in it and that statement is a call like expression statement. /// If valid, returns true with the identifier of the call like expression and the arguments of the /// call like expression, otherwise returns false with nulls. /// </summary> private (bool, TypedExpression, TypedExpression) IsValidScope(QsScope scope) { // if the scope has exactly one statement in it and that statement is a call like expression statement if (scope != null && scope.Statements.Length == 1 && scope.Statements[0].Statement is QsStatementKind.QsExpressionStatement expr && expr.Item.ResolvedType.Resolution.IsUnitType && expr.Item.Expression is ExpressionKind.CallLikeExpression call && !TypedExpression.IsPartialApplication(expr.Item.Expression) && call.Item1.Expression is ExpressionKind.Identifier) { var newCallIdentifier = call.Item1; var callTypeArguments = expr.Item.TypeParameterResolutions; // This relies on anything having type parameters must be a global callable. if (newCallIdentifier.Expression is ExpressionKind.Identifier id && id.Item1 is Identifier.GlobalCallable global && callTypeArguments.Any()) { // We are dissolving the application of arguments here, so the call's type argument // resolutions have to be moved to the 'identifier' sub expression. var combination = new TypeResolutionCombination(expr.Item); var combinedTypeArguments = combination.CombinedResolutionDictionary.Where(kvp => kvp.Key.Item1.Equals(global.Item)).ToImmutableDictionary(); QsCompilerError.Verify(combination.IsValid, "failed to combine type parameter resolution"); var globalCallable = this.SharedState.Compilation.Namespaces .Where(ns => ns.Name.Equals(global.Item.Namespace)) .Callables() .FirstOrDefault(c => c.FullName.Name.Equals(global.Item.Name)); QsCompilerError.Verify(globalCallable != null, $"Could not find the global reference {global.Item}."); var callableTypeParameters = globalCallable.Signature.TypeParameters .Select(x => x as QsLocalSymbol.ValidName); QsCompilerError.Verify(callableTypeParameters.All(x => x != null), $"Invalid type parameter names."); newCallIdentifier = new TypedExpression( ExpressionKind.NewIdentifier( id.Item1, QsNullable <ImmutableArray <ResolvedType> > .NewValue( callableTypeParameters .Select(x => combinedTypeArguments[Tuple.Create(global.Item, x.Item)]).ToImmutableArray())), TypedExpression.AsTypeArguments(combinedTypeArguments), call.Item1.ResolvedType, call.Item1.InferredInformation, call.Item1.Range); } return(true, newCallIdentifier, call.Item2); } return(false, null, null); }
public override Tuple <QsTuple <LocalVariableDeclaration <QsLocalSymbol> >, QsScope> onProvidedImplementation (QsTuple <LocalVariableDeclaration <QsLocalSymbol> > argTuple, QsScope body) { this._Scope.Reset(); try { body = this._Scope.Transform(body); } catch (Exception ex) { this.OnException?.Invoke(ex); this.Success = false; } return(new Tuple <QsTuple <LocalVariableDeclaration <QsLocalSymbol> >, QsScope>(argTuple, body)); }
/// <summary> /// Get the default function. /// Default function is on the form f#2 f#3 without decoration for parameters. /// </summary> /// <param name="scope"></param> /// <param name="nameSpace"></param> /// <param name="functionName"></param> /// <param name="parameterCount"></param> /// <returns></returns> public static QsFunction GetDefaultFunction( QsScope scope, string nameSpace, string functionName, int parametersCount) { string functionRealName = QsFunction.FormFunctionSymbolicName(functionName, parametersCount); QsFunction func = QsFunction.GetFunction(scope, nameSpace, functionRealName); return(func); }
/// <summary> /// Get sequence object from the scope memory. /// </summary> /// <param name="scope"></param> /// <param name="qsNamespace"></param> /// <param name="sequenceName"></param> /// <returns></returns> public static QsSequence GetSequence(QsScope scope, string qsNamespace, string sequenceName) { if (string.IsNullOrEmpty(qsNamespace)) { // no namespace included then it is from the local scope. var seq = (QsSequence)QsEvaluator.GetScopeValueOrNull(scope, qsNamespace, sequenceName); return(seq); } else { QsNamespace ns = QsNamespace.GetNamespace(scope, qsNamespace); return((QsSequence)ns.GetValueOrNull(sequenceName)); } }
private (QsCallable, ResolvedType) GenerateOperation(QsScope contents) { var newName = UniqueVariableNames.PrependGuid(this.CurrentCallable.Callable.FullName); var knownVariables = contents.KnownSymbols.Variables; var parameters = QsTuple <LocalVariableDeclaration <QsLocalSymbol> > .NewQsTuple(knownVariables .Select(var => QsTuple <LocalVariableDeclaration <QsLocalSymbol> > .NewQsTupleItem(new LocalVariableDeclaration <QsLocalSymbol>( QsLocalSymbol.NewValidName(var.VariableName), var.Type, new InferredExpressionInformation(false, false), var.Position, var.Range))) .ToImmutableArray()); var paramTypes = ResolvedType.New(ResolvedTypeKind.UnitType); if (knownVariables.Length == 1) { paramTypes = knownVariables.First().Type; } else if (knownVariables.Length > 1) { paramTypes = ResolvedType.New(ResolvedTypeKind.NewTupleType(knownVariables .Select(var => var.Type) .ToImmutableArray())); } var(signature, specializations) = this.MakeSpecializations(newName, paramTypes, SpecializationImplementation.NewProvided(parameters, contents)); var generatedCallable = new QsCallable( QsCallableKind.Operation, newName, ImmutableArray <QsDeclarationAttribute> .Empty, new Modifiers(AccessModifier.Internal), this.CurrentCallable.Callable.SourceFile, QsNullable <QsLocation> .Null, signature, parameters, specializations.ToImmutableArray(), ImmutableArray <string> .Empty, QsComments.Empty); // Change the origin of all type parameter references to use the new name and make all variables immutable generatedCallable = UpdateGeneratedOp.Apply(generatedCallable, knownVariables, this.CurrentCallable.Callable.FullName, newName); return(generatedCallable, signature.ArgumentType); }
/// <summary> /// Get the quantity from the parameter body on the form ([namespace:]variable) x:var or var /// </summary> public QsValue GetIndirectQuantity(QsScope scope) { try { var q = QsEvaluator.GetScopeQsValue(scope, NamespaceName, NamespaceVariableName); return(q); } catch (QsVariableNotFoundException e) { // add extra data to the exception about the parameter name itself. // its like accumulating information on the same exception. e.ExtraData = ParameterRawText; // and throw it again throw e; } }
public override QsScope Transform(QsScope scope) { var topStatements = ImmutableArray.CreateBuilder <QsStatement>(); var bottomStatements = new List <QsStatement>(); foreach (var statement in scope.Statements) { var transformed = this.onStatement(statement); if (this.SubSelector.SatisfiesCondition) { topStatements.Add(statement); } else { bottomStatements.Add(transformed); } } bottomStatements.Reverse(); return(new QsScope(topStatements.Concat(bottomStatements).ToImmutableArray(), scope.KnownSymbols)); }
public override QsScope OnScope(QsScope scope) { var statements = new List <QsStatement>(); foreach (var statement in scope.Statements) { this.SharedState.StatementLocation = statement.Location; var transformed = this.OnStatement(statement); this.SharedState.StatementLocation = QsNullable <QsLocation> .Null; statements.AddRange(this.SharedState.AdditionalStatements); this.SharedState.AdditionalStatements.Clear(); if (!(transformed.Statement is QsStatementKind.QsExpressionStatement expr && expr.Item.Expression == ExpressionKind.UnitValue)) { // Only add statements that are not free-floating Unit, which could have // been left behind by expression transformation. statements.Add(transformed); } } return(new QsScope(statements.ToImmutableArray(), scope.KnownSymbols)); }
public override QsScope OnScope(QsScope scope) { var parentSymbols = this.OnLocalDeclarations(scope.KnownSymbols); var statements = new List <QsStatement>(); foreach (var statement in scope.Statements) { if (statement.Statement is QsStatementKind.QsConditionalStatement) { var stm = ReshapeConditional(statement); stm = this.OnStatement(stm); statements.Add(stm); } else { statements.Add(this.OnStatement(statement)); } } return(new QsScope(statements.ToImmutableArray(), parentSymbols)); }
/// <summary> /// Get the function that is stored in the scope. /// </summary> /// <param name="scope"></param> /// <param name="realName"></param> /// <returns></returns> public static QsFunction GetFunction(QsScope scope, string qsNamespace, string functionName) { if (string.IsNullOrEmpty(qsNamespace)) { // no namespace included then it is from the local scope. // I am adding the mathmatical functions in the root namespace // so I will test for the function namespace and QsFunction function = (QsFunction)MathNamespace.GetValueOrNull(functionName); // built int math functions will be overwrite any other functions if (function != null) { return(function); } else { function = (QsFunction)QsEvaluator.GetScopeValueOrNull(scope, qsNamespace, functionName); } return(function); } else { try { QsNamespace ns = QsNamespace.GetNamespace(scope, qsNamespace); return((QsFunction)ns.GetValue(functionName)); } catch (QsVariableNotFoundException) { return(null); } } }
/// <summary> /// Called from Expressions. /// Get the function from the global heap or from namespace, and throw exception if not found. /// This function is used in building expression. /// </summary> /// <param name="scope"></param> /// <param name="realName"></param> /// <returns></returns> public static QsFunction GetFunctionAndThrowIfNotFound(QsScope scope, string functionFullName) { string nameSpace = string.Empty; string functionName = functionFullName; if (functionFullName.Contains(":")) { nameSpace = functionFullName.Substring(0, functionFullName.IndexOf(':')); functionName = functionFullName.Substring(functionFullName.IndexOf(':') + 1); } var f = GetFunction(scope, nameSpace, functionName); if (f == null) { throw new QsFunctionNotFoundException("Function: '" + functionName + "' Couldn't be found in " + nameSpace + "."); } else { return(f); } }
/// <summary> /// Given the body of an operation, auto-generates the (content of the) adjoint specialization, /// under the assumption that operation calls may only ever occur within expression statements, /// and while-loops cannot occur within operations. /// </summary> public static QsScope DistributeAdjointFunctorAndReverse(this QsScope scope) { scope = new ApplyFunctorToOperationCalls(QsFunctor.Adjoint).Transform(scope); scope = new ReverseOrderOfOperationCalls().Transform(scope); return(new StripLocationInformation().Transform(scope)); }
/// <summary> /// Generates a new operation with the body's contents. All the known variables at the /// start of the block will become parameters to the new operation, and the operation /// will have all the valid type parameters of the calling context as type parameters. /// The generated operation is returned, along with a call to the new operation is /// also returned with all the type parameters and known variables being forwarded to /// the new operation as arguments. /// /// The given body should be validated with the SharedState.IsValidScope before using this function. /// </summary> public bool LiftBody(QsScope body, out QsCallable callable, out QsStatement callStatement) { if (!this.IsValidScope) { callable = null; callStatement = null; return(false); } var(generatedOp, originalArgumentType) = this.GenerateOperation(body); var generatedOpType = ResolvedType.New(ResolvedTypeKind.NewOperation( Tuple.Create( originalArgumentType, ResolvedType.New(ResolvedTypeKind.UnitType)), generatedOp.Signature.Information)); // Forward the type parameters of the parent callable to the type arguments of the call to the generated operation. var typeArguments = this.CurrentCallable.TypeParameters; var generatedOpId = new TypedExpression( ExpressionKind.NewIdentifier( Identifier.NewGlobalCallable(generatedOp.FullName), typeArguments), typeArguments.IsNull ? TypeArgsResolution.Empty : typeArguments.Item .Select(type => Tuple.Create(generatedOp.FullName, ((ResolvedTypeKind.TypeParameter)type.Resolution).Item.TypeName, type)) .ToImmutableArray(), generatedOpType, new InferredExpressionInformation(false, false), QsNullable <Tuple <QsPositionInfo, QsPositionInfo> > .Null); var knownSymbols = body.KnownSymbols.Variables; TypedExpression arguments = null; if (knownSymbols.Any()) { var argumentArray = knownSymbols .Select(var => new TypedExpression( ExpressionKind.NewIdentifier( Identifier.NewLocalVariable(var.VariableName), QsNullable <ImmutableArray <ResolvedType> > .Null), TypeArgsResolution.Empty, var.Type, var.InferredInformation, QsNullable <Tuple <QsPositionInfo, QsPositionInfo> > .Null)) .ToImmutableArray(); arguments = new TypedExpression( ExpressionKind.NewValueTuple(argumentArray), TypeArgsResolution.Empty, ResolvedType.New(ResolvedTypeKind.NewTupleType(argumentArray.Select(expr => expr.ResolvedType).ToImmutableArray())), new InferredExpressionInformation(false, argumentArray.Any(exp => exp.InferredInformation.HasLocalQuantumDependency)), QsNullable <Tuple <QsPositionInfo, QsPositionInfo> > .Null); } else { arguments = new TypedExpression( ExpressionKind.UnitValue, TypeArgsResolution.Empty, ResolvedType.New(ResolvedTypeKind.UnitType), new InferredExpressionInformation(false, false), QsNullable <Tuple <QsPositionInfo, QsPositionInfo> > .Null); } var call = new TypedExpression( ExpressionKind.NewCallLikeExpression(generatedOpId, arguments), typeArguments.IsNull ? TypeArgsResolution.Empty : typeArguments.Item .Select(type => Tuple.Create(this.CurrentCallable.Callable.FullName, ((ResolvedTypeKind.TypeParameter)type.Resolution).Item.TypeName, type)) .ToImmutableArray(), ResolvedType.New(ResolvedTypeKind.UnitType), new InferredExpressionInformation(false, true), QsNullable <Tuple <QsPositionInfo, QsPositionInfo> > .Null); // set output parameters callable = generatedOp; callStatement = new QsStatement( QsStatementKind.NewQsExpressionStatement(call), LocalDeclarations.Empty, QsNullable <QsLocation> .Null, QsComments.Empty); return(true); }
public override void Walk(QsScope scope) { }
public override QsScope Transform(QsScope scope) => scope;
/// <summary> /// Eliminates all conjugations from the given scope by replacing them with the corresponding implementations (i.e. inlining them). /// The generation of the adjoint for the outer block is subject to the same limitation as any adjoint auto-generation. /// In particular, it is only guaranteed to be valid if operation calls only occur within expression statements, and /// throws an InvalidOperationException if the outer block contains while-loops. /// </summary> public static QsScope InlineConjugations(this QsScope scope) => new InlineConjugationStatements().Transform(scope);
/// <summary> /// Given the body of an operation, auto-generates the (content of the) controlled specialization /// using the default name for control qubits. /// </summary> public static QsScope GenerateControlled(this QsScope scope) { scope = ApplyFunctorToOperationCalls.ApplyControlled(scope); return(StripLocationInformation.Apply(scope)); }
/// <summary> /// Creates an operation call from the conditional control API for non-literal Result comparisons. /// The equalityScope and inequalityScope cannot both be null. /// </summary> private TypedExpression CreateApplyConditionallyExpression(TypedExpression conditionExpr1, TypedExpression conditionExpr2, QsScope equalityScope, QsScope inequalityScope) { QsCompilerError.Verify(equalityScope != null || inequalityScope != null, $"Cannot have null for both equality and inequality scopes when creating ApplyConditionally expressions."); var(isEqualityValid, equalityId, equalityArgs) = this.IsValidScope(equalityScope); var(isInequaltiyValid, inequalityId, inequalityArgs) = this.IsValidScope(inequalityScope); if (!isEqualityValid && equalityScope != null) { return(null); // ToDo: Diagnostic message - equality block exists, but is not valid } if (!isInequaltiyValid && inequalityScope != null) { return(null); // ToDo: Diagnostic message - inequality block exists, but is not valid } if (equalityScope == null) { (equalityId, equalityArgs) = this.GetNoOp(); } else if (inequalityScope == null) { (inequalityId, inequalityArgs) = this.GetNoOp(); } // Get characteristic properties from global id var props = ImmutableHashSet <OpProperty> .Empty; if (equalityId.ResolvedType.Resolution is ResolvedTypeKind.Operation op) { props = op.Item2.Characteristics.GetProperties(); if (inequalityId != null && inequalityId.ResolvedType.Resolution is ResolvedTypeKind.Operation defaultOp) { props = props.Intersect(defaultOp.Item2.Characteristics.GetProperties()); } } BuiltIn controlOpInfo; (bool adj, bool ctl) = (props.Contains(OpProperty.Adjointable), props.Contains(OpProperty.Controllable)); if (adj && ctl) { controlOpInfo = BuiltIn.ApplyConditionallyCA; } else if (adj) { controlOpInfo = BuiltIn.ApplyConditionallyA; } else if (ctl) { controlOpInfo = BuiltIn.ApplyConditionallyC; } else { controlOpInfo = BuiltIn.ApplyConditionally; } // Takes a single TypedExpression of type Result and puts in into a // value array expression with the given expression as its only item. TypedExpression BoxResultInArray(TypedExpression expression) => new TypedExpression( ExpressionKind.NewValueArray(ImmutableArray.Create(expression)), TypeArgsResolution.Empty, ResolvedType.New(ResolvedTypeKind.NewArrayType(ResolvedType.New(ResolvedTypeKind.Result))), new InferredExpressionInformation(false, expression.InferredInformation.HasLocalQuantumDependency), QsNullable <Tuple <QsPositionInfo, QsPositionInfo> > .Null); var equality = this.CreateValueTupleExpression(equalityId, equalityArgs); var inequality = this.CreateValueTupleExpression(inequalityId, inequalityArgs); var controlArgs = this.CreateValueTupleExpression( BoxResultInArray(conditionExpr1), BoxResultInArray(conditionExpr2), equality, inequality); var targetArgsTypes = ImmutableArray.Create(equalityArgs.ResolvedType, inequalityArgs.ResolvedType); return(this.CreateControlCall(controlOpInfo, props, controlArgs, targetArgsTypes)); }
public override Tuple <QsArgumentTuple, QsScope> OnProvidedImplementation(QsArgumentTuple argTuple, QsScope body) { this.SharedState.StartFunction(); this.SharedState.GenerateFunctionHeader(this.context.GetCurrentSpecialization(), argTuple); this.Transformation.Statements.OnScope(body); this.SharedState.EndFunction(); return(Tuple.Create(argTuple, body)); }
/// <summary> /// Creates an operation call from the conditional control API for Result literal comparisons. /// </summary> private TypedExpression CreateApplyIfExpression(QsResult result, TypedExpression conditionExpression, QsScope conditionScope, QsScope defaultScope) { var(isConditionValid, conditionId, conditionArgs) = this.IsValidScope(conditionScope); var(isDefaultValid, defaultId, defaultArgs) = this.IsValidScope(defaultScope); BuiltIn controlOpInfo; TypedExpression controlArgs; ImmutableArray <ResolvedType> targetArgsTypes; var props = ImmutableHashSet <OpProperty> .Empty; if (isConditionValid) { // Get characteristic properties from global id if (conditionId.ResolvedType.Resolution is ResolvedTypeKind.Operation op) { props = op.Item2.Characteristics.GetProperties(); if (defaultId != null && defaultId.ResolvedType.Resolution is ResolvedTypeKind.Operation defaultOp) { props = props.Intersect(defaultOp.Item2.Characteristics.GetProperties()); } } (bool adj, bool ctl) = (props.Contains(OpProperty.Adjointable), props.Contains(OpProperty.Controllable)); if (isDefaultValid) { if (adj && ctl) { controlOpInfo = BuiltIn.ApplyIfElseRCA; } else if (adj) { controlOpInfo = BuiltIn.ApplyIfElseRA; } else if (ctl) { controlOpInfo = BuiltIn.ApplyIfElseRC; } else { controlOpInfo = BuiltIn.ApplyIfElseR; } (TypedExpression, ImmutableArray <ResolvedType>) GetArgs(TypedExpression zeroId, TypedExpression zeroArgs, TypedExpression oneId, TypedExpression oneArgs) => (this.CreateValueTupleExpression( conditionExpression, this.CreateValueTupleExpression(zeroId, zeroArgs), this.CreateValueTupleExpression(oneId, oneArgs)), ImmutableArray.Create(zeroArgs.ResolvedType, oneArgs.ResolvedType)); (controlArgs, targetArgsTypes) = (result == QsResult.Zero) ? GetArgs(conditionId, conditionArgs, defaultId, defaultArgs) : GetArgs(defaultId, defaultArgs, conditionId, conditionArgs); } else if (defaultScope == null) { if (adj && ctl) { controlOpInfo = (result == QsResult.Zero) ? BuiltIn.ApplyIfZeroCA : BuiltIn.ApplyIfOneCA; } else if (adj) { controlOpInfo = (result == QsResult.Zero) ? BuiltIn.ApplyIfZeroA : BuiltIn.ApplyIfOneA; } else if (ctl) { controlOpInfo = (result == QsResult.Zero) ? BuiltIn.ApplyIfZeroC : BuiltIn.ApplyIfOneC; } else { controlOpInfo = (result == QsResult.Zero) ? BuiltIn.ApplyIfZero : BuiltIn.ApplyIfOne; } controlArgs = this.CreateValueTupleExpression( conditionExpression, this.CreateValueTupleExpression(conditionId, conditionArgs)); targetArgsTypes = ImmutableArray.Create(conditionArgs.ResolvedType); } else { return(null); // ToDo: Diagnostic message - default block exists, but is not valid } } else { return(null); // ToDo: Diagnostic message - condition block not valid } return(this.CreateControlCall(controlOpInfo, props, controlArgs, targetArgsTypes)); }
// utils for syntax tree transformations (i.e. methods that take a QsScope and return a QsScope) /// <summary> /// Given the body of an operation, auto-generates the (content of the) controlled specialization /// using the default name for control qubits. /// </summary> public static QsScope DistributeControlledFunctor(this QsScope scope) { scope = new ApplyFunctorToOperationCalls(QsFunctor.Controlled).Transform(scope); return(new StripLocationInformation().Transform(scope)); }
/// <summary> /// try to get the name /// </summary> /// <param name="scope"></param> /// <param name="moduleNamespace"></param> /// <returns></returns> public static QsNamespace GetNamespace(QsScope scope, string moduleNamespace) { return(GetNamespace(scope, moduleNamespace, false)); }