src/HOL/Integ/NatBin.thy
author obua
Tue, 11 May 2004 20:11:08 +0200
changeset 14738 83f1a514dcb4
parent 14467 bbfa6b01a55f
child 15003 6145dd7538d7
permissions -rw-r--r--
changes made due to new Ring_and_Field theory
     1 (*  Title:      HOL/NatBin.thy
     2     ID:         $Id$
     3     Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
     4     Copyright   1999  University of Cambridge
     5 *)
     6 
     7 header {* Binary arithmetic for the natural numbers *}
     8 
     9 theory NatBin = IntDiv:
    10 
    11 text {*
    12   Arithmetic for naturals is reduced to that for the non-negative integers.
    13 *}
    14 
    15 instance nat :: number ..
    16 
    17 defs (overloaded)
    18   nat_number_of_def:
    19      "(number_of::bin => nat) v == nat ((number_of :: bin => int) v)"
    20 
    21 
    22 subsection{*Function @{term nat}: Coercion from Type @{typ int} to @{typ nat}*}
    23 
    24 declare nat_0 [simp] nat_1 [simp]
    25 
    26 lemma nat_number_of [simp]: "nat (number_of w) = number_of w"
    27 by (simp add: nat_number_of_def)
    28 
    29 lemma nat_numeral_0_eq_0 [simp]: "Numeral0 = (0::nat)"
    30 by (simp add: nat_number_of_def)
    31 
    32 lemma nat_numeral_1_eq_1 [simp]: "Numeral1 = (1::nat)"
    33 by (simp add: nat_1 nat_number_of_def)
    34 
    35 lemma numeral_1_eq_Suc_0: "Numeral1 = Suc 0"
    36 by (simp add: nat_numeral_1_eq_1)
    37 
    38 lemma numeral_2_eq_2: "2 = Suc (Suc 0)"
    39 apply (unfold nat_number_of_def)
    40 apply (rule nat_2)
    41 done
    42 
    43 
    44 text{*Distributive laws for type @{text nat}.  The others are in theory
    45    @{text IntArith}, but these require div and mod to be defined for type
    46    "int".  They also need some of the lemmas proved above.*}
    47 
    48 lemma nat_div_distrib: "(0::int) <= z ==> nat (z div z') = nat z div nat z'"
    49 apply (case_tac "0 <= z'")
    50 apply (auto simp add: div_nonneg_neg_le0 DIVISION_BY_ZERO_DIV)
    51 apply (case_tac "z' = 0", simp add: DIVISION_BY_ZERO)
    52 apply (auto elim!: nonneg_eq_int)
    53 apply (rename_tac m m')
    54 apply (subgoal_tac "0 <= int m div int m'")
    55  prefer 2 apply (simp add: nat_numeral_0_eq_0 pos_imp_zdiv_nonneg_iff) 
    56 apply (rule inj_int [THEN injD], simp)
    57 apply (rule_tac r = "int (m mod m') " in quorem_div)
    58  prefer 2 apply force
    59 apply (simp add: nat_less_iff [symmetric] quorem_def nat_numeral_0_eq_0 zadd_int 
    60                  zmult_int)
    61 done
    62 
    63 (*Fails if z'<0: the LHS collapses to (nat z) but the RHS doesn't*)
    64 lemma nat_mod_distrib:
    65      "[| (0::int) <= z;  0 <= z' |] ==> nat (z mod z') = nat z mod nat z'"
    66 apply (case_tac "z' = 0", simp add: DIVISION_BY_ZERO)
    67 apply (auto elim!: nonneg_eq_int)
    68 apply (rename_tac m m')
    69 apply (subgoal_tac "0 <= int m mod int m'")
    70  prefer 2 apply (simp add: nat_less_iff nat_numeral_0_eq_0 pos_mod_sign) 
    71 apply (rule inj_int [THEN injD], simp)
    72 apply (rule_tac q = "int (m div m') " in quorem_mod)
    73  prefer 2 apply force
    74 apply (simp add: nat_less_iff [symmetric] quorem_def nat_numeral_0_eq_0 zadd_int zmult_int)
    75 done
    76 
    77 
    78 subsection{*Function @{term int}: Coercion from Type @{typ nat} to @{typ int}*}
    79 
    80 (*"neg" is used in rewrite rules for binary comparisons*)
    81 lemma int_nat_number_of [simp]:
    82      "int (number_of v :: nat) =  
    83          (if neg (number_of v :: int) then 0  
    84           else (number_of v :: int))"
    85 by (simp del: nat_number_of
    86 	 add: neg_nat nat_number_of_def not_neg_nat add_assoc)
    87 
    88 
    89 subsubsection{*Successor *}
    90 
    91 lemma Suc_nat_eq_nat_zadd1: "(0::int) <= z ==> Suc (nat z) = nat (1 + z)"
    92 apply (rule sym)
    93 apply (simp add: nat_eq_iff int_Suc)
    94 done
    95 
    96 lemma Suc_nat_number_of_add:
    97      "Suc (number_of v + n) =  
    98         (if neg (number_of v :: int) then 1+n else number_of (bin_succ v) + n)" 
    99 by (simp del: nat_number_of 
   100          add: nat_number_of_def neg_nat
   101               Suc_nat_eq_nat_zadd1 number_of_succ) 
   102 
   103 lemma Suc_nat_number_of [simp]:
   104      "Suc (number_of v) =  
   105         (if neg (number_of v :: int) then 1 else number_of (bin_succ v))"
   106 apply (cut_tac n = 0 in Suc_nat_number_of_add)
   107 apply (simp cong del: if_weak_cong)
   108 done
   109 
   110 
   111 subsubsection{*Addition *}
   112 
   113 (*"neg" is used in rewrite rules for binary comparisons*)
   114 lemma add_nat_number_of [simp]:
   115      "(number_of v :: nat) + number_of v' =  
   116          (if neg (number_of v :: int) then number_of v'  
   117           else if neg (number_of v' :: int) then number_of v  
   118           else number_of (bin_add v v'))"
   119 by (force dest!: neg_nat
   120           simp del: nat_number_of
   121           simp add: nat_number_of_def nat_add_distrib [symmetric]) 
   122 
   123 
   124 subsubsection{*Subtraction *}
   125 
   126 lemma diff_nat_eq_if:
   127      "nat z - nat z' =  
   128         (if neg z' then nat z   
   129          else let d = z-z' in     
   130               if neg d then 0 else nat d)"
   131 apply (simp add: Let_def nat_diff_distrib [symmetric] neg_eq_less_0 not_neg_eq_ge_0)
   132 apply (simp add: diff_is_0_eq nat_le_eq_zle)
   133 done
   134 
   135 lemma diff_nat_number_of [simp]: 
   136      "(number_of v :: nat) - number_of v' =  
   137         (if neg (number_of v' :: int) then number_of v  
   138          else let d = number_of (bin_add v (bin_minus v')) in     
   139               if neg d then 0 else nat d)"
   140 by (simp del: nat_number_of add: diff_nat_eq_if nat_number_of_def) 
   141 
   142 
   143 
   144 subsubsection{*Multiplication *}
   145 
   146 lemma mult_nat_number_of [simp]:
   147      "(number_of v :: nat) * number_of v' =  
   148        (if neg (number_of v :: int) then 0 else number_of (bin_mult v v'))"
   149 by (force dest!: neg_nat
   150           simp del: nat_number_of
   151           simp add: nat_number_of_def nat_mult_distrib [symmetric]) 
   152 
   153 
   154 
   155 subsubsection{*Quotient *}
   156 
   157 lemma div_nat_number_of [simp]:
   158      "(number_of v :: nat)  div  number_of v' =  
   159           (if neg (number_of v :: int) then 0  
   160            else nat (number_of v div number_of v'))"
   161 by (force dest!: neg_nat
   162           simp del: nat_number_of
   163           simp add: nat_number_of_def nat_div_distrib [symmetric]) 
   164 
   165 lemma one_div_nat_number_of [simp]:
   166      "(Suc 0)  div  number_of v' = (nat (1 div number_of v'))" 
   167 by (simp del: nat_numeral_1_eq_1 add: numeral_1_eq_Suc_0 [symmetric]) 
   168 
   169 
   170 subsubsection{*Remainder *}
   171 
   172 lemma mod_nat_number_of [simp]:
   173      "(number_of v :: nat)  mod  number_of v' =  
   174         (if neg (number_of v :: int) then 0  
   175          else if neg (number_of v' :: int) then number_of v  
   176          else nat (number_of v mod number_of v'))"
   177 by (force dest!: neg_nat
   178           simp del: nat_number_of
   179           simp add: nat_number_of_def nat_mod_distrib [symmetric]) 
   180 
   181 lemma one_mod_nat_number_of [simp]:
   182      "(Suc 0)  mod  number_of v' =  
   183         (if neg (number_of v' :: int) then Suc 0
   184          else nat (1 mod number_of v'))"
   185 by (simp del: nat_numeral_1_eq_1 add: numeral_1_eq_Suc_0 [symmetric]) 
   186 
   187 
   188 
   189 ML
   190 {*
   191 val nat_number_of_def = thm"nat_number_of_def";
   192 
   193 val nat_number_of = thm"nat_number_of";
   194 val nat_numeral_0_eq_0 = thm"nat_numeral_0_eq_0";
   195 val nat_numeral_1_eq_1 = thm"nat_numeral_1_eq_1";
   196 val numeral_1_eq_Suc_0 = thm"numeral_1_eq_Suc_0";
   197 val numeral_2_eq_2 = thm"numeral_2_eq_2";
   198 val nat_div_distrib = thm"nat_div_distrib";
   199 val nat_mod_distrib = thm"nat_mod_distrib";
   200 val int_nat_number_of = thm"int_nat_number_of";
   201 val Suc_nat_eq_nat_zadd1 = thm"Suc_nat_eq_nat_zadd1";
   202 val Suc_nat_number_of_add = thm"Suc_nat_number_of_add";
   203 val Suc_nat_number_of = thm"Suc_nat_number_of";
   204 val add_nat_number_of = thm"add_nat_number_of";
   205 val diff_nat_eq_if = thm"diff_nat_eq_if";
   206 val diff_nat_number_of = thm"diff_nat_number_of";
   207 val mult_nat_number_of = thm"mult_nat_number_of";
   208 val div_nat_number_of = thm"div_nat_number_of";
   209 val mod_nat_number_of = thm"mod_nat_number_of";
   210 *}
   211 
   212 
   213 subsection{*Comparisons*}
   214 
   215 subsubsection{*Equals (=) *}
   216 
   217 lemma eq_nat_nat_iff:
   218      "[| (0::int) <= z;  0 <= z' |] ==> (nat z = nat z') = (z=z')"
   219 by (auto elim!: nonneg_eq_int)
   220 
   221 (*"neg" is used in rewrite rules for binary comparisons*)
   222 lemma eq_nat_number_of [simp]:
   223      "((number_of v :: nat) = number_of v') =  
   224       (if neg (number_of v :: int) then (iszero (number_of v' :: int) | neg (number_of v' :: int))  
   225        else if neg (number_of v' :: int) then iszero (number_of v :: int)  
   226        else iszero (number_of (bin_add v (bin_minus v')) :: int))"
   227 apply (simp only: simp_thms neg_nat not_neg_eq_ge_0 nat_number_of_def
   228                   eq_nat_nat_iff eq_number_of_eq nat_0 iszero_def
   229             split add: split_if cong add: imp_cong)
   230 apply (simp only: nat_eq_iff nat_eq_iff2)
   231 apply (simp add: not_neg_eq_ge_0 [symmetric])
   232 done
   233 
   234 
   235 subsubsection{*Less-than (<) *}
   236 
   237 (*"neg" is used in rewrite rules for binary comparisons*)
   238 lemma less_nat_number_of [simp]:
   239      "((number_of v :: nat) < number_of v') =  
   240          (if neg (number_of v :: int) then neg (number_of (bin_minus v') :: int)  
   241           else neg (number_of (bin_add v (bin_minus v')) :: int))"
   242 by (simp only: simp_thms neg_nat not_neg_eq_ge_0 nat_number_of_def
   243                 nat_less_eq_zless less_number_of_eq_neg zless_nat_eq_int_zless
   244          cong add: imp_cong, simp) 
   245 
   246 
   247 
   248 
   249 (*Maps #n to n for n = 0, 1, 2*)
   250 lemmas numerals = nat_numeral_0_eq_0 nat_numeral_1_eq_1 numeral_2_eq_2
   251 
   252 
   253 subsection{*General Theorems About Powers Involving Binary Numerals*}
   254 
   255 text{*We cannot refer to the number @{term 2} in @{text Ring_and_Field.thy}.
   256 We cannot prove general results about the numeral @{term "-1"}, so we have to
   257 use @{term "- 1"} instead.*}
   258 
   259 lemma power2_eq_square: "(a::'a::{comm_semiring_1_cancel,ringpower})\<twosuperior> = a * a"
   260   by (simp add: numeral_2_eq_2 Power.power_Suc)
   261 
   262 lemma [simp]: "(0::'a::{comm_semiring_1_cancel,ringpower})\<twosuperior> = 0"
   263   by (simp add: power2_eq_square)
   264 
   265 lemma [simp]: "(1::'a::{comm_semiring_1_cancel,ringpower})\<twosuperior> = 1"
   266   by (simp add: power2_eq_square)
   267 
   268 text{*Squares of literal numerals will be evaluated.*}
   269 declare power2_eq_square [of "number_of w", standard, simp]
   270 
   271 lemma zero_le_power2 [simp]: "0 \<le> (a\<twosuperior>::'a::{ordered_idom,ringpower})"
   272   by (simp add: power2_eq_square zero_le_square)
   273 
   274 lemma zero_less_power2 [simp]:
   275      "(0 < a\<twosuperior>) = (a \<noteq> (0::'a::{ordered_idom,ringpower}))"
   276   by (force simp add: power2_eq_square zero_less_mult_iff linorder_neq_iff)
   277 
   278 lemma zero_eq_power2 [simp]:
   279      "(a\<twosuperior> = 0) = (a = (0::'a::{ordered_idom,ringpower}))"
   280   by (force simp add: power2_eq_square mult_eq_0_iff)
   281 
   282 lemma abs_power2 [simp]:
   283      "abs(a\<twosuperior>) = (a\<twosuperior>::'a::{ordered_idom,ringpower})"
   284   by (simp add: power2_eq_square abs_mult abs_mult_self)
   285 
   286 lemma power2_abs [simp]:
   287      "(abs a)\<twosuperior> = (a\<twosuperior>::'a::{ordered_idom,ringpower})"
   288   by (simp add: power2_eq_square abs_mult_self)
   289 
   290 lemma power2_minus [simp]:
   291      "(- a)\<twosuperior> = (a\<twosuperior>::'a::{comm_ring_1,ringpower})"
   292   by (simp add: power2_eq_square)
   293 
   294 lemma power_minus1_even: "(- 1) ^ (2*n) = (1::'a::{comm_ring_1,ringpower})"
   295 apply (induct_tac "n")
   296 apply (auto simp add: power_Suc power_add)
   297 done
   298 
   299 lemma power_even_eq: "(a::'a::ringpower) ^ (2*n) = (a^n)^2"
   300 by (simp add: power_mult power_mult_distrib power2_eq_square)
   301 
   302 lemma power_odd_eq: "(a::int) ^ Suc(2*n) = a * (a^n)^2"
   303 by (simp add: power_even_eq) 
   304 
   305 lemma power_minus_even [simp]:
   306      "(-a) ^ (2*n) = (a::'a::{comm_ring_1,ringpower}) ^ (2*n)"
   307 by (simp add: power_minus1_even power_minus [of a]) 
   308 
   309 lemma zero_le_even_power:
   310      "0 \<le> (a::'a::{ordered_idom,ringpower}) ^ (2*n)"
   311 proof (induct "n")
   312   case 0
   313     show ?case by (simp add: zero_le_one)
   314 next
   315   case (Suc n)
   316     have "a ^ (2 * Suc n) = (a*a) * a ^ (2*n)" 
   317       by (simp add: mult_ac power_add power2_eq_square)
   318     thus ?case
   319       by (simp add: prems zero_le_square zero_le_mult_iff)
   320 qed
   321 
   322 lemma odd_power_less_zero:
   323      "(a::'a::{ordered_idom,ringpower}) < 0 ==> a ^ Suc(2*n) < 0"
   324 proof (induct "n")
   325   case 0
   326     show ?case by (simp add: Power.power_Suc)
   327 next
   328   case (Suc n)
   329     have "a ^ Suc (2 * Suc n) = (a*a) * a ^ Suc(2*n)" 
   330       by (simp add: mult_ac power_add power2_eq_square Power.power_Suc)
   331     thus ?case
   332       by (simp add: prems mult_less_0_iff mult_neg)
   333 qed
   334 
   335 lemma odd_0_le_power_imp_0_le:
   336      "0 \<le> a  ^ Suc(2*n) ==> 0 \<le> (a::'a::{ordered_idom,ringpower})"
   337 apply (insert odd_power_less_zero [of a n]) 
   338 apply (force simp add: linorder_not_less [symmetric]) 
   339 done
   340 
   341 
   342 subsubsection{*Nat *}
   343 
   344 lemma Suc_pred': "0 < n ==> n = Suc(n - 1)"
   345 by (simp add: numerals)
   346 
   347 (*Expresses a natural number constant as the Suc of another one.
   348   NOT suitable for rewriting because n recurs in the condition.*)
   349 lemmas expand_Suc = Suc_pred' [of "number_of v", standard]
   350 
   351 subsubsection{*Arith *}
   352 
   353 lemma Suc_eq_add_numeral_1: "Suc n = n + 1"
   354 by (simp add: numerals)
   355 
   356 lemma Suc_eq_add_numeral_1_left: "Suc n = 1 + n"
   357 by (simp add: numerals)
   358 
   359 (* These two can be useful when m = number_of... *)
   360 
   361 lemma add_eq_if: "(m::nat) + n = (if m=0 then n else Suc ((m - 1) + n))"
   362 apply (case_tac "m")
   363 apply (simp_all add: numerals)
   364 done
   365 
   366 lemma mult_eq_if: "(m::nat) * n = (if m=0 then 0 else n + ((m - 1) * n))"
   367 apply (case_tac "m")
   368 apply (simp_all add: numerals)
   369 done
   370 
   371 lemma power_eq_if: "(p ^ m :: nat) = (if m=0 then 1 else p * (p ^ (m - 1)))"
   372 apply (case_tac "m")
   373 apply (simp_all add: numerals)
   374 done
   375 
   376 lemma diff_less': "[| 0<n; 0<m |] ==> m - n < (m::nat)"
   377 by (simp add: diff_less numerals)
   378 
   379 declare diff_less' [of "number_of v", standard, simp]
   380 
   381 
   382 subsection{*Comparisons involving (0::nat) *}
   383 
   384 text{*Simplification already does @{term "n<0"}, @{term "n\<le>0"} and @{term "0\<le>n"}.*}
   385 
   386 lemma eq_number_of_0 [simp]:
   387      "(number_of v = (0::nat)) =  
   388       (if neg (number_of v :: int) then True else iszero (number_of v :: int))"
   389 by (simp del: nat_numeral_0_eq_0 add: nat_numeral_0_eq_0 [symmetric] iszero_0)
   390 
   391 lemma eq_0_number_of [simp]:
   392      "((0::nat) = number_of v) =  
   393       (if neg (number_of v :: int) then True else iszero (number_of v :: int))"
   394 by (rule trans [OF eq_sym_conv eq_number_of_0])
   395 
   396 lemma less_0_number_of [simp]:
   397      "((0::nat) < number_of v) = neg (number_of (bin_minus v) :: int)"
   398 by (simp del: nat_numeral_0_eq_0 add: nat_numeral_0_eq_0 [symmetric])
   399 
   400 
   401 lemma neg_imp_number_of_eq_0: "neg (number_of v :: int) ==> number_of v = (0::nat)"
   402 by (simp del: nat_numeral_0_eq_0 add: nat_numeral_0_eq_0 [symmetric] iszero_0)
   403 
   404 
   405 
   406 subsection{*Comparisons involving Suc *}
   407 
   408 lemma eq_number_of_Suc [simp]:
   409      "(number_of v = Suc n) =  
   410         (let pv = number_of (bin_pred v) in  
   411          if neg pv then False else nat pv = n)"
   412 apply (simp only: simp_thms Let_def neg_eq_less_0 linorder_not_less 
   413                   number_of_pred nat_number_of_def 
   414             split add: split_if)
   415 apply (rule_tac x = "number_of v" in spec)
   416 apply (auto simp add: nat_eq_iff)
   417 done
   418 
   419 lemma Suc_eq_number_of [simp]:
   420      "(Suc n = number_of v) =  
   421         (let pv = number_of (bin_pred v) in  
   422          if neg pv then False else nat pv = n)"
   423 by (rule trans [OF eq_sym_conv eq_number_of_Suc])
   424 
   425 lemma less_number_of_Suc [simp]:
   426      "(number_of v < Suc n) =  
   427         (let pv = number_of (bin_pred v) in  
   428          if neg pv then True else nat pv < n)"
   429 apply (simp only: simp_thms Let_def neg_eq_less_0 linorder_not_less 
   430                   number_of_pred nat_number_of_def  
   431             split add: split_if)
   432 apply (rule_tac x = "number_of v" in spec)
   433 apply (auto simp add: nat_less_iff)
   434 done
   435 
   436 lemma less_Suc_number_of [simp]:
   437      "(Suc n < number_of v) =  
   438         (let pv = number_of (bin_pred v) in  
   439          if neg pv then False else n < nat pv)"
   440 apply (simp only: simp_thms Let_def neg_eq_less_0 linorder_not_less 
   441                   number_of_pred nat_number_of_def
   442             split add: split_if)
   443 apply (rule_tac x = "number_of v" in spec)
   444 apply (auto simp add: zless_nat_eq_int_zless)
   445 done
   446 
   447 lemma le_number_of_Suc [simp]:
   448      "(number_of v <= Suc n) =  
   449         (let pv = number_of (bin_pred v) in  
   450          if neg pv then True else nat pv <= n)"
   451 by (simp add: Let_def less_Suc_number_of linorder_not_less [symmetric])
   452 
   453 lemma le_Suc_number_of [simp]:
   454      "(Suc n <= number_of v) =  
   455         (let pv = number_of (bin_pred v) in  
   456          if neg pv then False else n <= nat pv)"
   457 by (simp add: Let_def less_number_of_Suc linorder_not_less [symmetric])
   458 
   459 
   460 (* Push int(.) inwards: *)
   461 declare zadd_int [symmetric, simp]
   462 
   463 lemma lemma1: "(m+m = n+n) = (m = (n::int))"
   464 by auto
   465 
   466 lemma lemma2: "m+m ~= (1::int) + (n + n)"
   467 apply auto
   468 apply (drule_tac f = "%x. x mod 2" in arg_cong)
   469 apply (simp add: zmod_zadd1_eq)
   470 done
   471 
   472 lemma eq_number_of_BIT_BIT:
   473      "((number_of (v BIT x) ::int) = number_of (w BIT y)) =  
   474       (x=y & (((number_of v) ::int) = number_of w))"
   475 by (simp only: simp_thms number_of_BIT lemma1 lemma2 eq_commute
   476                OrderedGroup.add_left_cancel add_assoc OrderedGroup.add_0
   477             split add: split_if cong: imp_cong) 
   478 
   479 
   480 lemma eq_number_of_BIT_Pls:
   481      "((number_of (v BIT x) ::int) = number_of bin.Pls) =  
   482       (x=False & (((number_of v) ::int) = number_of bin.Pls))"
   483 apply (simp only: simp_thms  add: number_of_BIT number_of_Pls eq_commute
   484             split add: split_if cong: imp_cong)
   485 apply (rule_tac x = "number_of v" in spec, safe)
   486 apply (simp_all (no_asm_use))
   487 apply (drule_tac f = "%x. x mod 2" in arg_cong)
   488 apply (simp add: zmod_zadd1_eq)
   489 done
   490 
   491 lemma eq_number_of_BIT_Min:
   492      "((number_of (v BIT x) ::int) = number_of bin.Min) =  
   493       (x=True & (((number_of v) ::int) = number_of bin.Min))"
   494 apply (simp only: simp_thms  add: number_of_BIT number_of_Min eq_commute
   495             split add: split_if cong: imp_cong)
   496 apply (rule_tac x = "number_of v" in spec, auto)
   497 apply (drule_tac f = "%x. x mod 2" in arg_cong, auto)
   498 done
   499 
   500 lemma eq_number_of_Pls_Min: "(number_of bin.Pls ::int) ~= number_of bin.Min"
   501 by auto
   502 
   503 
   504 
   505 subsection{*Literal arithmetic involving powers*}
   506 
   507 lemma nat_power_eq: "(0::int) <= z ==> nat (z^n) = nat z ^ n"
   508 apply (induct_tac "n")
   509 apply (simp_all (no_asm_simp) add: nat_mult_distrib)
   510 done
   511 
   512 lemma power_nat_number_of:
   513      "(number_of v :: nat) ^ n =  
   514        (if neg (number_of v :: int) then 0^n else nat ((number_of v :: int) ^ n))"
   515 by (simp only: simp_thms neg_nat not_neg_eq_ge_0 nat_number_of_def nat_power_eq
   516          split add: split_if cong: imp_cong)
   517 
   518 
   519 declare power_nat_number_of [of _ "number_of w", standard, simp]
   520 
   521 
   522 text{*For the integers*}
   523 
   524 lemma zpower_number_of_even:
   525      "(z::int) ^ number_of (w BIT False) =  
   526       (let w = z ^ (number_of w) in  w*w)"
   527 apply (simp del: nat_number_of  add: nat_number_of_def number_of_BIT Let_def)
   528 apply (simp only: number_of_add) 
   529 apply (rule_tac x = "number_of w" in spec, clarify)
   530 apply (case_tac " (0::int) <= x")
   531 apply (auto simp add: nat_mult_distrib power_even_eq power2_eq_square)
   532 done
   533 
   534 lemma zpower_number_of_odd:
   535      "(z::int) ^ number_of (w BIT True) =  
   536           (if (0::int) <= number_of w                    
   537            then (let w = z ^ (number_of w) in  z*w*w)    
   538            else 1)"
   539 apply (simp del: nat_number_of  add: nat_number_of_def number_of_BIT Let_def)
   540 apply (simp only: number_of_add nat_numeral_1_eq_1 not_neg_eq_ge_0 neg_eq_less_0) 
   541 apply (rule_tac x = "number_of w" in spec, clarify)
   542 apply (auto simp add: nat_add_distrib nat_mult_distrib power_even_eq power2_eq_square neg_nat)
   543 done
   544 
   545 declare zpower_number_of_even [of "number_of v", standard, simp]
   546 declare zpower_number_of_odd  [of "number_of v", standard, simp]
   547 
   548 
   549 
   550 ML
   551 {*
   552 val numerals = thms"numerals";
   553 val numeral_ss = simpset() addsimps numerals;
   554 
   555 val nat_bin_arith_setup =
   556  [Fast_Arith.map_data 
   557    (fn {add_mono_thms, mult_mono_thms, inj_thms, lessD, simpset} =>
   558      {add_mono_thms = add_mono_thms, mult_mono_thms = mult_mono_thms,
   559       inj_thms = inj_thms,
   560       lessD = lessD,
   561       simpset = simpset addsimps [Suc_nat_number_of, int_nat_number_of,
   562                                   not_neg_number_of_Pls,
   563                                   neg_number_of_Min,neg_number_of_BIT]})]
   564 *}
   565 
   566 setup nat_bin_arith_setup
   567 
   568 (* Enable arith to deal with div/mod k where k is a numeral: *)
   569 declare split_div[of _ _ "number_of k", standard, arith_split]
   570 declare split_mod[of _ _ "number_of k", standard, arith_split]
   571 
   572 lemma nat_number_of_Pls: "number_of bin.Pls = (0::nat)"
   573   by (simp add: number_of_Pls nat_number_of_def)
   574 
   575 lemma nat_number_of_Min: "number_of bin.Min = (0::nat)"
   576   apply (simp only: number_of_Min nat_number_of_def nat_zminus_int)
   577   apply (simp add: neg_nat)
   578   done
   579 
   580 lemma nat_number_of_BIT_True:
   581   "number_of (w BIT True) =
   582     (if neg (number_of w :: int) then 0
   583      else let n = number_of w in Suc (n + n))"
   584   apply (simp only: nat_number_of_def Let_def split: split_if)
   585   apply (intro conjI impI)
   586    apply (simp add: neg_nat neg_number_of_BIT)
   587   apply (rule int_int_eq [THEN iffD1])
   588   apply (simp only: not_neg_nat neg_number_of_BIT int_Suc zadd_int [symmetric] simp_thms)
   589   apply (simp only: number_of_BIT if_True zadd_assoc)
   590   done
   591 
   592 lemma nat_number_of_BIT_False:
   593     "number_of (w BIT False) = (let n::nat = number_of w in n + n)"
   594   apply (simp only: nat_number_of_def Let_def)
   595   apply (cases "neg (number_of w :: int)")
   596    apply (simp add: neg_nat neg_number_of_BIT)
   597   apply (rule int_int_eq [THEN iffD1])
   598   apply (simp only: not_neg_nat neg_number_of_BIT int_Suc zadd_int [symmetric] simp_thms)
   599   apply (simp only: number_of_BIT if_False zadd_0 zadd_assoc)
   600   done
   601 
   602 lemmas nat_number =
   603   nat_number_of_Pls nat_number_of_Min
   604   nat_number_of_BIT_True nat_number_of_BIT_False
   605 
   606 lemma Let_Suc [simp]: "Let (Suc n) f == f (Suc n)"
   607   by (simp add: Let_def)
   608 
   609 lemma power_m1_even: "(-1) ^ (2*n) = (1::'a::{number_ring,ringpower})"
   610 by (simp add: power_mult); 
   611 
   612 lemma power_m1_odd: "(-1) ^ Suc(2*n) = (-1::'a::{number_ring,ringpower})"
   613 by (simp add: power_mult power_Suc); 
   614 
   615 
   616 subsection{*Literal arithmetic and @{term of_nat}*}
   617 
   618 lemma of_nat_double:
   619      "0 \<le> x ==> of_nat (nat (2 * x)) = of_nat (nat x) + of_nat (nat x)"
   620 by (simp only: mult_2 nat_add_distrib of_nat_add) 
   621 
   622 lemma nat_numeral_m1_eq_0: "-1 = (0::nat)"
   623 by (simp only:  nat_number_of_def, simp)
   624 
   625 lemma int_double_iff: "(0::int) \<le> 2*x + 1 = (0 \<le> x)"
   626 by arith
   627 
   628 lemma of_nat_number_of_lemma:
   629      "of_nat (number_of v :: nat) =  
   630          (if 0 \<le> (number_of v :: int) 
   631           then (number_of v :: 'a :: number_ring)
   632           else 0)"
   633 apply (induct v, simp, simp add: nat_numeral_m1_eq_0)
   634 apply (simp only: number_of nat_number_of_def)
   635 txt{*Generalize in order to eliminate the function @{term number_of} and
   636 its annoying simprules*}
   637 apply (erule rev_mp)
   638 apply (rule_tac x="number_of bin :: int" in spec) 
   639 apply (rule_tac x="number_of bin :: 'a" in spec) 
   640 apply (simp add: nat_add_distrib of_nat_double int_double_iff)
   641 done
   642 
   643 lemma of_nat_number_of_eq [simp]:
   644      "of_nat (number_of v :: nat) =  
   645          (if neg (number_of v :: int) then 0  
   646           else (number_of v :: 'a :: number_ring))"
   647 by (simp only: of_nat_number_of_lemma neg_def, simp) 
   648 
   649 
   650 subsection {*Lemmas for the Combination and Cancellation Simprocs*}
   651 
   652 lemma nat_number_of_add_left:
   653      "number_of v + (number_of v' + (k::nat)) =  
   654          (if neg (number_of v :: int) then number_of v' + k  
   655           else if neg (number_of v' :: int) then number_of v + k  
   656           else number_of (bin_add v v') + k)"
   657 by simp
   658 
   659 lemma nat_number_of_mult_left:
   660      "number_of v * (number_of v' * (k::nat)) =  
   661          (if neg (number_of v :: int) then 0
   662           else number_of (bin_mult v v') * k)"
   663 by simp
   664 
   665 
   666 subsubsection{*For @{text combine_numerals}*}
   667 
   668 lemma left_add_mult_distrib: "i*u + (j*u + k) = (i+j)*u + (k::nat)"
   669 by (simp add: add_mult_distrib)
   670 
   671 
   672 subsubsection{*For @{text cancel_numerals}*}
   673 
   674 lemma nat_diff_add_eq1:
   675      "j <= (i::nat) ==> ((i*u + m) - (j*u + n)) = (((i-j)*u + m) - n)"
   676 by (simp split add: nat_diff_split add: add_mult_distrib)
   677 
   678 lemma nat_diff_add_eq2:
   679      "i <= (j::nat) ==> ((i*u + m) - (j*u + n)) = (m - ((j-i)*u + n))"
   680 by (simp split add: nat_diff_split add: add_mult_distrib)
   681 
   682 lemma nat_eq_add_iff1:
   683      "j <= (i::nat) ==> (i*u + m = j*u + n) = ((i-j)*u + m = n)"
   684 by (auto split add: nat_diff_split simp add: add_mult_distrib)
   685 
   686 lemma nat_eq_add_iff2:
   687      "i <= (j::nat) ==> (i*u + m = j*u + n) = (m = (j-i)*u + n)"
   688 by (auto split add: nat_diff_split simp add: add_mult_distrib)
   689 
   690 lemma nat_less_add_iff1:
   691      "j <= (i::nat) ==> (i*u + m < j*u + n) = ((i-j)*u + m < n)"
   692 by (auto split add: nat_diff_split simp add: add_mult_distrib)
   693 
   694 lemma nat_less_add_iff2:
   695      "i <= (j::nat) ==> (i*u + m < j*u + n) = (m < (j-i)*u + n)"
   696 by (auto split add: nat_diff_split simp add: add_mult_distrib)
   697 
   698 lemma nat_le_add_iff1:
   699      "j <= (i::nat) ==> (i*u + m <= j*u + n) = ((i-j)*u + m <= n)"
   700 by (auto split add: nat_diff_split simp add: add_mult_distrib)
   701 
   702 lemma nat_le_add_iff2:
   703      "i <= (j::nat) ==> (i*u + m <= j*u + n) = (m <= (j-i)*u + n)"
   704 by (auto split add: nat_diff_split simp add: add_mult_distrib)
   705 
   706 
   707 subsubsection{*For @{text cancel_numeral_factors} *}
   708 
   709 lemma nat_mult_le_cancel1: "(0::nat) < k ==> (k*m <= k*n) = (m<=n)"
   710 by auto
   711 
   712 lemma nat_mult_less_cancel1: "(0::nat) < k ==> (k*m < k*n) = (m<n)"
   713 by auto
   714 
   715 lemma nat_mult_eq_cancel1: "(0::nat) < k ==> (k*m = k*n) = (m=n)"
   716 by auto
   717 
   718 lemma nat_mult_div_cancel1: "(0::nat) < k ==> (k*m) div (k*n) = (m div n)"
   719 by auto
   720 
   721 
   722 subsubsection{*For @{text cancel_factor} *}
   723 
   724 lemma nat_mult_le_cancel_disj: "(k*m <= k*n) = ((0::nat) < k --> m<=n)"
   725 by auto
   726 
   727 lemma nat_mult_less_cancel_disj: "(k*m < k*n) = ((0::nat) < k & m<n)"
   728 by auto
   729 
   730 lemma nat_mult_eq_cancel_disj: "(k*m = k*n) = (k = (0::nat) | m=n)"
   731 by auto
   732 
   733 lemma nat_mult_div_cancel_disj:
   734      "(k*m) div (k*n) = (if k = (0::nat) then 0 else m div n)"
   735 by (simp add: nat_mult_div_cancel1)
   736 
   737 
   738 ML
   739 {*
   740 val eq_nat_nat_iff = thm"eq_nat_nat_iff";
   741 val eq_nat_number_of = thm"eq_nat_number_of";
   742 val less_nat_number_of = thm"less_nat_number_of";
   743 val power2_eq_square = thm "power2_eq_square";
   744 val zero_le_power2 = thm "zero_le_power2";
   745 val zero_less_power2 = thm "zero_less_power2";
   746 val zero_eq_power2 = thm "zero_eq_power2";
   747 val abs_power2 = thm "abs_power2";
   748 val power2_abs = thm "power2_abs";
   749 val power2_minus = thm "power2_minus";
   750 val power_minus1_even = thm "power_minus1_even";
   751 val power_minus_even = thm "power_minus_even";
   752 val zero_le_even_power = thm "zero_le_even_power";
   753 val odd_power_less_zero = thm "odd_power_less_zero";
   754 val odd_0_le_power_imp_0_le = thm "odd_0_le_power_imp_0_le";
   755 
   756 val Suc_pred' = thm"Suc_pred'";
   757 val expand_Suc = thm"expand_Suc";
   758 val Suc_eq_add_numeral_1 = thm"Suc_eq_add_numeral_1";
   759 val Suc_eq_add_numeral_1_left = thm"Suc_eq_add_numeral_1_left";
   760 val add_eq_if = thm"add_eq_if";
   761 val mult_eq_if = thm"mult_eq_if";
   762 val power_eq_if = thm"power_eq_if";
   763 val diff_less' = thm"diff_less'";
   764 val eq_number_of_0 = thm"eq_number_of_0";
   765 val eq_0_number_of = thm"eq_0_number_of";
   766 val less_0_number_of = thm"less_0_number_of";
   767 val neg_imp_number_of_eq_0 = thm"neg_imp_number_of_eq_0";
   768 val eq_number_of_Suc = thm"eq_number_of_Suc";
   769 val Suc_eq_number_of = thm"Suc_eq_number_of";
   770 val less_number_of_Suc = thm"less_number_of_Suc";
   771 val less_Suc_number_of = thm"less_Suc_number_of";
   772 val le_number_of_Suc = thm"le_number_of_Suc";
   773 val le_Suc_number_of = thm"le_Suc_number_of";
   774 val eq_number_of_BIT_BIT = thm"eq_number_of_BIT_BIT";
   775 val eq_number_of_BIT_Pls = thm"eq_number_of_BIT_Pls";
   776 val eq_number_of_BIT_Min = thm"eq_number_of_BIT_Min";
   777 val eq_number_of_Pls_Min = thm"eq_number_of_Pls_Min";
   778 val of_nat_number_of_eq = thm"of_nat_number_of_eq";
   779 val nat_power_eq = thm"nat_power_eq";
   780 val power_nat_number_of = thm"power_nat_number_of";
   781 val zpower_number_of_even = thm"zpower_number_of_even";
   782 val zpower_number_of_odd = thm"zpower_number_of_odd";
   783 val nat_number_of_Pls = thm"nat_number_of_Pls";
   784 val nat_number_of_Min = thm"nat_number_of_Min";
   785 val nat_number_of_BIT_True = thm"nat_number_of_BIT_True";
   786 val nat_number_of_BIT_False = thm"nat_number_of_BIT_False";
   787 val Let_Suc = thm"Let_Suc";
   788 
   789 val nat_number = thms"nat_number";
   790 
   791 val nat_number_of_add_left = thm"nat_number_of_add_left";
   792 val nat_number_of_mult_left = thm"nat_number_of_mult_left";
   793 val left_add_mult_distrib = thm"left_add_mult_distrib";
   794 val nat_diff_add_eq1 = thm"nat_diff_add_eq1";
   795 val nat_diff_add_eq2 = thm"nat_diff_add_eq2";
   796 val nat_eq_add_iff1 = thm"nat_eq_add_iff1";
   797 val nat_eq_add_iff2 = thm"nat_eq_add_iff2";
   798 val nat_less_add_iff1 = thm"nat_less_add_iff1";
   799 val nat_less_add_iff2 = thm"nat_less_add_iff2";
   800 val nat_le_add_iff1 = thm"nat_le_add_iff1";
   801 val nat_le_add_iff2 = thm"nat_le_add_iff2";
   802 val nat_mult_le_cancel1 = thm"nat_mult_le_cancel1";
   803 val nat_mult_less_cancel1 = thm"nat_mult_less_cancel1";
   804 val nat_mult_eq_cancel1 = thm"nat_mult_eq_cancel1";
   805 val nat_mult_div_cancel1 = thm"nat_mult_div_cancel1";
   806 val nat_mult_le_cancel_disj = thm"nat_mult_le_cancel_disj";
   807 val nat_mult_less_cancel_disj = thm"nat_mult_less_cancel_disj";
   808 val nat_mult_eq_cancel_disj = thm"nat_mult_eq_cancel_disj";
   809 val nat_mult_div_cancel_disj = thm"nat_mult_div_cancel_disj";
   810 
   811 val power_minus_even = thm"power_minus_even";
   812 val zero_le_even_power = thm"zero_le_even_power";
   813 *}
   814 
   815 
   816 subsection {* Configuration of the code generator *}
   817 
   818 ML {*
   819 infix 7 `*;
   820 infix 6 `+;
   821 
   822 val op `* = op * : int * int -> int;
   823 val op `+ = op + : int * int -> int;
   824 val `~ = ~ : int -> int;
   825 *}
   826 
   827 types_code
   828   "int" ("int")
   829 
   830 constdefs
   831   int_aux :: "int \<Rightarrow> nat \<Rightarrow> int"
   832   "int_aux i n == (i + int n)"
   833   nat_aux :: "nat \<Rightarrow> int \<Rightarrow> nat"
   834   "nat_aux n i == (n + nat i)"
   835 
   836 lemma [code]:
   837   "int_aux i 0 = i"
   838   "int_aux i (Suc n) = int_aux (i + 1) n" -- {* tail recursive *}
   839   "int n = int_aux 0 n"
   840   by (simp add: int_aux_def)+
   841 
   842 lemma [code]: "nat_aux n i = (if i <= 0 then n else nat_aux (Suc n) (i - 1))"
   843   by (simp add: nat_aux_def Suc_nat_eq_nat_zadd1) -- {* tail recursive *}
   844 lemma [code]: "nat i = nat_aux 0 i"
   845   by (simp add: nat_aux_def)
   846 
   847 consts_code
   848   "0" :: "int"                  ("0")
   849   "1" :: "int"                  ("1")
   850   "uminus" :: "int => int"      ("`~")
   851   "op +" :: "int => int => int" ("(_ `+/ _)")
   852   "op *" :: "int => int => int" ("(_ `*/ _)")
   853   "op <" :: "int => int => bool" ("(_ </ _)")
   854   "op <=" :: "int => int => bool" ("(_ <=/ _)")
   855   "neg"                         ("(_ < 0)")
   856 
   857 ML {*
   858 fun number_of_codegen thy gr s b (Const ("Numeral.number_of",
   859       Type ("fun", [_, Type ("IntDef.int", [])])) $ bin) =
   860         (Some (gr, Pretty.str (string_of_int (HOLogic.dest_binum bin)))
   861         handle TERM _ => None)
   862   | number_of_codegen thy gr s b (Const ("Numeral.number_of",
   863       Type ("fun", [_, Type ("nat", [])])) $ bin) =
   864         Some (Codegen.invoke_codegen thy s b (gr,
   865           Const ("IntDef.nat", HOLogic.intT --> HOLogic.natT) $
   866             (Const ("Numeral.number_of", HOLogic.binT --> HOLogic.intT) $ bin)))
   867   | number_of_codegen _ _ _ _ _ = None;
   868 *}
   869 
   870 setup {* [Codegen.add_codegen "number_of_codegen" number_of_codegen] *}
   871 
   872 end