逐步主鏈
S01 · definition
操作前
P(x):\ x\ \text{is prime},\quad x\in X操作後
Y=\{x\in X\mid P(x)\}條件:X=\{0,1,2,3,4,5,6,7,8,9\}
規則:set_builder · 依賴:G1
葉節點依據:set_builder + def_intro
把問題寫成一對 (X,Y):Y 由規格 P 以集合建構式定義,x∈Y 表示 x∈X 且 P(x)。Y 是正確答案的描述,與任何候選程序無關;D1、D2、D3 只是之後要拿來和 Y 比對的實作(MKO 第一段:規格與實作分開)。
S02 · implies
操作前
Y=\{x\in X\mid P(x)\}操作後
Y=\{2,3,5,7\}條件:X\ \text{finite and listed}
規則:prime_def · 依賴:S01, G1
葉節點依據:prime_def + divides_def + numeric_evaluation + finite_exhaustion
對 X 的十個元素逐一判定 P(x)。X 是明示有限集合,所以逐一檢查全部元素就得到 Y 的完整列表;判定細節在 S02.1 到 S02.3。結果 Y={2,3,5,7}。
S03 · equivalent
操作前
D\ \text{decides}\ (X,Y)\ \text{in}\ W操作後
(\forall x\in X,\ D\ \text{terminates on}\ x)\ \wedge\ (\forall x\in X,\ D(x)=\mathrm{true}\iff x\in Y)條件:W\ \text{fixed (G2)}
規則:def_unfold · 依賴:G2, mko_decision_problem_def
葉節點依據:def_unfold + mko_decision_problem_def
展開 MKO 的 decider 定義,得到兩個條款:(T) 對每個 x∈X 都終止;(C) 終止時輸出 true 恰好對應 x∈Y。兩個條款都量化在整個 X 上,而且都相對於固定的模型 W。之後分別為 D1 證明 (T) 與 (C)。
S04 · implies
操作前
x\in\{0,1\}操作後
D_1\ \text{terminates on}\ x,\ D_1(x)=\mathrm{false},\ x\notin Y條件:x<2
規則:while_semantics · 依賴:G3, S02.1
葉節點依據:while_semantics + prime_def
x=0 或 x=1 時,第 1 行的測試 x<2 為真,D1 立刻 return false,在有限步內終止。由 S02.1,這兩個輸入確實不在 Y,所以輸出與規格一致。
S05 · theorem_application
操作前
x\in X,\ x\ge 2
操作後
D_1\ \text{terminates on}\ x\ \text{after at most}\ x-2\le 7\ \text{loop passes}條件:x\ge 2
規則:L_loop_term · 依賴:G3, G1
葉節點依據:while_semantics + nat_induction + order_basics
套用引理 L_loop_term:x≥2 時迴圈最多完成 x−2 輪,之後測試 d<x 失敗,執行第 4 行 return true,或在某輪中提早 return false。X 中最大的 x 是 9,所以最多 7 輪。與 S04 合起來,D1 對每個 x∈X 都終止,條款 (T) 成立。
S06 · theorem_application
操作前
x\ge 2
操作後
\text{at every test of}\ d<x:\ 2\le d\le x\ \wedge\ \neg\exists e\,(2\le e<d\ \wedge\ e\mid x)條件:x\ge 2
規則:L_loop_inv · 依賴:G3
葉節點依據:nat_induction + divides_def + while_semantics
套用迴圈不變量 L_loop_inv:每次測試 d<x 時,d 在 2 與 x 之間,且 2 到 d−1 之間沒有 x 的因數。不變量把「迴圈已經檢查過什麼」寫成一個命題,讓 S07、S08 能由程式的出口推出 x 是否為質數。
S07 · implies
操作前
D_1(x)=\mathrm{true}操作後
x\in Y
條件:無
規則:prime_def · 依賴:S04, S06, G3
葉節點依據:prime_def + order_basics + while_semantics
D1 只在第 4 行輸出 true,而且由 S04,x<2 時不會到達第 4 行,所以 x≥2。到達第 4 行表示測試 d<x 失敗;不變量給 d≤x,依三分律得 d=x。不變量再給出:沒有 e 滿足 2≤e<x 且 e∣x,即 2 到 x−1 之間沒有因數。依 prime_def,x 是質數,x∈Y。
S08 · implies
操作前
D_1(x)=\mathrm{false}操作後
x\notin Y
條件:無
規則:case_analysis · 依賴:S04, S06, G3
葉節點依據:case_analysis + prime_def + divides_def + while_semantics
D1 只在兩處輸出 false。情況一:第 1 行,x<2,不是質數(S04)。情況二:迴圈中某次 x mod d=0;此時測試 d<x 剛通過,且不變量給 d≥2,所以 d 是滿足 2≤d≤x−1 的因數,x 不是質數。兩種情況涵蓋所有 return false 的位置,所以 x∉Y。
S09 · implies
操作前
D_1(x)=\mathrm{true}\Rightarrow x\in Y,\quad D_1(x)=\mathrm{false}\Rightarrow x\notin Y操作後
\forall x\in X,\ D_1(x)=\mathrm{true}\iff x\in Y條件:D_1\ \text{terminates on}\ x
規則:iff_intro · 依賴:S04, S05, S07, S08
葉節點依據:iff_intro + contrapositive + forall_intro
取任意 x∈X。由 S04、S05,D1 在 x 上終止,輸出 true 或 false 其中之一。(⇒) 是 S07。(⇐) 若 x∈Y,輸出不可能是 false,否則由 S08 得 x∉Y,矛盾;所以輸出是 true。兩向合成 ⇔;x 是任意的,依全稱推廣對所有 x∈X 成立,條款 (C) 成立。
S10 · implies
操作前
(\forall x\in X,\ D_1\ \text{terminates})\ \wedge\ (\forall x\in X,\ D_1(x)=\mathrm{true}\iff x\in Y)操作後
D_1\ \text{decides}\ (X,Y)\ \text{in}\ W條件:無
規則:and_intro_elim · 依賴:S03, S04, S05, S09
葉節點依據:and_intro_elim + def_unfold + case_analysis
條款 (T) 由 S04(x<2)與 S05(x≥2)合成,這兩種情況涵蓋 X 的每個元素;條款 (C) 是 S09。合取後依 S03 的等價折回定義:D1 是 (X,Y) 在 W 中的 decider。
S11 · implies
操作前
x=0,1,2,3,4,5,6,7,8,9
操作後
D_1(x)=\mathrm{F},\mathrm{F},\mathrm{T},\mathrm{T},\mathrm{F},\mathrm{T},\mathrm{F},\mathrm{T},\mathrm{F},\mathrm{F}\ =\ [x\in Y]條件:X\ \text{finite and listed}
規則:finite_exhaustion · 依賴:S02, S10, G3
葉節點依據:finite_exhaustion + numeric_evaluation + while_semantics
交叉核對:手動執行 D1 於全部十個輸入。例如 x=9:d=2 時 9 mod 2=1,d=3 時 9 mod 3=0,return false;x=7:d=2 到 6 的餘數 1、1、3、2、1,之後 d=7 測試失敗,return true。完整表格與 Y={2,3,5,7} 的成員表逐項相同。因為 X 有限且已全部列出,這張表本身也是條款 (C) 在 X 上的完整核對;但它只涵蓋 X(MKO 假設 a2)。
S12 · implies
操作前
x=4\in X:\ D_1\ \text{would return false}操作後
D_2\ \text{does not terminate on}\ 4\ \Rightarrow\ \neg(\forall x\in X,\ D_2\ \text{terminates})條件:無
規則:quantifier_negation · 依賴:S03, S02.2, G3
葉節點依據:quantifier_negation + while_semantics + divides_def
在 x=4 上,D1 的程式文字於 d=2 時得到 4 mod 2=0,會 return false;D2 此時改為執行 while true do skip,永不 return。所以存在 x∈X 使 D2 不終止,依量詞否定,條款 (T) 不成立,D2 不是 decider。D2 恰好在 Y 上以 true 停止,是 Y 的半決定程序;這正是 MKO 指出的誤解:只保證在 yes-instance 上接受,尚不足以保證總 decider;D2 真正違反的是對 no-instance 的終止性,而 D1 也只接受 yes-instance,卻會在其餘輸入拒絕並終止。
S13 · implies
操作前
D_3(x)=[x\bmod 2=1]
操作後
D_3(9)=\mathrm{true},\ 9\notin Y\ \Rightarrow\ \neg(\forall x\in X,\ D_3(x)=\mathrm{true}\iff x\in Y)條件:無
規則:quantifier_negation · 依賴:S03, S02, G3
葉節點依據:quantifier_negation + numeric_evaluation
D3 在有限步內終止,所以 (T) 成立;但 9 mod 2=1,D3(9)=true,而 9∉Y(S02.2);另外 D3(2)=false 而 2∈Y。存在反例,條款 (C) 不成立,D3 不是 decider。值得注意:在樣本 {3,4,5,6,7,8} 上 D3 與 Y 完全一致,所以抽樣一致不足以證明整個論域(MKO 第二段)。
局部子步與引理
S02.1 · implies
操作前
x\in\{0,1\}操作後
0\notin Y,\ 1\notin Y
條件:x<2
規則:prime_def · 依賴:S01
葉節點依據:prime_def + order_basics
質數必須 ≥2;0 與 1 都小於 2,所以 P(0)、P(1) 為假,0、1 不在 Y。
S02.2 · implies
操作前
x\in\{4,6,8,9\}操作後
4=2\cdot 2,\ 6=2\cdot 3,\ 8=2\cdot 4,\ 9=3\cdot 3\ \Rightarrow\ 4,6,8,9\notin Y
條件:2\le d\le x-1
規則:divides_def · 依賴:S01
葉節點依據:divides_def + prime_def + numeric_evaluation
依整除定義,2∣4、2∣6、2∣8、3∣9,而且 2 與 3 都滿足 2≤d≤x−1。依 prime_def 的等價形式,這四個數不是質數,不在 Y。
S02.3 · implies
操作前
x\in\{2,3,5,7\}操作後
2,3,5,7\in Y
條件:x\ge 2; x\bmod d\ne 0\ \text{for}\ 2\le d\le x-1
規則:prime_def · 依賴:S01
葉節點依據:prime_def + divides_def + numeric_evaluation
x=2 時 2≤d≤1 的範圍是空的;3 mod 2=1;5 除以 2、3、4 的餘數為 1、2、1;7 除以 2、3、4、5、6 的餘數為 1、1、3、2、1。這些數都 ≥2 且在 2 到 x−1 之間沒有因數,依 prime_def 都是質數。
S05.1 · implies
操作前
d=2\ \text{at the first test}操作後
\text{each pass either returns or replaces}\ d\ \text{by}\ d+1條件:無
規則:while_semantics · 依賴:G3, while_semantics
葉節點依據:while_semantics
第 2 行令 d=2。迴圈本體只有兩種結果:若 x mod d=0 則 return false,執行結束;否則執行 d:=d+1。本體中沒有其他改變 d 的敘述。
S05.2 · induction_step
操作前
\text{after}\ k\ \text{completed passes without return:}\ d=2+k操作後
\text{a pass starts only if}\ 2+k<x,\ \text{so at most}\ x-2\ \text{passes complete}條件:x\ge 2
規則:nat_induction · 依賴:S05.1
葉節點依據:nat_induction + order_basics + while_semantics
對 k 歸納:k=0 時 d=2;若完成 k 輪後 d=2+k,再完成一輪就是 d=2+(k+1)(S05.1)。第 k 輪開始前要先通過測試 d<x,即 2+k<x,也就是 k≤x−3,所以可能的輪次只有 k=0 到 x−3,共 x−2 輪。最後一輪完成後 d=x,測試失敗,第 4 行 return。因此執行在有限步內結束,引理 L_loop_term 得證。
S06.1 · induction_base
操作前
\text{first test},\ d=2操作後
2\le 2\le x\ \wedge\ \{e:2\le e<2\}=\varnothing條件:x\ge 2
規則:nat_induction · 依賴:G3, while_semantics
葉節點依據:nat_induction + order_basics
第一次測試時 d=2。因為 x≥2,有 2≤d≤x;滿足 2≤e<2 的整數 e 不存在,所以「沒有這樣的 e 整除 x」空真成立。不變量在初始時成立。
S06.2 · induction_step
操作前
2\le d\le x,\ \neg\exists e\,(2\le e<d\wedge e\mid x),\ d<x,\ x\bmod d\ne 0
操作後
d'=d+1:\ 2\le d'\le x\ \wedge\ \neg\exists e\,(2\le e<d'\wedge e\mid x)
條件:d<x; x\bmod d\ne 0
規則:nat_induction · 依賴:S06.1, divides_def, while_semantics
葉節點依據:nat_induction + divides_def + order_basics + while_semantics
設某次測試時不變量成立,測試 d<x 為真,且本輪沒有 return,也就是 x mod d≠0,故 d∤x。本輪後 d′=d+1。由 d<x 得 d′≤x,且 d′≥3≥2。滿足 2≤e<d′ 的 e 要嘛 e<d(依假設不整除 x),要嘛 e=d(剛驗證不整除 x)。所以下一次測試時不變量仍成立。S06.1 與 S06.2 合起來證得 L_loop_inv。