程序修复点的Coq简化

oul*_*ler 9 theorem-proving coq totality

有喜欢的战术什么simplProgram FixpointS'

特别是,如何证明以下琐碎的陈述?

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).*)
Run Code Online (Sandbox Code Playgroud)

显然,Program Fixpoint这个玩具示例没有必要,但我在一个更复杂的设置中面临同样的问题,我需要证明Program Fixpoint手动终止.

gal*_*ais 6

我不习惯使用它,Program因此可能有更好的解决方案,但这是我通过展开了解的bla,看到它是使用内部定义的,Fix_sub并使用来查看有关该函数的定理SearchAbout 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.
Run Code Online (Sandbox Code Playgroud)

在您的实际示例中,您可能需要引入归约引理,这样您就不必每次都做相同的工作。例如:

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.
Run Code Online (Sandbox Code Playgroud)

这样,下次您有一个时bla (S _),您可以简单地进行操作rewrite blaS_red

  • 这真的是最好的答案吗?当您必须手动编写归约引理时,这是否会使“Program Fixpoint”对于大型函数而言相对乏味? (3认同)
  • 同样,您可以为bla陈述等式引理:`forall n,bla n =用|匹配n。0 => 0 | S n'=> S(bla n')端。 (2认同)
  • 诸如“方程式”之类的最新插件会为您生成还原引理。 (2认同)