Coq 程序不动点:递归调用'let'和义务假设
假设我有以下Coq 程序不动点:递归调用'let'和义务假设,coq,totality,Coq,Totality,假设我有以下程序固定点: From Coq Require Import List Program. Import ListNotations. Program Fixpoint f l {measure (length l)}: list nat := let f_rec := (f (tl l) ) in match hd_error l with | Some n => n :: f_rec | None => [] end. (为了有一个简单的示例,这个示例基本上以一种非
程序固定点
:
From Coq Require Import List Program.
Import ListNotations.
Program Fixpoint f l {measure (length l)}: list nat :=
let f_rec := (f (tl l) ) in
match hd_error l with
| Some n => n :: f_rec
| None => []
end.
(为了有一个简单的示例,这个示例基本上以一种非常愚蠢的方式返回l
)
这里,我有一个对f
(存储在f_rec
中)的递归调用,它仅在l
包含元素时使用,这确保了当我使用f_rec
时,长度(tl)
确实小于长度l
但是,当我想解决这个义务的时候
Next Obligation.
我没有我需要的假设
(不知何故,我的印象是,它被理解为“在let in
位置计算f(tll)
”,而不是“在实际使用之前延迟计算”)
为了说明区别,如果我“内联”了
让。。。在
语句中:
Program Fixpoint f l {measure (length l)}: list nat :=
match hd_error l with
| Some n => n :: (f (tl l) )
| None => []
end.
Next Obligation.
destruct l.
在这里,我看到了环境中的一些n=hd\u错误[]
我的问题如下: 是否可能有我需要的假设,即让
生成的假设匹配。。。是否使用
语句
注意:移动
let
是一个解决方案,但我很想知道不这样做是否可行。例如,在各种上下文中使用f_rec
的情况下,它可能很有用,以避免重复f(tll)
一个技巧是明确要求您需要的假设(我最近在中看到它):
哇,这个小费真不错!
let f_rec := fun pf : length (tl l) < length l => f (tl l) in
Program Fixpoint f l {measure (length l)}: list nat :=
let f_rec := fun pf : length (tl l) < length l => f (tl l) in
match hd_error l with
| Some n => n :: f_rec _
| None => []
end.
Next Obligation. destruct l; [discriminate | auto]. Qed.