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