程序不动点的Coq单体

程序不动点的Coq单体,coq,theorem-proving,totality,Coq,Theorem Proving,Totality,对于程序定点s,是否有类似策略siml 特别是,一个人如何证明下面的琐碎陈述 Program Fixpoint bla (n:nat) {measure n} := match n with | 0 => 0 | S n' => S (bla n') end. Lemma obvious: forall n, bla n = n. induction n. reflexivity. (* I'm stuck here. For a normal fixpoint, I could

对于
程序定点
s,是否有类似策略
siml

特别是,一个人如何证明下面的琐碎陈述

Program Fixpoint bla (n:nat) {measure n} :=
match n with
| 0 => 0
| S n' => S (bla n')
end.

Lemma obvious: forall n, bla n = n. 
induction n. reflexivity.
(* I'm stuck here. For a normal fixpoint, I could for instance use 
simpl. rewrite IHn. reflexivity. But here, I couldn't find a tactic 
transforming bla (S n) to S (bla n).*)

显然,这个玩具示例不需要
程序固定点
,但我在更复杂的环境中面临同样的问题,我需要手动证明
程序固定点
的终止

我不习惯使用
程序
,所以可能有更好的解决方案,但这就是我通过展开
bla
得出的,看到它是使用
Fix_sub
内部定义的,并通过使用
搜索关于Fix_sub
查看关于该函数的定理

Lemma obvious: forall n, bla n = n.
Proof.
intro n ; induction n.
 reflexivity.
 unfold bla ; rewrite fix_sub_eq ; simpl ; fold (bla n).
 rewrite IHn ; reflexivity.

(* This can probably be automated using Ltac *)
 intros x f g Heq.
  destruct x.
  reflexivity.
  f_equal ; apply Heq.
Qed.
在您的实际示例中,您可能希望引入约化引理,这样您就不必每次都做相同的工作。例如:

Lemma blaS_red : forall n, bla (S n) = S (bla n).
Proof.
intro n.
 unfold bla ; rewrite fix_sub_eq ; simpl ; fold (bla n).
 reflexivity.

(* This can probably be automated using Ltac *)
 intros x f g Heq.
  destruct x.
  reflexivity.
  f_equal ; apply Heq.
Qed.

这样,下次你有一个bla(S),你可以简单地用同样的想法重写blaS(S),
bla(S)

,你可以陈述
bla的方程引理:
对于所有n,blan=match n与| 0=>0 | sn'=>S(blan')end。
这真的是最好的答案吗?当您必须手动编写简化引理时,这是否会使大型函数的
程序固定点
相对繁琐?更新的插件,如
等式
会为您生成简化引理。