src/HOL/Library/Code_Nat.thy
author Christian Sternagel
Thu, 30 Aug 2012 13:05:11 +0900
changeset 49087 7a17ba4bc997
parent 47108 2a1953f0d20d
permissions -rw-r--r--
added author
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
47108
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
     1
(*  Title:      HOL/Library/Code_Nat.thy
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
     2
    Author:     Stefan Berghofer, Florian Haftmann, TU Muenchen
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
     3
*)
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
     4
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
     5
header {* Implementation of natural numbers as binary numerals *}
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
     6
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
     7
theory Code_Nat
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
     8
imports Main
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
     9
begin
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    10
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    11
text {*
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    12
  When generating code for functions on natural numbers, the
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    13
  canonical representation using @{term "0::nat"} and
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    14
  @{term Suc} is unsuitable for computations involving large
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    15
  numbers.  This theory refines the representation of
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    16
  natural numbers for code generation to use binary
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    17
  numerals, which do not grow linear in size but logarithmic.
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    18
*}
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    19
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    20
subsection {* Representation *}
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    21
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    22
lemma [code_abbrev]:
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    23
  "nat_of_num = numeral"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    24
  by (fact nat_of_num_numeral)
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    25
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    26
code_datatype "0::nat" nat_of_num
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    27
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    28
lemma [code]:
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    29
  "num_of_nat 0 = Num.One"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    30
  "num_of_nat (nat_of_num k) = k"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    31
  by (simp_all add: nat_of_num_inverse)
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    32
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    33
lemma [code]:
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    34
  "(1\<Colon>nat) = Numeral1"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    35
  by simp
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    36
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    37
lemma [code_abbrev]: "Numeral1 = (1\<Colon>nat)"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    38
  by simp
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    39
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    40
lemma [code]:
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    41
  "Suc n = n + 1"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    42
  by simp
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    43
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    44
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    45
subsection {* Basic arithmetic *}
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    46
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    47
lemma [code, code del]:
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    48
  "(plus :: nat \<Rightarrow> _) = plus" ..
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    49
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    50
lemma plus_nat_code [code]:
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    51
  "nat_of_num k + nat_of_num l = nat_of_num (k + l)"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    52
  "m + 0 = (m::nat)"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    53
  "0 + n = (n::nat)"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    54
  by (simp_all add: nat_of_num_numeral)
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    55
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    56
text {* Bounded subtraction needs some auxiliary *}
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    57
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    58
definition dup :: "nat \<Rightarrow> nat" where
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    59
  "dup n = n + n"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    60
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    61
lemma dup_code [code]:
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    62
  "dup 0 = 0"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    63
  "dup (nat_of_num k) = nat_of_num (Num.Bit0 k)"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    64
  unfolding Num_def by (simp_all add: dup_def numeral_Bit0)
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    65
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    66
definition sub :: "num \<Rightarrow> num \<Rightarrow> nat option" where
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    67
  "sub k l = (if k \<ge> l then Some (numeral k - numeral l) else None)"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    68
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    69
lemma sub_code [code]:
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    70
  "sub Num.One Num.One = Some 0"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    71
  "sub (Num.Bit0 m) Num.One = Some (nat_of_num (Num.BitM m))"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    72
  "sub (Num.Bit1 m) Num.One = Some (nat_of_num (Num.Bit0 m))"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    73
  "sub Num.One (Num.Bit0 n) = None"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    74
  "sub Num.One (Num.Bit1 n) = None"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    75
  "sub (Num.Bit0 m) (Num.Bit0 n) = Option.map dup (sub m n)"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    76
  "sub (Num.Bit1 m) (Num.Bit1 n) = Option.map dup (sub m n)"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    77
  "sub (Num.Bit1 m) (Num.Bit0 n) = Option.map (\<lambda>q. dup q + 1) (sub m n)"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    78
  "sub (Num.Bit0 m) (Num.Bit1 n) = (case sub m n of None \<Rightarrow> None
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    79
     | Some q \<Rightarrow> if q = 0 then None else Some (dup q - 1))"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    80
  apply (auto simp add: nat_of_num_numeral
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    81
    Num.dbl_def Num.dbl_inc_def Num.dbl_dec_def
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    82
    Let_def le_imp_diff_is_add BitM_plus_one sub_def dup_def)
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    83
  apply (simp_all add: sub_non_positive)
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    84
  apply (simp_all add: sub_non_negative [symmetric, where ?'a = int])
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    85
  done
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    86
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    87
lemma [code, code del]:
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    88
  "(minus :: nat \<Rightarrow> _) = minus" ..
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    89
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    90
lemma minus_nat_code [code]:
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    91
  "nat_of_num k - nat_of_num l = (case sub k l of None \<Rightarrow> 0 | Some j \<Rightarrow> j)"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    92
  "m - 0 = (m::nat)"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    93
  "0 - n = (0::nat)"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    94
  by (simp_all add: nat_of_num_numeral sub_non_positive sub_def)
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    95
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    96
lemma [code, code del]:
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    97
  "(times :: nat \<Rightarrow> _) = times" ..
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    98
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
    99
lemma times_nat_code [code]:
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   100
  "nat_of_num k * nat_of_num l = nat_of_num (k * l)"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   101
  "m * 0 = (0::nat)"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   102
  "0 * n = (0::nat)"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   103
  by (simp_all add: nat_of_num_numeral)
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   104
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   105
lemma [code, code del]:
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   106
  "(HOL.equal :: nat \<Rightarrow> _) = HOL.equal" ..
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   107
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   108
lemma equal_nat_code [code]:
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   109
  "HOL.equal 0 (0::nat) \<longleftrightarrow> True"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   110
  "HOL.equal 0 (nat_of_num l) \<longleftrightarrow> False"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   111
  "HOL.equal (nat_of_num k) 0 \<longleftrightarrow> False"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   112
  "HOL.equal (nat_of_num k) (nat_of_num l) \<longleftrightarrow> HOL.equal k l"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   113
  by (simp_all add: nat_of_num_numeral equal)
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   114
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   115
lemma equal_nat_refl [code nbe]:
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   116
  "HOL.equal (n::nat) n \<longleftrightarrow> True"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   117
  by (rule equal_refl)
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   118
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   119
lemma [code, code del]:
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   120
  "(less_eq :: nat \<Rightarrow> _) = less_eq" ..
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   121
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   122
lemma less_eq_nat_code [code]:
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   123
  "0 \<le> (n::nat) \<longleftrightarrow> True"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   124
  "nat_of_num k \<le> 0 \<longleftrightarrow> False"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   125
  "nat_of_num k \<le> nat_of_num l \<longleftrightarrow> k \<le> l"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   126
  by (simp_all add: nat_of_num_numeral)
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   127
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   128
lemma [code, code del]:
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   129
  "(less :: nat \<Rightarrow> _) = less" ..
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   130
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   131
lemma less_nat_code [code]:
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   132
  "(m::nat) < 0 \<longleftrightarrow> False"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   133
  "0 < nat_of_num l \<longleftrightarrow> True"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   134
  "nat_of_num k < nat_of_num l \<longleftrightarrow> k < l"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   135
  by (simp_all add: nat_of_num_numeral)
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   136
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   137
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   138
subsection {* Conversions *}
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   139
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   140
lemma [code, code del]:
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   141
  "of_nat = of_nat" ..
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   142
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   143
lemma of_nat_code [code]:
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   144
  "of_nat 0 = 0"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   145
  "of_nat (nat_of_num k) = numeral k"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   146
  by (simp_all add: nat_of_num_numeral)
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   147
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   148
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   149
subsection {* Case analysis *}
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   150
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   151
text {*
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   152
  Case analysis on natural numbers is rephrased using a conditional
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   153
  expression:
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   154
*}
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   155
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   156
lemma [code, code_unfold]:
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   157
  "nat_case = (\<lambda>f g n. if n = 0 then f else g (n - 1))"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   158
  by (auto simp add: fun_eq_iff dest!: gr0_implies_Suc)
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   159
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   160
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   161
subsection {* Preprocessors *}
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   162
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   163
text {*
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   164
  The term @{term "Suc n"} is no longer a valid pattern.
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   165
  Therefore, all occurrences of this term in a position
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   166
  where a pattern is expected (i.e.~on the left-hand side of a recursion
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   167
  equation) must be eliminated.
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   168
  This can be accomplished by applying the following transformation rules:
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   169
*}
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   170
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   171
lemma Suc_if_eq: "(\<And>n. f (Suc n) \<equiv> h n) \<Longrightarrow> f 0 \<equiv> g \<Longrightarrow>
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   172
  f n \<equiv> if n = 0 then g else h (n - 1)"
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   173
  by (rule eq_reflection) (cases n, simp_all)
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   174
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   175
text {*
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   176
  The rules above are built into a preprocessor that is plugged into
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   177
  the code generator. Since the preprocessor for introduction rules
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   178
  does not know anything about modes, some of the modes that worked
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   179
  for the canonical representation of natural numbers may no longer work.
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   180
*}
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   181
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   182
(*<*)
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   183
setup {*
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   184
let
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   185
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   186
fun remove_suc thy thms =
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   187
  let
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   188
    val vname = singleton (Name.variant_list (map fst
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   189
      (fold (Term.add_var_names o Thm.full_prop_of) thms []))) "n";
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   190
    val cv = cterm_of thy (Var ((vname, 0), HOLogic.natT));
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   191
    fun lhs_of th = snd (Thm.dest_comb
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   192
      (fst (Thm.dest_comb (cprop_of th))));
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   193
    fun rhs_of th = snd (Thm.dest_comb (cprop_of th));
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   194
    fun find_vars ct = (case term_of ct of
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   195
        (Const (@{const_name Suc}, _) $ Var _) => [(cv, snd (Thm.dest_comb ct))]
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   196
      | _ $ _ =>
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   197
        let val (ct1, ct2) = Thm.dest_comb ct
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   198
        in 
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   199
          map (apfst (fn ct => Thm.apply ct ct2)) (find_vars ct1) @
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   200
          map (apfst (Thm.apply ct1)) (find_vars ct2)
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   201
        end
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   202
      | _ => []);
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   203
    val eqs = maps
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   204
      (fn th => map (pair th) (find_vars (lhs_of th))) thms;
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   205
    fun mk_thms (th, (ct, cv')) =
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   206
      let
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   207
        val th' =
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   208
          Thm.implies_elim
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   209
           (Conv.fconv_rule (Thm.beta_conversion true)
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   210
             (Drule.instantiate'
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   211
               [SOME (ctyp_of_term ct)] [SOME (Thm.lambda cv ct),
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   212
                 SOME (Thm.lambda cv' (rhs_of th)), NONE, SOME cv']
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   213
               @{thm Suc_if_eq})) (Thm.forall_intr cv' th)
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   214
      in
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   215
        case map_filter (fn th'' =>
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   216
            SOME (th'', singleton
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   217
              (Variable.trade (K (fn [th'''] => [th''' RS th']))
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   218
                (Variable.global_thm_context th'')) th'')
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   219
          handle THM _ => NONE) thms of
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   220
            [] => NONE
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   221
          | thps =>
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   222
              let val (ths1, ths2) = split_list thps
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   223
              in SOME (subtract Thm.eq_thm (th :: ths1) thms @ ths2) end
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   224
      end
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   225
  in get_first mk_thms eqs end;
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   226
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   227
fun eqn_suc_base_preproc thy thms =
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   228
  let
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   229
    val dest = fst o Logic.dest_equals o prop_of;
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   230
    val contains_suc = exists_Const (fn (c, _) => c = @{const_name Suc});
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   231
  in
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   232
    if forall (can dest) thms andalso exists (contains_suc o dest) thms
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   233
      then thms |> perhaps_loop (remove_suc thy) |> (Option.map o map) Drule.zero_var_indexes
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   234
       else NONE
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   235
  end;
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   236
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   237
val eqn_suc_preproc = Code_Preproc.simple_functrans eqn_suc_base_preproc;
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   238
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   239
in
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   240
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   241
  Code_Preproc.add_functrans ("eqn_Suc", eqn_suc_preproc)
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   242
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   243
end;
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   244
*}
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   245
(*>*)
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   246
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   247
code_modulename SML
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   248
  Code_Nat Arith
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   249
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   250
code_modulename OCaml
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   251
  Code_Nat Arith
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   252
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   253
code_modulename Haskell
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   254
  Code_Nat Arith
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   255
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   256
hide_const (open) dup sub
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   257
2a1953f0d20d merged fork with new numeral representation (see NEWS)
huffman
parents:
diff changeset
   258
end