| author | wenzelm | 
| Tue, 06 Jun 2023 11:07:49 +0200 | |
| changeset 78134 | a11ebc8c751a | 
| parent 77061 | 5de3772609ea | 
| child 81974 | f30022be9213 | 
| 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))" | |
| 78 | apply (auto simp add: nat_of_num_numeral | |
| 79 | Num.dbl_def Num.dbl_inc_def Num.dbl_dec_def | |
| 80 | Let_def le_imp_diff_is_add BitM_plus_one sub_def dup_def) | |
| 81 | apply (simp_all add: sub_non_positive) | |
| 82 | apply (simp_all add: sub_non_negative [symmetric, where ?'a = int]) | |
| 83 | done | |
| 84 | ||
| 66148 | 85 | declare [[code drop: "minus :: nat \<Rightarrow> _"]] | 
| 47108 | 86 | |
| 87 | lemma minus_nat_code [code]: | |
| 88 | "nat_of_num k - nat_of_num l = (case sub k l of None \<Rightarrow> 0 | Some j \<Rightarrow> j)" | |
| 89 | "m - 0 = (m::nat)" | |
| 90 | "0 - n = (0::nat)" | |
| 91 | by (simp_all add: nat_of_num_numeral sub_non_positive sub_def) | |
| 92 | ||
| 66148 | 93 | declare [[code drop: "times :: nat \<Rightarrow> _"]] | 
| 47108 | 94 | |
| 95 | lemma times_nat_code [code]: | |
| 96 | "nat_of_num k * nat_of_num l = nat_of_num (k * l)" | |
| 97 | "m * 0 = (0::nat)" | |
| 98 | "0 * n = (0::nat)" | |
| 99 | by (simp_all add: nat_of_num_numeral) | |
| 100 | ||
| 66148 | 101 | declare [[code drop: "HOL.equal :: nat \<Rightarrow> _"]] | 
| 47108 | 102 | |
| 103 | lemma equal_nat_code [code]: | |
| 104 | "HOL.equal 0 (0::nat) \<longleftrightarrow> True" | |
| 105 | "HOL.equal 0 (nat_of_num l) \<longleftrightarrow> False" | |
| 106 | "HOL.equal (nat_of_num k) 0 \<longleftrightarrow> False" | |
| 107 | "HOL.equal (nat_of_num k) (nat_of_num l) \<longleftrightarrow> HOL.equal k l" | |
| 108 | by (simp_all add: nat_of_num_numeral equal) | |
| 109 | ||
| 110 | lemma equal_nat_refl [code nbe]: | |
| 111 | "HOL.equal (n::nat) n \<longleftrightarrow> True" | |
| 112 | by (rule equal_refl) | |
| 113 | ||
| 66148 | 114 | declare [[code drop: "less_eq :: nat \<Rightarrow> _"]] | 
| 47108 | 115 | |
| 116 | lemma less_eq_nat_code [code]: | |
| 117 | "0 \<le> (n::nat) \<longleftrightarrow> True" | |
| 118 | "nat_of_num k \<le> 0 \<longleftrightarrow> False" | |
| 119 | "nat_of_num k \<le> nat_of_num l \<longleftrightarrow> k \<le> l" | |
| 120 | by (simp_all add: nat_of_num_numeral) | |
| 121 | ||
| 66148 | 122 | declare [[code drop: "less :: nat \<Rightarrow> _"]] | 
| 47108 | 123 | |
| 124 | lemma less_nat_code [code]: | |
| 125 | "(m::nat) < 0 \<longleftrightarrow> False" | |
| 126 | "0 < nat_of_num l \<longleftrightarrow> True" | |
| 127 | "nat_of_num k < nat_of_num l \<longleftrightarrow> k < l" | |
| 128 | by (simp_all add: nat_of_num_numeral) | |
| 129 | ||
| 77061 
5de3772609ea
generalized theory name: euclidean division denotes one particular division definition on integers
 haftmann parents: 
75937diff
changeset | 130 | 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 | 131 | |
| 
d165213e3924
execution of int division by class semiring_numeral_div, replacing pdivmod by divmod_abs
 haftmann parents: 
52435diff
changeset | 132 | lemma divmod_nat_code [code]: | 
| 77061 
5de3772609ea
generalized theory name: euclidean division denotes one particular division definition on integers
 haftmann parents: 
75937diff
changeset | 133 | "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 | 134 | "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 | 135 | "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 | 136 | 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 | 137 | |
| 61115 
3a4400985780
modernized name space management -- more uniform qualification;
 wenzelm parents: 
61076diff
changeset | 138 | end | 
| 
3a4400985780
modernized name space management -- more uniform qualification;
 wenzelm parents: 
61076diff
changeset | 139 | |
| 47108 | 140 | |
| 60500 | 141 | subsection \<open>Conversions\<close> | 
| 47108 | 142 | |
| 66148 | 143 | declare [[code drop: of_nat]] | 
| 47108 | 144 | |
| 145 | lemma of_nat_code [code]: | |
| 146 | "of_nat 0 = 0" | |
| 147 | "of_nat (nat_of_num k) = numeral k" | |
| 148 | by (simp_all add: nat_of_num_numeral) | |
| 149 | ||
| 150 | ||
| 52435 
6646bb548c6b
migration from code_(const|type|class|instance) to code_printing and from code_module to code_identifier
 haftmann parents: 
51143diff
changeset | 151 | code_identifier | 
| 
6646bb548c6b
migration from code_(const|type|class|instance) to code_printing and from code_module to code_identifier
 haftmann parents: 
51143diff
changeset | 152 | 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 | 153 | (SML) Arith and (OCaml) Arith and (Haskell) Arith | 
| 47108 | 154 | |
| 155 | end |