# 第一个寄存器程序 English · **简体中文** 这篇教程生成一个 Bell 态。你会用到一个寄存器、两条门操作和参考执行器。完成后,再把同一程序保存为 RIR 和 OriginIR-ext。 ## 定义操作 {obj}`Bits(2) ` 定义一个两位寄存器。我们先让低位进入叠加态,再以它为控制,对高位做 XOR。 ```{testcode} from oracq import Bits, Builder, simulate # 声明一个名为 bell_pair 的模块,公开接口是一个名为 pair 的两位 bits 寄存器。 b = Builder("bell_pair", {"pair": Bits(2)}) # 对 pair 的第 0 位(最低位)广播 H 门:|0> -> (|0>+|1>)/sqrt(2)。 b.h(b["pair"][0]) # 以第 0 位为源、第 1 位为目标做 XOR(逐位 CNOT):得到 (|00>+|11>)/sqrt(2)。 b.xor(b["pair"][0], b["pair"][1]) # 结束构建,得到不可变的 Operation(含模块与指令体)。 operation = b.finish() # 取出其中的 RIR Program:entry 指向 bell_pair,modules 里只有这一个模块。 program = operation.program() # 用无依赖的参考执行器模拟,返回稀疏振幅。 state = simulate(program) # 打印执行结果,下面的输出块会逐字复现这行打印。 print(state.amplitudes) # 振幅键是入口寄存器按声明顺序拼接出的整数元组;(0,) 即 00,(3,) 即 11。 assert set(state.amplitudes) == {(0,), (3,)} # 两个基态的幅度都应为 1/sqrt(2)。 assert abs(state.amplitudes[(0,)] - 2**-0.5) < 1e-12 assert abs(state.amplitudes[(3,)] - 2**-0.5) < 1e-12 ``` ```{testoutput} {(0,): (0.7071067811865475+0j), (3,): (0.7071067811865475+0j)} ``` {obj}`Builder ` 逐条收集上面的调用,`finish()` 返回不可变的 {obj}`Operation `。打印出的字典就是执行结果:键是入口寄存器的整数值组成的元组,`0` 表示 `00`,`3` 表示 `11`;`0.7071067811865475` 是 `1/√2` 的双精度表示。 ## 保存和导出 ```{testcode} from oracq import dumps, loads, export_originir # 序列化为规范 YAML:按键排序、两空格缩进,模块与指令结构原样保留。 text = dumps(program) # 打印全文;输出块里用 ... 省略了重复的中段。 print(text) # 反序列化回 Program 对象;解码是严格的,并会重新跑语义校验。 restored = loads(text) # 往返应逐字节等价:寄存器名、视图和模块结构都不丢失。 assert restored == program # 导出为模块化 OriginIR-ext 文本。 artifact = export_originir(restored) # 文本里应出现 DEF 模块定义:导出不会内联调用、不会展开成平坦门列表。 assert "DEF" in artifact.text # 打印 OriginIR-ext 文本;文本自带结尾换行,故 end=""。 print(artifact.text, end="") ``` ```{testoutput} entry: bell_pair modules: - attributes: [] body: - angle: null op: h operands: - parts: - register: pair start: 0 ... ... tag: Primitive value: null ... locals: [] name: bell_pair ... tag: Program version: '0.1' QINIT 2 CREG 0 DEF m_bell_pair_d029b74cecc4332d414ece8a(v_pair[2]) H v_pair[0] CNOT v_pair[0], v_pair[1] ENDDEF m_bell_pair_d029b74cecc4332d414ece8a(q[0], q[1]) ``` {obj}`dumps ` 生成前半段的文本,{obj}`loads ` 解码时会重新执行 {obj}`validate ` 的语义校验;{obj}`export_originir ` 返回的 {obj}`OriginIRArtifact ` 携带后半段的文本。前半段是规范 YAML 的骨架:{obj}`Program ` 持有模块表,模块的 `body` 里是指令,指令操作数用 `register`、`start` 等字段保留寄存器名与视图;`...` 之外的内容与实际打印逐字一致。后半段是 OriginIR-ext 文本:`QINIT 2` 声明两位量子寄存器,`CREG 0` 表示没有经典寄存器;`DEF m_bell_pair_<指纹>` 定义模块,后缀是由模块内容确定的指纹,同一模块只会导出一份定义;最后一行把入口量子位 `q[0], q[1]` 绑定到模块形参。导出不会先把所有调用复制成一个平坦门列表。 {obj}`simulate ` 适合这种小规模检查。需要实际后端时,仍使用同一个 {obj}`Program `,改为调用 {obj}`run_pysparq ` 或 {obj}`run_originir `。 ## 相关页面 - 手册:[核心概念](../manual/concepts.md)、[架构](../manual/architecture.md)、[后端与导出](../manual/backends.md) - 规范:[RIR 规范](../reference/rir.md)(JSON 结构与 OriginIR-ext 文法) - API 参考:[RIR 对象](../api/infrastructure/ir.rst)、[模块构造器](../api/infrastructure/builder.rst)、[寄存器参考执行器](../api/infrastructure/execution.rst)、[RIR 序列化](../api/infrastructure/serialization.rst) - 继续教程:[给算法替换 oracle](oracle-binding.md)、[运行与修改算法展示目录](gallery.md)