7 |
7 |
8 theory Extended_Nat |
8 theory Extended_Nat |
9 imports Main |
9 imports Main |
10 begin |
10 begin |
11 |
11 |
|
12 class infinity = |
|
13 fixes infinity :: "'a" |
|
14 |
|
15 notation (xsymbols) |
|
16 infinity ("\<infinity>") |
|
17 |
|
18 notation (HTML output) |
|
19 infinity ("\<infinity>") |
|
20 |
12 subsection {* Type definition *} |
21 subsection {* Type definition *} |
13 |
22 |
14 text {* |
23 text {* |
15 We extend the standard natural numbers by a special value indicating |
24 We extend the standard natural numbers by a special value indicating |
16 infinity. |
25 infinity. |
17 *} |
26 *} |
18 |
27 |
19 datatype enat = Fin nat | Infty |
28 typedef (open) enat = "UNIV :: nat option set" .. |
20 |
29 |
21 notation (xsymbols) |
30 definition Fin :: "nat \<Rightarrow> enat" where |
22 Infty ("\<infinity>") |
31 "Fin n = Abs_enat (Some n)" |
23 |
32 |
24 notation (HTML output) |
33 instantiation enat :: infinity |
25 Infty ("\<infinity>") |
34 begin |
26 |
35 definition "\<infinity> = Abs_enat None" |
27 |
36 instance proof qed |
28 lemma not_Infty_eq[iff]: "(x ~= Infty) = (EX i. x = Fin i)" |
37 end |
|
38 |
|
39 rep_datatype Fin "\<infinity> :: enat" |
|
40 proof - |
|
41 fix P i assume "\<And>j. P (Fin j)" "P \<infinity>" |
|
42 then show "P i" |
|
43 proof induct |
|
44 case (Abs_enat y) then show ?case |
|
45 by (cases y rule: option.exhaust) |
|
46 (auto simp: Fin_def infinity_enat_def) |
|
47 qed |
|
48 qed (auto simp add: Fin_def infinity_enat_def Abs_enat_inject) |
|
49 |
|
50 declare [[coercion "Fin :: nat \<Rightarrow> enat"]] |
|
51 |
|
52 lemma not_Infty_eq[iff]: "(x \<noteq> \<infinity>) = (EX i. x = Fin i)" |
29 by (cases x) auto |
53 by (cases x) auto |
30 |
54 |
31 lemma not_Fin_eq [iff]: "(ALL y. x ~= Fin y) = (x = Infty)" |
55 lemma not_Fin_eq [iff]: "(ALL y. x ~= Fin y) = (x = \<infinity>)" |
32 by (cases x) auto |
56 by (cases x) auto |
33 |
|
34 |
57 |
35 primrec the_Fin :: "enat \<Rightarrow> nat" |
58 primrec the_Fin :: "enat \<Rightarrow> nat" |
36 where "the_Fin (Fin n) = n" |
59 where "the_Fin (Fin n) = n" |
37 |
60 |
38 |
|
39 subsection {* Constructors and numbers *} |
61 subsection {* Constructors and numbers *} |
40 |
62 |
41 instantiation enat :: "{zero, one, number}" |
63 instantiation enat :: "{zero, one, number}" |
42 begin |
64 begin |
43 |
65 |
67 by (simp add: number_of_enat_def) |
89 by (simp add: number_of_enat_def) |
68 |
90 |
69 lemma one_iSuc: "1 = iSuc 0" |
91 lemma one_iSuc: "1 = iSuc 0" |
70 by (simp add: zero_enat_def one_enat_def iSuc_def) |
92 by (simp add: zero_enat_def one_enat_def iSuc_def) |
71 |
93 |
72 lemma Infty_ne_i0 [simp]: "\<infinity> \<noteq> 0" |
94 lemma Infty_ne_i0 [simp]: "(\<infinity>::enat) \<noteq> 0" |
73 by (simp add: zero_enat_def) |
95 by (simp add: zero_enat_def) |
74 |
96 |
75 lemma i0_ne_Infty [simp]: "0 \<noteq> \<infinity>" |
97 lemma i0_ne_Infty [simp]: "0 \<noteq> (\<infinity>::enat)" |
76 by (simp add: zero_enat_def) |
98 by (simp add: zero_enat_def) |
77 |
99 |
78 lemma zero_enat_eq [simp]: |
100 lemma zero_enat_eq [simp]: |
79 "number_of k = (0\<Colon>enat) \<longleftrightarrow> number_of k = (0\<Colon>nat)" |
101 "number_of k = (0\<Colon>enat) \<longleftrightarrow> number_of k = (0\<Colon>nat)" |
80 "(0\<Colon>enat) = number_of k \<longleftrightarrow> number_of k = (0\<Colon>nat)" |
102 "(0\<Colon>enat) = number_of k \<longleftrightarrow> number_of k = (0\<Colon>nat)" |
88 lemma zero_one_enat_neq [simp]: |
110 lemma zero_one_enat_neq [simp]: |
89 "\<not> 0 = (1\<Colon>enat)" |
111 "\<not> 0 = (1\<Colon>enat)" |
90 "\<not> 1 = (0\<Colon>enat)" |
112 "\<not> 1 = (0\<Colon>enat)" |
91 unfolding zero_enat_def one_enat_def by simp_all |
113 unfolding zero_enat_def one_enat_def by simp_all |
92 |
114 |
93 lemma Infty_ne_i1 [simp]: "\<infinity> \<noteq> 1" |
115 lemma Infty_ne_i1 [simp]: "(\<infinity>::enat) \<noteq> 1" |
94 by (simp add: one_enat_def) |
116 by (simp add: one_enat_def) |
95 |
117 |
96 lemma i1_ne_Infty [simp]: "1 \<noteq> \<infinity>" |
118 lemma i1_ne_Infty [simp]: "1 \<noteq> (\<infinity>::enat)" |
97 by (simp add: one_enat_def) |
119 by (simp add: one_enat_def) |
98 |
120 |
99 lemma Infty_ne_number [simp]: "\<infinity> \<noteq> number_of k" |
121 lemma Infty_ne_number [simp]: "(\<infinity>::enat) \<noteq> number_of k" |
100 by (simp add: number_of_enat_def) |
122 by (simp add: number_of_enat_def) |
101 |
123 |
102 lemma number_ne_Infty [simp]: "number_of k \<noteq> \<infinity>" |
124 lemma number_ne_Infty [simp]: "number_of k \<noteq> (\<infinity>::enat)" |
103 by (simp add: number_of_enat_def) |
125 by (simp add: number_of_enat_def) |
104 |
126 |
105 lemma iSuc_Fin: "iSuc (Fin n) = Fin (Suc n)" |
127 lemma iSuc_Fin: "iSuc (Fin n) = Fin (Suc n)" |
106 by (simp add: iSuc_def) |
128 by (simp add: iSuc_def) |
107 |
129 |
132 |
154 |
133 definition [nitpick_simp]: |
155 definition [nitpick_simp]: |
134 "m + n = (case m of \<infinity> \<Rightarrow> \<infinity> | Fin m \<Rightarrow> (case n of \<infinity> \<Rightarrow> \<infinity> | Fin n \<Rightarrow> Fin (m + n)))" |
156 "m + n = (case m of \<infinity> \<Rightarrow> \<infinity> | Fin m \<Rightarrow> (case n of \<infinity> \<Rightarrow> \<infinity> | Fin n \<Rightarrow> Fin (m + n)))" |
135 |
157 |
136 lemma plus_enat_simps [simp, code]: |
158 lemma plus_enat_simps [simp, code]: |
137 "Fin m + Fin n = Fin (m + n)" |
159 fixes q :: enat |
138 "\<infinity> + q = \<infinity>" |
160 shows "Fin m + Fin n = Fin (m + n)" |
139 "q + \<infinity> = \<infinity>" |
161 and "\<infinity> + q = \<infinity>" |
|
162 and "q + \<infinity> = \<infinity>" |
140 by (simp_all add: plus_enat_def split: enat.splits) |
163 by (simp_all add: plus_enat_def split: enat.splits) |
141 |
164 |
142 instance proof |
165 instance proof |
143 fix n m q :: enat |
166 fix n m q :: enat |
144 show "n + m + q = n + (m + q)" |
167 show "n + m + q = n + (m + q)" |
193 "m * n = (case m of \<infinity> \<Rightarrow> if n = 0 then 0 else \<infinity> | Fin m \<Rightarrow> |
216 "m * n = (case m of \<infinity> \<Rightarrow> if n = 0 then 0 else \<infinity> | Fin m \<Rightarrow> |
194 (case n of \<infinity> \<Rightarrow> if m = 0 then 0 else \<infinity> | Fin n \<Rightarrow> Fin (m * n)))" |
217 (case n of \<infinity> \<Rightarrow> if m = 0 then 0 else \<infinity> | Fin n \<Rightarrow> Fin (m * n)))" |
195 |
218 |
196 lemma times_enat_simps [simp, code]: |
219 lemma times_enat_simps [simp, code]: |
197 "Fin m * Fin n = Fin (m * n)" |
220 "Fin m * Fin n = Fin (m * n)" |
198 "\<infinity> * \<infinity> = \<infinity>" |
221 "\<infinity> * \<infinity> = (\<infinity>::enat)" |
199 "\<infinity> * Fin n = (if n = 0 then 0 else \<infinity>)" |
222 "\<infinity> * Fin n = (if n = 0 then 0 else \<infinity>)" |
200 "Fin m * \<infinity> = (if m = 0 then 0 else \<infinity>)" |
223 "Fin m * \<infinity> = (if m = 0 then 0 else \<infinity>)" |
201 unfolding times_enat_def zero_enat_def |
224 unfolding times_enat_def zero_enat_def |
202 by (simp_all split: enat.split) |
225 by (simp_all split: enat.split) |
203 |
226 |
272 end |
295 end |
273 |
296 |
274 lemma idiff_Fin_Fin[simp,code]: "Fin a - Fin b = Fin (a - b)" |
297 lemma idiff_Fin_Fin[simp,code]: "Fin a - Fin b = Fin (a - b)" |
275 by(simp add: diff_enat_def) |
298 by(simp add: diff_enat_def) |
276 |
299 |
277 lemma idiff_Infty[simp,code]: "\<infinity> - n = \<infinity>" |
300 lemma idiff_Infty[simp,code]: "\<infinity> - n = (\<infinity>::enat)" |
278 by(simp add: diff_enat_def) |
301 by(simp add: diff_enat_def) |
279 |
302 |
280 lemma idiff_Infty_right[simp,code]: "Fin a - \<infinity> = 0" |
303 lemma idiff_Infty_right[simp,code]: "Fin a - \<infinity> = 0" |
281 by(simp add: diff_enat_def) |
304 by(simp add: diff_enat_def) |
282 |
305 |
298 |
321 |
299 lemma iSuc_minus_1 [simp]: "iSuc n - 1 = n" |
322 lemma iSuc_minus_1 [simp]: "iSuc n - 1 = n" |
300 by(simp add: one_enat_def iSuc_Fin[symmetric] zero_enat_def[symmetric]) |
323 by(simp add: one_enat_def iSuc_Fin[symmetric] zero_enat_def[symmetric]) |
301 |
324 |
302 (*lemmas idiff_self_eq_0_Fin = idiff_self_eq_0[unfolded zero_enat_def]*) |
325 (*lemmas idiff_self_eq_0_Fin = idiff_self_eq_0[unfolded zero_enat_def]*) |
303 |
|
304 |
326 |
305 subsection {* Ordering *} |
327 subsection {* Ordering *} |
306 |
328 |
307 instantiation enat :: linordered_ab_semigroup_add |
329 instantiation enat :: linordered_ab_semigroup_add |
308 begin |
330 begin |
316 | \<infinity> \<Rightarrow> False)" |
338 | \<infinity> \<Rightarrow> False)" |
317 |
339 |
318 lemma enat_ord_simps [simp]: |
340 lemma enat_ord_simps [simp]: |
319 "Fin m \<le> Fin n \<longleftrightarrow> m \<le> n" |
341 "Fin m \<le> Fin n \<longleftrightarrow> m \<le> n" |
320 "Fin m < Fin n \<longleftrightarrow> m < n" |
342 "Fin m < Fin n \<longleftrightarrow> m < n" |
321 "q \<le> \<infinity>" |
343 "q \<le> (\<infinity>::enat)" |
322 "q < \<infinity> \<longleftrightarrow> q \<noteq> \<infinity>" |
344 "q < (\<infinity>::enat) \<longleftrightarrow> q \<noteq> \<infinity>" |
323 "\<infinity> \<le> q \<longleftrightarrow> q = \<infinity>" |
345 "(\<infinity>::enat) \<le> q \<longleftrightarrow> q = \<infinity>" |
324 "\<infinity> < q \<longleftrightarrow> False" |
346 "(\<infinity>::enat) < q \<longleftrightarrow> False" |
325 by (simp_all add: less_eq_enat_def less_enat_def split: enat.splits) |
347 by (simp_all add: less_eq_enat_def less_enat_def split: enat.splits) |
326 |
348 |
327 lemma enat_ord_code [code]: |
349 lemma enat_ord_code [code]: |
328 "Fin m \<le> Fin n \<longleftrightarrow> m \<le> n" |
350 "Fin m \<le> Fin n \<longleftrightarrow> m \<le> n" |
329 "Fin m < Fin n \<longleftrightarrow> m < n" |
351 "Fin m < Fin n \<longleftrightarrow> m < n" |
330 "q \<le> \<infinity> \<longleftrightarrow> True" |
352 "q \<le> (\<infinity>::enat) \<longleftrightarrow> True" |
331 "Fin m < \<infinity> \<longleftrightarrow> True" |
353 "Fin m < \<infinity> \<longleftrightarrow> True" |
332 "\<infinity> \<le> Fin n \<longleftrightarrow> False" |
354 "\<infinity> \<le> Fin n \<longleftrightarrow> False" |
333 "\<infinity> < q \<longleftrightarrow> False" |
355 "(\<infinity>::enat) < q \<longleftrightarrow> False" |
334 by simp_all |
356 by simp_all |
335 |
357 |
336 instance by default |
358 instance by default |
337 (auto simp add: less_eq_enat_def less_enat_def plus_enat_def split: enat.splits) |
359 (auto simp add: less_eq_enat_def less_enat_def plus_enat_def split: enat.splits) |
338 |
360 |
412 |
434 |
413 lemma min_enat_simps [simp]: |
435 lemma min_enat_simps [simp]: |
414 "min (Fin m) (Fin n) = Fin (min m n)" |
436 "min (Fin m) (Fin n) = Fin (min m n)" |
415 "min q 0 = 0" |
437 "min q 0 = 0" |
416 "min 0 q = 0" |
438 "min 0 q = 0" |
417 "min q \<infinity> = q" |
439 "min q (\<infinity>::enat) = q" |
418 "min \<infinity> q = q" |
440 "min (\<infinity>::enat) q = q" |
419 by (auto simp add: min_def) |
441 by (auto simp add: min_def) |
420 |
442 |
421 lemma max_enat_simps [simp]: |
443 lemma max_enat_simps [simp]: |
422 "max (Fin m) (Fin n) = Fin (max m n)" |
444 "max (Fin m) (Fin n) = Fin (max m n)" |
423 "max q 0 = q" |
445 "max q 0 = q" |
424 "max 0 q = q" |
446 "max 0 q = q" |
425 "max q \<infinity> = \<infinity>" |
447 "max q \<infinity> = (\<infinity>::enat)" |
426 "max \<infinity> q = \<infinity>" |
448 "max \<infinity> q = (\<infinity>::enat)" |
427 by (simp_all add: max_def) |
449 by (simp_all add: max_def) |
428 |
450 |
429 lemma Fin_ile: "n \<le> Fin m \<Longrightarrow> \<exists>k. n = Fin k" |
451 lemma Fin_ile: "n \<le> Fin m \<Longrightarrow> \<exists>k. n = Fin k" |
430 by (cases n) simp_all |
452 by (cases n) simp_all |
431 |
453 |