Rocq 内核修复:嵌套互余 cofixpoint 仅允许主分支递归调用外层 cofixpoint
形式化验证编程语言【免费下载链接】coqThe Rocq Prover is an interactive theorem prover, or proof assistant. It provides a formal language to write mathematical definitions, executable algorithms and theorems together with an environment for semi-interactive development of machine-checked proofs.项目地址https://gitcode.com/gh_mirrors/co/coq点击查看免费下载本文围绕 RocqCoq 继任者内核的一处守卫条件guard condition修复展开当互余 cofixpoint 嵌套在另一个 cofixpoint 之中时只有内层互余块的主分支main branch of the mutual允许对外层 cofixpoint 发起递归调用其余分支的此类调用将被内核拒绝。读完本文你将理解余归纳定义的守卫检查机制、本次修复在kernel/inductive.ml中的具体实现以及如何在测试套件中复现与验证这类修复。背景余归纳定义与 cofixpoint 的守卫条件Rocq 通过CoInductive定义余归纳类型coinductive types并通过CoFixpoint构造余递归定义。与Fix类似内核在类型检查时会校验 cofixpoint 的每个递归调用是否满足守卫条件递归调用必须出现在某个构造函数参数内部更精确地说出现在共域余归纳类型的严格子项路径上否则定义会被判定为非法。从源码看cofixpoint 在项表示中对应CoFix构造子接口在 kernel/constr.mli(* If [funnames [|f1,.....fn|]] [typarray [|t1,...tn|]] [bodies [b1,.....bn]] then [mkCoFix (i, (funnames, typarray, bodies))] constructs the ith function of the block [CoFixpoint f1 b1 with f2 b2 ... with fn bn.] *) type cofixpoint (constr, types, Sorts.relevance) pcofixpoint val mkCoFix : cofixpoint - constr一个互余块mutual block由若干分支组成语法上写作cofix f : ... with g : ... for f其中for f指定该块被展开时选取的分支也就是主分支。守卫条件的必要性在于保证内核的一致性consistency若允许未受守卫的余递归调用就可能构造出无穷下降序列进而在余归纳类型上导出悖论。历史上与此相关的守卫检查漏洞多次被修复例如doc/sphinx/changes.rst的 9.1.0 内核变更记录中就列有guard checking forgot to check non principal arguments of a fixpoint for unguarded uses of the fixpoint leading to an inconsistencydoc/sphinx/changes.rst等多项修复。问题本质嵌套互余 cofixpoint 中的递归调用许可changelog 文档doc/changelog/01-kernel/22392-no-nested-mutual-cofix-Fixed.rst记录的内容如下Fixed:On mutual cofixpoints nested in another, only the main branch of the mutual may do a recursive call of the outer cofixpointPR #22392修复 issue #22389by Yann Leray。即在修复前守卫检查对嵌套互余场景存在疏漏。所谓嵌套互余指在一个互余 cofixpoint 的定义体中又出现另一个互余 cofixpoint 块例如示意结构CoFixpoint outer : (cofix f : ... outer ... with g : ... outer ... for f)修复前内层互余块的非主分支如上述g即使递归调用了外层 cofixpoint也可能被守卫检查放过。由于非主分支并不参与该块的展开路径允许它绕过守卫地引用外层余递归定义会破坏每个递归调用都必须被构造函数包裹的封闭性理论上可被利用来构造不一致性。修复实现check_one_cofix对CoFix分支的新约束本次修复的核心位于内核守卫检查函数check_one_cofix中kernel/inductive.ml。它通过局部递归函数check_rec_call env alreadygrd n tree t遍历定义体其中alreadygrd记录当前是否已处于受保护位置n与nbfix标识当前外部互余块的递归变量范围tree描述共域余归纳类型的子项路径。当遍历遇到嵌套的CoFix时kernel/inductive.ml 的处理逻辑为| CoFix (i, (_, varit, vdefs as recdef)) - let () if not (List.for_all (noccur_with_meta n nbfix) args) then raise (CoFixGuardError (env, UnguardedRecursiveCall c)) in let () if not (Array.for_all (noccur_with_meta n nbfix) varit) then raise (CoFixGuardError (env, RecCallInTypeOfDef c)) in let nbfixinner Array.length vdefs in let env push_rec_types recdef env in let () if not (Array.for_all_i (fun j c - Int.equal i j || noccur_with_meta (n nbfixinner) nbfix c) 0 vdefs) then raise (CoFixGuardError (env, RecCallInNonMainMutual c)) in check_rec_call env alreadygrd (n nbfixinner) tree vdefs.(i)这段代码依次施加四重约束内层 cofixpoint 块自身的应用参数args中不得出现外层 cofixpoint 的递归调用否则报UnguardedRecursiveCall内层互余块的所有类型varit中不得出现外层 cofixpoint 的递归调用否则报RecCallInTypeOfDef遍历内层互余块的全部定义体vdefs对于索引j不是主分支i的定义体若其中出现外层 cofixpoint 的递归调用即noccur_with_meta (n nbfixinner) nbfix c为假直接抛出RecCallInNonMainMutual错误——这正是本次修复新增的约束主分支vdefs.(i)则继续递归进入check_rec_call只要递归调用受守卫位于构造函数参数内就仍然允许。需要特别说明的是上述约束针对的是外层 cofixpoint 的递归调用。检查进行到第 3 步时环境已通过push_rec_types recdef推入内层互余块因此外层 cofixpoint 的递归变量位于n nbfixinner之后的索引区间noccur_with_meta (n nbfixinner) nbfix c正是用来探测该定义体中是否引用了外层 cofixpoint。完整检查流程与错误报告check_rec_call的入口调用为check_rec_call env false 1 vlra defkernel/inductive.mlalreadygrd初始为false——定义体顶层位置直接调用自身不被视为受守卫。整块检查由check_cofix驱动kernel/inductive.mllet check_cofix ?evars env (_bodynum,(names,types,bodies as recdef)) let flags Environ.typing_flags env in if flags.check_guarded then let nbfix Array.length bodies in for i 0 to nbfix-1 do let fixenv push_rec_types recdef env in try let ((mind, _),_) codomain_is_coind ?evars env types.(i) in let vlra WfPaths.lookup_subterms env mind in check_one_cofix ?evars fixenv nbfix bodies.(i) vlra with CoFixGuardError (errenv,err) - error_ill_formed_rec_body errenv (Type_errors.CoFixGuardError err) names i fixenv (judgment_of_fixpoint recdef) done else ()要点如下每个分支的类型必须先满足codomain_is_coind即共域必须是余归纳类型否则报CodomainNotInductiveType整块检查受环境 typing flags 的check_guarded控制可关闭对应 kernel/environ.ml 中的deactivated_guard关闭时守卫检查整体跳过任何守卫违规包括新增的RecCallInNonMainMutual都会包装为CoFixGuardError最终经error_ill_formed_rec_body转为IllFormedRecBody类型的类型错误拒绝该定义。check_cofix的入口在类型检查器 kernel/typeops.ml 的CoFix (i,recdef)分支被调用与check_fix平行。全部 cofix 守卫错误类型集中在 kernel/type_errors.mli 的pcofix_guard_error中错误构造子含义CodomainNotInductiveType共域不是余归纳类型UnguardedRecursiveCall递归调用未受守卫NestedRecursiveOccurrences递归调用的参数中嵌套出现本块递归变量RecCallInTypeOfAbstraction递归调用出现在 λ 抽象的类型中RecCallInNonRecArgOfConstructor递归调用出现在构造函数的非递归参数中RecCallInTypeOfDef内层互余块的类型中引用外层递归变量RecCallInNonMainMutual内层互余块的非主分支体中引用外层递归变量本次修复新增RecCallInCaseFun/RecCallInCaseArg/RecCallInCasePred递归调用出现在 match 的返回函数、被匹配项或谓词中NotGuardedForm/ReturnPredicateNotCoInductive其他未受守卫形式测试与同类修复脉络仓库的失败测试 test-suite/failure/cofixpoint.v 专门覆盖嵌套 cofixpoint 的守卫检查其用例可追溯到 2014 年 Maxime Dénès 在 coqdev 上报告的问题CoInductive CoFalse : . CoInductive CoTrue : I. Fail CoFixpoint loop : CoFalse : (cofix f : loop with g : loop for f). Fail CoFixpoint loop : CoFalse : (cofix f : I with g : loop for g). Fail CoFixpoint loop : CoFalse : (cofix f : loop with g : I for f).这些用例验证了无论主分支还是非主分支未受守卫的外部 cofixpoint 递归调用如直接以loop为体都必须被拒绝。本次 #22392 修复在此基础上进一步收紧即使递归调用出现在受保护位置只要它位于内层互余块的非主分支体中同样必须被拒绝。test-suite/failure/目录下的失败测试全部以Fail标注预期被拒绝的定义回归测试时由测试框架确认这些定义确实无法通过内核检查。同类修复在 changelog 中并不孤立。doc/sphinx/changes.rst的 9.1.0 内核条目还记录了守卫检查对非主参数漏检#20415、嵌套 match 检查不完整#20457、跨 fixpoint 错误归约#20648等多项漏洞修复doc/sphinx/changes.rst可见守卫检查是内核一致性的长期关注点本次修复与之一脉相承。对使用者的影响对于普通用户本次修复的直观影响是在互余定义中嵌套另一个互余块时非主分支不再被允许调用外层 cofixpoint。此前可能碰巧通过检查的此类定义在新版内核中将得到类型错误报错源自RecCallInNonMainMutual。如果你在代码中确实需要在嵌套互余块的非主分支中使用外部余递归函数正确的做法是把该调用移到主分支体内或将其作为显式参数传入内层块从而让递归调用发生在受守卫且许可的位置。内核层面不做任何推测性放行——守卫条件必须由用户定义的结构显式满足。需要说明的是check_guarded这一 typing flag 的存在意味着守卫检查可以在某些实验性设置下被整体关闭见 kernel/environ.ml但关闭守卫检查会破坏内核的一致性保证只适用于专门的内核调试场景不应在正常开发中使用。小结本次修复PR #22392修复 issue #22389约束了嵌套互余 cofixpoint 的守卫检查只有内层互余块的主分支可以对外层 cofixpoint 做递归调用核心实现位于 kernel/inductive.ml通过RecCallInNonMainMutual错误拒绝非主分支中的外部递归调用检查流程完整链路为typeops.ml入口 →check_cofix→check_one_cofix→check_rec_call错误经CoFixGuardError/IllFormedRecBody上报相关回归测试见 test-suite/failure/cofixpoint.v此类守卫检查修复的演进脉络可查阅 doc/sphinx/changes.rst。赞分享形式化验证编程语言【免费下载链接】coqThe Rocq Prover is an interactive theorem prover, or proof assistant. It provides a formal language to write mathematical definitions, executable algorithms and theorems together with an environment for semi-interactive development of machine-checked proofs.项目地址https://gitcode.com/gh_mirrors/co/coq点击查看免费下载相关推荐GitHub Markdown与文档渲染技巧大全GitHub Markdown与文档渲染技巧大全 本文全面介绍了GitHub Markdown的高级使用技巧包括语法高亮与代码块优化、表情符号与图片嵌入技巧、教程文档CPython 修复深层嵌套 GenericAlias 的 __parameters__ 递归崩溃问题gh-issue-154275CPython 修复深层嵌套 GenericAlias 的 __parameters__ 递归崩溃问题gh issue 154275 导读 本文围绕 CPy编程语言语言运行时解释器标准库企业微信推送消息到微信免费方案Wecom酱搭建与使用全攻略企业微信推送消息到微信免费方案Wecom酱搭建与使用全攻略 你是不是也遇到过这样的场景服务器报警只能发邮件、监控通知要装一堆 App、想给自己微信发条定时提后端即时通讯Serverless上一篇YCBlogs Android WebView 问题实战手册从内核进化、性能优化到安全漏洞与 JS 交互的 16 个坑位全解下一篇智慧树自动刷课插件3分钟配置实现全自动学习体验创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

