__在从Coq中提取的Ocaml中
从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模块的未记录函数,但似乎定义的基本上是一个完全多态的函数,它吃掉了它的所有参数(不管它们的数量如何
\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
示例