用 cstar_mcp 进行 AI 辅助验证
前两节介绍了证明中两部分工作的自动化:策略负责匹配并消去空间资源,SMT 求解器负责解决剩余的纯目标。但在编写第一个证明块之前,数据采用什么逻辑模型、如何定义谓词族、选用什么循环不变式、用哪条引理填补证明的缺口,都无法由它们决定。此前在本教程中,这些判断都由人在 VSCode 中阅读符号状态后作出。 cstar_mcpcstar_mcp 将同样的工作流交给 AI 助手。它通过 MCP(Model Context Protocol,即 AI 助手调用外部工具的接口)向助手提供验证器的功能,让助手能够查看某一行的符号状态、搜索定理数据库、编辑证明块,再次检查验证结果。
服务器随工具链一起发布,位于 ~/.cstar/bin/cstar_mcp~/.cstar/bin/cstar_mcp。无论使用哪种助手,都可以按以下参数在 MCP 客户端中注册服务器:
- 传输方式:标准输入输出(由客户端启动的本地进程);
- 命令:二进制文件的绝对路径
/Users/you/.cstar/bin/cstar_mcp/Users/you/.cstar/bin/cstar_mcp,因为配置不是由 shell 读取的,~~不会被展开; - 参数:无;
- 环境变量:无需设置;可通过
CSTAR_MCP_MAX_STACKSCSTAR_MCP_MAX_STACKS提高常驻文件的数量上限(默认为三个)。
连接到服务器的助手可以看到六个工具。
| 工具 | 作用 |
|---|---|
cstar_showlspcstar_showlsp |
{path, line}{path, line}:某一源码行处的验证状态,即该行执行之后的状态。在函数内部查询时,回复包含 symbolic_statesymbolic_state 与作用域内的幽灵变量;在文件作用域(从函数的右花括号起),回复包含截至该行累积的 vcvc。lines: [...]lines: [...] 一次查询同一文件的多行,scopesscopes 则限制幽灵变量的转储内容。 |
search_theoremssearch_theorems |
{pattern, limit?}{pattern, limit?}:用正则表达式搜索具名 HOL Light 定理(包括定理语句);名字完全匹配的结果排在最前 |
search_conversionssearch_conversions |
{pattern, limit?}{pattern, limit?}:以同样的方式搜索具名变换 |
cstar_helpcstar_help |
{topic?}{topic?}:证明工作流指南,或其中的某个参考主题(syntaxsyntax、contractscontracts、memorymemory、predicatespredicates、loopsloops、bitopsbitops、aritharith、projectproject、techniquetechnique、operationsoperations、apiapi、errorserrors) |
cstar_killlspcstar_killlsp |
{path?}{path?}:发生内部故障后,终止某个文件或所有文件的证明器与常驻守护进程 |
cstar_interruptcstar_interrupt |
{}{}:中止一个无响应的证明器请求;证明器本身继续运行 |
cstar_showlspcstar_showlsp 是 Show Symbolic StateShow Symbolic State 对应的 MCP 工具,源码位置的查询规则与 VSCode 命令相同:查询函数内的行,显示该行执行后的状态;查询文件作用域中的行,返回截至该行收集到的验证报告。因此,只有查询文件真正的最后一行,且返回的 verification_conditionsverification_conditions、axiomsaxioms 与 strategiesstrategies 都为空时,文件才算通过验证。首次查询一个文件时比较慢,因为需要启动该文件的证明器并构建常驻守护进程;之后查询同一文件就能很快返回,守护进程也会自动处理文件的修改。默认最多有三个文件同时保持常驻(可通过环境变量 CSTAR_MCP_MAX_STACKSCSTAR_MCP_MAX_STACKS 提高上限),每个文件都有独立的证明器,因此在这些文件之间切换没有代价。查询第四个文件时,会淘汰最久未使用的那个,并在回复的 notenote 中说明。
cstar_helpcstar_help 提供的指南明确列出了工作流,与本教程此前手工完成的流程相同:
- 先设计数据的逻辑模型、谓词族、函数契约,以及折叠与展开引理,然后再编写代码与证明块;对于递归函数,可将结果的大小或高度等性质写入后置条件,以便在递归调用后直接使用这些性质;
- 每写完一个函数,就查询它的右花括号所在行,验证该函数;
- 验证失败时,查询证明块前后的可执行行,阅读符号状态;
- 搜索定理与变换数据库,寻找能填补证明缺口的定理或变换;
- 编辑证明块后再次查询,此时文件已预热;
- 最后查询文件的最后一行,返回的三个列表都必须为空。
将C* 中的前向证明中的 twicetwice 函数保存为独立项目中的 twice.ctwice.c;第 12 行是 int r = a + b;int r = a + b;,第 27 行是函数的右花括号。下面展示三次调用中助手发出的请求和服务器的回复(较长的值已截短;路径可使用绝对路径,也可相对于服务器启动时所在的目录):
cstar_showlsp {"path": "twice.c", "line": 12, "scopes": "none"}{ "flag": true, "lsp": { "function": "twice", "line": 12, "symbolic_state": "fact (0i <= n__pre) ** fact (n__pre <= 100i) ** data_at r__addr Tint ((n__pre + 1i) + n__pre - 1i) ** data_at b__addr Tint (n__pre - 1i) ** data_at a__addr Tint (n__pre + 1i) ** data_at n__addr Tint n__pre", … }}
cstar_showlsp {"path": "twice.c", "line": 12, "scopes": "none"}{ "flag": true, "lsp": { "function": "twice", "line": 12, "symbolic_state": "fact (0i <= n__pre) ** fact (n__pre <= 100i) ** data_at r__addr Tint ((n__pre + 1i) + n__pre - 1i) ** data_at b__addr Tint (n__pre - 1i) ** data_at a__addr Tint (n__pre + 1i) ** data_at n__addr Tint n__pre", … }}
这与 VSCode 面板在该行显示的状态相同,rr 所在的单元保存着尚未化简的和。查询最后一行时,返回的是验证报告。由于两个证明块都已写好,三个列表都为空:
cstar_showlsp {"path": "twice.c", "line": 27, "scopes": "none"}{ "flag": true, "lsp": { "line": 27, "vc": { "axioms": [], "strategies": [], "verification_conditions": [] }, … }}
cstar_showlsp {"path": "twice.c", "line": 27, "scopes": "none"}{ "flag": true, "lsp": { "line": 27, "vc": { "axioms": [], "strategies": [], "verification_conditions": [] }, … }}
搜索结果包含定理名字与定理语句,使用打印器的记号:
search_theorems {"pattern": "REVERSE_APPEND", "limit": 2}[ { "name": "REVERSE_APPEND", "statement": "|- forall l m. REVERSE (l ++ m) == REVERSE m ++ REVERSE l" }]
search_theorems {"pattern": "REVERSE_APPEND", "limit": 2}[ { "name": "REVERSE_APPEND", "statement": "|- forall l m. REVERSE (l ++ m) == REVERSE m ++ REVERSE l" }]
查询失败时,回复包含 flag: falseflag: false 和一个 diagnosticsdiagnostics 数组,报告内容与 VSCode 面板中显示的相同。数组中的每一项对应一个栈帧,记录文件、行、列,以及编译器或引擎的消息;消息包含失败的语句,如果有符号状态,也会一并给出。
cstar_mcpcstar_mcp通过 MCP 向 AI 助手提供验证器的功能:它随工具链发布,位于~/.cstar/bin~/.cstar/bin,在客户端中以标准输入输出服务器的形式注册,使用绝对路径,不带参数,并为每个文件启动独立的证明器。- 六个工具:
cstar_showlspcstar_showlsp(某一行的符号状态,或文件作用域处的验证报告)、search_theoremssearch_theorems与search_conversionssearch_conversions、cstar_helpcstar_help(指南及其主题),以及用于恢复的cstar_killlspcstar_killlsp与cstar_interruptcstar_interrupt。 - 工作流与本教程相同:先做设计,查询右花括号所在行,阅读失败前后的状态,搜索、编辑后再次查询。“通过验证”要求查询文件真正的最后一行,且返回的
verification_conditionsverification_conditions、axiomsaxioms与strategiesstrategies都为空。