风电紧固件技术要求详解:从高强螺栓到预紧力与疲劳设计

风电紧固件技术要求详解:从高强螺栓到预紧力与疲劳设计

很多人觉得紧固件这行没什么好讲的,可你一旦进了风电机舱里,想法马上会变。一台几兆瓦的风电机组,旋拧在主机舱、齿轮箱和偏航系统里的高强螺栓少说有几百颗,最大的到M42甚至M56,单颗预紧力达到几十吨。这些紧固件承载…

2026/10/13 8:55:40 阅读更多 →
LayaAir Widget教程:UI对齐与多分辨率适配原理及实战

LayaAir Widget教程:UI对齐与多分辨率适配原理及实战

Widget 是 LayaAir 里做 UI 对齐和适配的重要组件,这玩意儿几乎每个带界面的项目都会碰到。很多开发者一开始容易把它当成“设置坐标的辅助工具”,用完发现位置不对、不刷新、跟手动改坐标冲突,各种问题都来了。这篇文章结合我做 UI 适配踩过…

2026/10/13 8:55:46 阅读更多 →
分布式驱动汽车直接横摆力矩控制的分层架构设计实践

分布式驱动汽车直接横摆力矩控制的分层架构设计实践

做分布式驱动汽车稳定性控制,最直观的感受是:车变“活”了,但问题也变多了。四个轮子各自带一个驱动电机,每个轮子的扭矩都能独立控制,这对整车动力学控制来说是一个全新维度。传统燃油车时代,稳定性控制依…

