我有以下两个定义,导致了两个不同的错误信息。 第一个定义被拒绝是因为严格的正性,第二个定义是因为宇宙不一致性。
(* non-strictly positive *)
Inductive SwitchNSP (A : Type) : Type :=
| switchNSP : SwitchNSP bool -> SwitchNSP A.
Fail Inductive UseSwitchNSP :=
| useSwitchNSP : SwitchNSP UseSwitchNSP -> UseSwitchNSP.
(* universe inconsistency *)
Inductive SwitchNSPI : Type -> Type :=
| switchNSPI : forall A, SwitchNSPI bool -> SwitchNSPI A.
Fail Inductive UseSwitchNSPI :=
| useSwitchNSPI : SwitchNSPI UseSwitchNSPI -> UseSwitchNSPI.
在 Gitter 上聊天时发现宇宙(不)一致性首先得到检查,也就是说,第一个定义遵循此检查,但因为存在严格的正性问题而失败。
据我理解,如果 Coq 允许非严格正性数据类型定义,那么我可以构造出不使用fix
的非终止函数(这非常糟糕)。
为了让事情变得更加混乱,第一个定义在 Agda 中被接受,而第二个则会导致严格正性错误。
data Bool : Set where
True : Bool
False : Bool
data SwitchNSP (A : Set) : Set where
switchNSP : SwitchNSP Bool -> SwitchNSP A
data UseSwitchNSP : Set where
useSwitchNSP : SwitchNSP UseSwitchNSP -> UseSwitchNSP
data SwitchNSPI : Set -> Set where
switchNSPI : forall A -> SwitchNSPI Bool -> SwitchNSPI A
data UseSwitchNSPI : Set where
useSwitchNSP : SwitchNSPI UseSwitchNSPI -> UseSwitchNSPI
现在我的问题有两个方面:第一,我可以用上面的定义构造什么样的“邪恶例子”?第二,哪一个规则适用于上面的定义?
一些注释:
- 澄清一下,我认为我理解为什么第二个定义在类型检查方面是不允许的,但仍然觉得当定义被允许时,这里没有发生任何“邪恶”的事情。
- 我最初认为我的例子是这个问题的一个实例,但启用宇宙多态并不能帮助第二个定义。
- 我能否使用一些“技巧”来调整我的定义,使其被Coq接受?
UseSwitchNSPI
不会给语言增加不一致性。也就是说,如果语言是一致的,那么使用UseSwitchNSPI
就不可能构造出一个被接受的错误证明。"错误" 这个词有点过于强烈了,不允许使用UseSwitchNSPI
可能有技术上的原因(例如它可能与语言的某些其他特性不兼容,可能太难实现等)。 - effectfully