什么是Q#?
Q#是用于量子计算的可扩展的多范式特定领域编程语言。 Q#是一种量子编程语言,它可以用来描述如何在量子机器上执行指令。 可以定位的机器包括许多不同的抽象层次,从各种模拟器到实际的量子硬件。 Q#是多范式的,因为它支持功能和命令式编程风格。 Q#具有可扩展性,因为它允许编写程序到各种尺寸的机器,范围从仅有几百个量子位的小型机器到具有数百万个量子位的大型机器。 尽管大型物理机器可能只会在未来取得成果,但Q#允许程序员现在编写复杂的量子算法。 更重要的是,Q#允许以可扩展的方式执行各种任务,例如调试,分析,资源评估和某些特殊用途的模拟。
从技术角度来看,量子程序是一组特殊的经典函数,它们在被称为时会产生量子电路作为它们的副作用。 该观点的一个重要结果是用Q#编写的程序本身并不直接对量子比特进行建模,而是描述了经典控制计算机如何与这些量子比特进行交互。 通过设计,Q#因此不直接定义量子态或量子力学的其他属性,而是通过语言中定义的各种子程序的行为间接地定义量子态或其他属性。 例如,考虑Quantum Computing Concepts指南中讨论的状态 。 为了在Q#中准备这个状态,我们使用在 状态中初始化的量子位,并且 ,其中是Hadamard变换:
using (register = Qubit[1]) {let qubit = register[0];// At this point, qubit is in the state |0〉.H(qubit);// We've now applied H, such that our qubit is in H|0〉 = |+〉, as we wanted.
}
重要的是,在编写上述程序时,我们没有明确提到Q#中的状态,而是描述了状态如何通过我们的程序进行转换 。 因此,类似于图形着色器程序如何累积每个顶点变换的描述,Q#中的量子程序将量子态的变换累积起来。 这使得我们完全不知道每个目标机器上的量子状态是什么,根据机器情况可能会有不同的解释。
从Q#程序的角度来看,量子位是对目标机器内部结构的完全不透明的参考。 AQ#程序没有能力反思量子比特的状态,它在目标机器上的表示,或者它是否与该程序可用的任何其他量子位相同的量子位。 相反,程序可以调用诸如Measure
操作来从量子位获取信息,并且调用诸如X
和H
来对量子位的状态进行操作。 这些操作在语言中没有内在的定义,只有用于运行特定Q#程序的目标机器才具体。 AQ#程序重新组合目标机器定义的这些操作,以创建新的更高级的操作来表达量子计算。 通过这种方式,Q#可以很容易地表达量子和混合量子经典算法的基础逻辑,同时对于目标机器或模拟器的结构也是通用的。
具体来说,Q#程序由一个或多个操作 ,一个或多个功能和用户定义的类型组成。 操作用于描述量子机器状态的转换,并且是Q#程序的最基本的组成部分。 Q#中定义的每个操作都可以调用任意数量的其他操作,包括由语言定义并由每个目标机器实现的内置基本操作。 编译时,每个操作都表示为可以提供给目标计算机的.NET类类型。
与操作相比,函数用于描述纯粹的经典行为,除了计算经典输出值之外,没有任何效果。 Q#是一种强类型语言,并带有一组内置的基元类型以及对用户定义类型的支持。
在本指南的其余部分中,我们将看到如何使用不同的语言概念和结构来帮助我们通过操作,功能和类型的基本构建块来定义复杂的量子程序。
Q#源文件的结构
最起码,一个Q#源文件由一个名称空间声明组成,该声明指定了一个.NET名称空间,该名称空间将包含源文件中的定义。 来自其他Q#源文件和库的定义可以使用open
语句来包含。 例如,大多数定义基本门的操作都是在Microsoft.Quantum.Primitive命名空间中定义的。 为了使我们的代码可用,我们只需在每个文件的顶部open
该命名空间即可:
namespace Example { open Microsoft.Quantum.Primitive; // ... }
在命名空间中,每个Q#源文件可以定义操作 , 函数和用户定义类型的任意组合。 在本节的其余部分中,我们将逐一介绍并提供如何在实践中使用它们来制作有用的量子程序的例子。