48 |
48 |
49 |
49 |
50 (** Injectivity properties and induction **) |
50 (** Injectivity properties and induction **) |
51 |
51 |
52 (*Mathematical induction*) |
52 (*Mathematical induction*) |
53 val major::prems = goal Nat.thy |
53 val major::prems = Goal |
54 "[| n: nat; P(0); !!x. [| x: nat; P(x) |] ==> P(succ(x)) |] ==> P(n)"; |
54 "[| n: nat; P(0); !!x. [| x: nat; P(x) |] ==> P(succ(x)) |] ==> P(n)"; |
55 by (rtac ([nat_def, nat_bnd_mono, major] MRS def_induct) 1); |
55 by (rtac ([nat_def, nat_bnd_mono, major] MRS def_induct) 1); |
56 by (blast_tac (claset() addIs prems) 1); |
56 by (blast_tac (claset() addIs prems) 1); |
57 qed "nat_induct"; |
57 qed "nat_induct"; |
58 |
58 |
60 fun nat_ind_tac a prems i = |
60 fun nat_ind_tac a prems i = |
61 EVERY [res_inst_tac [("n",a)] nat_induct i, |
61 EVERY [res_inst_tac [("n",a)] nat_induct i, |
62 rename_last_tac a ["1"] (i+2), |
62 rename_last_tac a ["1"] (i+2), |
63 ares_tac prems i]; |
63 ares_tac prems i]; |
64 |
64 |
65 val major::prems = goal Nat.thy |
65 val major::prems = Goal |
66 "[| n: nat; n=0 ==> P; !!x. [| x: nat; n=succ(x) |] ==> P |] ==> P"; |
66 "[| n: nat; n=0 ==> P; !!x. [| x: nat; n=succ(x) |] ==> P |] ==> P"; |
67 by (rtac (major RS (nat_unfold RS equalityD1 RS subsetD) RS UnE) 1); |
67 by (rtac (major RS (nat_unfold RS equalityD1 RS subsetD) RS UnE) 1); |
68 by (DEPTH_SOLVE (eresolve_tac [singletonE,RepFunE] 1 |
68 by (DEPTH_SOLVE (eresolve_tac [singletonE,RepFunE] 1 |
69 ORELSE ares_tac prems 1)); |
69 ORELSE ares_tac prems 1)); |
70 qed "natE"; |
70 qed "natE"; |
71 |
71 |
72 val prems = goal Nat.thy "n: nat ==> Ord(n)"; |
72 Goal "n: nat ==> Ord(n)"; |
73 by (nat_ind_tac "n" prems 1); |
73 by (nat_ind_tac "n" [] 1); |
74 by (REPEAT (ares_tac [Ord_0, Ord_succ] 1)); |
74 by (REPEAT (ares_tac [Ord_0, Ord_succ] 1)); |
75 qed "nat_into_Ord"; |
75 qed "nat_into_Ord"; |
76 |
76 |
77 Addsimps [nat_into_Ord]; |
77 Addsimps [nat_into_Ord]; |
78 |
78 |
133 (** Variations on mathematical induction **) |
133 (** Variations on mathematical induction **) |
134 |
134 |
135 (*complete induction*) |
135 (*complete induction*) |
136 val complete_induct = Ord_nat RSN (2, Ord_induct); |
136 val complete_induct = Ord_nat RSN (2, Ord_induct); |
137 |
137 |
138 val prems = goal Nat.thy |
138 val prems = Goal |
139 "[| m: nat; n: nat; \ |
139 "[| m: nat; n: nat; \ |
140 \ !!x. [| x: nat; m le x; P(x) |] ==> P(succ(x)) \ |
140 \ !!x. [| x: nat; m le x; P(x) |] ==> P(succ(x)) \ |
141 \ |] ==> m le n --> P(m) --> P(n)"; |
141 \ |] ==> m le n --> P(m) --> P(n)"; |
142 by (nat_ind_tac "n" prems 1); |
142 by (nat_ind_tac "n" prems 1); |
143 by (ALLGOALS |
143 by (ALLGOALS |
144 (asm_simp_tac |
144 (asm_simp_tac |
145 (simpset() addsimps prems @ distrib_simps @ [le0_iff, le_succ_iff]))); |
145 (simpset() addsimps prems @ distrib_simps @ [le0_iff, le_succ_iff]))); |
146 qed "nat_induct_from_lemma"; |
146 qed "nat_induct_from_lemma"; |
147 |
147 |
148 (*Induction starting from m rather than 0*) |
148 (*Induction starting from m rather than 0*) |
149 val prems = goal Nat.thy |
149 val prems = Goal |
150 "[| m le n; m: nat; n: nat; \ |
150 "[| m le n; m: nat; n: nat; \ |
151 \ P(m); \ |
151 \ P(m); \ |
152 \ !!x. [| x: nat; m le x; P(x) |] ==> P(succ(x)) \ |
152 \ !!x. [| x: nat; m le x; P(x) |] ==> P(succ(x)) \ |
153 \ |] ==> P(n)"; |
153 \ |] ==> P(n)"; |
154 by (rtac (nat_induct_from_lemma RS mp RS mp) 1); |
154 by (rtac (nat_induct_from_lemma RS mp RS mp) 1); |
155 by (REPEAT (ares_tac prems 1)); |
155 by (REPEAT (ares_tac prems 1)); |
156 qed "nat_induct_from"; |
156 qed "nat_induct_from"; |
157 |
157 |
158 (*Induction suitable for subtraction and less-than*) |
158 (*Induction suitable for subtraction and less-than*) |
159 val prems = goal Nat.thy |
159 val prems = Goal |
160 "[| m: nat; n: nat; \ |
160 "[| m: nat; n: nat; \ |
161 \ !!x. x: nat ==> P(x,0); \ |
161 \ !!x. x: nat ==> P(x,0); \ |
162 \ !!y. y: nat ==> P(0,succ(y)); \ |
162 \ !!y. y: nat ==> P(0,succ(y)); \ |
163 \ !!x y. [| x: nat; y: nat; P(x,y) |] ==> P(succ(x),succ(y)) \ |
163 \ !!x y. [| x: nat; y: nat; P(x,y) |] ==> P(succ(x),succ(y)) \ |
164 \ |] ==> P(m,n)"; |
164 \ |] ==> P(m,n)"; |
178 by (ALLGOALS |
178 by (ALLGOALS |
179 (EVERY' [rtac (impI RS impI), rtac (nat_induct RS ballI), assume_tac, |
179 (EVERY' [rtac (impI RS impI), rtac (nat_induct RS ballI), assume_tac, |
180 blast_tac le_cs, blast_tac le_cs])); |
180 blast_tac le_cs, blast_tac le_cs])); |
181 qed "succ_lt_induct_lemma"; |
181 qed "succ_lt_induct_lemma"; |
182 |
182 |
183 val prems = goal Nat.thy |
183 val prems = Goal |
184 "[| m<n; n: nat; \ |
184 "[| m<n; n: nat; \ |
185 \ P(m,succ(m)); \ |
185 \ P(m,succ(m)); \ |
186 \ !!x. [| x: nat; P(m,x) |] ==> P(m,succ(x)) \ |
186 \ !!x. [| x: nat; P(m,x) |] ==> P(m,succ(x)) \ |
187 \ |] ==> P(m,n)"; |
187 \ |] ==> P(m,n)"; |
188 by (res_inst_tac [("P4","P")] |
188 by (res_inst_tac [("P4","P")] |
200 by (Blast_tac 1); |
200 by (Blast_tac 1); |
201 qed "nat_case_succ"; |
201 qed "nat_case_succ"; |
202 |
202 |
203 Addsimps [nat_case_0, nat_case_succ]; |
203 Addsimps [nat_case_0, nat_case_succ]; |
204 |
204 |
205 val major::prems = goal Nat.thy |
205 val major::prems = Goal |
206 "[| n: nat; a: C(0); !!m. m: nat ==> b(m): C(succ(m)) \ |
206 "[| n: nat; a: C(0); !!m. m: nat ==> b(m): C(succ(m)) \ |
207 \ |] ==> nat_case(a,b,n) : C(n)"; |
207 \ |] ==> nat_case(a,b,n) : C(n)"; |
208 by (rtac (major RS nat_induct) 1); |
208 by (rtac (major RS nat_induct) 1); |
209 by (ALLGOALS (asm_simp_tac (simpset() addsimps prems))); |
209 by (ALLGOALS (asm_simp_tac (simpset() addsimps prems))); |
210 qed "nat_case_type"; |
210 qed "nat_case_type"; |