Coq 类型参数和索引之间的差异?

Coq 类型参数和索引之间的差异?,coq,agda,dependent-type,type-theory,idris,Coq,Agda,Dependent Type,Type Theory,Idris,我不熟悉依赖类型,对两者之间的区别感到困惑。人们似乎通常说一个类型由另一个类型参数化,并由某个值索引。但是,在依赖类型的语言中,类型和术语之间难道没有区别吗?参数和指数之间的区别是基本的吗?你能给我举个例子,说明它们在编程和定理证明中的含义不同吗?下面是一个由某个值参数化的类型的例子: open import Data.Nat infixr 4 _∷_ data ≤List (n : ℕ) : Set where [] : ≤List n _∷_ : {m : ℕ} -> m

我不熟悉依赖类型,对两者之间的区别感到困惑。人们似乎通常说一个类型由另一个类型参数化,并由某个值索引。但是,在依赖类型的语言中,类型和术语之间难道没有区别吗?参数和指数之间的区别是基本的吗?你能给我举个例子,说明它们在编程和定理证明中的含义不同吗?

下面是一个由某个值参数化的类型的例子:

open import Data.Nat

infixr 4 _∷_

data ≤List (n : ℕ) : Set where
  []  : ≤List n
  _∷_ : {m : ℕ} -> m ≤ n -> ≤List n -> ≤List n

1≤3 : 1 ≤ 3
1≤3 = s≤s z≤n

3≤3 : 3 ≤ 3
3≤3 = s≤s (s≤s (s≤s z≤n))

example : ≤List 3
example = 3≤3 ∷ 1≤3 ∷ []
这是一种列表类型,每个元素都小于或等于
n
。一般的直觉是:如果某个属性适用于某个类型的每个居民,那么您可以将其抽象为参数。还有一条机械规则:“如果每个构造函数在第一个索引位置(在结果类型中)具有相同的变量,则第一个索引可以转换为新参数。” 这句话来自*,你应该读一读


当您看到一系列类型时,您可能会想知道它的每个参数是参数还是索引


参数仅表示类型在某种程度上是泛型的,其行为与提供的参数有关

例如,这意味着类型
列表T
将具有相同的形状,无论您考虑哪个
T
nil
cons t0 nil
cons t1(cons t2 nil)
,等等。
T
的选择仅影响可以为
t0
t1
插入的值,
t2


指数另一方面,可能会影响您在类型中找到的居民!这就是为什么我们说它们索引一个类型族,也就是说,每个索引都告诉您正在查看哪一个类型(在类型族中)(从这个意义上说,一个参数是退化情况,其中所有索引都指向同一组“形状”)

例如,类型族
Fin n
或有限大小集
n
包含非常不同的结构,具体取决于您选择的
n

索引
0
索引一个空集。 索引
1
用一个元素对集合进行索引

从这个意义上讲,了解指数的价值可能会带来重要的信息!通常,通过查看索引,可以了解哪些构造函数可能被使用,哪些构造函数可能没有被使用。这就是依赖类型语言中的模式匹配如何消除不可行的模式,并从模式触发中提取信息


这就是为什么在定义归纳族时,通常可以为整个类型定义参数,但必须为每个构造函数指定索引(因为允许为每个构造函数指定其所在的索引)

例如,我可以定义:

F (T : Type) : ℕ → Type
C1 : F T 0
C2 : F T 1
C3 : F T 0
这里,
T
是一个参数,而
0
1
是索引。当您收到类型为
ftn
x
时,查看
T
将不会显示有关
x
的任何信息。但是看看
n
会告诉你:

  • n
    0
  • n
    1
  • x
    必须是由矛盾伪造的,否则

类似地,如果您收到类型为
ft0
y
,您知道您只需要对
C1
C3

进行相关排序的模式匹配:将参数声明为参数(例如冒号左侧)而不是索引,除了可读性之外,还有什么好处吗?类型检查器能否始终恢复以下信息:哪一个索引是参数?啊,这里也处理了这一点:@SebastianGraf是的,将参数放在左侧会影响Coq生成的消除器的形状,以及依赖模式匹配的类型检查。“最好”将参数放在左边,因为它向Coq表明,在选择这些参数时,类型是“统一”的,这简化了以后的工作。这个定义呢
inclusive OnlyBool:Set->Type:=C:OnlyBool bool.
是否已参数化或索引?@user3584499这显然是一个索引,因为您可以在
C
构造函数中选择其值。