author | haftmann |
Thu, 26 Jun 2025 17:25:29 +0200 | |
changeset 82774 | 2865a6618cba |
parent 82773 | 4ec8e654112f |
permissions | -rw-r--r-- |
50023
28f3263d4d1b
refined stack of library theories implementing int and/or nat by target language numerals
haftmann
parents:
47108
diff
changeset
|
1 |
(* Title: HOL/Library/Code_Binary_Nat.thy |
51113
222fb6cb2c3e
factored out shared preprocessor setup into theory Code_Abstract_Nat, tuning descriptions
haftmann
parents:
50023
diff
changeset
|
2 |
Author: Florian Haftmann, TU Muenchen |
47108 | 3 |
*) |
4 |
||
60500 | 5 |
section \<open>Implementation of natural numbers as binary numerals\<close> |
47108 | 6 |
|
50023
28f3263d4d1b
refined stack of library theories implementing int and/or nat by target language numerals
haftmann
parents:
47108
diff
changeset
|
7 |
theory Code_Binary_Nat |
51113
222fb6cb2c3e
factored out shared preprocessor setup into theory Code_Abstract_Nat, tuning descriptions
haftmann
parents:
50023
diff
changeset
|
8 |
imports Code_Abstract_Nat |
47108 | 9 |
begin |
10 |
||
60500 | 11 |
text \<open> |
47108 | 12 |
When generating code for functions on natural numbers, the |
69593 | 13 |
canonical representation using \<^term>\<open>0::nat\<close> and |
14 |
\<^term>\<open>Suc\<close> is unsuitable for computations involving large |
|
47108 | 15 |
numbers. This theory refines the representation of |
16 |
natural numbers for code generation to use binary |
|
17 |
numerals, which do not grow linear in size but logarithmic. |
|
60500 | 18 |
\<close> |
47108 | 19 |
|
60500 | 20 |
subsection \<open>Representation\<close> |
47108 | 21 |
|
50023
28f3263d4d1b
refined stack of library theories implementing int and/or nat by target language numerals
haftmann
parents:
47108
diff
changeset
|
22 |
code_datatype "0::nat" nat_of_num |
28f3263d4d1b
refined stack of library theories implementing int and/or nat by target language numerals
haftmann
parents:
47108
diff
changeset
|
23 |
|
47108 | 24 |
lemma [code]: |
25 |
"num_of_nat 0 = Num.One" |
|
26 |
"num_of_nat (nat_of_num k) = k" |
|
27 |
by (simp_all add: nat_of_num_inverse) |
|
28 |
||
29 |
lemma [code]: |
|
61076 | 30 |
"(1::nat) = Numeral1" |
47108 | 31 |
by simp |
32 |
||
61076 | 33 |
lemma [code_abbrev]: "Numeral1 = (1::nat)" |
47108 | 34 |
by simp |
35 |
||
36 |
lemma [code]: |
|
37 |
"Suc n = n + 1" |
|
38 |
by simp |
|
39 |
||
40 |
||
60500 | 41 |
subsection \<open>Basic arithmetic\<close> |
47108 | 42 |
|
61115
3a4400985780
modernized name space management -- more uniform qualification;
wenzelm
parents:
61076
diff
changeset
|
43 |
context |
3a4400985780
modernized name space management -- more uniform qualification;
wenzelm
parents:
61076
diff
changeset
|
44 |
begin |
3a4400985780
modernized name space management -- more uniform qualification;
wenzelm
parents:
61076
diff
changeset
|
45 |
|
47108 | 46 |
lemma plus_nat_code [code]: |
82774
2865a6618cba
append (rather than prepend) code equations: the order within a theory is maintained in the resulting code
haftmann
parents:
82773
diff
changeset
|
47 |
"0 + n = (n::nat)" |
47108 | 48 |
"m + 0 = (m::nat)" |
82774
2865a6618cba
append (rather than prepend) code equations: the order within a theory is maintained in the resulting code
haftmann
parents:
82773
diff
changeset
|
49 |
"nat_of_num k + nat_of_num l = nat_of_num (k + l)" |
47108 | 50 |
by (simp_all add: nat_of_num_numeral) |
51 |
||
60500 | 52 |
text \<open>Bounded subtraction needs some auxiliary\<close> |
47108 | 53 |
|
61115
3a4400985780
modernized name space management -- more uniform qualification;
wenzelm
parents:
61076
diff
changeset
|
54 |
qualified definition dup :: "nat \<Rightarrow> nat" where |
47108 | 55 |
"dup n = n + n" |
56 |
||
57 |
lemma dup_code [code]: |
|
58 |
"dup 0 = 0" |
|
59 |
"dup (nat_of_num k) = nat_of_num (Num.Bit0 k)" |
|
50023
28f3263d4d1b
refined stack of library theories implementing int and/or nat by target language numerals
haftmann
parents:
47108
diff
changeset
|
60 |
by (simp_all add: dup_def numeral_Bit0) |
47108 | 61 |
|
61115
3a4400985780
modernized name space management -- more uniform qualification;
wenzelm
parents:
61076
diff
changeset
|
62 |
qualified definition sub :: "num \<Rightarrow> num \<Rightarrow> nat option" where |
47108 | 63 |
"sub k l = (if k \<ge> l then Some (numeral k - numeral l) else None)" |
64 |
||
65 |
lemma sub_code [code]: |
|
66 |
"sub Num.One Num.One = Some 0" |
|
67 |
"sub (Num.Bit0 m) Num.One = Some (nat_of_num (Num.BitM m))" |
|
68 |
"sub (Num.Bit1 m) Num.One = Some (nat_of_num (Num.Bit0 m))" |
|
69 |
"sub Num.One (Num.Bit0 n) = None" |
|
70 |
"sub Num.One (Num.Bit1 n) = None" |
|
55466 | 71 |
"sub (Num.Bit0 m) (Num.Bit0 n) = map_option dup (sub m n)" |
72 |
"sub (Num.Bit1 m) (Num.Bit1 n) = map_option dup (sub m n)" |
|
73 |
"sub (Num.Bit1 m) (Num.Bit0 n) = map_option (\<lambda>q. dup q + 1) (sub m n)" |
|
47108 | 74 |
"sub (Num.Bit0 m) (Num.Bit1 n) = (case sub m n of None \<Rightarrow> None |
75 |
| Some q \<Rightarrow> if q = 0 then None else Some (dup q - 1))" |
|
81974 | 76 |
by (auto simp: nat_of_num_numeral Num.dbl_def Num.dbl_inc_def Num.dbl_dec_def |
77 |
Let_def le_imp_diff_is_add BitM_plus_one sub_def dup_def |
|
78 |
sub_non_positive nat_add_distrib sub_non_negative) |
|
47108 | 79 |
|
80 |
lemma minus_nat_code [code]: |
|
82774
2865a6618cba
append (rather than prepend) code equations: the order within a theory is maintained in the resulting code
haftmann
parents:
82773
diff
changeset
|
81 |
"0 - n = (0::nat)" |
47108 | 82 |
"m - 0 = (m::nat)" |
82774
2865a6618cba
append (rather than prepend) code equations: the order within a theory is maintained in the resulting code
haftmann
parents:
82773
diff
changeset
|
83 |
"nat_of_num k - nat_of_num l = (case sub k l of None \<Rightarrow> 0 | Some j \<Rightarrow> j)" |
47108 | 84 |
by (simp_all add: nat_of_num_numeral sub_non_positive sub_def) |
85 |
||
86 |
lemma times_nat_code [code]: |
|
82774
2865a6618cba
append (rather than prepend) code equations: the order within a theory is maintained in the resulting code
haftmann
parents:
82773
diff
changeset
|
87 |
"0 * n = (0::nat)" |
47108 | 88 |
"m * 0 = (0::nat)" |
82774
2865a6618cba
append (rather than prepend) code equations: the order within a theory is maintained in the resulting code
haftmann
parents:
82773
diff
changeset
|
89 |
"nat_of_num k * nat_of_num l = nat_of_num (k * l)" |
47108 | 90 |
by (simp_all add: nat_of_num_numeral) |
91 |
||
92 |
lemma equal_nat_code [code]: |
|
93 |
"HOL.equal 0 (0::nat) \<longleftrightarrow> True" |
|
94 |
"HOL.equal 0 (nat_of_num l) \<longleftrightarrow> False" |
|
95 |
"HOL.equal (nat_of_num k) 0 \<longleftrightarrow> False" |
|
96 |
"HOL.equal (nat_of_num k) (nat_of_num l) \<longleftrightarrow> HOL.equal k l" |
|
97 |
by (simp_all add: nat_of_num_numeral equal) |
|
98 |
||
99 |
lemma equal_nat_refl [code nbe]: |
|
100 |
"HOL.equal (n::nat) n \<longleftrightarrow> True" |
|
101 |
by (rule equal_refl) |
|
102 |
||
103 |
lemma less_eq_nat_code [code]: |
|
104 |
"0 \<le> (n::nat) \<longleftrightarrow> True" |
|
105 |
"nat_of_num k \<le> 0 \<longleftrightarrow> False" |
|
106 |
"nat_of_num k \<le> nat_of_num l \<longleftrightarrow> k \<le> l" |
|
107 |
by (simp_all add: nat_of_num_numeral) |
|
108 |
||
109 |
lemma less_nat_code [code]: |
|
110 |
"(m::nat) < 0 \<longleftrightarrow> False" |
|
111 |
"0 < nat_of_num l \<longleftrightarrow> True" |
|
112 |
"nat_of_num k < nat_of_num l \<longleftrightarrow> k < l" |
|
113 |
by (simp_all add: nat_of_num_numeral) |
|
114 |
||
53069
d165213e3924
execution of int division by class semiring_numeral_div, replacing pdivmod by divmod_abs
haftmann
parents:
52435
diff
changeset
|
115 |
lemma divmod_nat_code [code]: |
82774
2865a6618cba
append (rather than prepend) code equations: the order within a theory is maintained in the resulting code
haftmann
parents:
82773
diff
changeset
|
116 |
"Euclidean_Rings.divmod_nat 0 n = (0, 0)" |
77061
5de3772609ea
generalized theory name: euclidean division denotes one particular division definition on integers
haftmann
parents:
75937
diff
changeset
|
117 |
"Euclidean_Rings.divmod_nat m 0 = (0, m)" |
82774
2865a6618cba
append (rather than prepend) code equations: the order within a theory is maintained in the resulting code
haftmann
parents:
82773
diff
changeset
|
118 |
"Euclidean_Rings.divmod_nat (nat_of_num k) (nat_of_num l) = divmod k l" |
77061
5de3772609ea
generalized theory name: euclidean division denotes one particular division definition on integers
haftmann
parents:
75937
diff
changeset
|
119 |
by (simp_all add: Euclidean_Rings.divmod_nat_def nat_of_num_numeral) |
53069
d165213e3924
execution of int division by class semiring_numeral_div, replacing pdivmod by divmod_abs
haftmann
parents:
52435
diff
changeset
|
120 |
|
61115
3a4400985780
modernized name space management -- more uniform qualification;
wenzelm
parents:
61076
diff
changeset
|
121 |
end |
3a4400985780
modernized name space management -- more uniform qualification;
wenzelm
parents:
61076
diff
changeset
|
122 |
|
47108 | 123 |
|
60500 | 124 |
subsection \<open>Conversions\<close> |
47108 | 125 |
|
126 |
lemma of_nat_code [code]: |
|
127 |
"of_nat 0 = 0" |
|
128 |
"of_nat (nat_of_num k) = numeral k" |
|
129 |
by (simp_all add: nat_of_num_numeral) |
|
130 |
||
131 |
||
52435
6646bb548c6b
migration from code_(const|type|class|instance) to code_printing and from code_module to code_identifier
haftmann
parents:
51143
diff
changeset
|
132 |
code_identifier |
6646bb548c6b
migration from code_(const|type|class|instance) to code_printing and from code_module to code_identifier
haftmann
parents:
51143
diff
changeset
|
133 |
code_module Code_Binary_Nat \<rightharpoonup> |
6646bb548c6b
migration from code_(const|type|class|instance) to code_printing and from code_module to code_identifier
haftmann
parents:
51143
diff
changeset
|
134 |
(SML) Arith and (OCaml) Arith and (Haskell) Arith |
47108 | 135 |
|
136 |
end |