| author | berghofe | 
| Wed, 07 Feb 2007 17:41:11 +0100 | |
| changeset 22270 | 4ccb7e6be929 | 
| parent 22046 | ce84c9887e2d | 
| child 22320 | d5260836d662 | 
| permissions | -rw-r--r-- | 
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 1 | (* Title: HOL/Library/EfficientNat.thy | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 2 | ID: $Id$ | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 3 | Author: Stefan Berghofer, TU Muenchen | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 4 | *) | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 5 | |
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 6 | header {* Implementation of natural numbers by integers *}
 | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 7 | |
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 8 | theory EfficientNat | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 9 | imports Main | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 10 | begin | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 11 | |
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 12 | text {*
 | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 13 | When generating code for functions on natural numbers, the canonical | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 14 | representation using @{term "0::nat"} and @{term "Suc"} is unsuitable for
 | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 15 | computations involving large numbers. The efficiency of the generated | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 16 | code can be improved drastically by implementing natural numbers by | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 17 | integers. To do this, just include this theory. | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 18 | *} | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 19 | |
| 20700 | 20 | subsection {* Logical rewrites *}
 | 
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 21 | |
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 22 | text {*
 | 
| 20700 | 23 | A int-to-nat conversion with domain | 
| 24 |   restricted to non-negative ints (in contrast to @{const nat}).
 | |
| 16770 
1f1b1fae30e4
Auxiliary functions to be used in generated code are now defined using "attach".
 berghofe parents: 
16295diff
changeset | 25 | *} | 
| 
1f1b1fae30e4
Auxiliary functions to be used in generated code are now defined using "attach".
 berghofe parents: 
16295diff
changeset | 26 | |
| 20641 | 27 | definition | 
| 21404 
eb85850d3eb7
more robust syntax for definition/abbreviation/notation;
 wenzelm parents: 
