Computer science Coq中递归函数的扩展 背景

Computer science Coq中递归函数的扩展 背景,computer-science,coq,lambda-calculus,theorem-proving,Computer Science,Coq,Lambda Calculus,Theorem Proving,我知道Iota缩减用于缩减/扩展递归函数。例如,给定以下简单递归函数(自然数上的阶乘)的应用: Iota Reduce扩展递归调用,有效地迭代递归函数一次: Eval lazy iota in ((fix fact (n:nat):nat := match n with | O => 1 | S m => n * fact m end) 2). = (fun n:nat => match n with | 0 => 1 | S m =>

我知道Iota缩减用于缩减/扩展递归函数。例如,给定以下简单递归函数(自然数上的阶乘)的应用:

Iota Reduce扩展递归调用,有效地迭代递归函数一次:

Eval lazy iota in ((fix fact (n:nat):nat := match n with | O => 1 | S m => n * fact m end) 2).
 = (fun n:nat =>
    match n with
    | 0 => 1
    | S m =>
        n *
        (fix fact (m : nat) : nat :=
           match m with
           | 0 => 1
           | S m0 => m * fact m0
           end) m
    end) 2.
这种行为很好地推广到相互递归的函数。例如,给定以下相互递归的函数定义:

Fixpoint even (n:nat):Prop := match n with | O => True | S m => odd m end
  with odd (n:nat):Prop := match n with | O => False | S m => even m end.
Iota减少将正确地扩展到分别为偶数或奇数的递归调用。要看到这一点,请考虑:

Theorem even_2 : even 2.
1 subgoal
==========
even 2
> lazy delta.

1 subgoal
==========
(fix even (n:nat):Prop := match n with ... end
 with odd (n:nat):Prop := match n with ... end
 for even) 2
> lazy iota.

1 subgoal
==========
(fun n:nat =>
  match n with
    | O => True
    | S m => (fix even (o:nat):Prop := match o with ... end
              with odd (o:nat):Prop := match o with ... end
              for odd) m
  end) 2
问题 这显然是正确的行为不幸的是,显然令人费解的是,在递归函数未应用于参数或参数普遍量化的情况下,Coq不会应用Iota缩减。例如,以下情况不起作用:

Theorem even_n : forall n:nat, even n.
1 subgoal
==========
forall n:nat, even n
> intro n.

1 subgoal
n : nat
==========
even n
> lazy delta.

1 subgoal
==========
(fix even (n:nat):Prop := match n with ... end
 with odd (n:nat):Prop := match n with ... end
 for even) n
> lazy iota. (* FAILS TO REDUCE! *)

1 subgoal
==========
(fix even (n:nat):Prop := match n with ... end
 with odd (n:nat):Prop := match n with ... end
 for even) n
我看不出Iota reduce应该依赖于周围环境的任何原因,并且已经尝试了上述的多种变体,试图获得Coq to Iota reduce递归函数。不幸的是,一切都不起作用

如何让Coq将Iota约简应用于未应用于任何参数或应用于通用量化参数的递归函数

任何帮助都将不胜感激。 谢谢
-Larry

这里的问题是iota规则对固定点有限制:该规则明确规定,如果递减参数以构造函数开头,iota只能应用于固定点

这样做是为了确保归纳构造的演算作为重写系统被严格规范化:如果我们可以始终应用iota,那么就有可能无限扩展所定义函数的递归出现

实际上,如果您想简化这样一个不动点,可以做两件事:

  • 手动销毁递归参数(
    n
    ,在您的情况下),然后减少。这在某些情况下更简单,但需要考虑很多情况。

  • 证明一个简化引理,并进行重写而不是简化。例如,您可以证明形式为
    奇数n~偶数n
    的引理,这在某些情况下可能对您有所帮助。您还可以将展开显式证明为引理(这一次,使用
    偶数
    的原始定义):


  • 您对奇数和偶数的定义似乎不正确:它们都定义了常量谓词
    fun=>False
    !谢谢你,亚瑟,你的回答正是我想知道的。我明白为什么Coq会引入这种约束,我很感谢您提供的解决方案。
    Theorem even_n : forall n:nat, even n.
    1 subgoal
    ==========
    forall n:nat, even n
    > intro n.
    
    1 subgoal
    n : nat
    ==========
    even n
    > lazy delta.
    
    1 subgoal
    ==========
    (fix even (n:nat):Prop := match n with ... end
     with odd (n:nat):Prop := match n with ... end
     for even) n
    > lazy iota. (* FAILS TO REDUCE! *)
    
    1 subgoal
    ==========
    (fix even (n:nat):Prop := match n with ... end
     with odd (n:nat):Prop := match n with ... end
     for even) n
    
    Goal forall n, even n = match n with | O => False | S m => odd m end.
    now destruct n.
    Qed.