√素数が有理数でないこと(その1)
前回の性質を少し一般化したものの tactics による証明です.
まず(その1)として,有理数が既約分数で表せることを定理にしておきます.
# g `!x. rational x ==> (?p q. &p * &p = x pow 2 * &q * &q /\ coprime (p,q))`;; val it : goalstack = 1 subgoal (1 total) `!x. rational x ==> (?p q. &p * &p = x pow 2 * &q * &q /\ coprime (p,q))`
rational の定義は整数によるものですが,ここでは自然数による
# RATIONAL_ALT;; val it : thm = |- !x. rational x <=> (?p q. ~(q = 0) /\ abs x = &p / &q)
で簡約します.
# e( SIMP_TAC [RATIONAL_ALT] THEN REPEAT STRIP_TAC );; val it : goalstack = 1 subgoal (1 total) 0 [`~(q = 0)`] 1 [`abs x = &p / &q`] `?p q. &p * &p = x pow 2 * &q * &q /\ coprime (p,q)`
この仮定のp,qをgcd (p,q)で割ったものを結論に用いればcoprime (p,q)なので証明が完成する流れです.
要になる既存の定理は
# GCD_COPRIME_EXISTS;; val it : thm = |- !a b. ~(gcd (a,b) = 0) ==> (?a' b'. a = a' * gcd (a,b) /\ b = b' * gcd (a,b) /\ coprime (a',b'))
ですので
# e( SUBGOAL_TAC "" `~(gcd (p,q) = 0)` [ASM_MESON_TAC [GCD_ZERO]] );; 0..0..1..solved at 4 val it : goalstack = 1 subgoal (1 total) 0 [`~(q = 0)`] 1 [`abs x = &p / &q`] 2 [`~(gcd (p,q) = 0)`] `?p q. &p * &p = x pow 2 * &q * &q /\ coprime (p,q)`
のように前件を用意(ここでMESONに参照させたのは
# GCD_ZERO;; val it : thm = |- !a b. gcd (a,b) = 0 <=> a = 0 /\ b = 0
です)して,MATCH_MPで後件を仮定に加えます(多重の特称量化の消去はCHOOSE_TACでは面倒ですので,MP_TAC で導入してシステムに STRIP させます).
# e( FIRST_ASSUM (MP_TAC o (MATCH_MP GCD_COPRIME_EXISTS)) THEN STRIP_TAC );; val it : goalstack = 1 subgoal (1 total) 0 [`~(q = 0)`] 1 [`abs x = &p / &q`] 2 [`~(gcd (p,q) = 0)`] 3 [`p = a' * gcd (p,q)`] 4 [`q = b' * gcd (p,q)`] 5 [`coprime (a',b')`] `?p q. &p * &p = x pow 2 * &q * &q /\ coprime (p,q)`
ここまでくれば,結論のp,qとして仮定のa',b'が使えることは,計算で判りますが,その計算が実は面倒です.
つまり,結論にある等式は実数についてのもの,仮定0,2,3,4にある等式は自然数ついてのものなので,それらを同時には処理できないのです.このような場合には,まず自然数から実数への単射 & を施した実数についての等式を REAL_FIELD などで証明し,更に
# [REAL_POW2_ABS; REAL_INJ; REAL_MUL];; val it : thm list = [|- !x. abs x pow 2 = x pow 2; |- !m n. &m = &n <=> m = n; |- !m n. &m * &n = &(m * n)]
を参照させて SIMP_RULE で簡約すれば
let lem1 = SIMP_RULE [REAL_POW2_ABS; REAL_INJ; REAL_MUL] (REAL_FIELD `~(&q = &0) ==> abs x = &p / &q ==> ~(&(gcd (p,q)) = &0) ==> &p = &a' * &(gcd (p,q)) ==> &q = &b' * &(gcd (p,q)) ==> &a' * &a' = abs x pow 2 * &b' * &b'`);; 2 basis elements and 0 critical pairs ... 17 basis elements and 0 critical pairs val lem1 : thm = |- ~(q = 0) ==> abs x = &p / &q ==> ~(gcd (p,q) = 0) ==> p = a' * gcd (p,q) ==> q = b' * gcd (p,q) ==> &(a' * a') = x pow 2 * &(b' * b')
が得られます.最後の&(a' * a'),&(b' * b')はREAL_MULの副作用で,同値の両辺を入れ替えた GSYM REAL_MUL を参照させ,もう一度簡約すれば &a' * &a',&b' * &b'に出来ますが,それは最後にMESONに任せましょう.
後はこのlem1の前件たちが現在のサブゴールの仮定を満たしていることをUNDISCH_ALL により HOL Light に判らせれば,MP_TAC でも ASSUME_TAC でも
# e( MP_TAC (UNDISCH_ALL lem1) );; val it : goalstack = 1 subgoal (1 total) 0 [`~(q = 0)`] 1 [`abs x = &p / &q`] 2 [`~(gcd (p,q) = 0)`] 3 [`p = a' * gcd (p,q)`] 4 [`q = b' * gcd (p,q)`] 5 [`coprime (a',b')`] `&(a' * a') = x pow 2 * &(b' * b') ==> (?p q. &p * &p = x pow 2 * &q * &q /\ coprime (p,q))`
のように後件が導入でき,先ほどの簡約の補正も含め,MESONに託せば
# e( ASM_MESON_TAC [REAL_MUL] );; 0..0..2..5..13..26..44..73..103..144..208..303..428..614..833..solved at 101 7 val it : goalstack = No subgoals
となります.
# let RATIONAL_COPRIME = top_thm () ;; val ( RATIONAL_COPRIME ) : thm = |- !x. rational x ==> (?p q. &p * &p = x pow 2 * &q * &q /\ coprime (p,q))
まとめれば
# let RATIONAL_COPRIME = prove (`!x. rational x ==> (?p q. &p * &p = x pow 2 * &q * &q /\ coprime (p,q))`, SIMP_TAC [RATIONAL_ALT] THEN REPEAT STRIP_TAC THEN SUBGOAL_TAC "" `~(gcd (p,q) = 0)` [ASM_MESON_TAC [GCD_ZERO]] THEN FIRST_ASSUM (MP_TAC o (MATCH_MP GCD_COPRIME_EXISTS)) THEN STRIP_TAC THEN MP_TAC (UNDISCH_ALL lem1) THEN ASM_MESON_TAC [REAL_MUL]);; 0..0..1..solved at 4 0..0..2..5..13..26..44..73..103..144..208..303..428..614..833..solved at 1017 val ( RATIONAL_COPRIME ) : thm = |- !x. rational x ==> (?p q. &p * &p = x pow 2 * &q * &q /\ coprime (p,q))
となります.
なお,MESONでは難しいですが,Prover9 ならこの程度はノーヒントで証明してくれます.
# [REAL_EQ_RDIV_EQ; REAL_NZ_IMP_LT; REAL_MUL; REAL_INJ; REAL_MUL_AC; REAL_EQ_RMUL_IMP; POW_2; REAL_POW2_ABS];; val it : thm list = [|- !x y z. &0 < z ==> (x = y / z <=> x * z = y); |- !n. ~(n = 0) ==> &0 < &n; |- !m n. &m * &n = &(m * n); |- !m n. &m = &n <=> m = n; |- m * n = n * m /\ (m * n) * p = m * n * p /\ m * n * p = n * m * p; |- !x y z. ~(z = &0) /\ x * z = y * z ==> x = y; |- !x. x pow 2 = x * x; |- !x. abs x pow 2 = x pow 2] # let lem1 = PV9 [REAL_EQ_RDIV_EQ; REAL_NZ_IMP_LT; REAL_MUL; REAL_INJ; REAL_MUL_AC; REAL_EQ_RMUL_IMP; POW_2; REAL_POW2_ABS] `~(q = 0) ==> abs x = &p / &q ==> ~(gcd (p,q) = 0) ==> p = a' * gcd (p,q) ==> q = b' * gcd (p,q) ==> &a' * &a' = x pow 2 * &b' * &b'`;; -------- Proof 1 -------- THEOREM PROVED ------ process 4804 exit (max_proofs) ------ CPU time (user): 12.187 val lem1 : thm = |- ~(q = 0) ==> abs x = &p / &q ==> ~(gcd (p,q) = 0) ==> p = a' * gcd (p,q) ==> q = b' * gcd (p,q) ==> &a' * &a' = x pow 2 * &b' * &b' # let RATIONAL_COPRIME = PV9 [RATIONAL_ALT; GCD_ZERO; GCD_COPRIME_EXISTS; REAL_MUL; lem1] `!x. rational x ==> (?p q. &p * &p = x pow 2 * &q * &q /\ coprime (p,q))`;; -------- Proof 1 -------- THEOREM PROVED ------ process 5676 exit (max_proofs) ------ CPU time (user): 32.764 val ( RATIONAL_COPRIME ) : thm = |- !x. rational x ==> (?p q. &p * &p = x pow 2 * &q * &q /\ coprime (p,q))
結局のところ,定理自動証明システムのパフォーマンスは,preproved theoremsの質と量,そしてそれを扱うproverの処理能力で定まる訳です.