1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

メルセンヌ数の基本定理の証明

Last updated at Posted at 2020-09-17

メルセンヌ数の基本定理の証明

2020_9_19 @suharahiromichi

はじめに

「メルセンヌ数 $M_{p}$ が素数のとき、pは素数である」という、メルセンヌ数の基本定理を証明します。この命題は、「逆」が成り立たないことで有名ですが、実際の証明では対偶を証明することになります。

ソースコードは以下にあります。
https://github.com/suharahiromichi/coq/blob/master/math/ssr_composite_number.v
Coq:8.17.0, MathComp:2.0.0


From mathcomp Require Import all_ssreflect.

https://github.com/suharahiromichi/coq/blob/master/common/ssromega.v
をインポートする必要があります。次の行は適宜修正してください。


From common Require Import ssromega.

Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.


問題

自然数 n が合成数なら、メルセンヌ数 $ M_{n} = 2^{n} - 1 $も合成数であることを証明します。
実際には、nが、1を越える任意のふたつの自然数に積であるとき(すなわち合成数であるとき)、$ 2^{n} -1 $ もふたつの自然数の積(合成数)であることを証明します。
また、合成数の定義は、「それより小さい、ふたつの正の整数の積で表される整数」ですが、ここでは、「ふたつの 1を越える自然数 の積で表される自然数」で証明します。もちろん、これは同値です(おまけを参照)。

証明

bigop の補題

MathComp の bigop.v の補題のうちのいくつかを総和(Σ)で使いやすい命題にしておきます([b])。


Section SUM.
  Lemma eq_sum m n a b : a =1 b ->
                         \sum_(m <= i < n)(a i) = \sum_(m <= j < n)(b j).
  Proof.
    move=> Hab.                             (* =1 は第1階の=です。 *)
    apply: eq_big_nat => i Hmn.
    by rewrite Hab.
  Qed.

  Lemma sum_distrr m n c a :
    m < n ->
    \sum_(m <= i < n)(c * (a i)) = c * (\sum_(m <= i < n)(a i)).
  Proof. by rewrite big_distrr. Qed.

  Lemma sum_add1 n a :
    \sum_(1 <= i < n.+1)(a i) = \sum_(0 <= i < n)(a i.+1).
  Proof. by rewrite big_add1 succnK. Qed.

  Lemma sum_first m n a :
    m < n ->
    \sum_(m <= i < n)(a i) = a m + \sum_(m.+1 <= i < n)(a i).
  Proof.
    move=> Hn.
    by rewrite big_ltn.
  Qed.

  Lemma sum_last m n a :
    m <= n ->
    \sum_(m <= i < n.+1)(a i) = \sum_(m <= i < n)(a i) + a n.
  Proof.
    move=> Hmn.
    by rewrite big_nat_recr.
  Qed.
End SUM.


補題

最初に補題として、[a] にも掲載されている次式を証明します。これは、a と b は自然数で、$1 \le a$ であれば成り立ちます。
$$ (2^{b} - 1) \sum_{i=0}^{a-1} 2^{i b} = 2^{a b} - 1, ただし 1 \le a $$


Section Composite_Number.

  Lemma l_e2_ab_1 a b :
    1 <= a ->
    (2^b - 1) * (\sum_(0 <= i < a) 2^(i * b)) = 2^(a * b) - 1.
  Proof.
    move=> Ha.

    (* 左辺を展開する。 *)
    rewrite mulnBl.

    (* 左辺、第1項 *)
    rewrite -sum_distrr //=.                (* 係数をΣの中に入れる。 *)
    (* Σの中身をまとめる。 *)
    have -> : \sum_(0 <= i < a) 2^b * 2^(i * b) = \sum_(0 <= i < a) 2^(i.+1 * b)
      by apply: eq_sum => i; rewrite -expnD mulnC -mulnS mulnC.
    rewrite -(sum_add1 a (fun x => 2^(x * b))). (* インデックスを1始まりにする。 *)
    rewrite [\sum_(1 <= i < a.+1) 2^(i * b)]sum_last //=. (* 最後の項をΣの外に出す。 *)
    (* \sum_(1 <= i < a) 2^(i * b) + 2^(a * b) *)

    (* 左辺、第2項 *)
    rewrite mul1n.
    rewrite [\sum_(0 <= i < a) 2^(i * b)]sum_first //=. (* 最初の項をΣの外に出す。 *)
    rewrite mul0n expn0.                                (* 2^(0*b) を 1 に書き換える。 *)
    rewrite [1 + \sum_(1 <= i < a) 2^(i * b)]addnC.
    (* - (\sum_(1 <= i < a) 2^(i * b) + 1) *)

    (* 左辺を整理する。 *)
    rewrite subnDl.
    (* 2^(a * b) - 1 *)

    (* 左辺と右辺が同じ。 *)
    done.
  Qed.


証明の概要

証明したい命題「nが、1を越える任意の2自然数に積であるとき(すなわち合成数であるとき)、$2^{n} - 1$ もふたつの自然数の積(合成数)である」
これをもうすこし噛み砕くと、aとbが1を越える任意の自然数であるとき、適当な1を越える自然数xとyが存在して、
$$ 2^{a b} - 1 = x y $$
が成り立つ、ということになります。ここで、 $ n = a b $ としています。
そして、適当な x と y について具体的に以下を代入すると、

\begin{eqnarray}
x = 2^{b} - 1
\\
y = \sum_{i=0}^{a-1} 2^{i b}
\end{eqnarray}

