Isabelle/Isar(その20)
次に帰納法の2つ目のサブゴールに移ります.
next case (Suc m)
と入力すると,Outputは
proof (state): step 7
this:
1 ≤ m ⟹ a m = 2 ^ m - 1
1 ≤ Suc mgoal (1 subgoal):
1. ⋀n. (1 ≤ n ⟹ a n = 2 ^ n - 1) ⟹ 1 ≤ Suc n ⟹ a (Suc n) = 2 ^ Suc n - 1
さらに使えるfactsをprint_factsで確認すると
facts:
:
a 1 = 1
1 ≤ Suc m
1 ≤ m ⟹ a m = 2 ^ m - 1
∀n. 1 ≤ n ⟹ a (Suc n) = 2 * a n + 1
Suc:
1 ≤ m ⟹ a m = 2 ^ m - 1
1 ≤ Suc m
Suc.IH: 1 ≤ m ⟹ a m = 2 ^ m - 1
Suc.prems: 1 ≤ Suc m
assms:
a 1 = 1
∀n. 1 ≤ n ⟹ a (Suc n) = 2 * a n + 1
this:
1 ≤ m ⟹ a m = 2 ^ m - 1
1 ≤ Suc m
となっています.これらから
show "?case"
すなわち
proof (prove): step 8
goal (1 subgoal):
1. a (Suc m) = 2 ^ Suc m - 1
を導く訳ですが,mについてはSuc.premsという当たり前のことしか判らず,Suc.IHを直ちに用いることはできませんので,mが0の場合と,1以上つまりSuc kと表せる場合とに分けて証明します.
それには,上記の?caseに対して,自然数の変数mが0か否かで場合を分けるという方法を
proof (cases m "?case")
のように適用して,print_casesにより得られた場合を確認すると
cases: 0: let "?case" = "a (Suc m) = 2 ^ Suc m - 1" assume "m = 0" Suc: fix nat_ let "?case" = "a (Suc m) = 2 ^ Suc m - 1" assume "m = Suc nat_"
となっていますので
case 0
と入力すれば,m = 0 がthisになるので
thus "?case" using assms(1)
と入力すれば
proof (prove): step 12 using this: m = 0 a 1 = 1 goal (1 subgoal): 1. a (Suc m) = 2 ^ Suc m - 1
なので,そのまま
by simp
と処理できます(これが事実上の帰納法のベースステップ).引き続き
next case (Suc k) thus "?case" using Suc.IH assms(2)
と入力すればOutputは
proof (prove): step 17
using this:
m = Suc k
1 ≤ ?n ⟹ a (Suc ?n) = 2 * a ?n + 1
1 ≤ m ⟹ a m = 2 ^ m - 1goal (1 subgoal):
1. a (Suc m) = 2 ^ Suc m - 1
ですから,?nにSuc kつまり1以上であるmがマッチすることはsimpにも判り
by simp qed
とすれば
show a (Suc m) = 2 ^ Suc m - 1
Successful attempt to solve goal by exported rule:
(1 ≤ ?m2 ⟹ a ?m2 = 2 ^ ?m2 - 1) ⟹
(1 ≤ Suc ?m2) ⟹ a (Suc ?m2) = 2 ^ Suc ?m2 - 1
proof (state): step 18this:
a (Suc m) = 2 ^ Suc m - 1goal:
No subgoals!
のように帰納法の2つ目のサブゴールが消えて
とすれば証明が完成します.
以上をまとめれば
lemma fixes "a" :: "nat => real" and "n" :: "nat" assumes "a 1 = 1" and "!!n. 1 <= n ==> a (Suc n) = 2 * a n + 1" shows "1 <= n ==> a n = 2 ^ n - 1" proof (induction n) case 0 thus "?case" by simp next case (Suc m) show "?case" proof (cases m "?case") case 0 thus "?case" using assms(1) by simp next case (Suc k) thus "?case" using assms(2) Suc.IH by simp qed qed
となります.
なお,単にa 1 = 1にするのが目的なら
lemma "(a::nat=>real) 1 = 1 & (ALL n. a (Suc n) = 2 * a n + 1) --> a n = 2 ^ n - 1" by (induction n, auto)
あるいは
lemma fixes "a" :: "nat => real" and "n" :: "nat" assumes "a 0 = 0" and "ALL n. a (Suc n) = 2 * a n + 1" shows "a n = 2 ^ n - 1" proof (induction n) case 0 show "?case" using assms(1) by simp next case (Suc m) thus "?case" using assms(2) by simp qed
のようにすれば充分です.