Agda Cubical中with匹配递归结果报无关参数错误的解决
错误产生原因
该错误由Cubical Agda模式匹配的实现局限触发:
- 你引入的
Fin类型定义为Σ ℕ (λ n → n < k)的西格玛类型,其中第三个分量(大小关系证明)是纯命题类型,被Agda标记为*不相关(irrelevant)*字段,只要命题成立,证明项的具体结构不影响计算。 - 当你直接将
Fin (suc k)解构为(suc j , q)形式、再使用with抽象递归调用结果时,Agda自动生成的with辅助函数会错误地将递归返回值中携带的高维路径结构(错误信息中大段的hcomp、primPOr等立方体原语项)作为相关参数,传入本应接收不相关值的证明字段位置,类型检查器检测到参数相关性不匹配,直接抛出错误。 - 本质是手动解构带不相关证明字段的索引类型时,
with抽象无法自动正确处理Cubical模式下路径参数的相关性标记。
正确实现方法
不要手动直接解构Fin的西格玛三元组、将不相关的大小证明暴露给with构造,可采用以下任意一种方案实现逻辑:
- 方案一:仅对
Fin的自然数分量(即fst fj)做分情况处理,不把大小关系证明纳入with抽象范围。大小证明属于命题,所有证明项定义相等,直接复用即可,不需要参与模式匹配。参考实现:
fsplit′ : ∀ {k} (fj : Fin (suc k)) → (flast ≡ fj) ⊎ (Σ[ fk ∈ Fin k ] inject< ≤-refl fk ≡ fj) fsplit′ {k = zero} fj = inl (Fin-fst-≡ (lemma (snd (snd fj)))) fsplit′ {k = suc k} fj with fst fj ... | 0 = inr (0 , Fin-fst-≡ refl) ... | suc j = let fj' : Fin k = j , pred-≤-pred (snd (snd fj)) in case fsplit′ fj' of λ { (inl p) → inl (cong (λ x → (suc (fst x)) , snd x) p) ; (inr (fk , q)) → inr (suc fk , cong (λ x → inject< ≤-refl (suc (fst fk)) , snd x) q) }
- 方案二:直接复用Cubical标准库预定义的
Fin析构函数。Cubical.Data.Fin模块本身已经提供了和需求完全一致的拆分功能,直接调用即可,不需要手动编写递归逻辑,也不需要接触类型内部的证明字段。 - 实践提示:Cubical模式下处理带索引的归纳类型时,尤其是内部携带命题证明的类型,优先使用类型提供的标准消除子、析构函数,尽量避免手动解构西格玛类型暴露内部证明分量,否则很容易触发
with抽象的相关性检查错误或高维路径类型错误。
内容的提问来源于stack exchange,提问作者Cactus
相关产品推荐
相关产品推荐