21287diff
changeset | 28 | nat_of_int :: "int \<Rightarrow> nat" where | 
| 20641 | 29 | "k \<ge> 0 \<Longrightarrow> nat_of_int k = nat k" | 
| 19889 | 30 | |
| 20839 | 31 | lemma nat_of_int_int: | 
| 32 | "nat_of_int (int n) = n" | |
| 33 | using zero_zle_int nat_of_int_def by simp | |
| 34 | ||
| 19889 | 35 | text {*
 | 
| 20700 | 36 | Case analysis on natural numbers is rephrased using a conditional | 
| 37 | expression: | |
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 38 | *} | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 39 | |
| 20839 | 40 | lemma [code unfold, code noinline]: "nat_case \<equiv> (\<lambda>f g n. if n = 0 then f else g (n - 1))" | 
| 20700 | 41 | proof - | 
| 42 | have rewrite: "\<And>f g n. nat_case f g n = (if n = 0 then f else g (n - 1))" | |
| 43 | proof - | |
| 44 | fix f g n | |
| 45 | show "nat_case f g n = (if n = 0 then f else g (n - 1))" | |
| 46 | by (cases n) simp_all | |
| 47 | qed | |
| 48 | show "nat_case \<equiv> (\<lambda>f g n. if n = 0 then f else g (n - 1))" | |
| 49 | by (rule eq_reflection ext rewrite)+ | |
| 50 | qed | |
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 51 | |
| 20839 | 52 | lemma [code inline]: | 
| 21454 | 53 | "nat_case f g n = (if n = 0 then f else g (nat_of_int (int n - 1)))" | 
| 54 | by (cases n) (simp_all add: nat_of_int_int) | |
| 20839 | 55 | |
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 56 | text {*
 | 
| 20700 | 57 | Most standard arithmetic functions on natural numbers are implemented | 
| 58 | using their counterparts on the integers: | |
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 59 | *} | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 60 | |
| 20641 | 61 | lemma [code func]: "0 = nat_of_int 0" | 
| 62 | by (simp add: nat_of_int_def) | |
| 63 | lemma [code func, code inline]: "1 = nat_of_int 1" | |
| 64 | by (simp add: nat_of_int_def) | |
| 65 | lemma [code func]: "Suc n = n + 1" | |
| 66 | by simp | |
| 21874 | 67 | lemma [code]: "m + n = nat (int m + int n)" | 
| 20641 | 68 | by arith | 
| 69 | lemma [code func, code inline]: "m + n = nat_of_int (int m + int n)" | |
| 70 | by (simp add: nat_of_int_def) | |
| 71 | lemma [code, code inline]: "m - n = nat (int m - int n)" | |
| 72 | by arith | |
| 21874 | 73 | lemma [code]: "m * n = nat (int m * int n)" | 
| 20641 | 74 | unfolding zmult_int by simp | 
| 75 | lemma [code func, code inline]: "m * n = nat_of_int (int m * int n)" | |
| 76 | proof - | |
| 77 | have "int (m * n) = int m * int n" | |
| 78 | by (induct m) (simp_all add: zadd_zmult_distrib) | |
| 79 | then have "m * n = nat (int m * int n)" by auto | |
| 80 | also have "\<dots> = nat_of_int (int m * int n)" | |
| 81 | proof - | |
| 82 | have "int m \<ge> 0" and "int n \<ge> 0" by auto | |
| 83 | have "int m * int n \<ge> 0" by (rule split_mult_pos_le) auto | |
| 84 | with nat_of_int_def show ?thesis by auto | |
| 85 | qed | |
| 86 | finally show ?thesis . | |
| 87 | qed | |
| 88 | lemma [code]: "m div n = nat (int m div int n)" | |
| 89 | unfolding zdiv_int [symmetric] by simp | |
| 90 | lemma [code func]: "m div n = fst (Divides.divmod m n)" | |
| 91 | unfolding divmod_def by simp | |
| 92 | lemma [code]: "m mod n = nat (int m mod int n)" | |
| 93 | unfolding zmod_int [symmetric] by simp | |
| 94 | lemma [code func]: "m mod n = snd (Divides.divmod m n)" | |
| 95 | unfolding divmod_def by simp | |
| 96 | lemma [code, code inline]: "(m < n) \<longleftrightarrow> (int m < int n)" | |
| 97 | by simp | |
| 98 | lemma [code func, code inline]: "(m \<le> n) \<longleftrightarrow> (int m \<le> int n)" | |
| 99 | by simp | |
| 21454 | 100 | lemma [code func, code inline]: "m = n \<longleftrightarrow> int m = int n" | 
| 101 | by simp | |
| 20641 | 102 | lemma [code func]: "nat k = (if k < 0 then 0 else nat_of_int k)" | 
| 103 | proof (cases "k < 0") | |
| 104 | case True then show ?thesis by simp | |
| 105 | next | |
| 106 | case False then show ?thesis by (simp add: nat_of_int_def) | |
| 107 | qed | |
| 20523 
36a59e5d0039
Major update to function package, including new syntax and the (only theoretical)
 krauss parents: 
20453diff
changeset | 108 | lemma [code func]: | 
| 20641 | 109 | "int_aux i n = (if int n = 0 then i else int_aux (i + 1) (nat_of_int (int n - 1)))" | 
| 110 | proof - | |
| 111 | have "0 < n \<Longrightarrow> int n = 1 + int (nat_of_int (int n - 1))" | |
| 112 | proof - | |
| 113 | assume prem: "n > 0" | |
| 114 | then have "int n - 1 \<ge> 0" by auto | |
| 115 | then have "nat_of_int (int n - 1) = nat (int n - 1)" by (simp add: nat_of_int_def) | |
| 116 | with prem show "int n = 1 + int (nat_of_int (int n - 1))" by simp | |
| 117 | qed | |
| 118 | then show ?thesis unfolding int_aux_def by simp | |
| 119 | qed | |
| 20356 | 120 | |
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 121 | |
| 20700 | 122 | subsection {* Code generator setup for basic functions *}
 | 
| 123 | ||
| 124 | text {*
 | |
| 125 |   @{typ nat} is no longer a datatype but embedded into the integers.
 | |
| 126 | *} | |
| 127 | ||
| 20839 | 128 | code_const "0::nat" | 
| 21113 | 129 | (SML "!(0 : IntInf.int)") | 
| 21911 
e29bcab0c81c
added OCaml code generation (without dictionaries)
 haftmann parents: 
21874diff
changeset | 130 | (OCaml "Big'_int.big'_int'_of'_int/ 0") | 
| 21113 | 131 | (Haskell "0") | 
| 20839 | 132 | |
| 133 | code_const "Suc" | |
| 21125 | 134 | (SML "IntInf.+ ((_), 1)") | 
| 21911 
e29bcab0c81c
added OCaml code generation (without dictionaries)
 haftmann parents: 
