src/HOL/Library/EfficientNat.thy
author huffman
Wed, 13 Jun 2007 03:31:11 +0200
changeset 23365 f31794033ae1
parent 23269 851b8ea067ac
child 23394 474ff28210c0
permissions -rw-r--r--
removed constant int :: nat => int; int is now an abbreviation for of_nat :: nat => int
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
22804
haftmann
parents: 22743
diff changeset
     9
imports Main Pretty_Int
15323
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
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
    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 {*
22845
5f9138bcb3d7 changed code generator invocation syntax
haftmann
parents: 22804
diff changeset
    23
  An int-to-nat conversion
20700
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
    24
  restricted to non-negative ints (in contrast to @{const nat}).
22320
d5260836d662 clarified explanation
haftmann
parents: 22046
diff changeset
    25
  Note that this restriction has no logical relevance and
d5260836d662 clarified explanation
haftmann
parents: 22046
diff changeset
    26
  is just a kind of proof hint -- nothing prevents you from 
d5260836d662 clarified explanation
haftmann
parents: 22046
diff changeset
    27
  writing nonsense like @{term "nat_of_int (-4)"}
16770
1f1b1fae30e4 Auxiliary functions to be used in generated code are now defined using "attach".
berghofe
parents: 16295
diff changeset
    28
*}
1f1b1fae30e4 Auxiliary functions to be used in generated code are now defined using "attach".
berghofe
parents: 16295
diff changeset
    29
20641
12554634e552 improvements for codegen 2
haftmann
parents: 20597
diff changeset
    30
definition
21404
eb85850d3eb7 more robust syntax for definition/abbreviation/notation;
wenzelm
parents: 21287
diff changeset
    31
  nat_of_int :: "int \<Rightarrow> nat" where
20641
12554634e552 improvements for codegen 2
haftmann
parents: 20597
diff changeset
    32
  "k \<ge> 0 \<Longrightarrow> nat_of_int k = nat k"
19889
2202a5648897 slight adaptions for code generator
haftmann
parents: 19828
diff changeset
    33
23365
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
    34
definition
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
    35
  int' :: "nat \<Rightarrow> int" where
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
    36
  "int' n = of_nat n"
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
    37
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
    38
lemma int'_Suc [simp]: "int' (Suc n) = 1 + int' n"
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
    39
unfolding int'_def by simp
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
    40
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
    41
lemma int'_add: "int' (m + n) = int' m + int' n"
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
    42
unfolding int'_def by (rule of_nat_add)
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
    43
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
    44
lemma int'_mult: "int' (m * n) = int' m * int' n"
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
    45
unfolding int'_def by (rule of_nat_mult)
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
    46
22395
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
    47
lemma nat_of_int_of_number_of:
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
    48
  fixes k
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
    49
  assumes "k \<ge> 0"
22804
haftmann
parents: 22743
diff changeset
    50
  shows "number_of k = nat_of_int (number_of k)"
22395
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
    51
  unfolding nat_of_int_def [OF prems] nat_number_of_def number_of_is_id ..
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
    52
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
    53
lemma nat_of_int_of_number_of_aux:
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
    54
  fixes k
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
    55
  assumes "Numeral.Pls \<le> k \<equiv> True"
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
    56
  shows "k \<ge> 0"
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
    57
  using prems unfolding Pls_def by simp
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
    58
20839
ed49d8709959 improvements for code_gen
haftmann
parents: 20713
diff changeset
    59
lemma nat_of_int_int:
23365
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
    60
  "nat_of_int (int' n) = n"
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
    61
  using nat_of_int_def int'_def by simp
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
    62
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
    63
lemma eq_nat_of_int: "int' n = x \<Longrightarrow> n = nat_of_int x"
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
    64
by (erule subst, simp only: nat_of_int_int)
20839
ed49d8709959 improvements for code_gen
haftmann
parents: 20713
diff changeset
    65
19889
2202a5648897 slight adaptions for code generator
haftmann
parents: 19828
diff changeset
    66
text {*
20700
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
    67
  Case analysis on natural numbers is rephrased using a conditional
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
    68
  expression:
15323
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
    69
*}
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
    70
