Exemplo n.º 1
0
            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));
            }
Exemplo n.º 2
0
        /// <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);
            }
        }
Exemplo n.º 3
0
        /// <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));
        }
Exemplo n.º 4
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());
        }
Exemplo n.º 5
0
        /// <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);
        }
Exemplo n.º 6
0
 /// <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));
 }
Exemplo n.º 9
0
        /// <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);
        }
Exemplo n.º 10
0
 /// <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));
     }
 }
Exemplo n.º 11
0
            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);
            }
Exemplo n.º 12
0
        /// <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;
            }
        }
Exemplo n.º 13
0
        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));
        }
Exemplo n.º 14
0
            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));
                }
Exemplo n.º 16
0
        /// <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);
                }
            }
        }
Exemplo n.º 17
0
        /// <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);
            }
        }
Exemplo n.º 18
0
 /// <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));
 }
Exemplo n.º 19
0
            /// <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);
            }
Exemplo n.º 20
0
 public override void Walk(QsScope scope)
 {
 }
Exemplo n.º 21
0
 public override QsScope Transform(QsScope scope) => scope;
Exemplo n.º 22
0
 /// <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);
Exemplo n.º 23
0
 /// <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));
                }
Exemplo n.º 27
0
        // 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));
        }
Exemplo n.º 28
0
 /// <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));
 }