Packages
只有当函数的arg是传递的arg的直接子项时才允许递归,以便Coq可以看到它实际终止了吗?
答案 0 :(得分:3)
如果函数g
保留了作为子项的属性,则可以编写这样的函数pred
。
某些标准函数具有此属性,例如sub
,From Coq Require Import Arith List.
Import ListNotations.
Fixpoint foo (x : nat) : nat :=
match x with
| O => 42
| S x' => foo (pred x'). (* foo (x' - 1) works too *)
end.
:
tl
另一方面,某些(标准)函数没有此属性,但可以重写以弥补此缺陷。例如。标准Fail Fixpoint bar (xs : list nat) : list nat :=
match xs with
| [] => []
| x :: xs' => bar (tl xs')
end.
函数不保留子项属性,因此以下操作失败:
Fixpoint new_tl {A : Type} (xs : list A) :=
match xs with
| [] => xs (* `tl` returns `[]` here *)
| _ :: xs' => xs'
end.
但如果我们重新定义尾部函数,那么
Fixpoint bar (xs : list nat) : list nat :=
match xs with
| [] => []
| x :: xs' => bar (new_tl xs')
end.
我们可以恢复所需的属性:
tl
new_tl
和tl
之间的唯一区别是,在空输入列表[]
的情况下,返回new_tl
,但public IEnumerable<Item> PickItems(Tab tab)
{
tab.Pick();
return tab.Items;
}
会返回原始列表。