21874diff
changeset | 135 | (OCaml "Big_int.succ'_big'_int") | 
| 21125 | 136 | (Haskell "!((_) + 1)") | 
| 20839 | 137 | |
| 20700 | 138 | setup {*
 | 
| 139 | CodegenData.del_datatype "nat" | |
| 140 | *} | |
| 141 | ||
| 142 | types_code | |
| 143 |   nat ("int")
 | |
| 144 | attach (term_of) {*
 | |
| 21846 | 145 | val term_of_nat = HOLogic.mk_number HOLogic.natT o IntInf.fromInt; | 
| 20700 | 146 | *} | 
| 147 | attach (test) {*
 | |
| 148 | fun gen_nat i = random_range 0 i; | |
| 149 | *} | |
| 150 | ||
| 151 | code_type nat | |
| 21113 | 152 | (SML "IntInf.int") | 
| 21911 
e29bcab0c81c
added OCaml code generation (without dictionaries)
 haftmann parents: 
21874diff
changeset | 153 | (OCaml "Big'_int.big'_int") | 
| 21113 | 154 | (Haskell "Integer") | 
| 20700 | 155 | |
| 156 | consts_code | |
| 20713 
823967ef47f1
renamed 0 and 1 to HOL.zero and HOL.one respectivly; introduced corresponding syntactic classes
 haftmann parents: 
20700diff
changeset | 157 |   "HOL.zero" :: nat ("0")
 | 
| 20700 | 158 |   Suc ("(_ + 1)")
 | 
| 159 | ||
| 160 | text {*
 | |
| 161 | Since natural numbers are implemented | |
| 162 |   using integers, the coercion function @{const "int"} of type
 | |
| 163 |   @{typ "nat \<Rightarrow> int"} is simply implemented by the identity function,
 | |
| 164 |   likewise @{const nat_of_int} of type @{typ "int \<Rightarrow> nat"}.
 | |
| 165 |   For the @{const "nat"} function for converting an integer to a natural
 | |
| 166 | number, we give a specific implementation using an ML function that | |
| 167 | returns its input value, provided that it is non-negative, and otherwise | |
| 168 |   returns @{text "0"}.
 | |
| 169 | *} | |
| 170 | ||
| 171 | consts_code | |
| 172 |   int ("(_)")
 | |
| 173 |   nat ("\<module>nat")
 | |
| 174 | attach {*
 | |
| 175 | fun nat i = if i < 0 then 0 else i; | |
| 176 | *} | |
| 177 | ||
| 178 | code_const int | |
| 179 | (SML "_") | |
| 21911 
e29bcab0c81c
added OCaml code generation (without dictionaries)
 haftmann parents: 
21874diff
changeset | 180 | (OCaml "_") | 
| 20700 | 181 | (Haskell "_") | 
| 182 | ||
| 183 | code_const nat_of_int | |
| 184 | (SML "_") | |
| 21911 
e29bcab0c81c
added OCaml code generation (without dictionaries)
 haftmann parents: 
21874diff
changeset | 185 | (OCaml "_") | 
| 20700 | 186 | (Haskell "_") | 
| 187 | ||
| 188 | ||
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 189 | subsection {* Preprocessors *}
 | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 190 | |
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 191 | text {*
 | 
| 20700 | 192 |   In contrast to @{term "Suc n"}, the term @{term "n + (1::nat)"} is no longer
 | 
| 193 | a constructor term. Therefore, all occurrences of this term in a position | |
| 194 | where a pattern is expected (i.e.\ on the left-hand side of a recursion | |
| 195 | equation or in the arguments of an inductive relation in an introduction | |
| 196 | rule) must be eliminated. | |
| 197 | This can be accomplished by applying the following transformation rules: | |
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 198 | *} | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 199 | |
| 16900 
e294033d1c0f
Rewrote function remove_suc, since it failed on some equations
 berghofe parents: 