22845
5f9138bcb3d7 changed code generator invocation syntax
haftmann
parents: 22804
diff changeset
    71
lemma [code unfold, code inline del]:
5f9138bcb3d7 changed code generator invocation syntax
haftmann
parents: 22804
diff changeset
    72
  "nat_case \<equiv> (\<lambda>f g n. if n = 0 then f else g (n - 1))"
20700
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
    73
proof -
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
    74
  have rewrite: "\<And>f g n. nat_case f g n = (if n = 0 then f else g (n - 1))"
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
    75
  proof -
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
    76
    fix f g n
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
    77
    show "nat_case f g n = (if n = 0 then f else g (n - 1))"
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
    78
      by (cases n) simp_all
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
    79
  qed
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
    80
  show "nat_case \<equiv> (\<lambda>f g n. if n = 0 then f else g (n - 1))"
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
    81
    by (rule eq_reflection ext rewrite)+ 
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
    82
qed
15323
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
    83
20839
ed49d8709959 improvements for code_gen
haftmann
parents: 20713
diff changeset
    84
lemma [code inline]:
23365
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
    85
  "nat_case = (\<lambda>f g n. if n = 0 then f else g (nat_of_int (int' n - 1)))"
22845
5f9138bcb3d7 changed code generator invocation syntax
haftmann
parents: 22804
diff changeset
    86
proof (rule ext)+
22743
e2b06bfe471a improved case unfolding
haftmann
parents: 22507
diff changeset
    87
  fix f g n
23365
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
    88
  show "nat_case f g n = (if n = 0 then f else g (nat_of_int (int' n - 1)))"
21454
a1937c51ed88 dropped eq const
haftmann
parents: 21404
diff changeset
    89
  by (cases n) (simp_all add: nat_of_int_int)
22743
e2b06bfe471a improved case unfolding
haftmann
parents: 22507
diff changeset
    90
qed
20839
ed49d8709959 improvements for code_gen
haftmann
parents: 20713
diff changeset
    91
15323
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
    92
text {*
20700
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
    93
  Most standard arithmetic functions on natural numbers are implemented
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
    94
  using their counterparts on the integers:
15323
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
    95
*}
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
    96
20641
12554634e552 improvements for codegen 2
haftmann
parents: 20597
diff changeset
    97
lemma [code func]: "0 = nat_of_int 0"
12554634e552 improvements for codegen 2
haftmann
parents: 20597
diff changeset
    98
  by (simp add: nat_of_int_def)
12554634e552 improvements for codegen 2
haftmann
parents: 20597
diff changeset
    99
lemma [code func, code inline]:  "1 = nat_of_int 1"
12554634e552 improvements for codegen 2
haftmann
parents: 20597
diff changeset
   100
  by (simp add: nat_of_int_def)
