如何获得嵌套修复的归纳原则

时间:2013-10-06 05:46:45

标签: recursion coq induction totality

我正在使用一个搜索一系列值的函数。

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。但是,在嵌套设置中,这是有道理的,因为我已经减少,而且我是外循环。

那么,是否有一种处理嵌套递归的标准方法,而不是相互递归?是否有更简单的方法来推理案例,而不涉及制定单独的归纳定理?由于我还没有找到自动生成它的方法,我想我一直都在直接写入归纳原理。

1 个答案:

答案 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.

您确定原始代码中的简单归纳是不够的?那些有根据的归纳法呢?