| author | wenzelm | 
| Tue, 18 Feb 2025 19:59:42 +0100 | |
| changeset 82195 | d818267e7821 | 
| parent 81974 | f30022be9213 | 
| child 82773 | 4ec8e654112f | 
| permissions | -rw-r--r-- | 
| 50023 
28f3263d4d1b
refined stack of library theories implementing int and/or nat by target language numerals
 haftmann parents: 
47108diff
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: 
50023diff
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: 
47108diff
changeset | 7 | theory Code_Binary_Nat | 
| 51113 
222fb6cb2c3e
factored out shared preprocessor setup into theory Code_Abstract_Nat, tuning descriptions
 haftmann parents: 
50023diff
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: 
47108diff
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: 
47108diff
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: 
61076diff
changeset | 43 | context | 
| 
3a4400985780
modernized name space management -- more uniform qualification;
 wenzelm parents: 
61076diff
changeset | 44 | begin | 
| 
3a4400985780
modernized name space management -- more uniform qualification;
 wenzelm parents: 
61076diff
changeset | 45 | |
| 66148 | 46 | declare [[code drop: "plus :: nat \<Rightarrow> _"]] | 
| 47108 | 47 | |
| 48 | lemma plus_nat_code [code]: | |
| 49 | "nat_of_num k + nat_of_num l = nat_of_num (k + l)" | |
| 50 | "m + 0 = (m::nat)" | |
| 51 | "0 + n = (n::nat)" | |
| 52 | by (simp_all add: nat_of_num_numeral) | |
| 53 | ||
| 60500 | 54 | text \<open>Bounded subtraction needs some auxiliary\<close> | 
| 47108 | 55 | |
| 61115 
3a4400985780
modernized name space management -- more uniform qualification;
 wenzelm parents: 
61076diff
changeset | 56 | qualified definition dup :: "nat \<Rightarrow> nat" where | 
| 47108 | 57 | "dup n = n + n" | 
| 58 | ||
| 59 | lemma dup_code [code]: | |
| 60 | "dup 0 = 0" | |
| 61 | "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: 
47108diff
changeset | 62 | by (simp_all add: dup_def numeral_Bit0) | 
| 47108 | 63 | |
| 61115 
3a4400985780
modernized name space management -- more uniform qualification;
 wenzelm parents: 
61076diff
changeset | 64 | qualified definition sub :: "num \<Rightarrow> num \<Rightarrow> nat option" where | 
| 47108 | 65 | "sub k l = (if k \<ge> l then Some (numeral k - numeral l) else None)" | 
| 66 | ||
| 67 | lemma sub_code [code]: | |
| 68 | "sub Num.One Num.One = Some 0" | |
| 69 | "sub (Num.Bit0 m) Num.One = Some (nat_of_num (Num.BitM m))" | |
| 70 | "sub (Num.Bit1 m) Num.One = Some (nat_of_num (Num.Bit0 m))" | |
| 71 | "sub Num.One (Num.Bit0 n) = None" | |
| 72 | "sub Num.One (Num.Bit1 n) = None" | |
| 55466 | 73 | "sub (Num.Bit0 m) (Num.Bit0 n) = map_option dup (sub m n)" | 
| 74 | "sub (Num.Bit1 m) (Num.Bit1 n) = map_option dup (sub m n)" | |
| 75 | "sub (Num.Bit1 m) (Num.Bit0 n) = map_option (\<lambda>q. dup q + 1) (sub m n)" | |
| 47108 | 76 | "sub (Num.Bit0 m) (Num.Bit1 n) = (case sub m n of None \<Rightarrow> None | 
| 77 | | Some q \<Rightarrow> if q = 0 then None else Some (dup q - 1))" | |
| 81974 | 78 | by (auto simp: nat_of_num_numeral Num.dbl_def Num.dbl_inc_def Num.dbl_dec_def | 
| 79 | Let_def le_imp_diff_is_add BitM_plus_one sub_def dup_def | |
| 80 | sub_non_positive nat_add_distrib sub_non_negative) | |
| 47108 | 81 | |
| 66148 | 82 | declare [[code drop: "minus :: nat \<Rightarrow> _"]] | 
| 47108 | 83 | |
| 84 | lemma minus_nat_code [code]: | |
| 85 | "nat_of_num k - nat_of_num l = (case sub k l of None \<Rightarrow> 0 | Some j \<Rightarrow> j)" | |
| 86 | "m - 0 = (m::nat)" | |
| 87 | "0 - n = (0::nat)" | |
| 88 | by (simp_all add: nat_of_num_numeral sub_non_positive sub_def) | |
| 89 | ||
| 66148 | 90 | declare [[code drop: "times :: nat \<Rightarrow> _"]] | 
| 47108 | 91 | |
| 92 | lemma times_nat_code [code]: | |
| 93 | "nat_of_num k * nat_of_num l = nat_of_num (k * l)" | |
| 94 | "m * 0 = (0::nat)" | |
| 95 | "0 * n = (0::nat)" | |
| 96 | by (simp_all add: nat_of_num_numeral) | |
| 97 | ||
| 66148 | 98 | declare [[code drop: "HOL.equal :: nat \<Rightarrow> _"]] | 
| 47108 | 99 | |
| 100 | lemma equal_nat_code [code]: | |
| 101 | "HOL.equal 0 (0::nat) \<longleftrightarrow> True" | |
| 102 | "HOL.equal 0 (nat_of_num l) \<longleftrightarrow> False" | |
| 103 | "HOL.equal (nat_of_num k) 0 \<longleftrightarrow> False" | |
| 104 | "HOL.equal (nat_of_num k) (nat_of_num l) \<longleftrightarrow> HOL.equal k l" | |
| 105 | by (simp_all add: nat_of_num_numeral equal) | |
| 106 | ||
| 107 | lemma equal_nat_refl [code nbe]: | |
| 108 | "HOL.equal (n::nat) n \<longleftrightarrow> True" | |
| 109 | by (rule equal_refl) | |
| 110 | ||
| 66148 | 111 | declare [[code drop: "less_eq :: nat \<Rightarrow> _"]] | 
| 47108 | 112 | |
| 113 | lemma less_eq_nat_code [code]: | |
| 114 | "0 \<le> (n::nat) \<longleftrightarrow> True" | |
| 115 | "nat_of_num k \<le> 0 \<longleftrightarrow> False" | |
| 116 | "nat_of_num k \<le> nat_of_num l \<longleftrightarrow> k \<le> l" | |
| 117 | by (simp_all add: nat_of_num_numeral) | |
| 118 | ||
| 66148 | 119 | declare [[code drop: "less :: nat \<Rightarrow> _"]] | 
| 47108 | 120 | |
| 121 | lemma less_nat_code [code]: | |
| 122 | "(m::nat) < 0 \<longleftrightarrow> False" | |
| 123 | "0 < nat_of_num l \<longleftrightarrow> True" | |
| 124 | "nat_of_num k < nat_of_num l \<longleftrightarrow> k < l" | |
| 125 | by (simp_all add: nat_of_num_numeral) | |
| 126 | ||
| 77061 
5de3772609ea
generalized theory name: euclidean division denotes one particular division definition on integers
 haftmann parents: 
