/// <summary>
                /// Gets an identifier and argument tuple for the built-in operation NoOp.
                /// </summary>
                private (TypedExpression, TypedExpression) GetNoOp()
                {
                    var opInfo = BuiltIn.NoOp;

                    var properties      = new[] { OpProperty.Adjointable, OpProperty.Controllable };
                    var characteristics = new CallableInformation(
                        ResolvedCharacteristics.FromProperties(properties),
                        new InferredCallableInformation(((BuiltInKind.Operation)opInfo.Kind).IsSelfAdjoint, false));

                    var unitType      = ResolvedType.New(ResolvedTypeKind.UnitType);
                    var operationType = ResolvedType.New(ResolvedTypeKind.NewOperation(
                                                             Tuple.Create(unitType, unitType),
                                                             characteristics));

                    var args = new TypedExpression(
                        ExpressionKind.UnitValue,
                        TypeArgsResolution.Empty,
                        unitType,
                        new InferredExpressionInformation(false, false),
                        QsNullable <Tuple <QsPositionInfo, QsPositionInfo> > .Null);
                    var typeArgs = ImmutableArray.Create(unitType);

                    var identifier = new TypedExpression(
                        ExpressionKind.NewIdentifier(
                            Identifier.NewGlobalCallable(opInfo.FullName),
                            QsNullable <ImmutableArray <ResolvedType> > .NewValue(typeArgs)),
                        typeArgs
                        .Zip(((BuiltInKind.Operation)opInfo.Kind).TypeParameters, (type, param) => Tuple.Create(opInfo.FullName, param, type))
                        .ToImmutableArray(),
                        operationType,
                        new InferredExpressionInformation(false, false),
                        QsNullable <Tuple <QsPositionInfo, QsPositionInfo> > .Null);

                    return(identifier, args);
                }
        internal static ResolvedType GetOperationType(IEnumerable <OpProperty> props, ResolvedType argumentType)
        {
            var characteristics = new CallableInformation(
                ResolvedCharacteristics.FromProperties(props),
                InferredCallableInformation.NoInformation);

            return(ResolvedType.New(ResolvedTypeKind.NewOperation(
                                        Tuple.Create(argumentType, ResolvedType.New(ResolvedTypeKind.UnitType)),
                                        characteristics)));
        }
                /// <summary>
                /// Creates an operation call from the conditional control API, given information
                /// about which operation to call and with what arguments.
                /// </summary>
                private TypedExpression CreateControlCall(BuiltIn opInfo, IEnumerable <OpProperty> properties, TypedExpression args, IEnumerable <ResolvedType> typeArgs)
                {
                    var characteristics = new CallableInformation(
                        ResolvedCharacteristics.FromProperties(properties),
                        new InferredCallableInformation(((BuiltInKind.Operation)opInfo.Kind).IsSelfAdjoint, false));

                    var unitType      = ResolvedType.New(ResolvedTypeKind.UnitType);
                    var operationType = ResolvedType.New(ResolvedTypeKind.NewOperation(
                                                             Tuple.Create(args.ResolvedType, unitType),
                                                             characteristics));

                    // Build the surrounding control call
                    var identifier = new TypedExpression(
                        ExpressionKind.NewIdentifier(
                            Identifier.NewGlobalCallable(opInfo.FullName),
                            typeArgs.Any()
                            ? QsNullable <ImmutableArray <ResolvedType> > .NewValue(typeArgs.ToImmutableArray())
                            : QsNullable <ImmutableArray <ResolvedType> > .Null),
                        typeArgs
                        .Zip(((BuiltInKind.Operation)opInfo.Kind).TypeParameters, (type, param) => Tuple.Create(opInfo.FullName, param, type))
                        .ToImmutableArray(),
                        operationType,
                        new InferredExpressionInformation(false, false),
                        QsNullable <Tuple <QsPositionInfo, QsPositionInfo> > .Null);

                    // Creates type resolutions for the call expression
                    var opTypeArgResolutions = typeArgs
                                               .SelectMany(x =>
                                                           x.Resolution is ResolvedTypeKind.TupleType tup
                            ? tup.Item
                            : ImmutableArray.Create(x))
                                               .Where(x => x.Resolution.IsTypeParameter)
                                               .Select(x => (x.Resolution as ResolvedTypeKind.TypeParameter).Item)
                                               .GroupBy(x => (x.Origin, x.TypeName))
                                               .Select(group =>
                    {
                        var typeParam = group.First();
                        return(Tuple.Create(typeParam.Origin, typeParam.TypeName, ResolvedType.New(ResolvedTypeKind.NewTypeParameter(typeParam))));
                    })
                                               .ToImmutableArray();

                    return(new TypedExpression(
                               ExpressionKind.NewCallLikeExpression(identifier, args),
                               opTypeArgResolutions,
                               unitType,
                               new InferredExpressionInformation(false, true),
                               QsNullable <Tuple <QsPositionInfo, QsPositionInfo> > .Null));
                }
Пример #4
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);
            }