src/HOL/NatBin.thy
changeset 29230 155f6c110dfc
parent 29045 3c8f48333731
child 29401 94fd5dd918f5
equal deleted inserted replaced
29229:6f6262027054 29230:155f6c110dfc
    37 
    37 
    38 notation (HTML output)
    38 notation (HTML output)
    39   square  ("(_\<twosuperior>)" [1000] 999)
    39   square  ("(_\<twosuperior>)" [1000] 999)
    40 
    40 
    41 
    41 
       
    42 subsection {* Predicate for negative binary numbers *}
       
    43 
       
    44 definition
       
    45   neg  :: "int \<Rightarrow> bool"
       
    46 where
       
    47   "neg Z \<longleftrightarrow> Z < 0"
       
    48 
       
    49 lemma not_neg_int [simp]: "~ neg (of_nat n)"
       
    50 by (simp add: neg_def)
       
    51 
       
    52 lemma neg_zminus_int [simp]: "neg (- (of_nat (Suc n)))"
       
    53 by (simp add: neg_def neg_less_0_iff_less del: of_nat_Suc)
       
    54 
       
    55 lemmas neg_eq_less_0 = neg_def
       
    56 
       
    57 lemma not_neg_eq_ge_0: "(~neg x) = (0 \<le> x)"
       
    58 by (simp add: neg_def linorder_not_less)
       
    59 
       
    60 text{*To simplify inequalities when Numeral1 can get simplified to 1*}
       
    61 
       
    62 lemma not_neg_0: "~ neg 0"
       
    63 by (simp add: One_int_def neg_def)
       
    64 
       
    65 lemma not_neg_1: "~ neg 1"
       
    66 by (simp add: neg_def linorder_not_less zero_le_one)
       
    67 
       
    68 lemma neg_nat: "neg z ==> nat z = 0"
       
    69 by (simp add: neg_def order_less_imp_le) 
       
    70 
       
    71 lemma not_neg_nat: "~ neg z ==> of_nat (nat z) = z"
       
    72 by (simp add: linorder_not_less neg_def)
       
    73 
       
    74 text {*
       
    75   If @{term Numeral0} is rewritten to 0 then this rule can't be applied:
       
    76   @{term Numeral0} IS @{term "number_of Pls"}
       
    77 *}
       
    78 
       
    79 lemma not_neg_number_of_Pls: "~ neg (number_of Int.Pls)"
       
    80   by (simp add: neg_def)
       
    81 
       
    82 lemma neg_number_of_Min: "neg (number_of Int.Min)"
       
    83   by (simp add: neg_def)
       
    84 
       
    85 lemma neg_number_of_Bit0:
       
    86   "neg (number_of (Int.Bit0 w)) = neg (number_of w)"
       
    87   by (simp add: neg_def)
       
    88 
       
    89 lemma neg_number_of_Bit1:
       
    90   "neg (number_of (Int.Bit1 w)) = neg (number_of w)"
       
    91   by (simp add: neg_def)
       
    92 
       
    93 lemmas neg_simps [simp] =
       
    94   not_neg_0 not_neg_1
       
    95   not_neg_number_of_Pls neg_number_of_Min
       
    96   neg_number_of_Bit0 neg_number_of_Bit1
       
    97 
       
    98 
    42 subsection{*Function @{term nat}: Coercion from Type @{typ int} to @{typ nat}*}
    99 subsection{*Function @{term nat}: Coercion from Type @{typ int} to @{typ nat}*}
    43 
   100 
    44 declare nat_0 [simp] nat_1 [simp]
   101 declare nat_0 [simp] nat_1 [simp]
    45 
   102 
    46 lemma nat_number_of [simp]: "nat (number_of w) = number_of w"
   103 lemma nat_number_of [simp]: "nat (number_of w) = number_of w"
    59 apply (unfold nat_number_of_def)
   116 apply (unfold nat_number_of_def)
    60 apply (rule nat_2)
   117 apply (rule nat_2)
    61 done
   118 done
    62 
   119 
    63 
   120 
    64 text{*Distributive laws for type @{text nat}.  The others are in theory
       
    65    @{text IntArith}, but these require div and mod to be defined for type
       
    66    "int".  They also need some of the lemmas proved above.*}
       
    67 
       
    68 lemma nat_div_distrib: "(0::int) <= z ==> nat (z div z') = nat z div nat z'"
       
    69 apply (case_tac "0 <= z'")
       
    70 apply (auto simp add: div_nonneg_neg_le0)
       
    71 apply (case_tac "z' = 0", simp)
       
    72 apply (auto elim!: nonneg_eq_int)
       
    73 apply (rename_tac m m')
       
    74 apply (subgoal_tac "0 <= int m div int m'")
       
    75  prefer 2 apply (simp add: nat_numeral_0_eq_0 pos_imp_zdiv_nonneg_iff) 
       
    76 apply (rule of_nat_eq_iff [where 'a=int, THEN iffD1], simp)
       
    77 apply (rule_tac r = "int (m mod m') " in quorem_div)
       
    78  prefer 2 apply force
       
    79 apply (simp add: nat_less_iff [symmetric] quorem_def nat_numeral_0_eq_0
       
    80                  of_nat_add [symmetric] of_nat_mult [symmetric]
       
    81             del: of_nat_add of_nat_mult)
       
    82 done
       
    83 
       
    84 (*Fails if z'<0: the LHS collapses to (nat z) but the RHS doesn't*)
       
    85 lemma nat_mod_distrib:
       
    86      "[| (0::int) <= z;  0 <= z' |] ==> nat (z mod z') = nat z mod nat z'"
       
    87 apply (case_tac "z' = 0", simp add: DIVISION_BY_ZERO)
       
    88 apply (auto elim!: nonneg_eq_int)
       
    89 apply (rename_tac m m')
       
    90 apply (subgoal_tac "0 <= int m mod int m'")
       
    91  prefer 2 apply (simp add: nat_less_iff nat_numeral_0_eq_0 pos_mod_sign)
       
    92 apply (rule int_int_eq [THEN iffD1], simp)
       
    93 apply (rule_tac q = "int (m div m') " in quorem_mod)
       
    94  prefer 2 apply force
       
    95 apply (simp add: nat_less_iff [symmetric] quorem_def nat_numeral_0_eq_0
       
    96                  of_nat_add [symmetric] of_nat_mult [symmetric]
       
    97             del: of_nat_add of_nat_mult)
       
    98 done
       
    99 
       
   100 text{*Suggested by Matthias Daum*}
       
   101 lemma int_div_less_self: "\<lbrakk>0 < x; 1 < k\<rbrakk> \<Longrightarrow> x div k < (x::int)"
       
   102 apply (subgoal_tac "nat x div nat k < nat x")
       
   103  apply (simp (asm_lr) add: nat_div_distrib [symmetric])
       
   104 apply (rule Divides.div_less_dividend, simp_all) 
       
   105 done
       
   106 
       
   107 subsection{*Function @{term int}: Coercion from Type @{typ nat} to @{typ int}*}
   121 subsection{*Function @{term int}: Coercion from Type @{typ nat} to @{typ int}*}
   108 
   122 
   109 (*"neg" is used in rewrite rules for binary comparisons*)
       
   110 lemma int_nat_number_of [simp]:
   123 lemma int_nat_number_of [simp]:
   111      "int (number_of v) =  
   124      "int (number_of v) =  
   112          (if neg (number_of v :: int) then 0  
   125          (if neg (number_of v :: int) then 0  
   113           else (number_of v :: int))"
   126           else (number_of v :: int))"
   114   unfolding nat_number_of_def number_of_is_id neg_def
   127   unfolding nat_number_of_def number_of_is_id neg_def
   136 done
   149 done
   137 
   150 
   138 
   151 
   139 subsubsection{*Addition *}
   152 subsubsection{*Addition *}
   140 
   153 
   141 (*"neg" is used in rewrite rules for binary comparisons*)
       
   142 lemma add_nat_number_of [simp]:
   154 lemma add_nat_number_of [simp]:
   143      "(number_of v :: nat) + number_of v' =  
   155      "(number_of v :: nat) + number_of v' =  
   144          (if v < Int.Pls then number_of v'  
   156          (if v < Int.Pls then number_of v'  
   145           else if v' < Int.Pls then number_of v  
   157           else if v' < Int.Pls then number_of v  
   146           else number_of (v + v'))"
   158           else number_of (v + v'))"
   244 
   256 
   245 lemma eq_nat_nat_iff:
   257 lemma eq_nat_nat_iff:
   246      "[| (0::int) <= z;  0 <= z' |] ==> (nat z = nat z') = (z=z')"
   258      "[| (0::int) <= z;  0 <= z' |] ==> (nat z = nat z') = (z=z')"
   247 by (auto elim!: nonneg_eq_int)
   259 by (auto elim!: nonneg_eq_int)
   248 
   260 
   249 (*"neg" is used in rewrite rules for binary comparisons*)
       
   250 lemma eq_nat_number_of [simp]:
   261 lemma eq_nat_number_of [simp]:
   251      "((number_of v :: nat) = number_of v') =  
   262      "((number_of v :: nat) = number_of v') =  
   252       (if neg (number_of v :: int) then (number_of v' :: int) \<le> 0
   263       (if neg (number_of v :: int) then (number_of v' :: int) \<le> 0
   253        else if neg (number_of v' :: int) then (number_of v :: int) = 0
   264        else if neg (number_of v' :: int) then (number_of v :: int) = 0
   254        else v = v')"
   265        else v = v')"
   625  LinArith.map_data
   636  LinArith.map_data
   626    (fn {add_mono_thms, mult_mono_thms, inj_thms, lessD, neqE, simpset} =>
   637    (fn {add_mono_thms, mult_mono_thms, inj_thms, lessD, neqE, simpset} =>
   627      {add_mono_thms = add_mono_thms, mult_mono_thms = mult_mono_thms,
   638      {add_mono_thms = add_mono_thms, mult_mono_thms = mult_mono_thms,
   628       inj_thms = inj_thms,
   639       inj_thms = inj_thms,
   629       lessD = lessD, neqE = neqE,
   640       lessD = lessD, neqE = neqE,
   630       simpset = simpset addsimps [Suc_nat_number_of, int_nat_number_of,
   641       simpset = simpset addsimps @{thms neg_simps} @
   631         @{thm not_neg_number_of_Pls}, @{thm neg_number_of_Min},
   642         [@{thm Suc_nat_number_of}, @{thm int_nat_number_of}]})
   632         @{thm neg_number_of_Bit0}, @{thm neg_number_of_Bit1}]})
       
   633 *}
   643 *}
   634 
   644 
   635 declaration {* K nat_bin_arith_setup *}
   645 declaration {* K nat_bin_arith_setup *}
   636 
   646 
   637 (* Enable arith to deal with div/mod k where k is a numeral: *)
   647 (* Enable arith to deal with div/mod k where k is a numeral: *)