先に証明した補題の式が得られます。
$$ (2^{b} - 1) \sum_{i=0}^{a-1} 2^{i b} = 2^{a b} - 1 $$

値の範囲

普通は、これで「証明終わり。」とするのですが、
1を越えるaとbに対して、xとyもまた1を越えるであることを示すことも忘れてはいけません。それも、別の補題として証明しておきます。


  (* 何か所かで使う補題。 *)
  Lemma lt1_le1 a : 1 < a -> 1 <= a.       (* 1 < a -> 1 <= a *)
  Proof. move=> H. by rewrite ltnW. Qed.   (* ssromega でも解ける。 *)

  (* 1 < x を証明する補題: *)
  Lemma e2b_1_ge2 b : 1 < b -> 1 < 2^b - 1. (* 1 < b -> 1 < 2^b - 1 *)
  Proof.
    move=> H.
    rewrite ltn_subRL addn1.
    rewrite -{1}(expn1 2).
    by rewrite ltn_exp2l.
  Qed.

  (* 1 < y を証明する補題: *)  
  Lemma sum0_2_e2ib a b :
    1 < a -> 1 < b -> 1 < \sum_(0 <= i < a) 2^(i * b).
  Proof.
    move=> Ha Hb.
    rewrite sum_first; last by apply: lt1_le1.
    rewrite sum_first; last done.
    have H1 : 1 <= 2^(0 * b) by rewrite mul0n expn0.
    have H2 : 1 <= 2^(1 * b) by rewrite mul1n expn_gt0 orb_idr.
    have H3 : 0 <= \sum_(1 <= i < a) 2^(i * b) by done. (* 0以上は自明。 *)
    by ssromega.
  Qed.


証明したいもの


  Lemma l_mersenne_composite (a b : nat) :
    1 < a -> 1 < b ->
    exists (x y : nat), 1 < x /\ 1 < y /\ (x * y = 2^(a * b) - 1).
  Proof.
    move=> Ha Hb.
    exists (2^b - 1), (\sum_(0 <= i < a) 2^(i * b)).
    split; [| split].
    - by apply: e2b_1_ge2.    (* 1 < x を証明する。 *)
    - by apply: sum0_2_e2ib.  (* 1 < y を証明する。 *)
    - move/lt1_le1 in Ha.     (* 前提を 1 < a から 1 <= a にする。 *)
      by apply: l_e2_ab_1.    (* x * y = ... を証明する。 *)
  Qed.


おまけ - 合成数の定義についての補題

「ある自然数が、より小さいふたつの自然数の積で表されるとき、そのふたつの自然数は1より大きい」ということを証明します。


  Lemma l_1m1n_mmn (m n : nat) : 1 < m -> 1 < n -> m < m * n.
  Proof.
    move=> Hm Hn.
    rewrite ltn_Pmulr //.
    by ssromega.                            (* 1 < m -> 0 < m *)
  Qed.

  Lemma l_1m1n_nmn (m n : nat) : 1 < m -> 1 < n -> n < m * n.
  Proof.
    move=> Hm Hn.
    rewrite ltn_Pmull //.
    by ssromega.                            (* 1 < n -> 0 < n *)
  Qed.

  Lemma l_nmn_1m (m n : nat) : n < m * n -> 1 < m.
  Proof.
    rewrite -{1}[n]mul1n ltn_mul2r.
    by case/andP.
  Qed.

  Lemma l_mmn_1n (m n : nat) : m < m * n -> 1 < n.
  Proof.
    rewrite -{1}[m]muln1 ltn_mul2l.
    by case/andP.
  Qed.


以上をまとめると、次のようになります。


  Lemma l_composite_hypo (m n : nat) :
    ((m < m * n) && (n < m * n)) = ((1 < m) && (1 < n)).
  Proof.
    apply/andP/andP; case=> Hm Hn; split.
    - by apply: l_nmn_1m Hn.
    - by apply: l_mmn_1n Hm.
    - by apply: l_1m1n_mmn.
    - by apply: l_1m1n_nmn.
  Qed.


前提を書き直した命題で証明してみます。


  Lemma l_mersenne_composite' (a b : nat) :
    a < a * b -> b < a * b ->
    exists (x y : nat), x < x * y /\ y < x * y /\ (x * y = 2^(a * b) - 1).
  Proof.
    move/l_mmn_1n => Hb.                    (* 1 < b にする。 *)
    move/l_nmn_1m => Ha.                    (* 1 < a にする。 *)
    exists (2^b - 1), (\sum_(0 <= i < a) 2^(i * b)).
    split ; [| split].
    - apply/l_1m1n_mmn.          (* Goal を 1 < x と 1 < y にする。 *)
      + by apply: e2b_1_ge2.     (* 1 < x を証明する。 *)
      + by apply: sum0_2_e2ib.   (* 1 < y を証明する。 *)

    - apply/l_1m1n_nmn.          (* Goal を 1 < x と 1 < y にする。 *)
      + by apply: e2b_1_ge2.     (* 1 < x を証明する。 *)
      + by apply: sum0_2_e2ib.   (* 1 < y を証明する。 *)

    - move/lt1_le1 in Ha.      (* 前提を 1 < a から 1 <= a にする。 *)
      by apply: l_e2_ab_1.     (* x * y = ... を証明する。 *)
  Qed.

End Composite_Number.


参考文献

[a] https://ja.wikipedia.org/wiki/メルセンヌ数

[b] https://github.com/suharahiromichi/coq/blob/master/csm/csm_4_6_bigop.v

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?