当处理非依赖类型时,Coq(通常)推断哪个参数在固定点中减少。但是,依赖类型的情况并非如此。
例如,考虑下面的示例,其中我有一个
A_list
它确保属性P对列表中的所有元素(类型a)都有效:
Require Import Coq.Lists.List.
Variable A: Type.
Variable P: A -> Prop.
Definition A_list := {a: list A | Forall P a}.
现在,假设我想要一个固定点递归地处理这样一个列表(这里的2个引理并不有趣)。dummy_arg用于模拟使用多个参数。)
Lemma Forall_tl: forall P (h: A) t, Forall P (h::t) -> Forall P t.
Admitted.
Lemma aux: forall (l1: list A) l2 P, l1 = l2 -> Forall P l1 -> Forall P l2.
Admitted.
Fixpoint my_fixpoint (l: A_list) (dummy_arg: A) :=
match (proj1_sig l) as x return proj1_sig l = x -> bool with
| nil => fun _ => true
| hd::tl =>
fun h =>
my_fixpoint (exist (Forall P) tl (Forall_tl P hd tl (aux _ _ _ h (proj2_sig l)))) dummy_arg
end eq_refl.
正如所料,它返回一个错误“无法猜测fix的递减参数”,因为严格地说,我们并没有递减参数。尽管如此,我们显然在减少
proj1_sig l
(嵌入在
sig
这也许可以用
Program Fixpoint
s、 但是,由于减少依赖类型的投影肯定是一种非常常见的模式,我想知道管理这种情况的“正确”方法是什么。