75937diff
changeset | 127 | declare [[code drop: Euclidean_Rings.divmod_nat]] | 
| 53069 
d165213e3924
execution of int division by class semiring_numeral_div, replacing pdivmod by divmod_abs
 haftmann parents: 
52435diff
changeset | 128 | |
| 
d165213e3924
execution of int division by class semiring_numeral_div, replacing pdivmod by divmod_abs
 haftmann parents: 
52435diff
changeset | 129 | lemma divmod_nat_code [code]: | 
| 77061 
5de3772609ea
generalized theory name: euclidean division denotes one particular division definition on integers
 haftmann parents: 
75937diff
changeset | 130 | "Euclidean_Rings.divmod_nat (nat_of_num k) (nat_of_num l) = divmod k l" | 
| 
5de3772609ea
generalized theory name: euclidean division denotes one particular division definition on integers
 haftmann parents: 
75937diff
changeset | 131 | "Euclidean_Rings.divmod_nat m 0 = (0, m)" | 
| 
5de3772609ea
generalized theory name: euclidean division denotes one particular division definition on integers
 haftmann parents: 
75937diff
changeset | 132 | "Euclidean_Rings.divmod_nat 0 n = (0, 0)" | 
| 
5de3772609ea
generalized theory name: euclidean division denotes one particular division definition on integers
 haftmann parents: 
75937diff
changeset | 133 | 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: 
52435diff
changeset | 134 | |
| 61115 
3a4400985780
modernized name space management -- more uniform qualification;
 wenzelm parents: 
61076diff
changeset | 135 | end | 
| 
3a4400985780
modernized name space management -- more uniform qualification;
 wenzelm parents: 
61076diff
changeset | 136 | |
| 47108 | 137 | |
| 60500 | 138 | subsection \<open>Conversions\<close> | 
| 47108 | 139 | |
| 66148 | 140 | declare [[code drop: of_nat]] | 
| 47108 | 141 | |
| 142 | lemma of_nat_code [code]: | |
| 143 | "of_nat 0 = 0" | |
| 144 | "of_nat (nat_of_num k) = numeral k" | |
| 145 | by (simp_all add: nat_of_num_numeral) | |
| 146 | ||
| 147 | ||
| 52435 
6646bb548c6b
migration from code_(const|type|class|instance) to code_printing and from code_module to code_identifier
 haftmann parents: 
51143diff
changeset | 148 | code_identifier | 
| 
6646bb548c6b
migration from code_(const|type|class|instance) to code_printing and from code_module to code_identifier
 haftmann parents: 
51143diff
changeset | 149 | 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: 
51143diff
changeset | 150 | (SML) Arith and (OCaml) Arith and (Haskell) Arith | 
| 47108 | 151 | |
| 152 | end |