You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Agda中使用map递归时如何通过终止检查?

问题根因

你定义的Foo是嵌套递归类型,构造器Bar接收的是List Foo而非直接的Foo类型值。Agda默认终止检查器不会穿透map这类高阶函数跟踪参数的结构递减关系,无法判定map process x中传入process的参数是外层Bar x的严格子结构,因此抛出终止检查失败错误。

最简修复方案

方案1:终止注解(改动最小)

如果你确认函数逻辑确实是按结构递减递归,直接在process前加{-# TERMINATING #-}注解,告知Agda跳过该函数的终止检查即可,代码改动只有一行:

open import Data.List using (List; map)

data Foo : Set where
  Bar : List Foo → Foo

data Foo2 : Set where
  Bar2 : List Foo2 → Foo2

{-# TERMINATING #-}
process : Foo → Foo2
process (Bar x) = Bar2 (map process x)

这个方案代码改动最少,适合快速验证、个人项目场景。

方案2:大小类型(不跳过检查,更严谨)

如果需要保留Agda的终止校验、避免标注TERMINATING带来的潜在风险,可以启用大小类型扩展,让Agda自动识别嵌套结构的递减性,仅需少量修改:

-- 顶部启用大小类型扩展
{-# OPTIONS --sized-types #-}
open import Data.List using (List; map)
open import Size using (Size; ↑_)

-- 给Foo加大小索引
data Foo : Size → Set where
  Bar : {i : Size} → List (Foo i) → Foo (↑ i)

data Foo2 : Set where
  Bar2 : List Foo2 → Foo2

-- 给process加大小参数,核心逻辑完全不需要改
process : {i : Size} → Foo i → Foo2
process (Bar x) = Bar2 (map process x)

这种写法下Agda可以通过大小索引自动证明递归参数严格递减,完全合规通过终止检查,适合需要高可靠性的正式代码场景。

内容的提问来源于stack exchange,提问作者Camelid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 01:24:21