これは、より進歩した誘導原理が有用な場合である。簡単には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.
簡単です誰かがコックの「初心者」のサブセットを使用してこれを証明する方法についてのヒントを与えることはできますか?
考えられるプルーフの一般的な構造を明らかにしているので、これはヒントと考えることができます。自動戦術は、rewrite
、apply
、destruct
などのような「手動」戦術に置き換えることができます。私はmathcomp libにを使用して短い証明貢献したいと思います
その'でもN:
はここで完全な証拠です。そして 'n∩n= m * n'でも' even(n *(S n)) 'を証明できるはずです。しかし、これが何かをシンプルにするかどうかは分かりません... – Bakuriu
"n - > even(n * m)"でも簡単に証明できると思いますか? – Shuzheng
おそらく。帰納的仮説「n * m」による「n *(S m ')= n + n * m」は偶数であり、「n/\ even m - > even(n + m)論文。 – Bakuriu