我正在阅读http://adam.chlipala.net/cpdt/html/Hoas.html,并试图了解有关参数HOAS(高阶抽象语法)的Coq代码:
Inductive Closed : forall t, Exp t -> Prop :=
| CConst : forall n,
Closed (Const n)
| CPlus : forall E1 E2,
Closed E1
-> Closed E2
-> Closed (Plus E1 E2)
| CApp : forall dom ran (E1 : Exp (dom --> ran)) E2,
Closed E1
-> Closed E2
-> Closed (App E1 E2)
| CAbs : forall dom ran (E1 : Exp1 dom ran),
Closed (Abs E1).
我对此有几个疑问:
Closed
?这是某种递归声明(没有结束条件的开始吗?)?或者,Inductive
定义有两种风格:1)常用的类型定义; 2)关于类型的某种陈述?这段代码是关于类型的声明,而不是定义。Closed
是什么意思?通常我可以想象参数HOAS是关于增强初始类型的。因此,我希望Closed
是增强型的类型,我可以定义常量John : Closed
。但是实际上它是从Exp t -> Prop
派生的,因此,在我看来,这不是初始类型的增强,而是关于初始类型的表达式的语句(谓词)。而且该谓词的结构反映了初始类型术语的结构,这就是为什么可以将其以某种方式用于结构归纳的原因。我也正在阅读https://coq.inria.fr/distrib/current/refman/language/gallina-specification-language.html#coq:cmd.definition一章“简单带注释的归纳类型”,但我不明白如何在构造函数中使用类型名称。
答案 0 :(得分:2)
在Coq中重复键入类型的名称非常好;这只是定义一个递归数据类型。考虑一下标准库中自然数的定义:
Inductive nat : Type :=
| O : nat
| S : nat -> nat.
这表示nat
类型是由两个构造函数O
和S
生成的。 S
类型的递归出现意味着我们可以使用先前构建的自然数来构造其他自然数。例如
Definition zero : nat := O.
Definition one : nat := S zero.
Definition two : nat := S one.
等您提供的示例Closed
有点不同,因为它定义了一个归纳性的命题族,而不是像自然数或列表之类的典型数据类型。对于任何Exp t
,该族均根据类型t
进行索引。除了这些差异之外,递归事件的行为与nat
的情况几乎相同。例如,CPlus
构造函数表示,为了证明Closed (Plus E1 E2)
成立,我们需要证明Closed E1
和Closed E2
持有。
我不明白您所说的“增强类型”或“初始类型”的含义,但是据我所知Closed E
是一个命题,表明表达式E : Exp t
没有自由变量。