Computer science Coq中递归函数的扩展 背景
我知道Iota缩减用于缩减/扩展递归函数。例如,给定以下简单递归函数(自然数上的阶乘)的应用: Iota Reduce扩展递归调用,有效地迭代递归函数一次: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 =>
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.