我试图在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证明?手册没有提及。
答案 0 :(得分:3)
在像这样的简单情况下,您不必展开well_founded
和MR
之类的定义,而是使用适当的引理。
要处理MR
,可以在Program.Wf中使用引理measure_wf
。
要证明tuple_lt
的良好基础,您可以基于另一个关系的良好基础依靠引理来显示某个关系的良好基础。在这里,我们可以使用well_founded_lt_compat
。在其他情况下,您可能会发现其他有用的引理,例如wf_inverse_image
,well_founded_ltof
或well_founded_gtof
。
tuple_lt
的充分基础的证明变得简单。
Lemma tuple_lt_wf : well_founded tuple_lt.
Proof.
apply well_founded_lt_compat with fst.
intros ? ? []; assumption.
Defined.
第二项义务的证明也是如此。
Next Obligation.
apply measure_wf. apply tuple_lt_wf.
Defined.
(请注意,在两种情况下,如果希望由Defined
定义的函数都在Coq中进行计算,则应以Qed
而不是Program Fixpoint
结束证明(否则,它会卡住) (不透明的证明);似乎您可以用Qed
结束第一义务的证明。)
您还可以对tuple_lt
使用以下更简单的定义:
Definition tuple_lt (p1 p2 : nat * nat) := fst p1 < fst p2.
在这种情况下,有充分根据的证明是微不足道的。
Lemma tuple_lt_wf : well_founded tuple_lt.
Proof.
apply well_founded_ltof.
Defined.