16861diff
changeset | 200 | theorem Suc_if_eq: "(\<And>n. f (Suc n) = h n) \<Longrightarrow> f 0 = g \<Longrightarrow> | 
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 201 | f n = (if n = 0 then g else h (n - 1))" | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 202 | by (case_tac n) simp_all | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 203 | |
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 204 | theorem Suc_clause: "(\<And>n. P n (Suc n)) \<Longrightarrow> n \<noteq> 0 \<Longrightarrow> P (n - 1) n" | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 205 | by (case_tac n) simp_all | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 206 | |
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 207 | text {*
 | 
| 20700 | 208 | The rules above are built into a preprocessor that is plugged into | 
| 209 | the code generator. Since the preprocessor for introduction rules | |
| 210 | does not know anything about modes, some of the modes that worked | |
| 211 | for the canonical representation of natural numbers may no longer work. | |
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 212 | *} | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 213 | |
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 214 | (*<*) | 
| 19791 | 215 | |
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 216 | ML {*
 | 
| 19791 | 217 | local | 
| 218 | val Suc_if_eq = thm "Suc_if_eq"; | |
| 219 | val Suc_clause = thm "Suc_clause"; | |
| 220 | fun contains_suc t = member (op =) (term_consts t) "Suc"; | |
| 221 | in | |
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 222 | |
| 15396 
0a36ccb79481
Preprocessors now transfer theorems to current theory in order to
 berghofe parents: 
15323diff
changeset | 223 | fun remove_suc thy thms = | 
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 224 | let | 
| 15396 
0a36ccb79481
Preprocessors now transfer theorems to current theory in order to
 berghofe parents: 
15323diff
changeset | 225 | val Suc_if_eq' = Thm.transfer thy Suc_if_eq; | 
| 20071 
8f3e1ddb50e6
replaced Term.variant(list) by Name.variant(_list);
 wenzelm parents: 
19889diff
changeset | 226 | val vname = Name.variant (map fst | 
| 20196 
9a19e4de6e2e
renamed add_term_varnames to Term.add_varnames (cf. Term.add_vars etc.);
 wenzelm parents: 
20105diff
changeset | 227 | (fold (Term.add_varnames o Thm.full_prop_of) thms [])) "x"; | 
| 21911 
e29bcab0c81c
added OCaml code generation (without dictionaries)
 haftmann parents: 
21874diff
changeset | 228 | val cv = cterm_of thy (Var ((vname, 0), HOLogic.natT)); | 
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 229 | fun lhs_of th = snd (Thm.dest_comb | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 230 | (fst (Thm.dest_comb (snd (Thm.dest_comb (cprop_of th)))))); | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 231 | fun rhs_of th = snd (Thm.dest_comb (snd (Thm.dest_comb (cprop_of th)))); | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 232 | fun find_vars ct = (case term_of ct of | 
| 16900 
e294033d1c0f
Rewrote function remove_suc, since it failed on some equations
 berghofe parents: 
16861diff
changeset | 233 |         (Const ("Suc", _) $ Var _) => [(cv, snd (Thm.dest_comb ct))]
 | 
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 234 | | _ $ _ => | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 235 | let val (ct1, ct2) = Thm.dest_comb ct | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 236 | in | 
| 16900 
e294033d1c0f
Rewrote function remove_suc, since it failed on some equations
 berghofe parents: 
16861diff
changeset | 237 | map (apfst (fn ct => Thm.capply ct ct2)) (find_vars ct1) @ | 
| 
e294033d1c0f
Rewrote function remove_suc, since it failed on some equations
 berghofe parents: 
16861diff
changeset | 238 | map (apfst (Thm.capply ct1)) (find_vars ct2) | 
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 239 | end | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 240 | | _ => []); | 
| 16900 
e294033d1c0f
Rewrote function remove_suc, since it failed on some equations
 berghofe parents: 
16861diff
changeset | 241 | val eqs = List.concat (map | 
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 242 | (fn th => map (pair th) (find_vars (lhs_of th))) thms); | 
| 16900 
e294033d1c0f
Rewrote function remove_suc, since it failed on some equations
 berghofe parents: 
16861diff
changeset | 243 | fun mk_thms (th, (ct, cv')) = | 
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 244 | let | 
| 16900 
e294033d1c0f
Rewrote function remove_suc, since it failed on some equations
 berghofe parents: 
16861diff
changeset | 245 | val th' = | 
| 
e294033d1c0f
Rewrote function remove_suc, since it failed on some equations
 berghofe parents: 
16861diff
changeset | 246 | Thm.implies_elim | 
| 15396 
0a36ccb79481
Preprocessors now transfer theorems to current theory in order to
 berghofe parents: 
15323diff
changeset | 247 | (Drule.fconv_rule (Thm.beta_conversion true) | 
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 248 | (Drule.instantiate' | 
| 15531 | 249 | [SOME (ctyp_of_term ct)] [SOME (Thm.cabs cv ct), | 
| 16900 
e294033d1c0f
Rewrote function remove_suc, since it failed on some equations
 berghofe parents: 
16861diff
changeset | 250 | SOME (Thm.cabs cv' (rhs_of th)), NONE, SOME cv'] | 
| 
e294033d1c0f
Rewrote function remove_suc, since it failed on some equations
 berghofe parents: 
16861diff
changeset | 251 | Suc_if_eq')) (Thm.forall_intr cv' th) | 
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 252 | in | 
| 21287 | 253 | case map_filter (fn th'' => | 
| 20287 
8cbcb46c3c09
replaced obsolete standard/freeze_all by Variable.trade;
 wenzelm parents: 
20196diff
changeset | 254 | SOME (th'', singleton | 
| 21287 | 255 | (Variable.trade (K (fn [th'''] => [th''' RS th'])) (Variable.thm_context th'')) th'') | 
| 16900 
e294033d1c0f
Rewrote function remove_suc, since it failed on some equations
 berghofe parents: 
16861diff
changeset | 256 | handle THM _ => NONE) thms of | 
| 
e294033d1c0f
Rewrote function remove_suc, since it failed on some equations
 berghofe parents: 
16861diff
changeset | 257 | [] => NONE | 
| 
e294033d1c0f
Rewrote function remove_suc, since it failed on some equations
 berghofe parents: 
16861diff
changeset | 258 | | thps => | 
| 19791 | 259 | let val (ths1, ths2) = split_list thps | 
| 20951 
868120282837
gen_rem(s) abandoned in favour of remove / subtract
 haftmann parents: 
20839diff
changeset | 260 | in SOME (subtract eq_thm (th :: ths1) thms @ ths2) end | 
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 261 | end | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 262 | in | 
| 19791 | 263 | case get_first mk_thms eqs of | 
| 16900 
e294033d1c0f
Rewrote function remove_suc, since it failed on some equations
 berghofe parents: 
16861diff
changeset | 264 | NONE => thms | 
| 
e294033d1c0f
Rewrote function remove_suc, since it failed on some equations
 berghofe parents: 
16861diff
changeset | 265 | | SOME x => remove_suc thy x | 
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 266 | end; | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 267 | |
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 268 | fun eqn_suc_preproc thy ths = | 
| 19791 | 269 | let | 
| 270 | val dest = fst o HOLogic.dest_eq o HOLogic.dest_Trueprop o prop_of | |
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 271 | in | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 272 | if forall (can dest) ths andalso | 
| 19791 | 273 | exists (contains_suc o dest) ths | 
| 15396 
0a36ccb79481
Preprocessors now transfer theorems to current theory in order to
 berghofe parents: 
15323diff
changeset | 274 | then remove_suc thy ths else ths | 
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 275 | end; | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 276 | |
| 15396 
0a36ccb79481
Preprocessors now transfer theorems to current theory in order to
 berghofe parents: 
15323diff
changeset | 277 | fun remove_suc_clause thy thms = | 
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 278 | let | 
| 15396 
0a36ccb79481
Preprocessors now transfer theorems to current theory in order to
 berghofe parents: 
15323diff
changeset | 279 | val Suc_clause' = Thm.transfer thy Suc_clause; | 
| 20071 
8f3e1ddb50e6
replaced Term.variant(list) by Name.variant(_list);
 wenzelm parents: 
19889diff
changeset | 280 | val vname = Name.variant (map fst | 
| 20196 
9a19e4de6e2e
renamed add_term_varnames to Term.add_varnames (cf. Term.add_vars etc.);
 wenzelm parents: 
20105diff
changeset | 281 | (fold (Term.add_varnames o Thm.full_prop_of) thms [])) "x"; | 
| 15531 | 282 |     fun find_var (t as Const ("Suc", _) $ (v as Var _)) = SOME (t, v)
 | 
| 283 | | find_var (t $ u) = (case find_var t of NONE => find_var u | x => x) | |
| 284 | | find_var _ = NONE; | |
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 285 | fun find_thm th = | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 286 | let val th' = ObjectLogic.atomize_thm th | 
| 15570 | 287 | in Option.map (pair (th, th')) (find_var (prop_of th')) end | 
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 288 | in | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 289 | case get_first find_thm thms of | 
| 15531 | 290 | NONE => thms | 
| 291 | | SOME ((th, th'), (Sucv, v)) => | |
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 292 | let | 
| 16861 | 293 | val cert = cterm_of (Thm.theory_of_thm th); | 
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 294 | val th'' = ObjectLogic.rulify (Thm.implies_elim | 
| 15396 
0a36ccb79481
Preprocessors now transfer theorems to current theory in order to
 berghofe parents: 
15323diff
changeset | 295 | (Drule.fconv_rule (Thm.beta_conversion true) | 
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 296 | (Drule.instantiate' [] | 
| 15531 | 297 |                 [SOME (cert (lambda v (Abs ("x", HOLogic.natT,
 | 
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 298 | abstract_over (Sucv, | 
| 19828 | 299 | HOLogic.dest_Trueprop (prop_of th')))))), | 
| 15531 | 300 | SOME (cert v)] Suc_clause')) | 
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 301 | (Thm.forall_intr (cert v) th')) | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 302 | in | 
| 15396 
0a36ccb79481
Preprocessors now transfer theorems to current theory in order to
 berghofe parents: 
15323diff
changeset | 303 | remove_suc_clause thy (map (fn th''' => | 
| 19617 | 304 | if (op = o pairself prop_of) (th''', th) then th'' else th''') thms) | 
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 305 | end | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 306 | end; | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 307 | |
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 308 | fun clause_suc_preproc thy ths = | 
| 19791 | 309 | let | 
| 19828 | 310 | val dest = fst o HOLogic.dest_mem o HOLogic.dest_Trueprop | 
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 311 | in | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 312 | if forall (can (dest o concl_of)) ths andalso | 
| 19791 | 313 | exists (fn th => member (op =) (foldr add_term_consts | 
| 21287 | 314 | [] (map_filter (try dest) (concl_of th :: prems_of th))) "Suc") ths | 
| 15396 
0a36ccb79481
Preprocessors now transfer theorems to current theory in order to
 berghofe parents: 
15323diff
changeset | 315 | then remove_suc_clause thy ths else ths | 
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 316 | end; | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 317 | |
| 19791 | 318 | end; (*local*) | 
| 319 | ||
| 21546 | 320 | local | 
| 321 | val meta_eq_to_obj_eq = thm "meta_eq_to_obj_eq"; | |
| 322 | val eq_reflection = thm "eq_reflection"; | |
| 323 | in fun lift_obj_eq f thy = | |
| 19791 | 324 | map (fn thm => thm RS meta_eq_to_obj_eq) | 
| 325 | #> f thy | |
| 21546 | 326 | #> map (fn thm => thm RS eq_reflection) | 
| 327 | end | |
| 19791 | 328 | *} | 
| 329 | ||
| 330 | setup {*
 | |
| 19603 | 331 | Codegen.add_preprocessor eqn_suc_preproc | 
| 332 | #> Codegen.add_preprocessor clause_suc_preproc | |
| 22046 | 333 | #> CodegenData.del_inline_proc "elim_number_of_nat" | 
| 334 |   #> CodegenData.add_preproc ("eqn_Suc", lift_obj_eq eqn_suc_preproc)
 | |
| 335 |   #> CodegenData.add_preproc ("clause_Suc", lift_obj_eq clause_suc_preproc)
 | |
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 336 | *} | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 337 | (*>*) | 
| 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 338 | |
| 21191 | 339 | subsection {* Module names *}
 | 
| 340 | ||
| 341 | code_modulename SML | |
| 342 | Nat Integer | |
| 343 | EfficientNat Integer | |
| 344 | ||
| 21911 
e29bcab0c81c
added OCaml code generation (without dictionaries)
 haftmann parents: 
21874diff
changeset | 345 | code_modulename OCaml | 
| 
e29bcab0c81c
added OCaml code generation (without dictionaries)
 haftmann parents: 
21874diff
changeset | 346 | Nat Integer | 
| 
e29bcab0c81c
added OCaml code generation (without dictionaries)
 haftmann parents: 
21874diff
changeset | 347 | EfficientNat Integer | 
| 
e29bcab0c81c
added OCaml code generation (without dictionaries)
 haftmann parents: 
21874diff
changeset | 348 | |
| 15323 
6c10fe1c0e17
Code generator plug-in for implementing natural numbers by integers.
 berghofe parents: diff
changeset | 349 | end |