【发布时间】:2023-04-06 13:25:02
【问题描述】:
背景
我了解 Iota 缩减用于缩减/扩展递归函数。例如,给定以下简单递归函数的应用(自然数的阶乘):
((fix fact (n:nat):nat := match n with | O => 1 | S m => n * fact m end) 2)
Iota 缩减扩展了递归调用,有效地迭代了递归函数一次:
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 缩减应该依赖于周围的上下文,并且已经尝试了对上述内容的多种变体,试图让 Coq 到 Iota 缩减递归函数。不幸的是,没有任何效果。
如何让 Coq 将 Iota 归约应用于未应用于任何参数或应用于普遍量化参数的递归函数?
任何帮助将不胜感激。 谢谢, - 拉里
【问题讨论】:
-
您对
odd和even的定义似乎不正确:它们都在定义常量谓词fun n => False!
标签: computer-science coq lambda-calculus theorem-proving