146 text {* A special form of induction for reasoning |
146 text {* A special form of induction for reasoning |
147 about @{term "m < n"} and @{term "m - n"} *} |
147 about @{term "m < n"} and @{term "m - n"} *} |
148 |
148 |
149 theorem diff_induct: "(!!x. P x 0) ==> (!!y. P 0 (Suc y)) ==> |
149 theorem diff_induct: "(!!x. P x 0) ==> (!!y. P 0 (Suc y)) ==> |
150 (!!x y. P x y ==> P (Suc x) (Suc y)) ==> P m n" |
150 (!!x y. P x y ==> P (Suc x) (Suc y)) ==> P m n" |
151 apply (rule_tac x = "m" in spec) |
151 apply (rule_tac x = m in spec) |
152 apply (induct_tac n) |
152 apply (induct_tac n) |
153 prefer 2 |
153 prefer 2 |
154 apply (rule allI) |
154 apply (rule allI) |
155 apply (induct_tac x) |
155 apply (induct_tac x, rules+) |
156 apply rules+ |
|
157 done |
156 done |
158 |
157 |
159 subsection {* Basic properties of "less than" *} |
158 subsection {* Basic properties of "less than" *} |
160 |
159 |
161 lemma wf_pred_nat: "wf pred_nat" |
160 lemma wf_pred_nat: "wf pred_nat" |
162 apply (unfold wf_def pred_nat_def) |
161 apply (unfold wf_def pred_nat_def, clarify) |
163 apply clarify |
162 apply (induct_tac x, blast+) |
164 apply (induct_tac x) |
|
165 apply blast+ |
|
166 done |
163 done |
167 |
164 |
168 lemma wf_less: "wf {(x, y::nat). x < y}" |
165 lemma wf_less: "wf {(x, y::nat). x < y}" |
169 apply (unfold less_def) |
166 apply (unfold less_def) |
170 apply (rule wf_pred_nat [THEN wf_trancl, THEN wf_subset]) |
167 apply (rule wf_pred_nat [THEN wf_trancl, THEN wf_subset], blast) |
171 apply blast |
|
172 done |
168 done |
173 |
169 |
174 lemma less_eq: "((m, n) : pred_nat^+) = (m < n)" |
170 lemma less_eq: "((m, n) : pred_nat^+) = (m < n)" |
175 apply (unfold less_def) |
171 apply (unfold less_def) |
176 apply (rule refl) |
172 apply (rule refl) |
178 |
174 |
179 subsubsection {* Introduction properties *} |
175 subsubsection {* Introduction properties *} |
180 |
176 |
181 lemma less_trans: "i < j ==> j < k ==> i < (k::nat)" |
177 lemma less_trans: "i < j ==> j < k ==> i < (k::nat)" |
182 apply (unfold less_def) |
178 apply (unfold less_def) |
183 apply (rule trans_trancl [THEN transD]) |
179 apply (rule trans_trancl [THEN transD], assumption+) |
184 apply assumption+ |
|
185 done |
180 done |
186 |
181 |
187 lemma lessI [iff]: "n < Suc n" |
182 lemma lessI [iff]: "n < Suc n" |
188 apply (unfold less_def pred_nat_def) |
183 apply (unfold less_def pred_nat_def) |
189 apply (simp add: r_into_trancl) |
184 apply (simp add: r_into_trancl) |
190 done |
185 done |
191 |
186 |
192 lemma less_SucI: "i < j ==> i < Suc j" |
187 lemma less_SucI: "i < j ==> i < Suc j" |
193 apply (rule less_trans) |
188 apply (rule less_trans, assumption) |
194 apply assumption |
|
195 apply (rule lessI) |
189 apply (rule lessI) |
196 done |
190 done |
197 |
191 |
198 lemma zero_less_Suc [iff]: "0 < Suc n" |
192 lemma zero_less_Suc [iff]: "0 < Suc n" |
199 apply (induct n) |
193 apply (induct n) |
249 by (rule notE, rule not_less0) |
241 by (rule notE, rule not_less0) |
250 |
242 |
251 lemma less_SucE: assumes major: "m < Suc n" |
243 lemma less_SucE: assumes major: "m < Suc n" |
252 and less: "m < n ==> P" and eq: "m = n ==> P" shows P |
244 and less: "m < n ==> P" and eq: "m = n ==> P" shows P |
253 apply (rule major [THEN lessE]) |
245 apply (rule major [THEN lessE]) |
254 apply (rule eq) |
246 apply (rule eq, blast) |
255 apply blast |
247 apply (rule less, blast) |
256 apply (rule less) |
|
257 apply blast |
|
258 done |
248 done |
259 |
249 |
260 lemma less_Suc_eq: "(m < Suc n) = (m < n | m = n)" |
250 lemma less_Suc_eq: "(m < Suc n) = (m < n | m = n)" |
261 by (blast elim!: less_SucE intro: less_trans) |
251 by (blast elim!: less_SucE intro: less_trans) |
262 |
252 |
321 apply (erule Suc_mono) |
310 apply (erule Suc_mono) |
322 done |
311 done |
323 |
312 |
324 lemma less_trans_Suc: |
313 lemma less_trans_Suc: |
325 assumes le: "i < j" shows "j < k ==> Suc i < k" |
314 assumes le: "i < j" shows "j < k ==> Suc i < k" |
326 apply (induct k) |
315 apply (induct k, simp_all) |
327 apply simp_all |
|
328 apply (insert le) |
316 apply (insert le) |
329 apply (simp add: less_Suc_eq) |
317 apply (simp add: less_Suc_eq) |
330 apply (blast dest: Suc_lessD) |
318 apply (blast dest: Suc_lessD) |
331 done |
319 done |
332 |
320 |
333 text {* Can be used with @{text less_Suc_eq} to get @{term "n = m | n < m"} *} |
321 text {* Can be used with @{text less_Suc_eq} to get @{term "n = m | n < m"} *} |
334 lemma not_less_eq: "(~ m < n) = (n < Suc m)" |
322 lemma not_less_eq: "(~ m < n) = (n < Suc m)" |
335 apply (rule_tac m = "m" and n = "n" in diff_induct) |
323 by (rule_tac m = m and n = n in diff_induct, simp_all) |
336 apply simp_all |
|
337 done |
|
338 |
324 |
339 text {* Complete induction, aka course-of-values induction *} |
325 text {* Complete induction, aka course-of-values induction *} |
340 lemma nat_less_induct: |
326 lemma nat_less_induct: |
341 assumes prem: "!!n. ALL m::nat. m < n --> P m ==> P n" shows "P n" |
327 assumes prem: "!!n. ALL m::nat. m < n --> P m ==> P n" shows "P n" |
342 apply (rule_tac a=n in wf_induct) |
328 apply (rule_tac a=n in wf_induct) |
343 apply (rule wf_pred_nat [THEN wf_trancl]) |
329 apply (rule wf_pred_nat [THEN wf_trancl]) |
344 apply (rule prem) |
330 apply (rule prem) |
345 apply (unfold less_def) |
331 apply (unfold less_def, assumption) |
346 apply assumption |
|
347 done |
332 done |
348 |
333 |
349 lemmas less_induct = nat_less_induct [rule_format, case_names less] |
334 lemmas less_induct = nat_less_induct [rule_format, case_names less] |
350 |
335 |
351 subsection {* Properties of "less than or equal" *} |
336 subsection {* Properties of "less than or equal" *} |
582 lemmas LeastI = wellorder_LeastI |
566 lemmas LeastI = wellorder_LeastI |
583 lemmas Least_le = wellorder_Least_le |
567 lemmas Least_le = wellorder_Least_le |
584 lemmas not_less_Least = wellorder_not_less_Least |
568 lemmas not_less_Least = wellorder_not_less_Least |
585 |
569 |
586 lemma Least_Suc: "[| P n; ~ P 0 |] ==> (LEAST n. P n) = Suc (LEAST m. P(Suc m))" |
570 lemma Least_Suc: "[| P n; ~ P 0 |] ==> (LEAST n. P n) = Suc (LEAST m. P(Suc m))" |
587 apply (case_tac "n") |
571 apply (case_tac "n", auto) |
588 apply auto |
|
589 apply (frule LeastI) |
572 apply (frule LeastI) |
590 apply (drule_tac P = "%x. P (Suc x) " in LeastI) |
573 apply (drule_tac P = "%x. P (Suc x) " in LeastI) |
591 apply (subgoal_tac " (LEAST x. P x) <= Suc (LEAST x. P (Suc x))") |
574 apply (subgoal_tac " (LEAST x. P x) <= Suc (LEAST x. P (Suc x))") |
592 apply (erule_tac [2] Least_le) |
575 apply (erule_tac [2] Least_le) |
593 apply (case_tac "LEAST x. P x") |
576 apply (case_tac "LEAST x. P x", auto) |
594 apply auto |
|
595 apply (drule_tac P = "%x. P (Suc x) " in Least_le) |
577 apply (drule_tac P = "%x. P (Suc x) " in Least_le) |
596 apply (blast intro: order_antisym) |
578 apply (blast intro: order_antisym) |
597 done |
579 done |
598 |
580 |
599 lemma Least_Suc2: "[|P n; Q m; ~P 0; !k. P (Suc k) = Q k|] ==> Least P = Suc (Least Q)" |
581 lemma Least_Suc2: "[|P n; Q m; ~P 0; !k. P (Suc k) = Q k|] ==> Least P = Suc (Least Q)" |
783 lemma add_less_mono1: "i < j ==> i + k < j + (k::nat)" |
763 lemma add_less_mono1: "i < j ==> i + k < j + (k::nat)" |
784 by (induct k) simp_all |
764 by (induct k) simp_all |
785 |
765 |
786 text {* strict, in both arguments *} |
766 text {* strict, in both arguments *} |
787 lemma add_less_mono: "[|i < j; k < l|] ==> i + k < j + (l::nat)" |
767 lemma add_less_mono: "[|i < j; k < l|] ==> i + k < j + (l::nat)" |
788 apply (rule add_less_mono1 [THEN less_trans]) |
768 apply (rule add_less_mono1 [THEN less_trans], assumption+) |
789 apply assumption+ |
769 apply (induct_tac j, simp_all) |
790 apply (induct_tac j) |
|
791 apply simp_all |
|
792 done |
770 done |
793 |
771 |
794 text {* A [clumsy] way of lifting @{text "<"} |
772 text {* A [clumsy] way of lifting @{text "<"} |
795 monotonicity to @{text "<="} monotonicity *} |
773 monotonicity to @{text "<="} monotonicity *} |
796 lemma less_mono_imp_le_mono: |
774 lemma less_mono_imp_le_mono: |
801 done |
779 done |
802 |
780 |
803 text {* non-strict, in 1st argument *} |
781 text {* non-strict, in 1st argument *} |
804 lemma add_le_mono1: "i <= j ==> i + k <= j + (k::nat)" |
782 lemma add_le_mono1: "i <= j ==> i + k <= j + (k::nat)" |
805 apply (rule_tac f = "%j. j + k" in less_mono_imp_le_mono) |
783 apply (rule_tac f = "%j. j + k" in less_mono_imp_le_mono) |
806 apply (erule add_less_mono1) |
784 apply (erule add_less_mono1, assumption) |
807 apply assumption |
|
808 done |
785 done |
809 |
786 |
810 text {* non-strict, in both arguments *} |
787 text {* non-strict, in both arguments *} |
811 lemma add_le_mono: "[| i <= j; k <= l |] ==> i + k <= j + (l::nat)" |
788 lemma add_le_mono: "[| i <= j; k <= l |] ==> i + k <= j + (l::nat)" |
812 apply (erule add_le_mono1 [THEN le_trans]) |
789 apply (erule add_le_mono1 [THEN le_trans]) |
990 apply (erule mult_le_mono2) |
964 apply (erule mult_le_mono2) |
991 done |
965 done |
992 |
966 |
993 text {* strict, in 1st argument; proof is by induction on @{text "k > 0"} *} |
967 text {* strict, in 1st argument; proof is by induction on @{text "k > 0"} *} |
994 lemma mult_less_mono2: "(i::nat) < j ==> 0 < k ==> k * i < k * j" |
968 lemma mult_less_mono2: "(i::nat) < j ==> 0 < k ==> k * i < k * j" |
995 apply (erule_tac m1 = "0" in less_imp_Suc_add [THEN exE]) |
969 apply (erule_tac m1 = 0 in less_imp_Suc_add [THEN exE], simp) |
996 apply simp |
|
997 apply (induct_tac x) |
970 apply (induct_tac x) |
998 apply (simp_all add: add_less_mono) |
971 apply (simp_all add: add_less_mono) |
999 done |
972 done |
1000 |
973 |
1001 lemma mult_less_mono1: "(i::nat) < j ==> 0 < k ==> i * k < j * k" |
974 lemma mult_less_mono1: "(i::nat) < j ==> 0 < k ==> i * k < j * k" |
1002 by (drule mult_less_mono2) (simp_all add: mult_commute) |
975 by (drule mult_less_mono2) (simp_all add: mult_commute) |
1003 |
976 |
1004 lemma zero_less_mult_iff [simp]: "(0 < (m::nat) * n) = (0 < m & 0 < n)" |
977 lemma zero_less_mult_iff [simp]: "(0 < (m::nat) * n) = (0 < m & 0 < n)" |
1005 apply (induct m) |
978 apply (induct m) |
1006 apply (case_tac [2] n) |
979 apply (case_tac [2] n, simp_all) |
1007 apply simp_all |
|
1008 done |
980 done |
1009 |
981 |
1010 lemma one_le_mult_iff [simp]: "(Suc 0 <= m * n) = (1 <= m & 1 <= n)" |
982 lemma one_le_mult_iff [simp]: "(Suc 0 <= m * n) = (1 <= m & 1 <= n)" |
1011 apply (induct m) |
983 apply (induct m) |
1012 apply (case_tac [2] n) |
984 apply (case_tac [2] n, simp_all) |
1013 apply simp_all |
|
1014 done |
985 done |
1015 |
986 |
1016 lemma mult_eq_1_iff [simp]: "(m * n = Suc 0) = (m = 1 & n = 1)" |
987 lemma mult_eq_1_iff [simp]: "(m * n = Suc 0) = (m = 1 & n = 1)" |
1017 apply (induct_tac m) |
988 apply (induct_tac m, simp) |
1018 apply simp |
989 apply (induct_tac n, simp, fastsimp) |
1019 apply (induct_tac n) |
|
1020 apply simp |
|
1021 apply fastsimp |
|
1022 done |
990 done |
1023 |
991 |
1024 lemma one_eq_mult_iff [simp]: "(Suc 0 = m * n) = (m = 1 & n = 1)" |
992 lemma one_eq_mult_iff [simp]: "(Suc 0 = m * n) = (m = 1 & n = 1)" |
1025 apply (rule trans) |
993 apply (rule trans) |
1026 apply (rule_tac [2] mult_eq_1_iff) |
994 apply (rule_tac [2] mult_eq_1_iff, fastsimp) |
1027 apply fastsimp |
|
1028 done |
995 done |
1029 |
996 |
1030 lemma mult_less_cancel2: "((m::nat) * k < n * k) = (0 < k & m < n)" |
997 lemma mult_less_cancel2: "((m::nat) * k < n * k) = (0 < k & m < n)" |
1031 apply (safe intro!: mult_less_mono1) |
998 apply (safe intro!: mult_less_mono1) |
1032 apply (case_tac k) |
999 apply (case_tac k, auto) |
1033 apply auto |
|
1034 apply (simp del: le_0_eq add: linorder_not_le [symmetric]) |
1000 apply (simp del: le_0_eq add: linorder_not_le [symmetric]) |
1035 apply (blast intro: mult_le_mono1) |
1001 apply (blast intro: mult_le_mono1) |
1036 done |
1002 done |
1037 |
1003 |
1038 lemma mult_less_cancel1 [simp]: "(k * (m::nat) < k * n) = (0 < k & m < n)" |
1004 lemma mult_less_cancel1 [simp]: "(k * (m::nat) < k * n) = (0 < k & m < n)" |
1039 by (simp add: mult_less_cancel2 mult_commute [of k]) |
1005 by (simp add: mult_less_cancel2 mult_commute [of k]) |
1040 |
1006 |
1041 declare mult_less_cancel2 [simp] |
1007 declare mult_less_cancel2 [simp] |
1042 |
1008 |
1043 lemma mult_le_cancel1 [simp]: "(k * (m::nat) <= k * n) = (0 < k --> m <= n)" |
1009 lemma mult_le_cancel1 [simp]: "(k * (m::nat) <= k * n) = (0 < k --> m <= n)" |
1044 apply (simp add: linorder_not_less [symmetric]) |
1010 by (simp add: linorder_not_less [symmetric], auto) |
1045 apply auto |
|
1046 done |
|
1047 |
1011 |
1048 lemma mult_le_cancel2 [simp]: "((m::nat) * k <= n * k) = (0 < k --> m <= n)" |
1012 lemma mult_le_cancel2 [simp]: "((m::nat) * k <= n * k) = (0 < k --> m <= n)" |
1049 apply (simp add: linorder_not_less [symmetric]) |
1013 by (simp add: linorder_not_less [symmetric], auto) |
1050 apply auto |
|
1051 done |
|
1052 |
1014 |
1053 lemma mult_cancel2: "(m * k = n * k) = (m = n | (k = (0::nat)))" |
1015 lemma mult_cancel2: "(m * k = n * k) = (m = n | (k = (0::nat)))" |
1054 apply (cut_tac less_linear) |
1016 apply (cut_tac less_linear, safe, auto) |
1055 apply safe |
|
1056 apply auto |
|
1057 apply (drule mult_less_mono1, assumption, simp)+ |
1017 apply (drule mult_less_mono1, assumption, simp)+ |
1058 done |
1018 done |
1059 |
1019 |
1060 lemma mult_cancel1 [simp]: "(k * m = k * n) = (m = n | (k = (0::nat)))" |
1020 lemma mult_cancel1 [simp]: "(k * m = k * n) = (m = n | (k = (0::nat)))" |
1061 by (simp add: mult_cancel2 mult_commute [of k]) |
1021 by (simp add: mult_cancel2 mult_commute [of k]) |