Goal and scope
Take the input set X={0,1,2,3,4,5,6,7,8,9}, the specification P(x): 'x is prime', and the yes-instance set Y={x∈X ∣ P(x)}. In the explicit while-program model W, prove that the trial-division procedure D1 terminates on every x∈X and that D1(x)=true exactly when x∈Y, so D1 is a decider for (X,Y); then show that D2, which halts only on yes-instances, and D3, which tests only parity, are not deciders.
Works inside the MKO's scope: a fixed finite input set X with Y⊆X (assumption a1) and an explicit computational model and input representation (assumption a2). The conclusion covers this X only; it draws no conclusion about computability or undecidability over all natural numbers, does not treat the general theory of semi-decision procedures, and does not change the canonical MKO or its English edition.
Main derivation
S01 · definition
Before
P(x):\ x\ \text{is prime},\quad x\in XAfter
Y=\{x\in X\mid P(x)\}Conditions: X=\{0,1,2,3,4,5,6,7,8,9\}
Rule: set_builder · Uses: G1
Leaf basis: set_builder + def_intro
Write the problem as a pair (X,Y): Y is defined from the specification P by set-builder notation, and x∈Y means x∈X and P(x). Y describes the correct answers and does not depend on any candidate program; D1, D2 and D3 are implementations to be compared with Y later (MKO paragraph 1: specification and implementation are separate).
S02 · implies
Before
Y=\{x\in X\mid P(x)\}After
Y=\{2,3,5,7\}Conditions: X\ \text{finite and listed}
Rule: prime_def · Uses: S01, G1
Leaf basis: prime_def + divides_def + numeric_evaluation + finite_exhaustion
Decide P(x) for each of the ten elements of X. X is an explicitly listed finite set, so checking every element yields the complete list of Y; the details are in S02.1 to S02.3. The result is Y={2,3,5,7}.
S03 · equivalent
Before
D\ \text{decides}\ (X,Y)\ \text{in}\ WAfter
(\forall x\in X,\ D\ \text{terminates on}\ x)\ \wedge\ (\forall x\in X,\ D(x)=\mathrm{true}\iff x\in Y)Conditions: W\ \text{fixed (G2)}
Rule: def_unfold · Uses: G2, mko_decision_problem_def
Leaf basis: def_unfold + mko_decision_problem_def
Unfold the MKO's definition of a decider into two clauses: (T) termination on every x∈X; (C) the output is true exactly when x∈Y. Both clauses quantify over all of X and both are relative to the fixed model W. (T) and (C) are then proved separately for D1.
S04 · implies
Before
x\in\{0,1\}After
D_1\ \text{terminates on}\ x,\ D_1(x)=\mathrm{false},\ x\notin YConditions: x<2
Rule: while_semantics · Uses: G3, S02.1
Leaf basis: while_semantics + prime_def
For x=0 or x=1 the test x<2 on line 1 is true, so D1 returns false immediately and terminates after finitely many steps. By S02.1 these two inputs are indeed not in Y, so the output agrees with the specification.
S05 · theorem_application
Before
x\in X,\ x\ge 2
After
D_1\ \text{terminates on}\ x\ \text{after at most}\ x-2\le 7\ \text{loop passes}Conditions: x\ge 2
Rule: L_loop_term · Uses: G3, G1
Leaf basis: while_semantics + nat_induction + order_basics
Apply Lemma L_loop_term: for x≥2 the loop completes at most x−2 passes, after which the test d<x fails and line 4 returns true, unless some pass returns false earlier. The largest x in X is 9, so at most 7 passes. Together with S04, D1 terminates on every x∈X, so clause (T) holds.
S06 · theorem_application
Before
x\ge 2
After
\text{at every test of}\ d<x:\ 2\le d\le x\ \wedge\ \neg\exists e\,(2\le e<d\ \wedge\ e\mid x)Conditions: x\ge 2
Rule: L_loop_inv · Uses: G3
Leaf basis: nat_induction + divides_def + while_semantics
Apply the loop invariant L_loop_inv: whenever d<x is tested, d lies between 2 and x and x has no divisor between 2 and d−1. The invariant records as a proposition what the loop has already checked, so that S07 and S08 can infer from the exit point whether x is prime.
S07 · implies
Before
D_1(x)=\mathrm{true}After
x\in Y
Conditions: none
Rule: prime_def · Uses: S04, S06, G3
Leaf basis: prime_def + order_basics + while_semantics
D1 outputs true only on line 4, and by S04 line 4 is not reached when x<2, so x≥2. Reaching line 4 means the test d<x failed; the invariant gives d≤x, so by trichotomy d=x. The invariant then says no e with 2≤e<x divides x, i.e. x has no divisor between 2 and x−1. By prime_def x is prime, so x∈Y.
S08 · implies
Before
D_1(x)=\mathrm{false}After
x\notin Y
Conditions: none
Rule: case_analysis · Uses: S04, S06, G3
Leaf basis: case_analysis + prime_def + divides_def + while_semantics
D1 outputs false in only two places. Case one: line 1, x<2, not prime (S04). Case two: in the loop with x mod d=0; the test d<x has just passed and the invariant gives d≥2, so d is a divisor with 2≤d≤x−1 and x is not prime. The two cases cover every 'return false' in the program, so x∉Y.
S09 · implies
Before
D_1(x)=\mathrm{true}\Rightarrow x\in Y,\quad D_1(x)=\mathrm{false}\Rightarrow x\notin YAfter
\forall x\in X,\ D_1(x)=\mathrm{true}\iff x\in YConditions: D_1\ \text{terminates on}\ x
Rule: iff_intro · Uses: S04, S05, S07, S08
Leaf basis: iff_intro + contrapositive + forall_intro
Take any x∈X. By S04 and S05, D1 terminates on x with output true or false. (⇒) is S07. (⇐) If x∈Y, the output cannot be false, for then S08 would give x∉Y, a contradiction; so the output is true. The two directions give ⇔; since x was arbitrary, generalization gives it for all x∈X, so clause (C) holds.
S10 · implies
Before
(\forall x\in X,\ D_1\ \text{terminates})\ \wedge\ (\forall x\in X,\ D_1(x)=\mathrm{true}\iff x\in Y)After
D_1\ \text{decides}\ (X,Y)\ \text{in}\ WConditions: none
Rule: and_intro_elim · Uses: S03, S04, S05, S09
Leaf basis: and_intro_elim + def_unfold + case_analysis
Clause (T) combines S04 (x<2) and S05 (x≥2), and these two cases cover every element of X; clause (C) is S09. Their conjunction folds back through the equivalence of S03: D1 is a decider for (X,Y) in W.
S11 · implies
Before
x=0,1,2,3,4,5,6,7,8,9
After
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]Conditions: X\ \text{finite and listed}
Rule: finite_exhaustion · Uses: S02, S10, G3
Leaf basis: finite_exhaustion + numeric_evaluation + while_semantics
Cross-check: run D1 by hand on all ten inputs. For example x=9: at d=2, 9 mod 2=1; at d=3, 9 mod 3=0, return false; x=7: the remainders for d=2 to 6 are 1, 1, 3, 2, 1, then the test fails at d=7 and it returns true. The full table agrees entry by entry with membership in Y={2,3,5,7}. Because X is finite and fully listed, this table is by itself a complete check of clause (C) on X; but it covers X only (MKO assumption a2).
S12 · implies
Before
x=4\in X:\ D_1\ \text{would return false}After
D_2\ \text{does not terminate on}\ 4\ \Rightarrow\ \neg(\forall x\in X,\ D_2\ \text{terminates})Conditions: none
Rule: quantifier_negation · Uses: S03, S02.2, G3
Leaf basis: quantifier_negation + while_semantics + divides_def
On x=4 the text of D1 finds 4 mod 2=0 at d=2 and would return false; D2 instead executes 'while true do skip' and never returns. So some x∈X makes D2 fail to terminate; by quantifier negation clause (T) fails and D2 is not a decider. D2 halts with true exactly on Y, so it is a semi-decision procedure for Y; this is the misconception the MKO names: accepting exactly the yes-instances alone does not ensure a total decider. D2 fails termination on no-instances, while D1 also accepts exactly the yes-instances but rejects and halts on the remaining inputs.
S13 · implies
Before
D_3(x)=[x\bmod 2=1]
After
D_3(9)=\mathrm{true},\ 9\notin Y\ \Rightarrow\ \neg(\forall x\in X,\ D_3(x)=\mathrm{true}\iff x\in Y)Conditions: none
Rule: quantifier_negation · Uses: S03, S02, G3
Leaf basis: quantifier_negation + numeric_evaluation
D3 terminates after finitely many steps, so (T) holds; but 9 mod 2=1 gives D3(9)=true while 9∉Y (S02.2), and also D3(2)=false while 2∈Y. A counterexample exists, so clause (C) fails and D3 is not a decider. Note that on the sample {3,4,5,6,7,8} D3 agrees with Y completely, so agreement on a sample does not prove agreement on the whole domain (MKO paragraph 2).
Substeps and lemmas
S02.1 · implies
Before
x\in\{0,1\}After
0\notin Y,\ 1\notin Y
Conditions: x<2
Rule: prime_def · Uses: S01
Leaf basis: prime_def + order_basics
A prime must be at least 2; 0 and 1 are less than 2, so P(0) and P(1) are false and 0, 1 are not in Y.
S02.2 · implies
Before
x\in\{4,6,8,9\}After
4=2\cdot 2,\ 6=2\cdot 3,\ 8=2\cdot 4,\ 9=3\cdot 3\ \Rightarrow\ 4,6,8,9\notin Y
Conditions: 2\le d\le x-1
Rule: divides_def · Uses: S01
Leaf basis: divides_def + prime_def + numeric_evaluation
By the definition of divisibility, 2∣4, 2∣6, 2∣8 and 3∣9, and in each case 2≤d≤x−1. By the equivalent form in prime_def these four numbers are not prime and are not in Y.
S02.3 · implies
Before
x\in\{2,3,5,7\}After
2,3,5,7\in Y
Conditions: x\ge 2; x\bmod d\ne 0\ \text{for}\ 2\le d\le x-1
Rule: prime_def · Uses: S01
Leaf basis: prime_def + divides_def + numeric_evaluation
For x=2 the range 2≤d≤1 is empty; 3 mod 2=1; the remainders of 5 by 2, 3, 4 are 1, 2, 1; the remainders of 7 by 2, 3, 4, 5, 6 are 1, 1, 3, 2, 1. Each of these numbers is at least 2 and has no divisor between 2 and x−1, so by prime_def each is prime.
S05.1 · implies
Before
d=2\ \text{at the first test}After
\text{each pass either returns or replaces}\ d\ \text{by}\ d+1Conditions: none
Rule: while_semantics · Uses: G3, while_semantics
Leaf basis: while_semantics
Line 2 sets d=2. The loop body has only two outcomes: if x mod d=0 it returns false and the run ends; otherwise it executes d:=d+1. No other statement in the body changes d.
S05.2 · induction_step
Before
\text{after}\ k\ \text{completed passes without return:}\ d=2+kAfter
\text{a pass starts only if}\ 2+k<x,\ \text{so at most}\ x-2\ \text{passes complete}Conditions: x\ge 2
Rule: nat_induction · Uses: S05.1
Leaf basis: nat_induction + order_basics + while_semantics
Induct on k: for k=0, d=2; if d=2+k after k completed passes, one more completed pass gives d=2+(k+1) (S05.1). Pass number k can start only if the test d<x passes, that is 2+k<x, i.e. k≤x−3, so the possible passes are k=0 to x−3, which is x−2 passes. After the last one d=x, the test fails and line 4 returns. So the run ends after finitely many steps, proving Lemma L_loop_term.
S06.1 · induction_base
Before
\text{first test},\ d=2After
2\le 2\le x\ \wedge\ \{e:2\le e<2\}=\varnothingConditions: x\ge 2
Rule: nat_induction · Uses: G3, while_semantics
Leaf basis: nat_induction + order_basics
At the first test d=2. Since x≥2 we have 2≤d≤x; no integer e satisfies 2≤e<2, so 'no such e divides x' holds vacuously. The invariant holds initially.
S06.2 · induction_step
Before
2\le d\le x,\ \neg\exists e\,(2\le e<d\wedge e\mid x),\ d<x,\ x\bmod d\ne 0
After
d'=d+1:\ 2\le d'\le x\ \wedge\ \neg\exists e\,(2\le e<d'\wedge e\mid x)
Conditions: d<x; x\bmod d\ne 0
Rule: nat_induction · Uses: S06.1, divides_def, while_semantics
Leaf basis: nat_induction + divides_def + order_basics + while_semantics
Suppose the invariant holds at a test, the test d<x is true, and the pass does not return, that is x mod d≠0, so d∤x. After the pass d′=d+1. From d<x we get d′≤x, and d′≥3≥2. Any e with 2≤e<d′ has either e<d (not a divisor by hypothesis) or e=d (just shown not to divide x). So the invariant holds at the next test. S06.1 and S06.2 together prove L_loop_inv.