【发布时间】:2019-04-16 09:06:56
【问题描述】:
我试图在 Coq 中创建一个函数,它有一个非常复杂的终止参数。为方便起见,我可以编写函数,使其具有自然数作为第一个参数,以便数字或它后面的参数在结构上更小。
当尝试使用嵌套修复方法对两个参数进行递归时,Coq 抱怨包含递减数语义的证明参数不是归纳类型。
我可能可以手动进行有根据的递归,但我想使用 Program Fixpoint 或 Equations。使用 Program Fixpoint,我得到了一个非常丑陋的有根据的证明版本。下面是一个演示丑陋的最小代码示例。
Require Import Program Omega.
Inductive tuple_lt : (nat * nat) -> (nat * nat) -> Prop :=
fst_lt : forall a b c d, a < c -> tuple_lt (a, b) (c, d).
Program Fixpoint f (a : nat) (b : nat) {measure (a, b) (tuple_lt)} :=
match a with
| 0 => 0
| S n => f n b
end.
Next Obligation.
apply fst_lt. auto.
Qed.
Next Obligation.
unfold well_founded. unfold MR.
义务如下所示:
forall a : {_ : nat & nat}, Acc (fun x y : {_ : nat & nat} => tuple_lt (projT1 x, projT2 x) (projT1 y, projT2 y)) a
我能否以某种方式将Acc tuple_lt 的证明转换为丑陋的证明或避免生成它?
标准库中是否有关于两个参数的结构递归的证明?
我什至如何使用方程式编写手动 WF 证明?手册没有提到这一点。
【问题讨论】:
-
我回答了帖子的主要问题。我没有评论第二段,我不明白,我也没有处理方程。
-
关于方程式的情况,你可以有类似下面的东西(不确定我是否理解正确,但这是你对原来问题的修复,对吧?):
Equations foo p1 p2 : return_type by wf (size1 p1 + size2 p2) :=所以基本上你有措施对于您认为会减少的每个参数(size1和size2),只需检查总和(或者如果您愿意,您可以做一些更复杂的事情......)。方程式通常会设法自动检查递归调用是否正常(否则您必须证明它)。
标签: coq