__在从Coq中提取的Ocaml中

__在从Coq中提取的Ocaml中,ocaml,coq,Ocaml,Coq,从Coq中提取的Ocaml代码(在某些情况下)包括一个类型\uu和一个函数\u,定义如下: type __ = Obj.t let __ = let rec f _ = Obj.repr f in Obj.repr f 文件中说,在过去,这种类型被定义为单位(因此\uuuu可以被视为()),但存在(罕见的)情况,即\uuuuu类型的值被应用于\uuuuu类型的值 \uuuu使用OCaml中的Obj模块的未记录函数,但似乎定义的基本上是一个完全多态的函数,它吃掉了它的所有参数(不管它们的数量如何

从Coq中提取的Ocaml代码(在某些情况下)包括一个类型
\uu
和一个函数
\u
,定义如下:

type __ = Obj.t
let __ = let rec f _ = Obj.repr f in Obj.repr f
文件中说,在过去,这种类型被定义为
单位
(因此
\uuuu
可以被视为
()
),但存在(罕见的)情况,即
\uuuuu
类型的值被应用于
\uuuuu
类型的值

\uuuu
使用OCaml中的
Obj
模块的未记录函数,但似乎定义的基本上是一个完全多态的函数,它吃掉了它的所有参数(不管它们的数量如何)


是否有一些关于不能消除
\uuuu
的情况的文件,并且这种类型的值应用于同一类型的值,无论是从理论上(在不可能消除的情况下构造Coq术语)还是从实践上(显示发生这种情况的实际情况)观点?

中引用的参考文献很好地概述了擦除问题。具体来说,报告和文章都详细说明了如何删除CIC术语的类型方案和逻辑部分,以及为什么必须有
\uuuux=\uuuu
。问题不完全在于
\uu
可以应用于自身,而是它可以应用于任何东西

不幸的是,目前还不清楚这种行为在任何非病理性病例中是否重要。这里给出的动机是能够提取任何Coq术语,并且文档中没有提到任何从实践角度来看非常有趣的案例。上给出的示例如下:

Definition foo (X : Type) (f : nat -> X) (g : X -> nat) := g (f 0).
Definition bar := foo True (fun _ => I).
执行递归提取栏。将给出以下结果:

type __ = Obj.t
let __ = let rec f _ = Obj.repr f in Obj.repr f

type nat =
| O
| S of nat

(** val foo : (nat -> 'a1) -> ('a1 -> nat) -> nat **)

let foo f g =
  g (f O)

(** val bar : (__ -> nat) -> nat **)

let bar =
  foo (Obj.magic __)
由于
foo
Type
上是多态的,因此无法简化其主体上的
fo
应用程序,因为它可能具有计算内容。但是,由于
Prop
类型的子类型
foo
也可以应用于
True
,这是在
栏中发生的情况。当我们试图减少
时,我们将
应用于
O

这个特殊的例子不是很有趣,因为它可以完全内联
foo

let bar g =
  g __
由于
True
不能应用于任何东西,如果
g
对应于任何合法的Coq术语,那么它的
\uuu
参数也不会应用于任何东西,因此使用
\uuu=()
是安全的(我相信)。然而,在某些情况下,无法事先知道是否可以进一步应用已擦除的术语,这使得有必要对
\uuuu
进行一般定义。例如,查看文件末尾附近的
Fun
示例