Coq依赖类型

时间:2014-09-26 21:34:03

标签: coq dependent-type

我是Coq的新手,需要一些简单的例子帮助我开始。特别是我有兴趣使用依赖类型定义向量(固定大小列表)的一些操作。我从Vector包开始,尝试实现一些额外的功能。例如,我很难实现琐碎的'take'和'drop'函数,这些函数从列表中取出或删除第一个'p'元素。

Require Import Vector.

Fixpoint take {A} {n} (p:nat) (a: t A n) : p<=n -> t A p := 
   match a return ( p<=n -> t A p) with
     | cons A v (S m) => cons (hd v) (take m (tl v)) m
     | nil => fun pf => a
   end.

错误(在nil的情况下)是:

The term "a" has type "t A n" while it is expected to have type "t A p".

有人可以帮我解决一些问题吗?谢谢!

1 个答案:

答案 0 :(得分:5)

我不了解你的做法。当参数为非空向量时,您总是返回非空向量,但take必须在nil时返回p=0,无论向量如何。

这是构建take的一种方法。我不是使用假设p <= n,而是将参数n的长度表示为要采用的元素数量p和结尾元素数量m的总和,这可能是if p <= n。这允许更容易的递归定义,因为(S p') + m在结构上等于S (p' + m)。请注意,歧视取决于要采取的元素数量:如果采用0则返回nil,否则返回cons head new_tail

此版本的take函数具有所需的计算行为,因此剩下的就是定义一个具有所需证明内容的函数。我使用Program功能来方便地做到这一点:填写计算内容(琐碎,我只需要说我想使用m = n - p),然后完成证明义务(这是简单的算术)

Require Import Arith.
Require Import Vector.

Fixpoint take_plus {A} {m} (p:nat) : t A (p+m) -> t A p := 
   match p return t A (p+m) -> t A p with
     | 0 => fun a => nil _
     | S p' => fun a => cons A (hd a) _ (take_plus p' (tl a))
   end.
Program Definition take A n p (a : t A n) (H : p <= n) : t A p :=
          take_plus (m := n - p) p a.
Solve Obligations using auto with arith.

对于newdrop : forall A n p, t A n -> p <= n -> t A (n-p),以下方法有效。你需要通过告诉它在递归调用中变成pn来帮助Coq。

Program Fixpoint newdrop  {A} {n} p : t A n -> p <= n -> t A (n-p) :=
   match p return t A n -> p <= n -> t A (n-p) with
     | 0 => fun a H => a
     | S p' => fun a H => newdrop p' (tl a) (_ : p' <= n - 1)
   end.
Next Obligation.
omega.
Qed.
Next Obligation.
omega.
Qed.
Next Obligation.
omega.
Qed.
Next Obligation.
omega.
Qed.

我不知道Solve Obligations using omega.为什么不起作用,但单独解决每项义务都有效。