当前位置:首页 > 科研成果库

形式化验证的边界感:数学证明能替工程判断兜底吗

2026-10-28 19:57:58小研科研成果库13
一次硬件评审上,模型检查报告显示“零违例”。项目负责人松了口气。旁边的软件工程师却追问:约束是谁写的?环境假设覆盖了哪些模式?报告里的性质,和需求文档是一回事吗?会议室安静了几秒。 这几乎就是形式化验证在工程现场的真实处境。它给出的是强证据,不是免检章。更准确地说,它证明的是:在给定模型、给定性质、给定假设下,不存在某类反例。模型之外的东西,它不负责。

“零违例”背后,有一层没被证明的东西

形式化验证的常见路线并不神秘。模型检查把系统状态空间展开,穷举可达状态,看是否违反时序逻辑性质;定理证明把系统与规格写成逻辑命题,用交互或自动证明器推导;抽象解释则在有限域上给出保守近似。三者都依赖同一个前提:规格说明必须忠实表达意图。这句话听起来像废话,工程里却常常失守。 我见过一个总线仲裁器案例。安全性性质写成“任意时刻最多一个主设备获得授权”,证明通过。可需求里还有一条隐含约束:高紧迫请求在低等级请求连续占用时必须在若干周期内得到响应。这是活性性质,没写进属性集。工具没有错,证明也没有错,漏掉的是人的翻译过程。

规格错误比实现错误更隐蔽。实现错误至少还能靠测试和反例暴露;规格错误会让整套证明围绕一个错误命题展开。证明越漂亮,团队越容易放下戒心。这很危险。

形式化验证规格说明与实现偏差示意图形式化验证规格说明与实现偏差示意图

抽象不是免费的:证明能拼起来吗

真实系统不可能逐门逐状态验证。抽象不可避免。处理器验证会把数据通路抽象成事务,缓存一致性协议会把无限队列截断成有限模型,编译器验证会把源语言语义和目标语言语义分别形式化。问题在于,抽象要保留哪些性质,舍弃哪些细节,往往没有统一答案。

一个常见误区是把子系统证明直接拼成系统证明。局部性质成立,组合后未必成立。环境假设在局部是合理的,到了上层可能被破坏。于是有了假设保证推理、契约式设计、接口自动机等方法。它们试图把“谁假设了什么”写清楚,让组合验证有据可依。可工程落地时,契约本身也会腐化。接口改了,假设没改,证明脚本还在跑,绿灯依旧亮着。

这不是工具缺陷,是维护问题。形式化验证的资产不是一次报告,而是规格、假设、证明脚本和反例解释组成的活文档。没有版本管理,没有回归机制,没有和需求追踪挂钩,它会很快退化成昂贵的装饰品。

工具可信度与人的判断

模型检查器、SMT求解器、定理证明器本身也是软件。它们可能有 bug,可能对某些边界条件给出不可靠结果。高保障场景会要求工具认证、证明检查器独立复核、甚至生成可机器检查的证明证书。可多数团队没有这个预算。

模型检查的完备性是相对于模型和性质而言的。状态空间截断、位宽约束、环境假设都会改变结论,覆盖率指标也不能替代性质覆盖。更现实的路径是分层使用。安全关键模块用强形式化,普通模块用轻量静态分析;协议和并发控制更适合模型检查,数值算法更适合区间抽象或定理证明;把反例回灌到仿真和测试里,让形式化与测试互相校验。这里没有万能配方,只有成本与风险的匹配。

硬件模型检查工具链与证明证书流程图硬件模型检查工具链与证明证书流程图

边界感比技术选型更重要

边界感比技术选型更重要边界感比技术选型更重要 形式化验证擅长什么?状态空间有限且语义清晰的协议、控制器、硬件微架构、编译器中间表示、密码学协议、区块链合约。这些领域规格相对稳定,环境可建模,错误代价高。它不擅长什么?需求还在漂移的产品、物理世界耦合极强的系统、依赖人类操作的流程、以及“正确”本身都说不清的业务规则。

所以真正难的不是跑通工具,而是回答三个问题:我们到底想证明什么;模型漏掉了什么;谁来维护这些假设。答不上来,零违例就只是零违例,不是安全。

趋势上,形式化正在变轻。属性测试、模糊测试、运行时验证、契约检查把形式化思想拆碎,塞进日常流水线。大语言模型可以辅助写规格、补不变式、解释反例,但它生成的规格仍需人来审。数学证明能替工程判断兜底吗?不能。它能做的是把判断的前提摊开,让含糊的地方无处可藏。