我想证明计算a
和b
之间的累积和会终止。
我使用Acc lt x
术语来表示递归减少,就像这样
Require Import Omega.
Lemma L1 : forall a b, a<b -> (b-(1+a)) < (b-a).
intros; omega. Qed.
Lemma term_lemma: forall a b, Acc lt (b-a) -> Acc lt (b-(1+a)).
intros; inversion H; clear H; constructor; intros; apply H0; omega.
Defined.
Fixpoint cumsum a b (H: Acc lt (b-a)) {struct H} : nat.
refine (
match lt_dec a b with
| left a_lt_b => a + cumsum (1+a) b _
| right a_ge_b => if beq_nat a b then a else 0
end
).
apply (term_lemma _ _ H).
Qed.
它会清除所有子目标,但不会在Qed
语句中进行类型检查。 Coq抱怨道:
Recursive definition of cumsum is ill-formed
Recursive call to cumsum has principal argument equal to
"term_lemma a b H" instead of a subterm of "H".
我想我应该以某种方式使用L1
来表明递归调用中H
项中的参数实际上更小,但我该怎么做?
答案 0 :(得分:2)
因为您在使用H
重新构建类似内容之前反转constructor ; apply H0
,所以您得到的term_lemma
模式匹配等同于您想要的模式,但会混淆Coq的终止检查器(您可以使用Print NAME.
检查术语。)
如果您记得a < b
感谢您在lt_dec a b
上的案例分析,则无需执行所有此反转业务。通过让你的引理采取额外的论证,你现在可以使用Acc
可见性谓词的严格子项来获得你的见证:
Require Import Omega.
Lemma term_lemma: forall a b, a < b -> Acc lt (b-a) -> Acc lt (b-(1+a)).
intros a b altb [H]; apply H; omega.
Defined.
Fixpoint cumsum a b (H: Acc lt (b-a)) {struct H} : nat.
refine (
match lt_dec a b with
| left a_lt_b => a + cumsum (1+a) b _
| right a_ge_b => if beq_nat a b then a else 0
end
).
apply (term_lemma _ _ a_lt_b H).
Defined.