#注解(annotations)

Silq 支持 !qfreemfreeconstlifted 的注解。

#经典(Classical)类型 !

为指名类型 τ 可能仅有经典值(而不是叠加态(superpositions)),我们注解它为 !τ!\tau 。这保证了我们能更自由地复制和删除这种类型的值。例如,1+21+2 有类型 !int[n] 。经比较, H(0)12n(0+1)\frac{1}{\sqrt{2^n}}\left(\ket{0}+\ket{1}\right) ,从而是非经典的:它有 𝔹 类型而非 !𝔹 类型。

示例:如下函数 classicalExample 接受两个参数 x (一个经典布尔值)和 f 。后者接受一个经典布尔值并返回一个经典布尔值。此外, f 本身是经典的,这意味着它是经典已知的。

def classicalExample(x: !𝔹, f: !𝔹 !!𝔹){
  return f(x);  //f 是经典的
}

示例(非经典):如下函数 captureQuantum 说明了一个非经典函数。它返回一个捕获量子变量 x 的函数。因此,捕获的状态处于叠加态,这意味着我们不能将捕获称为经典状态。

def captureQuantum(x: 𝔹){
  captured := λ(). { // 函数 captured 不接受任何参数
    return H(x); // 函数 captured 的主体将 H 应用于 x
  };
  return captured: 𝟙 → 𝔹; // 返回的函数不是经典函数
}

下面总结经典类型的一些有用的属性:

  • 我们可以忽略重复的经典注释: !!τ ≡ !τ
  • 经典类型和元组的代换: !(τ × τ) ≡ !τ × !τ (类似于 n>2 的元组 n)。因此,我们还有 !(τ × τ) ≡ !(τ × !τ) ≡ !(!τ × τ) ≡ !(!τ × !τ)
  • 经典类型和数组的代换: !τ[] ≡ (!τ)[] ≡ !(τ[])
  • 经典类型和固定长度数组的代换: !τ^n ≡ (!τ)^n ≡ !(τ^n)
  • 经典值可以重新解释为量子值: !τ <: τ

# qfree

使用 qfree 注解表示求值函数或表达式既不会引入也不会破坏叠加态。 qfree 注解确保(1)在经典参数上计算 qfree 函数会产生经典结果和(2)启用自动非计算。

例 1(非 qfree ): H 函数不是 qfree 类型,因为它引入了叠加态:它将 0\ket{0} 映射为 \facs\Big(\ket{0}+\ket{1}\Big) 。

例 2 : X 函数是 qfree 类型,因为它既不引入也不破坏叠加态:它将 b=01γbb\sum_{b=0}^{1}\gamma_{b}\ket{b} 映射为 b=01γb1b\sum_{b=0}^{1}\gamma_{b}\ket{1-b}

例 3 :逻辑或(比如 x||y )是一种 const 𝔹×const 𝔹→qfree 𝔹 ,因为对两个值进行或运算既不会引入也不会破坏叠加态。
例 4 :下面的 myEval 函数传入一个 qfree 类型函数 f 并返回计算结果为假。因此 myEval 自身也是 qfree 类型的。

def myEval(f: 𝔹 → qfree 𝔹) qfree {
  return f(false);  //myEval 是 qfree 类型
}

# mfree

mfree 注解表示可以在不应用任何测量的情况下执行函数。

例:下面的 myEval 函数传入一个 mfree 类型函数作为参数并返回计算结果为假。因此 myEval 自身也是 mfree 类型的。

def myEval(f: 𝔹 → mfree 𝔹) mfree {
  return f(false);  //myEval 是 mfree 类型
}

# const

const 注解表示在给定上下文中不会更改的变量。具体来说,函数的每个参数和上下文中的每个变量都可以注解为 const 。我们可以更自由地使用常量参数和变量,因为它们保证在给定的上下文中保持不变。

例:下面的 myEval 函数传入一个常量 x 和一个函数 f ,它的第一个参数为 const

def myEval(const x: 𝔹, f: const 𝔹 !→ 𝔹){
  return f(x);
}

# lifted

lifted 注解是一种简写,表示只有常量参数的 qfree 函数(经典参数被隐式地视为常量)。

例: MyOr 函数是 lifted 类型:

def MyOr(x: 𝔹, y: !𝔹)lifted{ //x 和 y 是隐式常量
  return x||y;  // MyOr 是 lifted 类型 
}

# 类型

Silq 支持以下类型。在这个列表中, n 代表一个任意 !N 类型。

  • 𝟙 (或 1 ):仅包含元素 () 的单独类型
  • 𝔹 (或 B ):布尔值
  • (或 N ):自然数 0,1,0,1,\dots(必须是经典的)
  • (或 Z ):整数 ,1,0,1,\dots,-1,0,1,\dots(必须是经典的)
  • (或 Q ):有理数(必须是经典的)
  • (或 R ):实数(必须是经典的)。仿真语义是实现定义(通常是浮点数)。
  • int[n] :n 位整数编码在 2 的补码
  • uint[n] :n 位无符号整数
  • τ×...×τ (或 τ x ... x τ ):元组类型,像是 𝔹×int[n]
  • τ[] :可变长度数组
  • τ^n :长度为 n 的向量
  • :类型 τ ,但仅限于经典值
  • [const] τ×...× [const] τ → [mfree|qfree] τ :函数,可选地注释为 mfreeqfree ,其输入类型可选地注释为 const

# 类型转换

# 类型注释

# 安全类型转换

# 不安全类型强制转换

# 语句和表达式

# 控制流

  • 语法: if e {...} else {...}

# 循环

#赋值(Assignments)

对于赋值,Silq 还支持修改单个矢量 / 数组元素,如以下代码片段所示:

def uniformSuperposition[n: !](): 𝔹^n {
  vec := vector(n, 0: 𝔹);  // 长度为 n 的向量用零填充
  for i in [0..n) {
    vec[i] := H(vec[i]);
  }
  return vec;
}

def overwrite[n: !](): 𝔹^n {
  vec := uniformSuperposition[n]();
  vec[0] := H(vec[1]);
  return vec;
} // 错误:组件更换的索引必须相同

# 表达式

  • 常量:
  • Lambda 抽象 (选项 1)
  • Lambda 抽象 (选项 2)

# 函数

在下文中,我们讨论 Silq 的函数。

# 解除操作

# 逆向

# 其它函数

下表列出了 Silq 支持的其他函数。

# 量子索引

Silq 也支持量子索引 e1 [e2],对于非经典的 e2 ,如果 e1 不包括任何经典组件(例如,非经典类型,函数类型或数组类型)。

# 调试

# 入口点

运行程序的入口点是 main 函数。

# Unicode 输入

# 键入 Unicode 符号

# 通用 Unicode 符号

# 参考资料 [1]


  1. Silq - Documentation ↩︎