如 @拉格朗日的忧郁 所说,编程与量子力学的类比目前并没有严格的科学基础,那些概念层面的联系都是似是而非的。不过在这些似是而非的联系中,我发现了一些有趣且非常有启发性的内容。这些内容引导我提出了一种新的软件构造理论-可逆计算理论,它可以超越传统软件构造理论如面向对象和组件理论的限制,实现粗粒度的、系统级别的复用。
注意,这里的可逆计算理论与物理中已经存在的可逆计算机概念并不一致,虽然它们都强调了可逆性的重要性。
可逆计算与可逆计算机有着同样的物理学思想来源,虽然具体的技术内涵并不一致,但它们目标却是统一的。正如云计算试图实现计算的云化一样,可逆计算和可逆计算机试图实现的都是计算的可逆化 。参见可逆计算的方法论来源
一. 两阶段提交与量子纠缠
向DeepSeek提问:
先简单介绍量子纠缠和两阶段提交,然后用|提交>+|提交> 与 |回滚>+|回滚>这种叠加态来说明两者的相似性
以下是DeepSeek AI的回答:
量子纠缠(Quantum Entanglement)
量子纠缠是量子力学中的核心现象。当两个或多个粒子形成纠缠态时,它们的量子态将不可分割地关联:
- 叠加性:纠缠系统的状态是各粒子状态的叠加(如 |↑↑> + |↓↓>)
- 非定域性:对其中一个粒子的测量会瞬间决定其他粒子的状态(即使相隔光年)
- 概率坍缩:测量前系统处于概率性叠加态,测量后坍缩为确定态
两阶段提交(2-Phase Commit, 2PC)
2PC是分布式事务的原子性协议,通过协调者(Coordinator)确保所有参与者(Participants)的一致性:
- 准备阶段 :协调者询问所有参与者能否提交
- 参与者锁定资源并返回"就绪"(Ready)或"中止"(Abort)
- 提交阶段:若所有参与者就绪,协调者广播提交(Commit);否则广播回滚(Rollback)
参与者状态的量子化表示
假设每个参与者的事务状态可以用量子态描述:
- 基态 :
|提交> = |0>
|回滚> = |1>
- 准备阶段的叠加态 :
当参与者响应"就绪"时,其状态进入叠加态:
|状态> = α|0> + β|1>
(其中 |α|² 为提交概率,|β|² 为回滚概率)
全局纠缠态的形成
所有参与者与协调者形成逻辑纠缠态:
scss
|全局状态> = (|0>₁⊗|0>₂⊗...⊗|0>ₙ) + (|1>₁⊗|1>₂⊗...⊗|1>ₙ)
- 物理意义 :
所有参与者要么全部提交(|0>⊗|0>⊗...),要么全部回滚(|1>⊗|1>⊗...) - 纠缠特征 :
单个参与者的状态无法独立描述,必须通过全局状态定义
协议执行与量子坍缩的类比
阶段演化示意图
css
准备阶段 协调者决策 状态坍缩
|?> ────────────> α|0> + β|1> ───[Commit/Abort]───> |0> 或 |1>
(初始不确定态) (叠加态) (观测行为) (确定态)
关键对应关系
-
准备阶段 → 量子叠加态
- 参与者进入"就绪"状态 ≈ 量子系统处于
|0> + |1>
叠加态 - 此时事务结果仍具有不确定性
- 参与者进入"就绪"状态 ≈ 量子系统处于
-
协调者决策 → 量子测量
- 协调者的最终指令(Commit/Abort)相当于对系统进行测量
- 触发所有参与者的状态同步坍缩
-
日志持久化 → 量子退相干抑制
- 事务日志确保状态可追溯 ≈ 量子纠错维持纠缠态
这里强调的是观察者层面观测到的事实,与底层世界是经典的还是量子的没有关系。
二. Paxos协议与量子纠缠
Paxos是一个分布式一致性算法,用于在不可靠的节点间达成共识。它的核心阶段包括准备阶段和接受阶段,通过多数派原则确保一致性。在没有全局时钟或即时通信的情况下,各个节点无法实时知道整个系统的状态,因此存在不确定期。如果把整个分布式系统看作是一个宏观世界,那么在这个宏观世界中系统在任一时刻(由逻辑时钟模拟的全局时间)的状态就处于|已达成共识> + |未达成共识>
的叠加状态中。
对Paxos协议的详细分析,参见
向DeepSeek提问:
先简单介绍Paxos协议,然后说明分布式系统中因为没有全局知识无法判定当前是否已经达成共识,然后通过主动选择一个不冲突的选项造成选择空间塌缩。说明这种情况与量子纠缠的相似性。
以下是DeepSeek的回答:
Paxos协议核心机制
共识达成三阶段
-
提案阶段(Prepare)
- Proposer生成递增提案编号n,向Acceptor广播Prepare请求
- Acceptor承诺:不再接受编号≤n的提案,并返回已接受的最大编号提案(若存在)
-
承诺阶段(Promise)
- Proposer收到多数派响应后,选择已存在的最⼤编号提案值v(或自定新值)
- 向Acceptor发送Accept(n, v)请求
-
接受阶段(Accept)
- Acceptor接受编号n的提案(若未违背承诺),持久化存储(n, v)
- 多数派接受后,值v被确定为系统共识
分布式系统的认知局限
全局知识缺失的困境
-
无上帝视角:
- 节点仅掌握局部信息,无法实时感知全网状态
- 不同节点对"当前是否已达成共识"存在观测延迟
-
不确定叠加态:
- 在共识最终确定前,系统处于潜在多值叠加态
- 例如可能同时存在:
|共识值> = α|A> + β|B> + γ|C>
(α,β,γ为各值被接受的概率权重)
-
活锁风险:
- 多个Proposer持续生成更高编号提案,导致共识无法收敛
- 类似量子系统无法稳定坍缩的叠加震荡
主动选择与空间坍缩
Paxos的坍缩触发机制
-
多数派观测器原理:
- 任意多数派Acceptor构成等效观测系统
- 一旦多数派接受某个提案,其值即成为客观事实(即使部分节点未感知)
-
选择空间坍缩过程:
css|A>+|B>+|C> ------[多数派Accept(n,v)]------> |v> (叠加态) (主动选择触发) (确定态)
- 通过强制选择一个不冲突的值(如取最大编号提案值),消除其他可能性
- 类似量子测量打破叠加态,使系统坍缩到单一基态
-
坍缩传递性:
- 新加入节点通过查询Acceptor历史记录同步状态
- 类似量子纠缠态的信息同步(但受限于光速延迟)
与量子纠缠的隐喻对比
相似性维度
特性 | Paxos协议 | 量子纠缠系统 |
---|---|---|
状态不确定性 | 共识达成前存在多值可能性 | 测量前处于概率叠加态 |
坍缩触发机制 | 多数派接受提案行为 | 观测测量行为 |
状态传播方式 | 通过消息传递同步确定态 | 非定域性关联瞬时同步 |
容错能力 | 容忍少数派故障(拜占庭容错) | 量子纠错容忍局部退相干 |
思想实验:薛定谔的共识值
假设一个未决提案:
|共识值> = 0.6|X> + 0.4|Y>
- 工程视角:60%节点倾向X,40%倾向Y,但尚未达成多数派
- Paxos操作 :
- Proposer探测到最高编号提案为X
- 通过Accept(n,X)使系统坍缩到|X>
- 量子隐喻 :
相当于对纠缠粒子进行关联测量,迫使整个系统选择一致状态
三. 软件构造与波粒二象性
目前大部分人对于软件结构构造的基本理解都是基于还原论的,总是不断向下分解,寻找原子化的成分,然后使用原子进行组装。原本虚拟化的组件概念在潜意识中实际上是被看作是真实存在的离散个体,类似于物质世界中的粒子,通过嵌套组合来构造世界。但是物理世界中存在着另一种构造方式,那就是波。波是连续存在的模式,通过干涉叠加来构造世界。
一个有趣的问题是,我们能不能通过类似波的叠加的方式来构造软件,从而超越整体-部分这种组合方式?
传统上构造好X之后,如果要修改,一定是要修改X本身。而如果是一种叠加方式,则可以通过额外补充一个Delta,在不直接改变X的情况下得到一个新的Y。
css
X = A + B + C
Y = A + B + D
= X + (-C + D)
= X + Delta
传统的软件工程体系下,即使可以做到某种增量式开发,往往也是需要特殊设计很多扩展点,并不是任意地方的修改都可以通过Delta方式进行定制修改的。特别是传统的软件工程中增量一般都意味着增加新的功能,很少涉及到逆向减少已有的功能特性这种设计。Delta定制使得我们可以通过增加实现减少。
需要注意的是,叠加构造要求Delta必然是正和负的混合体,必须扩大软件的结构空间包含逆元。
XLang语言是世界上第一个在语言中明确定义领域结构坐标并内置通用的差量计算规则的程序语言,它的设计遵循可逆计算理论的指导。
使用XLang开发的系统无需做任何额外的工作,就自动支持Delta定制。这使得产品化产品的开发成本得以大幅降低。比如说一个银行核心系统在打包成jar包之后,无需修改基础产品的代码,所有针对特定用户的定制修改、二次开发都可以作为Delta差量单独存放,通过切换Delta就可以实现多个不同的定制版本。同样的机制可以用于多租户定制。
Delta定制可以实现精确到单个属性的定制。而传统软件工程只能提供少数事先定义的扩展点,很难实现所有地方都支持细粒度定制。比如我只想定义一个按钮的某个属性,往往都需要增加一个新的组件或者页面。所有业务层面关注的概念都可以逐个进行定制,这是所谓的连续性的一种表现。
组件的黑箱模型类似于高中阶段牛顿力学的世界观,它是完全机械化的:刚体的运动完全由它的质心坐标和尺寸形状朝向等少数几个参数来描述,刚体的内部构造无法被观测也无关紧要,刚体之间通过直接接触发生相互作用, 刚体的形状必须精确匹配才能构成一个无缝的整体。即使是在古典力学中,稍微高级一点的观点也都会转换到拉格朗日表述或者哈密尔顿表述,它的精神实质是转向场论的世界观。 所谓的场(Field),其实就是建立一个无所不在的坐标系,然后在坐标系的每一点上都可以指定一个物理量。场的自由度是无限的,但是通过坐标系它是可描述的、可定义的、可研究的,在坐标系的每一点上我们都可以精确的度量局部的变化。在场的世界观中,我们面对的核心图像是对象总是浸泡在场(无所不在的坐标系)中,而不再是孤立对象之间的两两相互作用。
XLang的详细介绍参见
- 为什么说XLang是一门创新的程序语言?
- 关于"为什么说XLang是一门创新的程序语言"一文的答疑
- DeepSeek的通俗版解释:XLang为什么是一门创新的编程语言?
- 关于"为什么XLang是一门创新的程序语言"一文的进一步解释
- 关于XLang语言的第三轮答疑
四. 可逆计算与相互作用绘景
计算机科学存在两种基本的世界观:图灵机和Lambda演算,它们指出了到达图灵完备的两条技术路线。但是量子力学中却存在着三种世界图景:薛定谔图景,海森堡图景和狄拉克图景。为什么计算机科学有两种基本世界观,但是量子力学却存在三种世界图景?它们之间是否存在什么对应关系?
实际上,计算机科学中实现图灵完备的基本技术路线也可以被看作是有三条,它们和量子力学的世界图景存在如下对应关系:
- 图灵机 <=> 薛定谔图景
- Lambda演算 <=> 海森堡图景
- 可逆计算 <=> 狄拉克图景
以下是具体的分析。首先,量子力学中最基本的世界图景同样是两个,狄拉克图景是前两种图景自然衍生的结果
- 薛定谔图景中算子固定,态函数演化
- 海森堡图景中态函数固定,而算子演化
- 狄拉克图景(相互作用图景)中态函数和算符都不固定,它们都随时间演化
在狄拉克图景中,我们将系统的Hamiltion量拆分为已知的部分和待研究的微小扰动
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> H = H 0 + H 1 H = H_0 + H_1 </math>H=H0+H1
然后研究系统如何偏离已知模型进行演化,即我们所关心的是差量描述的演化情况。在相互作用图景下,态函数和算符都随时间演化。
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> i ℏ d d t ∣ ψ I ( t ) ⟩ = H 1 ∣ ψ I ( t ) ⟩ i ℏ d d t ∣ A I ( t ) ⟩ = [ A I ( t ) , H 0 ] i\hbar \frac d {dt} |\psi_I(t)\rangle = H_1|\psi_I(t)\rangle \\ i\hbar \frac d {dt} |A_I(t)\rangle = [A_I(t), H_0] </math>iℏdtd∣ψI(t)⟩=H1∣ψI(t)⟩iℏdtd∣AI(t)⟩=[AI(t),H0]
根据这三种图景都可以得到完全一致的物理测量结果
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> ⟨ ψ S ( t ) ∣ A S ∣ ψ S ( t ) ⟩ = ⟨ ψ H ∣ A H ( t ) ∣ ψ H ⟩ = ⟨ ψ I ( t ) ∣ A I ( t ) ∣ ψ I ( t ) ⟩ \langle \psi_S(t)|A_S|\psi_S(t)\rangle = \langle \psi_H|A_H(t)|\psi_H\rangle = \langle \psi_I(t)|A_I(t)|\psi_I(t)\rangle </math>⟨ψS(t)∣AS∣ψS(t)⟩=⟨ψH∣AH(t)∣ψH⟩=⟨ψI(t)∣AI(t)∣ψI(t)⟩
有趣的是,相互作用图景是物理学家在实际工作中使用最多的图景。事实上,数学物理中存在一个专门的分支:微扰论(Perturbation Theroy),它系统化的研究在已知模型的基础上添加微小的扰动量,新的模型如何演化的问题。而理论物理中绝大多数有价值的计算都是在微扰论的框架下进行。
如果把量子力学和计算机理论做个对比,我们会发现量子力学中的世界图景和计算机理论的世界观之间存在一个有趣的对应关系。
- 图灵机是一种结构固化的机器,它具有可枚举的有限的状态集合,只能执行有限的几条操作指令,但是可以从无限长的纸带上读取和保存数据。例如我们日常使用的电脑,它在出厂的时候硬件功能就已经确定了,但是通过安装不同的软件,传入不同的数据文件,最终它可以自动产生任意复杂的目标输出。图灵机的计算过程在形式上可以写成
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> 目标输出 = 固定的机器(无限复杂的输入) 目标输出 = 固定的机器 (无限复杂的输入) </math>目标输出=固定的机器(无限复杂的输入)
- 与图灵机相反的是,lambda演算的核心概念是函数,一个函数就是一台小型的计算机器,函数的复合仍然是函数,也就是说可以通过机器和机器的递归组合来产生更加复杂的机器。lambda演算的计算能力与图灵机等价,这意味着如果允许我们不断创建更加复杂的机器,即使输入一个常数0,我们也可以得到任意复杂的目标输出。
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> 目标输出 = 无限复杂的机器(固定的输入) 目标输出 = 无限复杂的机器(固定的输入) </math>目标输出=无限复杂的机器(固定的输入)
计算机科学中的两个基本理论在形式上都可以被表达为 Y = F(X)这样一种抽象的形式。如果仿照狄拉克图景的导出过程,我们认识到在真实的物理世界中,人类的认知总是有限的,所有的量都需要区分已知的部分和未知的部分,因此我们需要进行如下分解:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> Y = F ( X ) = ( F 0 + F 1 ) ( X 0 + X 1 ) = F 0 ( X 0 ) + Δ \begin{aligned} Y &= F(X) \\ &= (F_0 + F_1) (X_0+X_1)\\ &= F_0(X_0) + \Delta \end{aligned} </math>Y=F(X)=(F0+F1)(X0+X1)=F0(X0)+Δ
重新整理一下符号,我们就得到了一个适应范围更加广泛的计算模式
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> Y = F ( X ) ⊕ Δ Y = F(X) \oplus \Delta </math>Y=F(X)⊕Δ
除了函数运算F(X)之外,这里出现了一个新的结构运算符⊕,它表示两个元素之间的合成运算,并不是普通数值意义上的加法,同时引出了一个新的概念:差量△。△的特异之处在于,它必然包含某种负元素,F(X)与△合并在一起之后的结果并不一定是"增加"了输出,而完全可能是"减少"。 在物理学中,差量△存在的必然性以及△包含逆元这一事实完全是不言而喻的,因为物理学的建模必须要考虑到两个基本事实:
- 世界是"测不准"的,噪声永远存在
- 模型的复杂度要和问题内在的复杂度相匹配,它捕获的是问题内核中稳定不变的趋势及规律。
例如,对以下的数据
我们所建立的模型只能是类似图(a)中的简单曲线,图(b)中的模型试图精确拟合每一个数据点在数学上称之为过拟合,它难以描述新的数据,而图(c)中限制差量只能为正值则会极大的限制模型的描述精度。
可逆计算理论提出了一个新的软件构造公式,将以上的计算模式落实为实现图灵完备的一条具体的技术路线。
ini
App = Delta x-extends Generator<DSL>
- App : 所需要构建的目标应用程序
- DSL: 领域特定语言(Domain Specific Language),针对特定业务领域定制的业务逻辑描述语言,也是所谓领域模型的文本表示形式
- Generator : 根据领域模型提供的信息,反复应用生成规则可以推导产生大量的衍生代码。实现方式包括独立的代码生成工具,以及基于元编程(Metaprogramming)的编译期模板展开
- Delta : 根据已知模型推导生成的逻辑与目标应用程序逻辑之间的差异被识别出来,并收集在一起,构成独立的差量描述
- x-extends: 差量描述与模型生成部分通过类似面向切面编程(Aspect Oriented Programming)的技术结合在一起,这其中涉及到对模型生成部分的增加、修改、替换、删除等一系列操作
DSL是对关键性领域信息的一种高密度的表达,它直接指导Generator生成代码,这一点类似于图灵计算通过输入数据驱动机器执行内置指令。而如果把Generator看作是文本符号的替换生成,则它的执行和复合规则完全就是lambda演算的翻版。差量合并在某种意义上是一种很新奇的操作,因为它要求我们具有一种细致入微、无所不达的变化收集能力,能够把散布系统各处的同阶小量分离出来并合并在一起,这样差量才具有独立存在的意义和价值。同时,系统中必须明确建立逆元和逆运算的概念,在这样的概念体系下差量作为"存在"与"不存在"的混合体才可能得到表达。
图灵机能够实现图灵完备的根本原因在于图灵机可以被看作是一种虚拟机,它可以模拟所有其他的自动计算机器,而如果我们不断提升虚拟机的抽象层次,就会得到可以直接"运行"所谓领域特定语言(DSL)的虚拟机,但是因为DSL关注的重点是特定领域概念,它必然无法以最便利的方式表达所有通用计算逻辑(否则它就成为了通用语言),必然会导致某种信息溢出,成为所谓的Delta项。
图灵机和lambda演算建立了通用计算机的概念基础,在理论上解决了计算的可行性问题,即为什么可以存在一种通用的机器执行机械化的动作,使用有限资源来完成所有我们能够想见的计算。在通用计算机已经普及的今天,我们所面临的最大的实际问题是如何有效的进行计算的问题。计算效率的提高依赖于我们发现计算中的"捷径",而这依赖于我们对问题本质的洞察,而洞察的产生与问题的表述形式息息相关。表象(representation)变换本身甚至就是解决问题的一种方式,因为变换后的问题表象有可能使得解决方案变得清晰可见。可逆计算借助于领域模型和差量描述,提供了一种新的、系统化的表象变换方式,使我们的注意力得以聚焦在待解决的新问题上。
关于表象变换的作用,参见 解耦的方法远不止依赖注入
基于可逆计算的基本公式,我们可以很自然的得到如下推广的软件构造方法
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> A p p = B i z ⊕ G 1 ( D S L 1 ) ⊕ G 2 ( D S L 2 ) + . . . ≡ ( B i z , D S L 1 , D S L 2 , . . . ) \begin{aligned} App &= Biz \oplus G1(DSL1) \oplus G2(DSL2) + ...\\ & \equiv (Biz, DSL1, DSL2, ...) \end{aligned} </math>App=Biz⊕G1(DSL1)⊕G2(DSL2)+...≡(Biz,DSL1,DSL2,...)
如果把Generator(也可以是Translator或者Transformer)看作是已知的背景知识,在符号层面隐去它们的存在(类似于物理学中引入泊松括号),我们可以将App看作是一组DSL所构成的特性向量。也就是说,在第一代、第二代、第三代程序语言的发展过程中,不断的提升抽象层次,但它们仍然都是通用程序语言,但是发展到第四代程序语言,我们很可能得到的不是另一种通用程序语言,而是大量领域特定语言所构成的DSL森林,通过它们我们可以形成对原有程序结构的一种新的表示和认知。
进一步的介绍参见:
五. DSL森林与微分流形
现代物理学所研究的时空不能用一个全局性的欧几里得坐标系来描述,必须使用多个欧式空间拼接所构成的所谓微分流形来描述。
在编程领域,传统上都是使用所谓的通用程序语言如Java, C等来表达业务逻辑。如果把一个语言看作是一种描述坐标系,编程相当于是将业务映射到这个坐标空间中。问题在于通用程序语言的坐标在业务层面是不稳定的。比如说,在数据模型层面增加了一个字段,用通用语言表达的时候,可能很多地方都需要手动修改代码。但是如果是模型驱动架构,在数据模型这个DSL(领域特定语言,Domain Specific Language)中可能只需要修改一个地方,然后会自动推导得到其他地方的修改。我们可以说,增加字段这个变化在数据模型所定义的坐标系中只会产生一个局部的扰动。
类比圆在欧几里得坐标系中的描述以及在最适宜的极坐标系中的描述。
可逆计算理论指出了一条系统化的利用多个DSL来表达业务逻辑的技术路线。
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> // 横向分解,产生多个 D S L A p p = D e l t a + G 1 ⟨ D S L 1 ⟩ + G 2 ⟨ D S L 2 ⟩ + . . . // 深度分解,产生多个 D S L A p p = D e l t a + G 1 ⟨ D e l t a 2 + G 2 ⟨ D e l t a 3 + G 3 ⟨ D S L 3 ⟩ ⟩ ⟩ \begin{aligned} & \text{// 横向分解,产生多个 DSL} \\ App &= Delta + G_1\langle DSL_1\rangle + G_2\langle DSL_2\rangle + ... \\ \\ &\text{// 深度分解,产生多个 DSL} \\ App &= Delta + G_1\langle Delta_2 + G_2\langle Delta_3 + G_3\langle DSL_3\rangle\rangle\rangle \end{aligned} </math>AppApp// 横向分解,产生多个 DSL=Delta+G1⟨DSL1⟩+G2⟨DSL2⟩+...// 深度分解,产生多个 DSL=Delta+G1⟨Delta2+G2⟨Delta3+G3⟨DSL3⟩⟩⟩
大量的DSL构成DSL森林,然后协同解决问题。
这里需要强调的是,每个DSL语言都自动定义了一个适用于局部领域的坐标系统 。这个概念听起来有点微妙,但是如果学习过微分几何中的活动标架法,就可以很快理解它。一般情况下我们都是在一个选定的坐标系统中来定义运动,但是活动标架法利用运动本身的内在特性自动定义了一个附着在运动轨迹上的内禀坐标系统,换句话说运动在坐标系中发生,同时运动本身生成了一个坐标系 。类似的,业务逻辑使用DSL来表达,同时表达业务的时候使用的DSL的抽象语法树及其节点属性就自动构成了一个坐标系。具体来说,抽象语法树上的每个属性具有唯一的xpath,比如/task/steps[@name=a]/@name
表示步骤a的name属性。因为任何逻辑都是需要用程序语言来表达,所以不存在这个坐标系没有覆盖的情况,所有业务必然是在这个坐标系所定义的坐标空间中发生。
活动标架法的本质是用几何对象的内在特性替代外部强加的坐标系 ,这与现代物理中"背景无关性"(如广义相对论)和计算机科学中"领域专用语言"(DSL)的设计理念不谋而合------通过对象自身结构定义描述框架,而非依赖外部抽象。
基于可逆计算理论设计的低代码平台NopPlatform已开源:
- gitee: gitee.com/canonical-e...
- github: github.com/entropy-clo...
- gitcode:gitcode.com/canonical-e...
- 开发示例:gitee.com/canonical-e...
- 可逆计算原理和Nop平台介绍及答疑:www.bilibili.com/video/BV14u...
- 官网国际站: nop-platform.github.io/
- 网友Crazydan Studio建立的Nop开发实践分享网站: nop.crazydan.io/