减少依赖类型的参数

时间:2018-08-22 10:27:59

标签: coq dependent-type termination

在处理非依赖类型时,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}.

现在,说我想让一个固定点递归地使用这样的列表(这里的两个引理并不有趣。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可能可以解决此问题,但是由于在依赖类型的投影上减小它必须是一种非常常见的模式,因此我想知道管理这种情况的“正确”方法是什么。

1 个答案:

答案 0 :(得分:2)

您可以使用我在this answer中提到的一种方法(包括Program)解决此问题。 如果将列表和证明脱钩,则可以使用普通递归来完成:

Fixpoint my_fixpoint (l: list A) (pf : Forall P l) (dummy_arg: A) : bool :=
match l as x return Forall P x -> bool with
| nil => fun _ => true
| hd::tl => fun h => my_fixpoint tl (Forall_tl P hd tl h) dummy_arg
end pf.