在Coq中,Inductive sig (A:Type) (P:A -> Prop) : Type :=
exist : forall x:A, P x -> sig P.
被定义为
proj1_sig
我读作
" sig P是一种类型,其中P是取A并返回Prop的函数。定义类型,使得如果P x成立,则类型A的元素x的类型为sig P. #34;
Definition proj1_sig (e:sig P) := match e with
| exist _ a b => a
end.
定义为
leave_to
我不知道该怎么做。有人可以提供更直观的理解吗?
答案 0 :(得分:7)
sig
定义类型,如果
x
成立,A
类型的sig P
类型为P x
。
这不完全正确:我们不能说x : sig A P
。 e
类型的居民sig A P
基本上是元素x : A
的对和P x
拥有的证明(这称为{{} 3}})。 x
和P x
被"包裹"一起使用数据构造函数exist
。
要看到这一点,我们首先考虑非依赖对类型prod
,其定义如下:
Inductive prod (A B : Type) : Type := pair : A -> B -> A * B
prod
的居民是成对的,例如pair 1 true
(或使用符号,(1, true)
),其中两个组件的类型 彼此。
由于Coq中的A -> B
只是forall _ : A, B
(定义为dependent pair)的语法糖,因此prod
的定义可以被移植到
Inductive prod (A B : Type) : Type := pair : forall _ : A, B -> prod A B
上面的定义可能有助于看到sig A P
的元素是(依赖)对。
proj1_sig
从实现中我们可以看到proj1_sig e
解包了这对
返回第一个组件,即。 x
,丢弃了P x
的证明。
here模块包含以下注释:
(sig A P)
或更具暗示性{x:A | P x}
,表示A
类型的元素子集,它满足谓词P
。
如果我们查看proj1_sig
Check proj1_sig.
proj1_sig : forall (A : Type) (P : A -> Prop), {x : A | P x} -> A
我们会看到proj1_sig
为我们提供了一种从子集A
恢复超集{x : A | P x}
元素的方法。
fst
和proj1_sig
另外,我们可以说在某种意义上proj1_sig
类似于Coq.Init.Specif
函数,它返回一对的第一个组成部分:
Check @fst.
fst : forall A B : Type, A * B -> A
fst
有一个微不足道的属性:
Goal forall A B (a : A) (b : B),
fst (a, b) = a.
Proof. reflexivity. Qed.
我们可以为proj1_sig
:
Goal forall A (P : A -> Prop) (x : A) (prf : P x),
proj1_sig (exist P x prf) = x.
Proof. reflexivity. Qed.