2014-09-26 91 views
2

我是Coq新手,需要一些帮助,以帮助一些简单的示例让我开始。具体而言,我有兴趣使用依赖类型来定义向量的一些操作(固定大小列表)。我从Vector包开始尝试实现一些附加功能。例如,我很难实现简单的'take'和'drop'函数,这些函数会从列表中删除第一个'p'元素。Coq依赖类型

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

我不知道如何回答你的问题,但是当我想要认真学习Coq时,我买了一本好书。它被称为“交互定理证明和发展”。此外,这个问题可能更适合cs.se,但我不确定。 – 2014-09-26 22:36:43

+0

@PhilipWhite这不是关于[cs.se]的话题,因为它严格地关于Coq中的编程,而不是理解理论基础。这个问题在[so]上会很好。 – Gilles 2014-09-27 22:22:31

+0

@krokodil - 这个问题在这里是题外话,因为它不是关于CS理论。如果您愿意,我可以迁移您的问题堆栈溢出。否则,这个问题将很快关闭。 – 2014-09-28 01:20:52

回答

5

我不明白你的方法。当参数是非空向量时,您总是返回一个非空向量,但take必须返回nil,而不管向量是否为p=0

以下是建立take的一种方法。我没有使用假设p <= n,而是将参数n的长度表示为要采用的元素的数量与尾部元素的数量m的总和,其可能是如果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.不工作,但每解决个别的义务工作。

+0

谢谢!这非常有帮助! – krokodil 2014-09-28 16:44:37

+0

这里'nil'的参数是什么意思?这个构造函数不带任何参数。我不完全理解这部分是如何工作的。 – krokodil 2014-09-29 20:24:10

+1

@krokodil构造函数'nil'将元素类型('A')作为参数。我让科克推断它。如果你设置了隐式参数,你不需要(或能够)指定它。 – Gilles 2014-09-29 20:37:24