在coq中定义多态类型

在coq中定义多态类型,coq,Coq,所以我在做一个学习coq的练习。我试图根据这种编码定义一种类型: 对于所有X.(X->X)->X->X`这是来自阿隆佐教堂(他提出了自然数的编码)的,如下所示: Definition succ (n : nat) : nat := fun (X : Type) (f : X -> X) (x : X) => f (n X f x). Definition plus (n m : nat) : nat := fun (X : Type) (f : X -> X) (x : X)

所以我在做一个学习coq的练习。我试图根据这种编码定义一种类型: 对于所有X.(X->X)->X->X`这是来自阿隆佐教堂(他提出了自然数的编码)的,如下所示:

Definition succ (n : nat) : nat :=
fun (X : Type) (f : X -> X) (x : X) => f (n X f x).
Definition plus (n m : nat) : nat :=
fun (X : Type) (f : X -> X) (x : X) => (n X f (m X f x)).
Theorem plus_succ: forall (n : nat),
  plus n one = succ n.
Proof.
  intros.
0,f:x:x

1,f:x:fx

2,f:x:f(外汇)

3,f:x:f(f(fx))

n,f:x:fnx:

我的代码如下:

Definition nat:=对于所有X:Type,(X->X)->X->X.

这个练习需要我定义表达式0、1、2和3,它们将相应的数字编码为nat的元素: 下面是我认为会发生的事情

Definition zero : nat :=
  fun (X : Type) (f : X -> X) (x : X) => x.
Definition one : nat := 
  fun (X : Type) (f : X -> X) (x : X) => f x.
Definition two : nat :=
  fun (X : Type) (f : X -> X) (x : X) => f (f x).
Definition three : nat :=
  fun (X:Type)(f: X -> X)(x: X) => f ( f ( f x )).
我的问题是我需要证明+n one=succn。n是我定义的类型Nat

我的成功函数定义如下:

Definition succ (n : nat) : nat :=
fun (X : Type) (f : X -> X) (x : X) => f (n X f x).
Definition plus (n m : nat) : nat :=
fun (X : Type) (f : X -> X) (x : X) => (n X f (m X f x)).
Theorem plus_succ: forall (n : nat),
  plus n one = succ n.
Proof.
  intros.
我的plus功能定义如下:

Definition succ (n : nat) : nat :=
fun (X : Type) (f : X -> X) (x : X) => f (n X f x).
Definition plus (n m : nat) : nat :=
fun (X : Type) (f : X -> X) (x : X) => (n X f (m X f x)).
Theorem plus_succ: forall (n : nat),
  plus n one = succ n.
Proof.
  intros.
当我试图证明加上n=SUCN时,我陷入了中间,不知道如何证明。 代码如下:

Definition succ (n : nat) : nat :=
fun (X : Type) (f : X -> X) (x : X) => f (n X f x).
Definition plus (n m : nat) : nat :=
fun (X : Type) (f : X -> X) (x : X) => (n X f (m X f x)).
Theorem plus_succ: forall (n : nat),
  plus n one = succ n.
Proof.
  intros.
1子目标 n:纳特 ______________________________________(1/1) 加n一=成功n

我没有办法做倒装或者任何其他战术…(我是Coq的新手,到目前为止我已经学会了列表、保利、归纳和战术)

这让我想到,我上面定义的一个、两个或所有定义都不准确。
如果有人能帮我或给我一些提示,我将不胜感激!谢谢

在Coq中使用教堂编码本身并不是一个坏主意,但你将无法对这种类型的居民说太多(除了像你那样构建一些居民之外)

第一个问题是,这种Church编码的居民是函数,只有当两个函数计算到相同的值(直到展开、beta缩减、匹配缩减和修复)时,你才能证明它们在纯Coq中是相等的。 这不是
加n one
succn
的情况:您在lhs
funxfx=>f(nxfx)
和rhs
funxfx=>nxf(fx)
。您希望证明的是
对于所有(X:type)(f:X->X)(X:X),f(nxfx)=nxf(fx)
,然后您需要使用
函数可扩展性
,这是一条公理,说明函数之间的相等性是由函数在其域的每个点上的值决定的(有关这一点的更多详细信息,请参见stdlib中的
Coq.Logic.FunctionalExtensionity
)。这一公理经常被假设,但也不是无辜的(例如,它会阻止计算)

您将遇到的第二个问题是,您希望
nat=forall X,(X->X)的居民->X->X
在它们的第一个参数
X:Type
中是参数化函数,但实际上并没有什么强制要求。事实上,如果假设附加公理,例如在纯Coq(没有任何公理)中排除中间,则可以构造非参数居民,Bernardy和Lasson的结果表明,事实上,你的类型
nat
的所有居民都是参数化的,但是你不能将这个结果内化。没有参数化,你就没有子弹来证明方程,比如
f(nxfx)=nxf(fx)

所以你的麻烦来自这两个问题:

  • 在没有函数可扩展性的情况下,可以证明的函数之间的相等性非常有限,并且
  • 在纯Coq中,您无法在内部表示类型的量化是参数化的

  • 如果您想了解更多关于参数化的这些问题,以及使用Church编码(或其变体)仍然可以实现的功能,我建议您看看Chlipala。

    特别是,我认为OP需要
    功能性_扩展性_dep
    ,因为
    X:Type
    参数。