/// <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)); }
/// <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); }