Aptos Leaner 验证栈的 V5 Denotation 设计:单一指称语义与单一一致性定理 Aptos Leaner 验证栈的 V5 Denotation 设计单一指称语义与单一一致性定理【免费下载链接】aptos-coreAptos is a layer 1 blockchain built to support the widespread use of blockchain through better technology and user experience.项目地址: https://gitcode.com/GitHub_Trending/ap/aptos-core本篇文章基于当前仓库中的设计文档 denotation.md 展开系统讲解 Aptos 实验性 Lean 4 验证栈third_party/move/lean下的 leaner 系列包当前采用的验证设计用一个denote函数把已验证的 LIR 程序指称到Spec规范单子再用一个denote_agrees一致性定理把它与 big-step 语义相连从而把每个函数目标的验证成本压缩到一次定义性展开加叶子求解。读完本文你将理解该方案为何能取代按目标生成一致性证明的三条历史路线、九条性能原则分别约束什么、里程碑 D0–D4 的推进顺序以及仓库中对应的源码模块与测试台账。背景为什么需要一个指称、一个一致性证明Leaner 验证栈的权威语义是BigStep见 leaner-ir/LeanerIR/Semantics/BigStep.lean可执行形态是带燃料的解释器而verify f必须产出关于 big-step 关系的定理。v0 栈v0/move当年能自动验证 225 个函数、每个亚秒级是因为它的浅层形式就是语义本身——没有第二套模型需要证明一致。但代价是两条结构性缺陷缺少跨程序的元理论且与执行之间存在未证明的鸿沟存储还是公理化的。leaner 栈要同时保住自动化与可证性因此不能简单回到浅层即权威。v2 设计见 historical/verification-v2.md提出的正确形状是保留 deep 语义为参照增加一个浅层指称denotation用证明而非假设把它与参照连接起来。V5 即本设计文档denotation.md的最终形态2026-09-08 定稿取代了 frame-free row 路线certifying-execution.md和 normalize/native 路线generic-route.md。核心设计两个定义、一个定理、一个 per-target 展开设计的骨架是两个定义加一个定理都只写一次denote : ExecutableUnit → FunctionHandle → Array RuntimeValue → Spec RuntimeState Failure (Array RuntimeValue) denote_agrees : ∀ unit function arguments, Spec.Equiv (denote unit function arguments) (meaning unit function arguments)denote是已验证单元本身的 Lean 函数对函数体表达式 arenaValidation/IndexedArena.lean做结构递归fuel 由 arena 大小界定见 Proofs/Fuel.lean或对由 arena 一次性物化的树递归D0 里程碑裁定二选一。刻意不用良基递归——良基递归对 whnf 与simp不透明内核无法在具体数据上展开它。每个 LIR 构造恰好对应一个 case。递归调用通过 Proofs/Recursion.lean 的 oracle 消费被调函数递归 SCC 取其中已定义的fixBody最小不动点循环取 Proofs/NativeLoop.lean 中Runs/Fails/Undefined不动点存储与引用采用类型化 family store 与预言prophecy编码prophetic-references.md。denote_agrees只证明一次对 fuel 或树做归纳、面向BigStep.EvalFunction复用 Proofs/Denotation.lean 中已有的逐构造一致性引理作为归纳情形。它就是 v2 想要的 LIR 元理论也是裸verify成功有意义的依据。per targetverify f在denote unit f之上陈述契约elaborator 在具体单元上展开denote得到封闭浅层项t用定义性等价rfl或simp only [denote]证明denote unit f t然后只对t推理。每个目标不再需要证明任何一致性。denote是类型化且无 frame的由已验证类型索引为Spec RuntimeState Failure ⟦τ⟧原生载体局部变量由 continuation 绑定引用为预言值展开后的目标中不出现RuntimeFrame、row 或 loan registry。这不是可选项而是硬要求——v0 亚秒级的根因就是目标呈此形状而 row 路线每函数数秒正是目标携带了 frame 与调用边界回写。代码cProofs/Representation.lean只出现在一致性归纳里永不进入目标。源码中的四个模块实现落在leaner-ir/LeanerIR/Proofs/Denote/下四个文件文件职责关键内容Types.lean原生载体类型、row、codec、状态操作及其 wp 规则互递归族NTy/NRow/NRowscarrier、HList、variantCarrierCodecComp/checkedInt/CheckedOp/CompareOp/BitOp/位移wp_ite、wp_bottom等Term.lean类型化项与Term.denoteTerm ρ Γ τ、Args含reborrow、Exports、Flowvalue/return/break/continue、Term.denote、Function.denote、wp_call、wp_flowBind、wp_loopAtCompile.leancompileFunction对 fuel 结构递归ntyOfFuel、compileExpr、compilePlace、compileArgs、compileOperation、compilePrimitive、LoanRole、siteRoles、typeFuel/unitFuelAgreement.lean命名公理与向SatisfiesFunction的运输compileFunction_agrees当前为 axiom、satisfies_typedMeaning、satisfiesFunction_of_denote另外 Close.lean 提供 closerlir_denote/lir_denote_normsimp 集、state-fact 与 leaf 策略Verify.lean 拥有verify、#leaner_verify、#leaner_require_native[_all]命令Contract.lean 保存契约翻译与准备。不变的底线设计明确列出四条不变BigStep是权威。verify f必须是关于已验证 LIR big-step 关系的定理靠证明连接、绝不靠假设。elaborated LeanerLang 项由前端与元程序生成若定理只关于 elaborator 输出信任根将不可证伪——这正是 v2 拒绝浅层即权威的原因。单一语义。解释器、big-step 关系、验证器运行同一个模型含引用的预言编码解释器保持可执行形态和 MonoVM 差分锚点其可靠性与 fuel 完备性不变。非空泛。裸verify成功仅当 LIR 每个节点都有可执行语义时才有意义准备阶段拒绝其余情况v2 的 vacuity 发现mut X[a].f.g曾降级为无运行时含义的 value-levelselect链使Satisfies的部分正确性对任何契约空泛成立。三主张分离。CLAUDE.md 中声明的三件事保持独立源码验证、降级到字节码、以及两者之间尚未证明的编译器正确性定理。九条性能原则v0 曾以亚秒成本自动验证 225 个函数其后每条路线都变慢性能审计verification-perf-audit.md与 v0 自己的分析v0/move/Move/performance-analysis.md把差距归于同一小撮原因。以下九条原则是那些原因的反面每条都附证据与检查方式D0 若违反任一条即失败不看测得的数字目标只含数学、不含机械。verify推理的项只提及源码提到的内容原生载体值、局部变量的 Lean binder、mut的预言值、类型化 family store。不出现RuntimeFrame、row、loan registry、arena、表达式 id 或字符串。检查elaborator 审计展开项的常量出现即拒绝目标。只翻译一次在任何义务产生之前绝不做符号执行。对程序数据的全部计算发生在denote的定义性展开里先于第一个义务义务中永不出现denote、求值器或 arena 查找。检查展开项无denote/解释器常量DenotePerformance.exp 把展开成本与闭合成本分开记录。最弱前置条件而非展开的关系。每个组合子一条 wp 规则wp (bind a f) ↔ wp a (fun v wp (f v))无存在量词、每个子项只出现一次、随函数体线性增长良定义性结构化且从不展开。检查wp 规则是命名 simp 集里每个组合子一条引理义务数等于退出路径数加显式不变量义务数。一次遍历、一个上下文。函数体只遍历一次、按退出路径切分而不是为ok/aborts/undefined各遍历一次simp_all、subst_vars这类上下文级 pass 只在叶子目标上、只对该叶子自己的上下文运行。证据bump_twice曾因闭合 pass 对每个残差目标重处理整个上下文而搜索受限在每证明对象 25k heartbeats审计 F1/F1c。按契约模块化。调用在边界贡献被调函数的契约原生等式而非其函数体泛型函数体证明一次、实例化使用。证据泛型语言检查点把调用者从 50M heartbeats 降到 14M因为不再重验证被调函数。可判定叶子其余全部结构化。叶子目标是Int上的线性算术带 range 证书由omega闭合或有限枚举由decide闭合没有 tactic 在义务结构上搜索或回溯closer 不匹配目标形状。证据Certify.lean拒绝0 args.item.val这类不支持的形状。检查closer 是 simp 清单后接omega/decide/grind无路由选择。热路径上的数值同一性。Id、存储键、variant 索引是Nat每个字面量只有一种拼写。证据审计 F2热比较中的字符串同一性、F3数组拼写多义、F5嵌套归纳上的派生BEq是partial。预计算清单、稳定键。证明用到的每个 simp 清单都是注册过的 simp 集lir_denote、lir_denote_norm绝不写成长显式列表——simp only [list]每次调用都会重新 elaborate 每条当正规形清单增长时这成了每目标恒定 0.8M heartbeats。键控重写引理的类型HList、variantCarrier不可归约可归约的键在目标中被归约、在引理中却卡住重写会静默失配。逐目标对照 v0 度量。DenotePerformance.exp逐目标记录 heartbeats、证明对象、展开成本闸门是同一契约在 v0 上的每函数时间再生成只点名变更本应移动的目标。其中 1、2、3、6 是架构性的按denote与 closer 的构造成立或失败正是此前路线违反的4、5、7、8、9 是工程纪律部分被旧路线找回、不能再丢。走过的弯路v2 的教训v2 原本要求一条面向Spec的、验证后 LIR 的单一泛型指称用一条归纳证明的一致性定理连到BigStep即 V5per-target 发射一致性证明只是可接受的第二名等 V5 落地即弃。但 V5 从未被 scope、从未被尝试临时方案成了架构。随后三次路线重写script、normalize/compose、native每次都按构造重复三件事一个由 shape 匹配元程序逐目标生成的原生组合子LeanerLang/Native*.lean、一条把它连到 frame 模型的协议律Proofs/*Agreement.lean逐目标组装成computationRepresents、以及为新目标形状补 closer 支持Proofs/Certify.lean它拒绝不认识的形状。每条路线的协议库都不完整于是每条都需要上一条兜底移除 fallback 只会暴露依赖而非消除它——61 个 Check 文件中有 42 个因构造缺三件中的一件而失败。面向证明的Proofs/树有 41k 行覆盖面却不及 v0 那 15k 行的语义加验证器。已携带与未携带的构造当前检查点2026-09-08见 test-organization.md 的 35/61 台账下已携带标量与检查算术、比较、布尔运算、无符号、检查移位与转换、常量、if、let、块、abort、assert、提前return、赋值、break/continue含带标签的、带invariant子句的循环自动 frame 把表头处每个不可变局部钉到其入口值、经被调函数发布定理的直接单态调用、元组、结构体、带 variant 测试与载荷选择的枚举match以此形态到达、局部变量共享借用、可变引用NTy.ref带原生当前值的 loan参数、原地修改、类型化投影路径、局部 lender、从被调函数导出处结算的重借参数以及运行时键控全局 map 上的存储globalRead、globalContains、globalBorrow、globalPublish、globalTake可变全局借用留下运行时 hole其死亡标记按 key 回写。被拒绝的构造会被点名。未携带|、^、有符号位运算、向量台账中每一行type of a local is not carried、泛型调用/构造器/字段、递归被调函数须先于调用者验证drain、recursive_choose、用作摘要的未指定纯被调函数plus_one、绑定或调用参数之外的 mutable borrowreborrow、返回引用、携带活全局借用的循环Language/Loops的drain、资源不变量GlobalInv、CrossInv、Rust profile 的原语、嵌套解构模式。实现定下的规则文档还记录了实现过程中沉淀的四条规则closer 是 worklist带标记循环上的 wp 取循环规则被调函数取该函数的定理递归迭代取循环假设语法 binder、合取或条件会分裂只有 head 是wp的目标才重归一化调用的 post 假设在重归一化前消费specialize 蕴含、split 存在、代换 witness、用状态等式重写。leaf 先清除所有计算假设contradiction曾把整个单元经准备假设归约掉把上下文中每个 range 证书的边界作为独立事实加入绝不重写某个项所依赖的证书——它留下的 cast 在 transparency 与 simp 匹配处未类型化用上下文饱和分裂 range-check 条件最后由omega/decide判定。有符号商与余数使用宽度特定 range 事实而非绝对值。清单inventory是 simp 集、绝不写显式列表否则每调用 0.8M heartbeats。HList与variantCarrier不可归约所以任何右侧构造 row 值的引理都要在 row 类型上陈述而非其展开到的乘积。Rows 是互递归族NTy/NRow/NRows嵌套归纳无法派生 decidable equalityenum 携带其 variant 名的两两不同性聚合参数以解构方式引入、每个 variant 一个目标指称定义中绝不出现do-notation。假设台账LeanerIR.Proofs.Denote.compileFunction_agrees是 axiom用户 2026-09-08 决定直到归纳完成每个verified定理在#print axioms下列出它除此之外无任何 admitted。里程碑 D0–D4状态里程碑闸门D0DONE 2026-09-08协议被假设命名 axiom用户决定对Denotation.lean已覆盖的直线子集值、局部、检查算术、赋值、返回、单态调用实现denote与denote_agrees定理无sorry闭合Language/Arithmetic与Language/Integers经定义性展开验证per-target 展开与闭合成本记录进Performance.exp并与 v0 逐函数时间对比展开单独报告D1DONE 2026-09-08除递归drain、recursive_choose控制流分支、带载荷的 enum match、带不变量的结构化循环、递归Verification/Loops、LoopInvariants、Calls、Callees、递归Corpus目标、Language/Loops、Enums、EnumPatterns、ControlForms通过D2IN PROGRESS引用与存储已携带Account、Storage、Read、Prophecies、Corpus、Normalized通过开放资源不变量、带活全局借用的循环、返回引用、向量 loan存储与引用类型化全局 family、作用域借用、预言、返回引用Account、GlobalBorrows、GlobalInv、References、Loans、Prophecies、Storage通过D3未开始泛型V4 继承与 Rust profile 指称Language/Generics、Verification/Generics、GenericScalarCalls、Rust-profile fixtures 通过D4未开始退役删除逐目标computationRepresents生成、LeanerLang/Native*生成器、denote_agrees未消费的Proofs/*Agreement.lean模块、Certify.lean的 shape 路由在不变 caps 下全量 Check 审计Performance.exp达到 v0 平价目标Move 与 Rust 套件全绿D0 同时是可行性闸门若直线子集的归纳无法闭合或定义性展开的成本超过它所替代的协议证明应在 D1 前停下并报告。工作纪律与测试要求文档规定了四条纪律不新增Proofs/*Agreement.lean模块、LeanerLang/Native*生成器或Certify.leanshape casedenote不携带的构造即点名它的负向检查不再向退役路线移植 fixture只能由检查台账在不变 caps 下晋升denote_agrees中无sorry2026-09-08 那条命名 axiom 是临时项靠证明移除闭合不了的 case 就是denote不携带的构造成本由DenotePerformance.exp逐目标闸住不许抬高 caps。测试要求每个denotecase 必须带其归纳 casecase 未闭合的构造不进denote正向检查是闸门中点名的现有 Check fixtures、契约文本不变、只在不变 caps 下通过才晋升负向检查对每个不携带的构造给出点名诊断且每个新构造上的假ensures必须失败v2 vacuity 发现的要求Performance.exp逐目标记录展开与闭合成本再生成只点名应移动的目标。性能闸门实际数据可见 DenotePerformance.exp直线目标 transport 约 26 万 heartbeats、typed 约 180 万到 2500 万循环目标约 1800 万到 2100 万三 variantmatchtotal约 3500 万e2e 检查驱动把单目标验证 heartbeats 上限设为 18 万即 180k。这与文档中直线 1.7–6M、循环约 20M、带匹配契约的三 variant match 35M的记录吻合。开放问题逐目标展开的证书内核rfl与simp only [denote]哪个更便宜对 arena 的 fuel 与物化树哪个展开更便宜——在 D0 中测量。泛型参数如何携带按类型参数索引的载体族当前 D0 采用还是单态化视图V4。既有协议引理中哪些作为归纳 case 存活、哪些直接重证——由归纳本身决定不由模块划分决定。结语V5denotation设计的核心是把每函数一个协议证明永久替换为一个denote定义 一个denote_agrees归纳 每个目标一次rfl级展开。它不改变BigStep的权威地位不新增语义模型把 v0 的自动化形状wp 规则加omega/decide叶子在 deep 语义之上完整恢复同时让每个构造的扩展成本固定在一个denotecase、一个归纳 case、至多一个 wp 引理。仓库中 Types.lean、Term.lean、Compile.lean、Agreement.lean 与 Close.lean 五份实现文件、DenotePerformance.exp 性能台账、以及 Check/ 下的验收 fixtures 共同构成可复现的证据链是深入该验证栈的首选入口。【免费下载链接】aptos-coreAptos is a layer 1 blockchain built to support the widespread use of blockchain through better technology and user experience.项目地址: https://gitcode.com/GitHub_Trending/ap/aptos-core创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考