`list_rec`的第一个输入何时不是常量函数?

时间:2016-12-31 21:51:33

标签: coq

list_rec函数的类型为:

list_rec
 : forall (A : Type) (P : list A -> Set),
   P nil ->
   (forall (a : A) (l : list A), P l -> P (a :: l)%list) ->
   forall l : list A, P l

在我提出的所有示例中,P只是一个忽略输入列表的常量函数,无论如何都返回相同的类型。例如,P可能是fun _ : list A => natfun _ : list A => list B。使P的输出依赖于输入的一些用例是什么?为什么类型为P list A -> Set而不仅仅是Set

2 个答案:

答案 0 :(得分:3)

例如,我们可以使用list_rec和非常量P函数来实现将列表转换为向量的函数(长度索引列表)。

Require List Vector.
Import List.ListNotations Vector.VectorNotations.
Set Implicit Arguments.

Section VecExample.
Variable A : Set.
Definition P (xs : list A) : Set := Vector.t A (length xs).

Definition list_to_vector : forall xs : list A, Vector.t A (length xs) := 
  list_rec P [] (fun x _ vtail => x :: vtail).
End VecExample.

您可以将它与Vector.of_list函数的标准定义进行比较,该函数完全相同(t表示以下代码中的Vector.t),使用显式递归而不是隐藏它递归原则背后:

Fixpoint of_list {A} (l : list A) : t A (length l) :=
match l as l' return t A (length l') with
  |Datatypes.nil => []
  |(h :: tail)%list => (h :: (of_list tail))
end.

一个简单的测试:

Eval compute in list_to_vector [1;2;3].
Eval compute in Vector.of_list [1;2;3].

两个函数调用都返回相同的结果:

= [1; 2; 3]
     : Vector.t nat (length [1; 2; 3])

答案 1 :(得分:2)

尝试证明s ++ [] = s

[提示:将P定义为fun s => s ++ [] = s。]