19 Real analysis (1)

 次の2つのパッケージの使用例を示します.OCamlの#useの代わりに,HOL Lightのneedsを使うとファイルのリロードが防げます.

needs "Library/analysis.ml";;
needs "Library/transc.ml";;

 まずは,チェビシェフの多項式

# let cheb = define
`(!x. cheb 0 x = &1) /\
(!x. cheb 1 x = x) /\
(!n x. cheb (n + 2) x = &2 * x * cheb (n + 1) x - cheb n x)`;;
val cheb : thm =
|- (!x. cheb 0 x = &1) /\
(!x. cheb 1 x = x) /\
(!n x. cheb (n + 2) x = &2 * x * cheb (n + 1) x - cheb n x)

余弦のn倍角公式

# g `!n x. cheb n (cos x) = cos(&n * x)`;;
val it : goalstack = 1 subgoal (1 total)

`!n x. cheb n (cos x) = cos (&n * x)`

を与えることの証明です.証明には2ステップの仮定をとる帰納法を用いますが,先に証明した

# num2_INDUCTION;;
val it : thm =
|- !P. P 0 /\ P 1 /\ (!n. P n /\ P (SUC n) ==> P (SUC (SUC n)))
==> (!n. P n)

ではなく

# [ADD1; GSYM ADD_ASSOC];;
val it : thm list =
[|- !m. SUC m = m + 1; |- !m n p. (m + n) + p = m + n + p]

を参照して,SUCを消去した

# let CHEB_INDUCT = prove
(`!P. P 0 /\ P 1 /\ (!n. P n /\ P(n + 1) ==> P(n + 2)) ==> !n. P n`,
GEN_TAC THEN STRIP_TAC THEN
SUBGOAL_THEN `!n. P n /\ P(n + 1)` (fun th -> MESON_TAC[th]) THEN
INDUCT_TAC THEN ASM_SIMP_TAC[ADD1; GSYM ADD_ASSOC] THEN
ASM_SIMP_TAC[ARITH]);;
0..0..solved at 2
val ( CHEB_INDUCT ) : thm =
|- !P. P 0 /\ P 1 /\ (!n. P n /\ P (n + 1) ==> P (n + 2)) ==> (!n. P n)

を用います.なお,上の

SUBGOAL_THEN `!n. P n /\ P(n + 1)` (fun th -> MESON_TAC[th])

の部分は MESON_TAC[s] により t が証明できるとき
SUBGOAL_THEN s (fun s -> MESON_TAC[s]):
({A1;...;An} ?- t) |-> ({A1;...;An} ?- s)
例えば

# g `a \/ b`;;
Warning: Free variables in goal: a, b
val it : goalstack = 1 subgoal (1 total)

`a \/ b`

# e (SUBGOAL_THEN `a:bool` (fun s -> MESON_TAC[s]) );;
val it : goalstack = 1 subgoal (1 total)

`a`

のように,t をその十分条件である s に置き換えるテクニックであり,例えば

# g `a \/ b`;;
Warning: Free variables in goal: a, b
val it : goalstack = 1 subgoal (1 total)

`a \/ b`

# e (MATCH_MP_TAC (MESON[]`a==>(a\/b)`) );;
val it : goalstack = 1 subgoal (1 total)

`a`

でも結果は同じですが,MESON_TACを用いれば,sからtを導く際にASMを参照して ASM_MESON_TAC[s] とすることも可能です.

 num2_INDUCTION の改訂版を幾つか書いておきます.

# let num2_INDUCTION = prove(
`!P. P 0 /\ P 1 /\ (!n. P n /\ P (n+1) ==> P (n+2) ) ==> (!n. P n)` ,
( REPEAT STRIP_TAC THEN SUBGOAL_THEN `!n. P n /\ P (n+1)` (fun th -> MESON_TA
C[th]) ) THEN
( INDUCT_TAC ) THEN
( ASM_SIMP_TAC[ADD1;GSYM ADD_ASSOC] ) THEN
( ASM_SIMP_TAC[ARITH] ) );;
0..0..solved at 2
val num2_INDUCTION : thm =
|- !P. P 0 /\ P 1 /\ (!n. P n /\ P (n + 1) ==> P (n + 2)) ==> (!n. P n)
#
let num2_INDUCTION = prove(
`!P. P 0 /\ P 1 /\ (!n. P n /\ P (n+1) ==> P (n+2)) ==> (!n. P n)`,
REPEAT STRIP_TAC THEN
SUBGOAL_THEN `!n. P n /\ P (n+1)` ASSUME_TAC THENL
[ INDUCT_TAC THEN ASM_SIMP_TAC[ADD1;GSYM ADD_ASSOC] THEN ASM_SIMP_TAC[ARITH];
ASM_SIMP_TAC[] ] );;
val num2_INDUCTION : thm =
|- !P. P 0 /\ P 1 /\ (!n. P n /\ P (n + 1) ==> P (n + 2)) ==> (!n. P n)