23365
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   101
lemma [code func]: "Suc n = nat_of_int (int' n + 1)"
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   102
  by (simp add: eq_nat_of_int)
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   103
lemma [code]: "m + n = nat (int' m + int' n)"
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   104
  by (simp add: int'_def nat_eq_iff2)
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   105
lemma [code func, code inline]: "m + n = nat_of_int (int' m + int' n)"
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   106
  by (simp add: eq_nat_of_int int'_add)
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   107
lemma [code, code inline]: "m - n = nat (int' m - int' n)"
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   108
  by (simp add: int'_def nat_eq_iff2)
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   109
lemma [code]: "m * n = nat (int' m * int' n)"
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   110
  unfolding int'_def
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   111
  by (simp add: of_nat_mult [symmetric] del: of_nat_mult)
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   112
lemma [code func, code inline]: "m * n = nat_of_int (int' m * int' n)"
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   113
  by (simp add: eq_nat_of_int int'_mult)
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   114
lemma [code]: "m div n = nat (int' m div int' n)"
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   115
  unfolding int'_def zdiv_int [symmetric] by simp
20641
12554634e552 improvements for codegen 2
haftmann
parents: 20597
diff changeset
   116
lemma [code func]: "m div n = fst (Divides.divmod m n)"
12554634e552 improvements for codegen 2
haftmann
parents: 20597
diff changeset
   117
  unfolding divmod_def by simp
23365
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   118
lemma [code]: "m mod n = nat (int' m mod int' n)"
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   119
  unfolding int'_def zmod_int [symmetric] by simp
20641
12554634e552 improvements for codegen 2
haftmann
parents: 20597
diff changeset
   120
lemma [code func]: "m mod n = snd (Divides.divmod m n)"
12554634e552 improvements for codegen 2
haftmann
parents: 20597
diff changeset
   121
  unfolding divmod_def by simp
23365
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   122
lemma [code, code inline]: "(m < n) \<longleftrightarrow> (int' m < int' n)"
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   123
  unfolding int'_def by simp
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   124
lemma [code func, code inline]: "(m \<le> n) \<longleftrightarrow> (int' m \<le> int' n)"
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   125
  unfolding int'_def by simp
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   126
lemma [code func, code inline]: "m = n \<longleftrightarrow> int' m = int' n"
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   127
  unfolding int'_def by simp
20641
12554634e552 improvements for codegen 2
haftmann
parents: 20597
diff changeset
   128
lemma [code func]: "nat k = (if k < 0 then 0 else nat_of_int k)"
12554634e552 improvements for codegen 2
haftmann
parents: 20597
diff changeset
   129
proof (cases "k < 0")
12554634e552 improvements for codegen 2
haftmann
parents: 20597
diff changeset
   130
  case True then show ?thesis by simp
12554634e552 improvements for codegen 2
haftmann
parents: 20597
diff changeset
   131
next
12554634e552 improvements for codegen 2
haftmann
parents: 20597
diff changeset
   132
  case False then show ?thesis by (simp add: nat_of_int_def)
12554634e552 improvements for codegen 2
haftmann
parents: 20597
diff changeset
   133
qed
20523
36a59e5d0039 Major update to function package, including new syntax and the (only theoretical)
krauss
parents: 20453
diff changeset
   134
lemma [code func]:
23365
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   135
  "int_aux i n = (if int' n = 0 then i else int_aux (i + 1) (nat_of_int (int' n - 1)))"
20641
12554634e552 improvements for codegen 2
haftmann
parents: 20597
diff changeset
   136
proof -
23365
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   137
  have "0 < n \<Longrightarrow> int' n = 1 + int' (nat_of_int (int' n - 1))"
20641
12554634e552 improvements for codegen 2
haftmann
parents: 20597
diff changeset
   138
  proof -
12554634e552 improvements for codegen 2
haftmann
parents: 20597
diff changeset
   139
    assume prem: "n > 0"
23365
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   140
    then have "int' n - 1 \<ge> 0" unfolding int'_def by auto
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   141
    then have "nat_of_int (int' n - 1) = nat (int' n - 1)" by (simp add: nat_of_int_def)
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   142
    with prem show "int' n = 1 + int' (nat_of_int (int' n - 1))" unfolding int'_def by simp
20641
12554634e552 improvements for codegen 2
haftmann
parents: 20597
diff changeset
   143
  qed
23365
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   144
  then show ?thesis unfolding int_aux_def int'_def by simp
20641
12554634e552 improvements for codegen 2
haftmann
parents: 20597
diff changeset
   145
qed
20356
21e7e9093940 improvements for 2nd codegenerator
haftmann
parents: 20287
diff changeset
   146
22395
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   147
lemma div_nat_code [code func]:
23365
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   148
  "m div k = nat_of_int (fst (divAlg (int' m, int' k)))"
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   149
  unfolding div_def [symmetric] int'_def zdiv_int [symmetric]
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   150
  unfolding int'_def [symmetric] nat_of_int_int ..
22395
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   151
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   152
lemma mod_nat_code [code func]:
23365
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   153
  "m mod k = nat_of_int (snd (divAlg (int' m, int' k)))"
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   154
  unfolding mod_def [symmetric] int'_def zmod_int [symmetric]
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   155
  unfolding int'_def [symmetric] nat_of_int_int ..
22395
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   156
20700
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   157
subsection {* Code generator setup for basic functions *}
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   158
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   159
text {*
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   160
  @{typ nat} is no longer a datatype but embedded into the integers.
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   161
*}
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   162
22507
haftmann
parents: 22423
diff changeset
   163
code_datatype nat_of_int
haftmann
parents: 22423
diff changeset
   164
22804
haftmann
parents: 22743
diff changeset
   165
code_type nat
haftmann
parents: 22743
diff changeset
   166
  (SML "IntInf.int")
haftmann
parents: 22743
diff changeset
   167
  (OCaml "Big'_int.big'_int")
haftmann
parents: 22743
diff changeset
   168
  (Haskell "Integer")
20839
ed49d8709959 improvements for code_gen
haftmann
parents: 20713
diff changeset
   169
20700
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   170
types_code
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   171
  nat ("int")
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   172
attach (term_of) {*
21846
c898fdd6ff2d proper use of IntInf instead of InfInf;
wenzelm
parents: 21820
diff changeset
   173
val term_of_nat = HOLogic.mk_number HOLogic.natT o IntInf.fromInt;
20700
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   174
*}
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   175
attach (test) {*
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   176
fun gen_nat i = random_range 0 i;
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   177
*}
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   178
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   179
consts_code
22921
475ff421a6a3 consts in consts_code Isar commands are now referred to by usual term syntax
haftmann
parents: 22900
diff changeset
   180
  "0 \<Colon> nat" ("0")
20700
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   181
  Suc ("(_ + 1)")
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   182
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   183
text {*
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   184
  Since natural numbers are implemented
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   185
  using integers, the coercion function @{const "int"} of type
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   186
  @{typ "nat \<Rightarrow> int"} is simply implemented by the identity function,
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   187
  likewise @{const nat_of_int} of type @{typ "int \<Rightarrow> nat"}.
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   188
  For the @{const "nat"} function for converting an integer to a natural
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   189
  number, we give a specific implementation using an ML function that
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   190
  returns its input value, provided that it is non-negative, and otherwise
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   191
  returns @{text "0"}.
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   192
*}
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   193
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   194
consts_code
23365
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   195
  int' ("(_)")
20700
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   196
  nat ("\<module>nat")
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   197
attach {*
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   198
fun nat i = if i < 0 then 0 else i;
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   199
*}
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   200
23365
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   201
code_const int'
20700
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   202
  (SML "_")
21911
e29bcab0c81c added OCaml code generation (without dictionaries)
haftmann
parents: 21874
diff changeset
   203
  (OCaml "_")
20700
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   204
  (Haskell "_")
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   205
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   206
code_const nat_of_int
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   207
  (SML "_")
21911
e29bcab0c81c added OCaml code generation (without dictionaries)
haftmann
parents: 21874
diff changeset
   208
  (OCaml "_")
20700
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   209
  (Haskell "_")
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   210
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   211
15323
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   212
subsection {* Preprocessors *}
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
text {*
22395
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   215
  Natural numerals should be expressed using @{const nat_of_int}.
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   216
*}
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   217
22845
5f9138bcb3d7 changed code generator invocation syntax
haftmann
parents: 22804
diff changeset
   218
lemmas [code inline del] = nat_number_of_def
22395
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   219
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   220
ML {*
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   221
fun nat_of_int_of_number_of thy cts =
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   222
  let
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   223
    val simplify_less = Simplifier.rewrite 
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   224
      (HOL_basic_ss addsimps (@{thms less_numeral_code} @ @{thms less_eq_numeral_code}));
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   225
    fun mk_rew (t, ty) =
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   226
      if ty = HOLogic.natT andalso IntInf.<= (0, HOLogic.dest_numeral t) then
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   227
        Thm.capply @{cterm "(op \<le>) Numeral.Pls"} (Thm.cterm_of thy t)
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   228
        |> simplify_less
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   229
        |> (fn thm => @{thm nat_of_int_of_number_of_aux} OF [thm])
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   230
        |> (fn thm => @{thm nat_of_int_of_number_of} OF [thm])
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   231
        |> (fn thm => @{thm eq_reflection} OF [thm])
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   232
        |> SOME
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   233
      else NONE
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   234
  in
23269
851b8ea067ac simplified/renamed add_numerals;
wenzelm
parents: 23017
diff changeset
   235
    fold (HOLogic.add_numerals o Thm.term_of) cts []
22395
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   236
    |> map_filter mk_rew
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   237
  end;
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   238
*}
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   239
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   240
setup {*
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   241
  CodegenData.add_inline_proc ("nat_of_int_of_number_of", nat_of_int_of_number_of)
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   242
*}
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   243
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   244
text {*
20700
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   245
  In contrast to @{term "Suc n"}, the term @{term "n + (1::nat)"} is no longer
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   246
  a constructor term. Therefore, all occurrences of this term in a position
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   247
  where a pattern is expected (i.e.\ on the left-hand side of a recursion
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   248
  equation or in the arguments of an inductive relation in an introduction
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   249
  rule) must be eliminated.
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   250
  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
   251
*}
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   252
16900
e294033d1c0f Rewrote function remove_suc, since it failed on some equations
berghofe
parents: 16861
diff changeset
   253
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
   254
  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
   255
  by (case_tac n) simp_all
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   256
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   257
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
   258
  by (case_tac n) simp_all
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   259
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   260
text {*
20700
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   261
  The rules above are built into a preprocessor that is plugged into
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   262
  the code generator. Since the preprocessor for introduction rules
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   263
  does not know anything about modes, some of the modes that worked
7e3450c10c2d updated theory description
haftmann
parents: 20641
diff changeset
   264
  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
   265
*}
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   266
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   267
(*<*)
19791
ab326de16ad5 refined code generation
haftmann
parents: 19617
diff changeset
   268
15323
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   269
ML {*
19791
ab326de16ad5 refined code generation
haftmann
parents: 19617
diff changeset
   270
local
ab326de16ad5 refined code generation
haftmann
parents: 19617
diff changeset
   271
  val Suc_if_eq = thm "Suc_if_eq";
ab326de16ad5 refined code generation
haftmann
parents: 19617
diff changeset
   272
  val Suc_clause = thm "Suc_clause";
ab326de16ad5 refined code generation
haftmann
parents: 19617
diff changeset
   273
  fun contains_suc t = member (op =) (term_consts t) "Suc";
ab326de16ad5 refined code generation
haftmann
parents: 19617
diff changeset
   274
in
15323
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   275
15396
0a36ccb79481 Preprocessors now transfer theorems to current theory in order to
berghofe
parents: 15323
diff changeset
   276
fun remove_suc thy thms =
15323
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   277
  let
15396
0a36ccb79481 Preprocessors now transfer theorems to current theory in order to
berghofe
parents: 15323
diff changeset
   278
    val Suc_if_eq' = Thm.transfer thy Suc_if_eq;
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19889
diff changeset
   279
    val vname = Name.variant (map fst
20196
9a19e4de6e2e renamed add_term_varnames to Term.add_varnames (cf. Term.add_vars etc.);
wenzelm
parents: 20105
diff changeset
   280
      (fold (Term.add_varnames o Thm.full_prop_of) thms [])) "x";
21911
e29bcab0c81c added OCaml code generation (without dictionaries)
haftmann
parents: 21874
diff changeset
   281
    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
   282
    fun lhs_of th = snd (Thm.dest_comb
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   283
      (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
   284
    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
   285
    fun find_vars ct = (case term_of ct of
16900
e294033d1c0f Rewrote function remove_suc, since it failed on some equations
berghofe
parents: 16861
diff changeset
   286
        (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
   287
      | _ $ _ =>
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   288
        let val (ct1, ct2) = Thm.dest_comb ct
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   289
        in 
16900
e294033d1c0f Rewrote function remove_suc, since it failed on some equations
berghofe
parents: 16861
diff changeset
   290
          map (apfst (fn ct => Thm.capply ct ct2)) (find_vars ct1) @
e294033d1c0f Rewrote function remove_suc, since it failed on some equations
berghofe
parents: 16861
diff changeset
   291
          map (apfst (Thm.capply ct1)) (find_vars ct2)
15323
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   292
        end
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   293
      | _ => []);
16900
e294033d1c0f Rewrote function remove_suc, since it failed on some equations
berghofe
parents: 16861
diff changeset
   294
    val eqs = List.concat (map
15323
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   295
      (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: 16861
diff changeset
   296
    fun mk_thms (th, (ct, cv')) =
15323
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   297
      let
16900
e294033d1c0f Rewrote function remove_suc, since it failed on some equations
berghofe
parents: 16861
diff changeset
   298
        val th' =
e294033d1c0f Rewrote function remove_suc, since it failed on some equations
berghofe
parents: 16861
diff changeset
   299
          Thm.implies_elim
22900
f8a7c10e1bd0 moved conversions to structure Conv;
wenzelm
parents: 22845
diff changeset
   300
           (Conv.fconv_rule (Thm.beta_conversion true)
15323
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   301
             (Drule.instantiate'
15531
08c8dad8e399 Deleted Library.option type.
skalberg
parents: 15396
diff changeset
   302
               [SOME (ctyp_of_term ct)] [SOME (Thm.cabs cv ct),
16900
e294033d1c0f Rewrote function remove_suc, since it failed on some equations
berghofe
parents: 16861
diff changeset
   303
                 SOME (Thm.cabs cv' (rhs_of th)), NONE, SOME cv']
e294033d1c0f Rewrote function remove_suc, since it failed on some equations
berghofe
parents: 16861
diff changeset
   304
               Suc_if_eq')) (Thm.forall_intr cv' th)
15323
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   305
      in
21287
a713ae348e8a tuned Variable.trade;
wenzelm
parents: 21191
diff changeset
   306
        case map_filter (fn th'' =>
20287
8cbcb46c3c09 replaced obsolete standard/freeze_all by Variable.trade;
wenzelm
parents: 20196
diff changeset
   307
            SOME (th'', singleton
21287
a713ae348e8a tuned Variable.trade;
wenzelm
parents: 21191
diff changeset
   308
              (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: 16861
diff changeset
   309
          handle THM _ => NONE) thms of
e294033d1c0f Rewrote function remove_suc, since it failed on some equations
berghofe
parents: 16861
diff changeset
   310
            [] => NONE
e294033d1c0f Rewrote function remove_suc, since it failed on some equations
berghofe
parents: 16861
diff changeset
   311
          | thps =>
19791
ab326de16ad5 refined code generation
haftmann
parents: 19617
diff changeset
   312
              let val (ths1, ths2) = split_list thps
22360
26ead7ed4f4b moved eq_thm etc. to structure Thm in Pure/more_thm.ML;
wenzelm
parents: 22320
diff changeset
   313
              in SOME (subtract Thm.eq_thm (th :: ths1) thms @ ths2) end
15323
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   314
      end
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   315
  in
19791
ab326de16ad5 refined code generation
haftmann
parents: 19617
diff changeset
   316
    case get_first mk_thms eqs of
16900
e294033d1c0f Rewrote function remove_suc, since it failed on some equations
berghofe
parents: 16861
diff changeset
   317
      NONE => thms
e294033d1c0f Rewrote function remove_suc, since it failed on some equations
berghofe
parents: 16861
diff changeset
   318
    | SOME x => remove_suc thy x
15323
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   319
  end;
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   320
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   321
fun eqn_suc_preproc thy ths =
19791
ab326de16ad5 refined code generation
haftmann
parents: 19617
diff changeset
   322
  let
ab326de16ad5 refined code generation
haftmann
parents: 19617
diff changeset
   323
    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
   324
  in
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   325
    if forall (can dest) ths andalso
19791
ab326de16ad5 refined code generation
haftmann
parents: 19617
diff changeset
   326
      exists (contains_suc o dest) ths
15396
0a36ccb79481 Preprocessors now transfer theorems to current theory in order to
berghofe
parents: 15323
diff changeset
   327
    then remove_suc thy ths else ths
15323
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   328
  end;
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   329
15396
0a36ccb79481 Preprocessors now transfer theorems to current theory in order to
berghofe
parents: 15323
diff changeset
   330
fun remove_suc_clause thy thms =
15323
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   331
  let
15396
0a36ccb79481 Preprocessors now transfer theorems to current theory in order to
berghofe
parents: 15323
diff changeset
   332
    val Suc_clause' = Thm.transfer thy Suc_clause;
20071
8f3e1ddb50e6 replaced Term.variant(list) by Name.variant(_list);
wenzelm
parents: 19889
diff changeset
   333
    val vname = Name.variant (map fst
20196
9a19e4de6e2e renamed add_term_varnames to Term.add_varnames (cf. Term.add_vars etc.);
wenzelm
parents: 20105
diff changeset
   334
      (fold (Term.add_varnames o Thm.full_prop_of) thms [])) "x";
15531
08c8dad8e399 Deleted Library.option type.
skalberg
parents: 15396
diff changeset
   335
    fun find_var (t as Const ("Suc", _) $ (v as Var _)) = SOME (t, v)
08c8dad8e399 Deleted Library.option type.
skalberg
parents: 15396
diff changeset
   336
      | find_var (t $ u) = (case find_var t of NONE => find_var u | x => x)
08c8dad8e399 Deleted Library.option type.
skalberg
parents: 15396
diff changeset
   337
      | find_var _ = NONE;
15323
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   338
    fun find_thm th =
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   339
      let val th' = ObjectLogic.atomize_thm th
15570
8d8c70b41bab Move towards standard functions.
skalberg
parents: 15531
diff changeset
   340
      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
   341
  in
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   342
    case get_first find_thm thms of
15531
08c8dad8e399 Deleted Library.option type.
skalberg
parents: 15396
diff changeset
   343
      NONE => thms
08c8dad8e399 Deleted Library.option type.
skalberg
parents: 15396
diff changeset
   344
    | SOME ((th, th'), (Sucv, v)) =>
15323
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   345
        let
16861
7446b4be013b tuned fold on terms;
wenzelm
parents: 16770
diff changeset
   346
          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
   347
          val th'' = ObjectLogic.rulify (Thm.implies_elim
22900
f8a7c10e1bd0 moved conversions to structure Conv;
wenzelm
parents: 22845
diff changeset
   348
            (Conv.fconv_rule (Thm.beta_conversion true)
15323
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   349
              (Drule.instantiate' []
15531
08c8dad8e399 Deleted Library.option type.
skalberg
parents: 15396
diff changeset
   350
                [SOME (cert (lambda v (Abs ("x", HOLogic.natT,
15323
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   351
                   abstract_over (Sucv,
19828
f1dccc547595 Removed "code del" declarations again.
berghofe
parents: 19791
diff changeset
   352
                     HOLogic.dest_Trueprop (prop_of th')))))),
15531
08c8dad8e399 Deleted Library.option type.
skalberg
parents: 15396
diff changeset
   353
                 SOME (cert v)] Suc_clause'))
15323
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   354
            (Thm.forall_intr (cert v) th'))
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   355
        in
15396
0a36ccb79481 Preprocessors now transfer theorems to current theory in order to
berghofe
parents: 15323
diff changeset
   356
          remove_suc_clause thy (map (fn th''' =>
19617
7cb4b67d4b97 avoid raw equality on type thm;
wenzelm
parents: 19603
diff changeset
   357
            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
   358
        end
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   359
  end;
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   360
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   361
fun clause_suc_preproc thy ths =
19791
ab326de16ad5 refined code generation
haftmann
parents: 19617
diff changeset
   362
  let
19828
f1dccc547595 Removed "code del" declarations again.
berghofe
parents: 19791
diff changeset
   363
    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
   364
  in
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   365
    if forall (can (dest o concl_of)) ths andalso
19791
ab326de16ad5 refined code generation
haftmann
parents: 19617
diff changeset
   366
      exists (fn th => member (op =) (foldr add_term_consts
21287
a713ae348e8a tuned Variable.trade;
wenzelm
parents: 21191
diff changeset
   367
        [] (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: 15323
diff changeset
   368
    then remove_suc_clause thy ths else ths
15323
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   369
  end;
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   370
19791
ab326de16ad5 refined code generation
haftmann
parents: 19617
diff changeset
   371
end; (*local*)
ab326de16ad5 refined code generation
haftmann
parents: 19617
diff changeset
   372
22743
e2b06bfe471a improved case unfolding
haftmann
parents: 22507
diff changeset
   373
fun lift_obj_eq f thy =
e2b06bfe471a improved case unfolding
haftmann
parents: 22507
diff changeset
   374
  map (fn thm => thm RS @{thm meta_eq_to_obj_eq})
19791
ab326de16ad5 refined code generation
haftmann
parents: 19617
diff changeset
   375
  #> f thy
22928
1feef3b54ce1 beta/eta conversion after preprocessor
haftmann
parents: 22921
diff changeset
   376
  #> map (fn thm => thm RS @{thm eq_reflection})
1feef3b54ce1 beta/eta conversion after preprocessor
haftmann
parents: 22921
diff changeset
   377
  #> map (Conv.fconv_rule Drule.beta_eta_conversion)
19791
ab326de16ad5 refined code generation
haftmann
parents: 19617
diff changeset
   378
*}
ab326de16ad5 refined code generation
haftmann
parents: 19617
diff changeset
   379
ab326de16ad5 refined code generation
haftmann
parents: 19617
diff changeset
   380
setup {*
19603
9801b391c8b3 added preprocs for CodegenTheorems
haftmann
parents: 19481
diff changeset
   381
  Codegen.add_preprocessor eqn_suc_preproc
9801b391c8b3 added preprocs for CodegenTheorems
haftmann
parents: 19481
diff changeset
   382
  #> Codegen.add_preprocessor clause_suc_preproc
22046
ce84c9887e2d named preprocessors
haftmann
parents: 21911
diff changeset
   383
  #> CodegenData.add_preproc ("eqn_Suc", lift_obj_eq eqn_suc_preproc)
ce84c9887e2d named preprocessors
haftmann
parents: 21911
diff changeset
   384
  #> 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
   385
*}
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   386
(*>*)
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   387
21191
c00161fbf990 code generator module naming improved
haftmann
parents: 21125
diff changeset
   388
subsection {* Module names *}
c00161fbf990 code generator module naming improved
haftmann
parents: 21125
diff changeset
   389
c00161fbf990 code generator module naming improved
haftmann
parents: 21125
diff changeset
   390
code_modulename SML
c00161fbf990 code generator module naming improved
haftmann
parents: 21125
diff changeset
   391
  Nat Integer
c00161fbf990 code generator module naming improved
haftmann
parents: 21125
diff changeset
   392
  EfficientNat Integer
c00161fbf990 code generator module naming improved
haftmann
parents: 21125
diff changeset
   393
21911
e29bcab0c81c added OCaml code generation (without dictionaries)
haftmann
parents: 21874
diff changeset
   394
code_modulename OCaml
e29bcab0c81c added OCaml code generation (without dictionaries)
haftmann
parents: 21874
diff changeset
   395
  Nat Integer
e29bcab0c81c added OCaml code generation (without dictionaries)
haftmann
parents: 21874
diff changeset
   396
  EfficientNat Integer
e29bcab0c81c added OCaml code generation (without dictionaries)
haftmann
parents: 21874
diff changeset
   397
23017
00c0e4c42396 uniform module names for code generation
haftmann
parents: 22928
diff changeset
   398
code_modulename Haskell
00c0e4c42396 uniform module names for code generation
haftmann
parents: 22928
diff changeset
   399
  Nat Integer
00c0e4c42396 uniform module names for code generation
haftmann
parents: 22928
diff changeset
   400
  EfficientNat Integer
00c0e4c42396 uniform module names for code generation
haftmann
parents: 22928
diff changeset
   401
23365
f31794033ae1 removed constant int :: nat => int;
huffman
parents: 23269
diff changeset
   402
hide const nat_of_int int'
22395
b573f1f566e1 improved handling of nat numerals
haftmann
parents: 22360
diff changeset
   403
15323
6c10fe1c0e17 Code generator plug-in for implementing natural numbers by integers.
berghofe
parents:
diff changeset
   404
end