coq - 使用 Omega 证明 Coq 中的引理

标签 coq proof induction

我正在尝试使用 Omega 在 Coq 中进行证明。我花了很多时间在上面,但什么也没想到。不得不说我是Coq的新手,对这种语言不是很放心,也没有太多经验。但我正在努力。

这是我要证明的代码:

Require Import Arith Omega.

Fixpoint div2 (n : nat) :=
 match n with
   S (S p) => S (div2 p)
 | _ => 0
 end.

Fixpoint mod2 (n : nat) :=
 match n with
   S (S p) => mod2 p
 | x => x
 end.

为了证明这一点,我认为首先通过归纳法证明这个引理会有所帮助:

Lemma div2_eq : forall n, 2 * div2 n + mod2 n = n.

然后这个,使用 omega 和 div2_eq :

Lemma div2_le : forall n, div2 n <= n.

但我没能走得更远。

有人知道怎么办吗?

最佳答案

您可以轻松地从函数 div2mod2 导出归纳原理,如下所示:

Functional Scheme div2_ind := Induction for div2 Sort Prop.
Functional Scheme mod2_ind := Induction for mod2 Sort Prop.

div2_indmod2_ind 有或多或少的类型:

forall P1,
  P1 0 0 ->
  P1 1 0 ->
  (forall n1, P1 n1 (div2 n1) -> P1 (S (S n1)) (S (div2 n1))) ->
  forall n1, P1 n1 (div2 n1)

forall P1,
  P1 0 0 ->
  P1 1 1 ->
  (forall n1, P1 n1 (mod2 n1) -> P1 (S (S n1)) (mod2 n1)) ->
  forall n1, P1 n1 (mod2 n1)

要应用这些定理,您可以方便地编写 functional induction (div2 n)functional induction (mod2 n),您通常可以编写 induction n.

但是更强的归纳原理与这些函数相关联:

Lemma nat_ind_alt : forall P1 : nat -> Prop,
  P1 0 ->
  P1 1 ->
  (forall n1, P1 n1 -> P1 (S (S n1))) ->
  forall n1, P1 n1.
Proof.
intros P1 H1 H2 H3. induction n1 as [[| [| n1]] H4] using lt_wf_ind.
  info_auto.
  info_auto.
  info_auto.
Qed.

事实上,任何函数的定义域都是有用的归纳原理的线索。例如,与函数 plus : nat -> nat -> natmult : nat -> nat -> nat 的域相关的归纳原则只是结构归纳.这让我想知道为什么 Functional Scheme 不只是生成这些更通用的原则。

在任何情况下,你的定理证明都变成了:

Lemma div2_eq : forall n, 2 * div2 n + mod2 n = n.
Proof.
induction n as [| | n1 H1] using nat_ind_alt.
  simpl in *. omega.
  simpl in *. omega.
  simpl in *. omega.
Qed.

Lemma div2_le : forall n, div2 n <= n.
Proof.
induction n as [| | n1 H1] using nat_ind_alt.
  simpl. omega.
  simpl. omega.
  simpl. omega.
Qed.

您应该熟悉函数归纳法,但更重要的是,您应该真正熟悉有根据的归纳法。

关于coq - 使用 Omega 证明 Coq 中的引理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13690147/

相关文章:

security - 理论上是否有可能设计一个可证明不可破解的硬件/软件系统?

types - 如何在agda中通过W类型进行编码?

coq - 如何在 Coq 中使用自定义归纳原理?

coq - 如何在 Coq 中切换当前目标?

coq - 如何在证明过程中将单个统一变量变成目标

string - 使用 Ogden’s Lemma 与常规 Pumping Lemma 进行上下文无关语法

coq - 如何解构/泛化程序重写的匹配语句

coq - 为什么 Coquelicot 会弄乱我的子弹?

proof - 在 Idris REPL 中使用 cong 进行实验