Though Set
and Type
Coq 中有所不同,这主要是由于历史原因。如今,大多数发展并不依赖于Set
不同于Type
。特别是,如果您替换,亚当的评论也有意义Set
by Type
到处。要点是,当您想要定义一个可以在执行期间计算的数据类型(例如数字)时,您需要将其放入Set
or Type
而不是 Prop
。这是因为生活在其中的事物Prop
当你从 Coq 中提取程序时会被删除,所以在Prop
最终不会计算任何东西。
至于你的第二个问题:Set
是生活在其中的东西Type
,但不在Set
,如以下代码片段所示。
Check Set : Type. (* This works *)
Fail Check Set : Set.
(* The command has indeed failed with message: *)
(* The term "Set" has type "Type" while it is expected to have type *)
(* "Set" (universe inconsistency: Cannot enforce Set+1 <= Set). *)
这一限制是为了防止理论中出现悖论。这几乎是您看到的唯一区别Set
and Type
默认情况下。您还可以通过使用以下命令调用 Coq 来使它们更加不同-impredicative-set
option:
(* Needs -impredicative-set; otherwise, the first line will also fail.*)
Check (forall A : Set, A -> A) : Set.
Universe u.
Fail Check (forall A : Type@{u}, A -> A) : Type@{u}.
(* The command has indeed failed with message: *)
(* The term "forall A : Type, A -> A" has type "Type@{u+1}" *)
(* while it is expected to have type "Type@{u}" (universe inconsistency: Cannot enforce *)
(* u < u because u = u). *)
请注意,我必须添加Universe u.
声明强制两次出现Type
处于同一水平。如果没有这个声明,Coq 会默默地把这两个Type
处于不同的宇宙层次,命令都会被接受。 (这并不意味着Type
会有相同的行为Set
在这个例子中,因为Type@{u}
and Type@{v}
是不同的事情,当u
and v
是不同的!)
如果您想知道为什么此功能很有用,那么这并非偶然。绝大多数 Coq 开发并不依赖它。它默认是关闭的,因为它与一些通常被认为在 Coq 开发中更有用的公理不兼容,例如强排中律:
forall A : Prop, {A} + {~ A}
With -impredicative-set
打开时,这个公理会产生一个悖论,而默认情况下使用它是安全的。