【问题标题】:Coq: Proving that the product of n and (S n) is evenCoq:证明 n 和 (S n) 的乘积是偶数
【发布时间】:2016-11-24 17:16:36
【问题描述】:

给定过程even,我想证明even (n * (S n)) = true对于所有自然数n

使用归纳法,对于n = 0 的情况,很容易看出这是true。但是,(S n) * (S (S n)) 的情况很难简化。

我考虑过证明 even (m * n) = even m /\ even n 的引理,但这似乎并不容易。

另外,很容易看出如果even n = true iff。 even (S n) = false.

Fixpoint even (n: nat) : bool :=
  match n with
  | O => true
  | 1 => false
  | S (S n') => even n'
  end.

有人可以提示如何使用 Coq 的“初学者”子集来证明这一点吗?

【问题讨论】:

  • 我将开始证明even n -> even (n * m)(适用于所有m)。那么由于even n <-> (even (S n) = false)n*m = m*n 你应该能够证明even (n * (S n))。不确定这是否简化了任何事情......
  • 你认为“even n -> even (n * m)”容易证明吗?
  • 也许吧。考虑一下:n * (S m') = n + n * m' 通过归纳假设n*m' 是偶数,even n /\ even m -> even (n+m) 产生了论文。
  • 谢谢,但是 "even (n + m)" 似乎很难证明(虽然乍一看很容易)。
  • 为什么?如果n = O 然后使用simpl 可以得到n+m = m,这甚至是假设。如果n = (S (S n')) 然后使用simpl 你会得到S (S (n' + m)),它通过归纳假设+even n <-> even (S ( S n)) 产生论文的事实。你只需要even n -> (n = O \/ n = S (S n') /\ even n') 似乎并不难归纳证明。

标签: functional-programming coq


【解决方案1】:

在这种情况下,更高级的归纳原理可能会很有用。在this answer中有简要描述。

Require Import Coq.Arith.Arith.
Require Import Coq.Bool.Bool.    

Lemma pair_induction (P : nat -> Prop) :
  P 0 -> P 1 -> (forall n, P n -> P (S n) -> P (S (S n))) ->
  forall n, P n.
Proof.
  intros ? ? ? n. enough (P n /\ P (S n)) by tauto.
  induction n; intuition.
Qed.

现在,让我们定义几个辅助引理。它们是显而易见的,可以使用pair_induction 原理和一些自动证明轻松证明。

Lemma even_mul2 : forall n, Nat.even (2 * n) = true.
Proof.
  induction n; auto.
  now replace (2 * S n) with (2 + 2 * n) by ring.
Qed.

Lemma even_add_even : forall m n,
  Nat.even m = true ->
  Nat.even (m + n) = Nat.even n.
Proof.
  now induction m using pair_induction; auto.
Qed.

Lemma even_add_mul2 : forall m n,
  Nat.even (2 * m + n) = Nat.even n.
Proof.
  intros; apply even_add_even, even_mul2.
Qed.

Lemma even_S : forall n,
  Nat.even (S n) = negb (Nat.even n).
Proof.
  induction n; auto.
  simpl (Nat.even (S (S n))).   (* not necessary -- just to make things clear *)
  apply negb_sym. assumption.
Qed.

以下引理展示了如何在乘法上“分配”even。它在证明我们的主要目标方面起着重要作用。几乎总是泛化有很大帮助。

Lemma even_mult : forall m n,
  Nat.even (m * n) = Nat.even m || Nat.even n.
Proof.
  induction m using pair_induction; simpl; auto.
  intros n. replace (n + (n + m * n)) with (2 * n + m * n) by ring.
  now rewrite even_add_mul2.
Qed.

现在,目标的证明是微不足道的

Goal forall n, Nat.even (n * (S n)) = true.
  intros n. now rewrite even_mult, even_S, orb_negb_r.
Qed.

有人可以提示如何使用 Coq 的“初学者”子集来证明这一点吗?

您可以认为这是一个提示,因为它揭示了可能证明的一般结构。自动策略可能会被“手动”策略取代,例如rewriteapplydestruct 等。

【讨论】:

  • 证明中的orb是什么?
  • 真的需要配对感应吗?
  • (1) 您可以发出以下查询:Print orb. 来检查它是什么。它是布尔“或”。当然你可以不用对归纳法——记住,它是用户定义的,它不是一些隐藏的 Coq 机制。这只是加强归纳假设的一种方法。
  • @Shuzheng 我已经简化了目标的证明。如果您将even 定义为Fixpoint even (n: nat) : bool := match n with | O => true | S n' => negb (even n') end.,则证明可能会更简单
【解决方案2】:

我想使用 mathcomp 库提供一个更短的证明:

From mathcomp Require Import all_ssreflect all_algebra.

Lemma P n : ~~ odd (n * n.+1).
Proof. by rewrite odd_mul andbN. Qed.

odd_mul 由简单归纳证明,odd_add 也是如此。

【讨论】:

  • 这里odd的定义与问题中的even相比具有不同的结构,这就是为什么简单归纳在这种情况下效果很好。
【解决方案3】:

另一个版本,本着@ejgallego 的回答。 让我们为偶数谓词给出另一个定义。这样做的目的是使简单归纳的证明变得容易,因此不需要使用pair_induction。主要思想是,我们要证明even2 的一些性质,然后我们将利用Nat.eveneven2 外延相等的事实将even2 的性质转移到Nat.even 上。

Require Import Coq.Bool.Bool.

Fixpoint even2 (n : nat) : bool :=
  match n with
  | O => true
  | S n' => negb (even2 n')
  end.

让我们证明Nat.eveneven2 在扩展上是相等的。

Lemma even_S n :
  Nat.even (S n) = negb (Nat.even n).
Proof. induction n; auto. apply negb_sym; assumption. Qed.

Lemma even_equiv_even2 n :
  Nat.even n = even2 n.
Proof. induction n; auto. now rewrite even_S, IHn. Qed.

even2 的一些分布引理:

Lemma even2_distr_add m n :
  even2 (m + n) = negb (xorb (even2 m) (even2 n)).
Proof.
  induction m; simpl.
  - now destruct (even2 n).
  - rewrite IHm. now destruct (even2 m); destruct (even2 n).
Qed.

Lemma even2_distr_mult m n :
  even2 (m * n) = even2 m || even2 n.
Proof.
  induction m; auto; simpl.
  rewrite even2_distr_add, IHm.
  now destruct (even2 m); destruct (even2 n).
Qed.

最后,我们能够证明我们的目标,使用 Nat.eveneven2 之间的相等性。

Goal forall n, Nat.even (n * (S n)) = true.
  intros n.
  now rewrite even_equiv_even2, even2_distr_mult, orb_negb_r.
Qed.

【讨论】:

  • 我很难证明“even_add_even”。我在问题中附上了我的部分证明。这里“nat_ind2”是你的“pair_induction”。你能给我一个提示如何进行吗?
  • simpl. rewrite IH_m'. reflexivity. simpl in H. apply H.
【解决方案4】:

使用标准库的简短版本:

Require Import Coq.Arith.Arith.

Goal forall n, Nat.even (n * (S n)) = true.
  intros n.
  now rewrite Nat.even_mul, Nat.even_succ, Nat.orb_even_odd.
Qed.

【讨论】:

    【解决方案5】:

    对于它的价值,这是我对解决方案的看法。基本思想是,不是证明谓词P n,而是证明P n /\ P (S n),这是等价的,但第二个公式允许使用简单的归纳。

    这是完整的证明:

    Require Import Nat.
    Require Import Omega.
    
    Definition claim n := even (n * (S n)) = true.
    
    (* A technical Lemma, needed in the proof *)
    Lemma tech: forall n m, even n = true -> even (n + 2*m) = true.
    Proof.
      intros. induction m.
      * simpl. replace (n+0) with n; intuition.
      * replace (n + 2 * S m) with (S (S (n+2*m))); intuition.
    Qed.
    
    (* A simple identity, that Coq needs help to prove *)
    Lemma ident: forall n, 
        (S (S n) * S (S (S n))) = (S n * S( S n) + 2*(S (S n))).
        (* (n+2)*(n+3) = (n+1)*(n+2) + 2*(n+2) *)
    Proof.
      intro.
      replace (S (S (S n))) with ((S n) + 2) by intuition.
      remember (S (S n)) as m.
      replace (m * (S n + 2)) with ((S n + 2) * m) by intuition.
      intuition.
    Qed.
    
    (* The claim to be proved by simple induction *)
    Lemma nsn: forall n, claim n /\ claim (S n).
    Proof.
      intros.
      unfold claim.
      induction n.
      *  intuition.
      *  intuition. rewrite ident. apply tech; auto.
    Qed.     
    
    (* The final result is now a simple corollary *)
    Theorem thm: forall n, claim n.
    Proof.
      apply nsn.
    Qed.
    

    【讨论】:

    • 谢谢,这是一个很好的证明:-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-12
    • 1970-01-01
    • 2017-07-10
    • 1970-01-01
    • 2012-09-29
    相关资源
    最近更新 更多