√素数が有理数でないこと(その2)

以下,表題の証明です.

# g `!s. prime s ==> ~rational (sqrt (&s))` ;;
val it : goalstack = 1 subgoal (1 total)

`!s. prime s ==> ~rational (sqrt (&s))`

まず,全称量化を外し,前件を仮定に廻して,結論を(その1)の定理でリライトします.

# e( GEN_TAC THEN DISCH_TAC THEN
     DISCH_THEN (MP_TAC o (MATCH_MP RATIONAL_COPRIME)) );;
val it : goalstack = 1 subgoal (1 total)

  0 [`prime s`]

`(?p q. &p * &p = sqrt (&s) pow 2 * &q * &q /\ coprime (p,q)) ==> F`

更に根号を外します.

# e( SIMP_TAC [REAL_POS; SQRT_POW_2; REAL_MUL; REAL_INJ] );;
val it : goalstack = 1 subgoal (1 total)

  0 [`prime s`]

`~(?p q. p * p = s * q * q /\ coprime (p,q))`

あとは「dividesにより結論にある等式の左辺はsで割り切れ,仮定によりsは素数なのでPRIME_DIVPRODが使えて,s divides p.再びdividesにより(s * x) * s * x = s * q * qとなり,MULT_AC と PRIME の ~(p = 0) によりMULT_LCANCELが適用できて s * x * x = q * q.従って,pと同様にs divides qとなるが,これはcoprime (p,q)に反する.」

# [divides; PRIME_DIVPROD; MULT_AC; PRIME; MULT_LCANCEL; coprime];;
val it : thm list =
  [|- a divides b <=> (?x. b = a * x);
   |- !p a b. prime p /\ p divides a * b ==> p divides a \/ p divides b;
   |- m * n = n * m /\ (m * n) * p = m * n * p /\ m * n * p = n * m * p;
   |- !p. prime p <=>
          ~(p = 0) /\ ~(p = 1) /\ (!m. 0 < m /\ m < p ==> coprime (p,m));
   |- !a b c. ~(a = 0) /\ a * b = a * c ==> b = c;
   |- coprime (a,b) <=> (!d. d divides a /\ d divides b ==> d = 1)]

という証明をPV9がノーヒントで完成してくれます.

# e( ASM_PV9_TAC it );;
-------- Proof 1 --------

THEOREM PROVED

------ process 5536 exit (max_proofs) ------
CPU time (user): 0.90300000002
val it : goalstack = No subgoals

名前を付けて出来上がり.

# let SQRT_PRIME_NOT_RATIONAL = top_thm();;
val ( SQRT_PRIME_NOT_RATIONAL ) : thm =
  |- !s. prime s ==> ~rational (sqrt (&s))

proveにまとめると

prove
 (`!s. prime s ==> ~rational (sqrt (&s))`,
  GEN_TAC THEN DISCH_TAC THEN
  DISCH_THEN (MP_TAC o (MATCH_MP RATIONAL_COPRIME)) THEN
  SIMP_TAC [REAL_POS; SQRT_POW_2; REAL_MUL; REAL_INJ] THEN
  ASM_PV9_TAC[divides; PRIME_DIVPROD; MULT_AC; PRIME; MULT_LCANCEL; coprime]);;

MESON版

prove
 (`!s. prime s ==> ~rational (sqrt (&s))`,
  GEN_TAC THEN DISCH_TAC THEN
  DISCH_THEN (MP_TAC o (MATCH_MP RATIONAL_COPRIME)) THEN
  SIMP_TAC [REAL_POS; SQRT_POW_2; REAL_MUL; REAL_INJ] THEN STRIP_TAC THEN
  SUBGOAL_TAC "" `s divides p` [ASM_MESON_TAC[divides; PRIME_DIVPROD]] THEN
  FIRST_ASSUM (CHOOSE_TAC o (SIMP_RULE [divides])) THEN
  SUBGOAL_TAC "" `q * q = s * x * x:num`
              [ASM_MESON_TAC[PRIME; MULT_AC; MULT_LCANCEL]] THEN
  ASM_MESON_TAC [divides; PRIME_DIVPROD; PRIME; coprime]);;