2026/10/13 8:55:50 阅读更多 →

最新新闻

迷你SQL 2000轻量数据库:DLL清单、部署与排错指南

迷你SQL 2000轻量数据库:DLL清单、部署与排错指南

简介:迷你SQL 2000是一款面向Windows平台的轻量级数据库管理系统,适配WINXP、WIN7及WIN10的32位与64位环境,适合个人用户与小型企业解决低资源占用下的数据存储与管理需求。它可视为SQL Server 2000的精简版本,保留数据库引擎与基…

2026/10/13 13:01:12 阅读更多 →
技术博客标题缺失:t3code无法解析的合规性说明

技术博客标题缺失:t3code无法解析的合规性说明

我无法根据“t3code”这一标题生成符合要求的博文内容。原因如下:标题信息严重不足: “t3code”本身不具备明确语义,既非广为人知的开源项目(如未在GitHub、NPM、官方文档或主流技术社区中形成共识性指代),…

2026/10/13 13:01:12 阅读更多 →
揭秘市面上那些热门的SEO优化服务机构!

揭秘市面上那些热门的SEO优化服务机构!

痛点深度剖析我们团队在实践中发现,当前SEO优化行业存在诸多难题。众多客户反馈,做了半年的SEO优化,关键词排名毫无提升,对SEO效果产生质疑,技术白皮书显示,多数传统SEO见效周期长,流量获取成本…

