我正在使用一个搜索一系列值的函数。
Require Import List.
(* Implementation of ListTest omitted. *)
Definition ListTest (l : list nat) := false.
Definition SearchCountList n :=
(fix f i l := match i with
| 0 => ListTest (rev l)
| S i1 =>
(fix g j l1 := match j with
| 0 => false
| S j1 =>
if f i1 (j :: l1)
then true
else g j1 l1
end) (n + n) (i :: l)
end) n nil
.
我希望能够推断出这个功能。
然而,我似乎无法让coq的内置感应原理设施起作用。
Functional Scheme SearchCountList := Induction for SearchCountList Sort Prop.
Error: GRec not handled
看起来coq被设置用于处理相互递归,而不是嵌套递归。在这种情况下,我基本上有2个嵌套for循环。
但是,转换为相互递归也不是那么容易:
Definition SearchCountList_Loop :=
fix outer n i l {struct i} :=
match i with
| 0 => ListTest (rev l)
| S i1 => inner n i1 (n + n) (i :: l)
end
with inner n i j l {struct j} :=
match j with
| 0 => false
| S j1 =>
if outer n i (j :: l)
then true
else inner n i j1 l
end
for outer
.
但是会产生错误
对inner的递归调用具有等于的主参数 “
n + n
”代替“i1
”。
因此,看起来我需要使用measure来让它直接接受定义。很遗憾我有时会重置j。但是,在嵌套设置中,这是有道理的,因为我已经减少,而且我是外循环。
那么,是否有一种处理嵌套递归的标准方法,而不是相互递归?是否有更简单的方法来推理案例,而不涉及制定单独的归纳定理?由于我还没有找到自动生成它的方法,我想我一直都在直接写入归纳原理。
答案 0 :(得分:0)
在这种情况下,有一种避免相互递归的技巧:您可以在f i1
内计算f
并将结果传递给g
。
Fixpoint g (f_n_i1 : list nat -> bool) (j : nat) (l1 : list nat) : bool :=
match j with
| 0 => false
| S j1 => if f_n_i1 (j :: l1) then true else g f_n_i1 j1 l1
end.
Fixpoint f (n i : nat) (l : list nat) : bool :=
match i with
| 0 => ListTest (rev l)
| S i1 => g (f n i1) (n + n) (i :: l)
end.
Definition SearchCountList (n : nat) : bool := f n n nil.
您确定原始代码中的简单归纳是不够的?那些有根据的归纳法呢?