Coq:证明n和(S n)的乘积是偶数

时间:2016-11-24 17:16:37

标签: functional-programming coq

鉴于程序even,我想为所有自然数even (n * (S n)) = true证明n

使用归纳,对于案例true,很容易看出n = 0。但是,案例(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的“初学者”子集来证明这一点吗?

5 个答案:

答案 0 :(得分:4)

这是一种更先进的感应原理可能有用的情况。在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等一样的策略。

答案 1 :(得分:3)

我想使用mathcomp lib提供更短的证明:

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

答案 2 :(得分:2)

另一个版本,本着@ ejgallego的回答。 让我们给出偶数谓词的另一个定义。这样做的目的是通过简单的感应简单地进行校样,因此不需要使用my_list=['dirty room', 'do to i', 'dormitory', 'dry to or i', 'i to rod', 'or to i dry', 'rod to i', 'room i dry', 'root i dry', 'to rod i'] result = list(filter(lambda x: x.count(' ') < 2, my_list)) 。主要思想是我们将证明pair_induction的某些属性,然后我们将使用even2Nat.even在扩展上相等的事实来转移{{1}的属性1}}到even2

even2

我们假设Nat.evenRequire Import Coq.Bool.Bool. Fixpoint even2 (n : nat) : bool := match n with | O => true | S n' => negb (even2 n') end. 在扩展上相等。

Nat.even

even2的一些分布引理:

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.

最后,我们可以使用even2Lemma 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.even

答案 3 :(得分:1)

使用标准库的简短版本:

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.

答案 4 :(得分:1)

对于它的价值,这是我对解决方案的看法。基本的想法是,而不是证明谓词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.