2026/10/13 13:01:12 阅读更多 →
t3code 跨平台工具链实战:Electron 桌面端与 CLI 安装配置全指南

t3code 跨平台工具链实战:Electron 桌面端与 CLI 安装配置全指南

1. 从 t3code 这个关键词说起:它到底指什么第一次看到 "t3code" 这个词,很多人会一头雾水。它不像 "vscode" 那样有明确的官方定义,也不像某个知名框架那样有完整的文档站。从热词组合来看,t3code 更像是一个…

2026/10/13 13:01:12 阅读更多 →
感知机入门:从零实现到多层感知机突破异或问题

感知机入门:从零实现到多层感知机突破异或问题

感知机(Perceptron)是神经网络最初的模样,也是很多人入门深度学习时绕不过去的第一个模型。说它门槛低,是因为你只要会加权求和,再写一个 if 判断,就能把一个感知机跑起来;说它后劲大&#xff0…

2026/10/13 13:01:12 阅读更多 →
Unity水下波光Shader:动态折射与材质自适应光照实现

Unity水下波光Shader:动态折射与材质自适应光照实现

1. 这个效果到底在解决什么问题:水面光影的“动态欺骗”本质很多人看到“Unity Shader实现水中波光照射动物身上的效果”这个标题,第一反应是:“不就是加个高光贴图或者用个Blinn-Phong算一下反射吗?”——这恰恰是踩进第一个认知…

2026/10/13 13:00:12 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →