我可以定义以下归纳类型:
Inductive T : Type -> Type :=
| c1 : forall (A : Type), A -> T A
| c2 : T unit.
但是命令Check (c1 (T nat))
失败,并显示以下消息:术语T nat
的类型为Type@{max(Set, Top.3+1)}
,而预期的类型为Type@{Top.3}
(宇宙不一致)。
如何调整上面的归纳定义,以使c1 (T nat)
不会导致Universe不一致,并且不设置Universe多态性?
以下方法可行,但我希望在不添加相等性的情况下获得解决方案:
Inductive T (A : Type) : Type :=
| c1 : A -> T A
| c2' : A = unit -> T A.
Definition c2 : T unit := c2' unit eq_refl.
Check (c1 (T nat)).
(*
c1 (T nat)
: T nat -> T (T nat)
*)
答案 0 :(得分:3)
首先让我回答一个问题,即为什么我们首先会导致宇宙不一致。
宇宙不一致是Coq为避免通过罗素悖论证明False
而提出的错误,其原因是考虑了所有不包含自身的集合。
有一个变体在类型理论中更方便形式化,称为Hurken悖论。有关更多详细信息,请参见Coq.Logic.Hurkens
。 Hurken悖论有一个特殊之处,那就是证明没有任何类型可以缩回较小的类型。也就是说,给定
U := Type@{u}
A : U
down : U -> A
up : A -> U
up_down : forall (X:U), up (down X) = X
我们可以证明False
。
这几乎就是您的Inductive
类型的设置。用Universe注释类型,您可以从
Inductive T : Type@{i} -> Type@{j} :=
| c1 : forall (A : Type@{i}), A -> T A
| c2 : T unit.
请注意,我们可以反转此归纳法;我们可以写
Definition c1' (A : Type@{i}) (v : T A) : A
:= match v with
| c1 A x => x
| c2 => tt
end.
Lemma c1'_c1 (A : Type@{i}) : forall v, c1' A (c1 A v) = v.
Proof. reflexivity. Qed.
暂时假设c1 (T nat)
进行了类型检查。自T nat : Type@{j}
起,这将需要j <= i
。如果它给了我们j < i
,那么我们就定了。我们可以写c1 Type@{j}
。这正是我上面提到的Hurken变种的设置!我们可以定义
u = j
U := Type@{j}
A := T Type@{j}
down : U -> A := c1 Type@{j}
up : A -> U := c1' Type@{j}
up_down := c1'_c1 Type@{j}
,因此证明False
。
Coq需要实施避免这种矛盾的规则。如here所述,规则是对于归纳的构造函数的每个(非参数)自变量,如果自变量的类型在Universe u
中具有排序,则归纳的Universe限制为>= u
。在这种情况下,这比Coq需要严格。如SkySkimmer here所述,Coq可以识别直接出现在归纳索引处的参数,并以无视参数的相同方式来忽略它们。
所以,为了最终回答您的问题,我相信以下是您唯一的选择:
Set Universe Polymorphism
,以便在T (T nat)
中,两个T
采用不同的Universe参数。 (等效地,您可以编写Polymorphic Inductive
。):
之后的参数移动到它之前的参数。)-type-in-type
传递给Coq,以完全禁用Universe检查。False
的证明。(可能涉及模块子类型化,例如,参见this recent bug in modules with universes。))