Types Coq can';我看不出这两种类型是一样的

Types Coq can';我看不出这两种类型是一样的,types,functional-programming,coq,Types,Functional Programming,Coq,我试图在一个向量上定义rev函数,它的大小嵌入其中,我不知道如何在它上定义rev函数 以下是我的类型定义: 归纳向量{X:Type}:nat->Type->Type :=Nil:vect 0 X |缺点:所有n,X->vectnx->vectsn(sn)X . 我在上面定义了一些有用的函数: fixpointapp{X:Type}{nm:nat}(v1:vectnx)(v2:vectmx) :矢量(n+m)X:= 将v1与 |零=>v2 |Cons x xs=>Cons x(应用程序xs v

我试图在一个向量上定义rev函数,它的大小嵌入其中,我不知道如何在它上定义rev函数

以下是我的类型定义:

归纳向量{X:Type}:nat->Type->Type
:=Nil:vect 0 X
|缺点:所有n,X->vectnx->vectsn(sn)X
.

我在上面定义了一些有用的函数:

fixpointapp{X:Type}{nm:nat}(v1:vectnx)(v2:vectmx)
:矢量(n+m)X:=
将v1与
|零=>v2
|Cons x xs=>Cons x(应用程序xs v2)
结束。
不动点折叠左{xy:Type}{n:nat}(f:Y->X->Y)(acc:Y)(v:vectnx)
:Y:=
匹配
|无=>acc
|Cons x xs=>折叠左f(f acc x)xs
结束。

现在,我想定义rev。我的第一次尝试是通过左折,但结果完全失败了

Fixpoint rev{X:Type}{n:nat}(v:@vect X nx):@vect X nx:=
折叠左(fun{X:Type}{k:nat}(acc:vectkx)(X:X)=>X:::acc{}v。
我不理解错误
错误:这个术语的类型是产品,而它应该是排序。


我的第二次尝试几乎是好的,但是Coq看不到“sn=(n+1)”的本质,我不知道如何告诉Coq

Fixpoint rev{X:Type}{n:nat}(v:@vect X nx):@vect X nx:=
将(向量nx)返回值(向量nx)中的v与
|零=>零
|Cons_xxs=>app(rev xs){{x}
结束。
错误是
术语“app(rev X n0 xs){{X}}”的类型为“vect(n0+1)X”,而预期的类型为“vect(sn0)X”

如果您对coq代码有任何其他意见,请不要犹豫

fold_left
的第一个显式参数的类型必须为
?1->?2->?1
,即返回类型与第一个参数相同的两个参数的函数。[相关]“产品”是功能的Coq术语。您正在传递一个形式为
fun(X:Type)bcd=>…
的术语,因此
?1
Type
,术语
fun cd=>…
(显然有产品类型)必须具有给定上下文的类型
,因此它必须具有类型
Type
,即它必须是排序

如果您试图解决这个问题,您会发现您的
fold\u left
函数在这里不起作用:您需要在迭代过程中改变向量的长度,但是
fold\u left
的迭代器参数在迭代过程中有一个不变的类型。使用您拥有的
fold_left
函数,如果从长度为0的向量累加器
Nil
开始,您将得到相同类型的结果,同样是长度为0的向量

我还没有考虑如何定义一个更通用的迭代器,让您可以定义
rev
,但我相信这是可能的


至于您的第二次尝试,
vect(n0+1)X
vect(sn0)X
的问题在于它们不是相同的类型,因为
n0+1
不能转换为
sn0
。术语
n0+1
相等但不可转换,用作类型的术语只有在可转换时才可互换

如果两种类型相等,则可以编写一个函数,将一种类型的项“强制转换”为另一种类型的项。事实上,一般的函数是
eq_rect
,相等类型族的析构函数。您可能会发现,定义一个专门的函数来将向量转换为长度可证明但不一定可转换相等的向量

Definition vect_eq_nat {X : Type} {m n : nat} (H : m = n) v :=
  eq_rect _ (fun k => @vect X k X) v _ H.
如果
eq\u rect
的用法没有立即突出,您可以通过策略定义此类功能。只需确保定义的函数不仅具有正确的类型,而且具有所需的结果,并使定义透明

Definition vect_eq_nat {X : Type} {m n : nat} : m = n -> @vect X m X -> @vect X n X.
intros.
rewrite <- H.
exact X0.
Defined.
Print vect_eq_nat.
现在您可以使用此辅助定义定义
rev

Fixpoint rev {X : Type} {n : nat} (v : @vect X n X) : @vect X n X :=
  match v in (vect n X) return (vect n X) with
    | Nil => Nil
    | Cons _ x xs => vect_plus_comm (app (rev xs) (Cons _ x Nil))
  end.
您可以使用
Program Fixpoint
直接定义
rev
,一旦您将铸造步骤放置到位。唯一的证明义务是
sn0
n0+1
之间的平等

Program Fixpoint rev' {X : Type} {n : nat} (v : @vect X n X) : @vect X n X :=
  match v in (vect n X) return (vect n X) with
    | Nil => Nil
    | Cons _ x xs => vect_eq_nat _ (app (rev' xs) (Cons _ x Nil))
  end.
Solve Obligation 0 using (intros; omega).

左折叠的一种类型是
forall(X:type)(Y:nat->type)(nk:nat),(forall m:nat,ym->X->Y(sm))->yk->vectxn->Y(n+k)
Fixpoint rev {X : Type} {n : nat} (v : @vect X n X) : @vect X n X :=
  match v in (vect n X) return (vect n X) with
    | Nil => Nil
    | Cons _ x xs => vect_plus_comm (app (rev xs) (Cons _ x Nil))
  end.
Program Fixpoint rev' {X : Type} {n : nat} (v : @vect X n X) : @vect X n X :=
  match v in (vect n X) return (vect n X) with
    | Nil => Nil
    | Cons _ x xs => vect_eq_nat _ (app (rev' xs) (Cons _ x Nil))
  end.
Solve Obligation 0 using (intros; omega).