src/HOL/Word/Bit_Representation.thy
author haftmann
Thu Oct 30 21:02:01 2014 +0100 (2014-10-30)
changeset 58834 773b378d9313
parent 58645 94bef115c08f
child 58874 7172c7ffb047
permissions -rw-r--r--
more simp rules concerning dvd and even/odd
     1 (* 
     2   Author: Jeremy Dawson, NICTA
     3 *) 
     4 
     5 header {* Integers as implict bit strings *}
     6 
     7 theory Bit_Representation
     8 imports Misc_Numeric
     9 begin
    10 
    11 subsection {* Constructors and destructors for binary integers *}
    12 
    13 definition Bit :: "int \<Rightarrow> bool \<Rightarrow> int" (infixl "BIT" 90)
    14 where
    15   "k BIT b = (if b then 1 else 0) + k + k"
    16 
    17 lemma Bit_B0:
    18   "k BIT False = k + k"
    19    by (unfold Bit_def) simp
    20 
    21 lemma Bit_B1:
    22   "k BIT True = k + k + 1"
    23    by (unfold Bit_def) simp
    24   
    25 lemma Bit_B0_2t: "k BIT False = 2 * k"
    26   by (rule trans, rule Bit_B0) simp
    27 
    28 lemma Bit_B1_2t: "k BIT True = 2 * k + 1"
    29   by (rule trans, rule Bit_B1) simp
    30 
    31 definition bin_last :: "int \<Rightarrow> bool"
    32 where
    33   "bin_last w \<longleftrightarrow> w mod 2 = 1"
    34 
    35 lemma bin_last_odd:
    36   "bin_last = odd"
    37   by (rule ext) (simp add: bin_last_def even_iff_mod_2_eq_zero)
    38 
    39 definition bin_rest :: "int \<Rightarrow> int"
    40 where
    41   "bin_rest w = w div 2"
    42 
    43 lemma bin_rl_simp [simp]:
    44   "bin_rest w BIT bin_last w = w"
    45   unfolding bin_rest_def bin_last_def Bit_def
    46   using mod_div_equality [of w 2]
    47   by (cases "w mod 2 = 0", simp_all)
    48 
    49 lemma bin_rest_BIT [simp]: "bin_rest (x BIT b) = x"
    50   unfolding bin_rest_def Bit_def
    51   by (cases b, simp_all)
    52 
    53 lemma bin_last_BIT [simp]: "bin_last (x BIT b) = b"
    54   unfolding bin_last_def Bit_def
    55   by (cases b) simp_all
    56 
    57 lemma BIT_eq_iff [iff]: "u BIT b = v BIT c \<longleftrightarrow> u = v \<and> b = c"
    58   apply (auto simp add: Bit_def)
    59   apply arith
    60   apply arith
    61   done
    62 
    63 lemma BIT_bin_simps [simp]:
    64   "numeral k BIT False = numeral (Num.Bit0 k)"
    65   "numeral k BIT True = numeral (Num.Bit1 k)"
    66   "(- numeral k) BIT False = - numeral (Num.Bit0 k)"
    67   "(- numeral k) BIT True = - numeral (Num.BitM k)"
    68   unfolding numeral.simps numeral_BitM
    69   unfolding Bit_def
    70   by (simp_all del: arith_simps add_numeral_special diff_numeral_special)
    71 
    72 lemma BIT_special_simps [simp]:
    73   shows "0 BIT False = 0" and "0 BIT True = 1"
    74   and "1 BIT False = 2" and "1 BIT True = 3"
    75   and "(- 1) BIT False = - 2" and "(- 1) BIT True = - 1"
    76   unfolding Bit_def by simp_all
    77 
    78 lemma Bit_eq_0_iff: "w BIT b = 0 \<longleftrightarrow> w = 0 \<and> \<not> b"
    79   apply (auto simp add: Bit_def)
    80   apply arith
    81   done
    82 
    83 lemma Bit_eq_m1_iff: "w BIT b = -1 \<longleftrightarrow> w = -1 \<and> b"
    84   apply (auto simp add: Bit_def)
    85   apply arith
    86   done
    87 
    88 lemma BitM_inc: "Num.BitM (Num.inc w) = Num.Bit1 w"
    89   by (induct w, simp_all)
    90 
    91 lemma expand_BIT:
    92   "numeral (Num.Bit0 w) = numeral w BIT False"
    93   "numeral (Num.Bit1 w) = numeral w BIT True"
    94   "- numeral (Num.Bit0 w) = (- numeral w) BIT False"
    95   "- numeral (Num.Bit1 w) = (- numeral (w + Num.One)) BIT True"
    96   unfolding add_One by (simp_all add: BitM_inc)
    97 
    98 lemma bin_last_numeral_simps [simp]:
    99   "\<not> bin_last 0"
   100   "bin_last 1"
   101   "bin_last (- 1)"
   102   "bin_last Numeral1"
   103   "\<not> bin_last (numeral (Num.Bit0 w))"
   104   "bin_last (numeral (Num.Bit1 w))"
   105   "\<not> bin_last (- numeral (Num.Bit0 w))"
   106   "bin_last (- numeral (Num.Bit1 w))"
   107   unfolding expand_BIT bin_last_BIT by (simp_all add: bin_last_def zmod_zminus1_eq_if)
   108 
   109 lemma bin_rest_numeral_simps [simp]:
   110   "bin_rest 0 = 0"
   111   "bin_rest 1 = 0"
   112   "bin_rest (- 1) = - 1"
   113   "bin_rest Numeral1 = 0"
   114   "bin_rest (numeral (Num.Bit0 w)) = numeral w"
   115   "bin_rest (numeral (Num.Bit1 w)) = numeral w"
   116   "bin_rest (- numeral (Num.Bit0 w)) = - numeral w"
   117   "bin_rest (- numeral (Num.Bit1 w)) = - numeral (w + Num.One)"
   118   unfolding expand_BIT bin_rest_BIT by (simp_all add: bin_rest_def zdiv_zminus1_eq_if)
   119 
   120 lemma less_Bits: 
   121   "v BIT b < w BIT c \<longleftrightarrow> v < w \<or> v \<le> w \<and> \<not> b \<and> c"
   122   unfolding Bit_def by auto
   123 
   124 lemma le_Bits: 
   125   "v BIT b \<le> w BIT c \<longleftrightarrow> v < w \<or> v \<le> w \<and> (\<not> b \<or> c)" 
   126   unfolding Bit_def by auto
   127 
   128 lemma pred_BIT_simps [simp]:
   129   "x BIT False - 1 = (x - 1) BIT True"
   130   "x BIT True - 1 = x BIT False"
   131   by (simp_all add: Bit_B0_2t Bit_B1_2t)
   132 
   133 lemma succ_BIT_simps [simp]:
   134   "x BIT False + 1 = x BIT True"
   135   "x BIT True + 1 = (x + 1) BIT False"
   136   by (simp_all add: Bit_B0_2t Bit_B1_2t)
   137 
   138 lemma add_BIT_simps [simp]:
   139   "x BIT False + y BIT False = (x + y) BIT False"
   140   "x BIT False + y BIT True = (x + y) BIT True"
   141   "x BIT True + y BIT False = (x + y) BIT True"
   142   "x BIT True + y BIT True = (x + y + 1) BIT False"
   143   by (simp_all add: Bit_B0_2t Bit_B1_2t)
   144 
   145 lemma mult_BIT_simps [simp]:
   146   "x BIT False * y = (x * y) BIT False"
   147   "x * y BIT False = (x * y) BIT False"
   148   "x BIT True * y = (x * y) BIT False + y"
   149   by (simp_all add: Bit_B0_2t Bit_B1_2t algebra_simps)
   150 
   151 lemma B_mod_2': 
   152   "X = 2 ==> (w BIT True) mod X = 1 & (w BIT False) mod X = 0"
   153   apply (simp (no_asm) only: Bit_B0 Bit_B1)
   154   apply simp
   155   done
   156 
   157 lemma bin_ex_rl: "EX w b. w BIT b = bin"
   158   by (metis bin_rl_simp)
   159 
   160 lemma bin_exhaust:
   161   assumes Q: "\<And>x b. bin = x BIT b \<Longrightarrow> Q"
   162   shows "Q"
   163   apply (insert bin_ex_rl [of bin])  
   164   apply (erule exE)+
   165   apply (rule Q)
   166   apply force
   167   done
   168 
   169 primrec bin_nth where
   170   Z: "bin_nth w 0 \<longleftrightarrow> bin_last w"
   171   | Suc: "bin_nth w (Suc n) \<longleftrightarrow> bin_nth (bin_rest w) n"
   172 
   173 lemma bin_abs_lem:
   174   "bin = (w BIT b) ==> bin ~= -1 --> bin ~= 0 -->
   175     nat (abs w) < nat (abs bin)"
   176   apply clarsimp
   177   apply (unfold Bit_def)
   178   apply (cases b)
   179    apply (clarsimp, arith)
   180   apply (clarsimp, arith)
   181   done
   182 
   183 lemma bin_induct:
   184   assumes PPls: "P 0"
   185     and PMin: "P (- 1)"
   186     and PBit: "!!bin bit. P bin ==> P (bin BIT bit)"
   187   shows "P bin"
   188   apply (rule_tac P=P and a=bin and f1="nat o abs" 
   189                   in wf_measure [THEN wf_induct])
   190   apply (simp add: measure_def inv_image_def)
   191   apply (case_tac x rule: bin_exhaust)
   192   apply (frule bin_abs_lem)
   193   apply (auto simp add : PPls PMin PBit)
   194   done
   195 
   196 lemma Bit_div2 [simp]: "(w BIT b) div 2 = w"
   197   unfolding bin_rest_def [symmetric] by (rule bin_rest_BIT)
   198 
   199 lemma bin_nth_eq_iff:
   200   "bin_nth x = bin_nth y \<longleftrightarrow> x = y"
   201 proof -
   202   have bin_nth_lem [rule_format]: "ALL y. bin_nth x = bin_nth y --> x = y"
   203     apply (induct x rule: bin_induct)
   204       apply safe
   205       apply (erule rev_mp)
   206       apply (induct_tac y rule: bin_induct)
   207         apply safe
   208         apply (drule_tac x=0 in fun_cong, force)
   209        apply (erule notE, rule ext, 
   210             drule_tac x="Suc x" in fun_cong, force)
   211       apply (drule_tac x=0 in fun_cong, force)
   212      apply (erule rev_mp)
   213      apply (induct_tac y rule: bin_induct)
   214        apply safe
   215        apply (drule_tac x=0 in fun_cong, force)
   216       apply (erule notE, rule ext, 
   217            drule_tac x="Suc x" in fun_cong, force)
   218       apply (metis Bit_eq_m1_iff Z bin_last_BIT)
   219     apply (case_tac y rule: bin_exhaust)
   220     apply clarify
   221     apply (erule allE)
   222     apply (erule impE)
   223      prefer 2
   224      apply (erule conjI)
   225      apply (drule_tac x=0 in fun_cong, force)
   226     apply (rule ext)
   227     apply (drule_tac x="Suc ?x" in fun_cong, force)
   228     done
   229   show ?thesis
   230   by (auto elim: bin_nth_lem)
   231 qed
   232 
   233 lemmas bin_eqI = ext [THEN bin_nth_eq_iff [THEN iffD1]]
   234 
   235 lemma bin_eq_iff:
   236   "x = y \<longleftrightarrow> (\<forall>n. bin_nth x n = bin_nth y n)"
   237   using bin_nth_eq_iff by auto
   238 
   239 lemma bin_nth_zero [simp]: "\<not> bin_nth 0 n"
   240   by (induct n) auto
   241 
   242 lemma bin_nth_1 [simp]: "bin_nth 1 n \<longleftrightarrow> n = 0"
   243   by (cases n) simp_all
   244 
   245 lemma bin_nth_minus1 [simp]: "bin_nth (- 1) n"
   246   by (induct n) auto
   247 
   248 lemma bin_nth_0_BIT: "bin_nth (w BIT b) 0 \<longleftrightarrow> b"
   249   by auto
   250 
   251 lemma bin_nth_Suc_BIT: "bin_nth (w BIT b) (Suc n) = bin_nth w n"
   252   by auto
   253 
   254 lemma bin_nth_minus [simp]: "0 < n ==> bin_nth (w BIT b) n = bin_nth w (n - 1)"
   255   by (cases n) auto
   256 
   257 lemma bin_nth_numeral:
   258   "bin_rest x = y \<Longrightarrow> bin_nth x (numeral n) = bin_nth y (pred_numeral n)"
   259   by (simp add: numeral_eq_Suc)
   260 
   261 lemmas bin_nth_numeral_simps [simp] =
   262   bin_nth_numeral [OF bin_rest_numeral_simps(2)]
   263   bin_nth_numeral [OF bin_rest_numeral_simps(5)]
   264   bin_nth_numeral [OF bin_rest_numeral_simps(6)]
   265   bin_nth_numeral [OF bin_rest_numeral_simps(7)]
   266   bin_nth_numeral [OF bin_rest_numeral_simps(8)]
   267 
   268 lemmas bin_nth_simps = 
   269   bin_nth.Z bin_nth.Suc bin_nth_zero bin_nth_minus1
   270   bin_nth_numeral_simps
   271 
   272 
   273 subsection {* Truncating binary integers *}
   274 
   275 definition bin_sign :: "int \<Rightarrow> int"
   276 where
   277   bin_sign_def: "bin_sign k = (if k \<ge> 0 then 0 else - 1)"
   278 
   279 lemma bin_sign_simps [simp]:
   280   "bin_sign 0 = 0"
   281   "bin_sign 1 = 0"
   282   "bin_sign (- 1) = - 1"
   283   "bin_sign (numeral k) = 0"
   284   "bin_sign (- numeral k) = -1"
   285   "bin_sign (w BIT b) = bin_sign w"
   286   unfolding bin_sign_def Bit_def
   287   by simp_all
   288 
   289 lemma bin_sign_rest [simp]: 
   290   "bin_sign (bin_rest w) = bin_sign w"
   291   by (cases w rule: bin_exhaust) auto
   292 
   293 primrec bintrunc :: "nat \<Rightarrow> int \<Rightarrow> int" where
   294   Z : "bintrunc 0 bin = 0"
   295 | Suc : "bintrunc (Suc n) bin = bintrunc n (bin_rest bin) BIT (bin_last bin)"
   296 
   297 primrec sbintrunc :: "nat => int => int" where
   298   Z : "sbintrunc 0 bin = (if bin_last bin then -1 else 0)"
   299 | Suc : "sbintrunc (Suc n) bin = sbintrunc n (bin_rest bin) BIT (bin_last bin)"
   300 
   301 lemma sign_bintr: "bin_sign (bintrunc n w) = 0"
   302   by (induct n arbitrary: w) auto
   303 
   304 lemma bintrunc_mod2p: "bintrunc n w = (w mod 2 ^ n)"
   305   apply (induct n arbitrary: w, clarsimp)
   306   apply (simp add: bin_last_def bin_rest_def Bit_def zmod_zmult2_eq)
   307   done
   308 
   309 lemma sbintrunc_mod2p: "sbintrunc n w = (w + 2 ^ n) mod 2 ^ (Suc n) - 2 ^ n"
   310   apply (induct n arbitrary: w)
   311    apply simp
   312    apply (subst mod_add_left_eq)
   313    apply (simp add: bin_last_def)
   314    apply arith
   315   apply (simp add: bin_last_def bin_rest_def Bit_def)
   316   apply (clarsimp simp: mod_mult_mult1 [symmetric] 
   317          zmod_zdiv_equality [THEN diff_eq_eq [THEN iffD2 [THEN sym]]])
   318   apply (rule trans [symmetric, OF _ emep1])
   319   apply auto
   320   done
   321 
   322 subsection "Simplifications for (s)bintrunc"
   323 
   324 lemma bintrunc_n_0 [simp]: "bintrunc n 0 = 0"
   325   by (induct n) auto
   326 
   327 lemma sbintrunc_n_0 [simp]: "sbintrunc n 0 = 0"
   328   by (induct n) auto
   329 
   330 lemma sbintrunc_n_minus1 [simp]: "sbintrunc n (- 1) = -1"
   331   by (induct n) auto
   332 
   333 lemma bintrunc_Suc_numeral:
   334   "bintrunc (Suc n) 1 = 1"
   335   "bintrunc (Suc n) (- 1) = bintrunc n (- 1) BIT True"
   336   "bintrunc (Suc n) (numeral (Num.Bit0 w)) = bintrunc n (numeral w) BIT False"
   337   "bintrunc (Suc n) (numeral (Num.Bit1 w)) = bintrunc n (numeral w) BIT True"
   338   "bintrunc (Suc n) (- numeral (Num.Bit0 w)) =
   339     bintrunc n (- numeral w) BIT False"
   340   "bintrunc (Suc n) (- numeral (Num.Bit1 w)) =
   341     bintrunc n (- numeral (w + Num.One)) BIT True"
   342   by simp_all
   343 
   344 lemma sbintrunc_0_numeral [simp]:
   345   "sbintrunc 0 1 = -1"
   346   "sbintrunc 0 (numeral (Num.Bit0 w)) = 0"
   347   "sbintrunc 0 (numeral (Num.Bit1 w)) = -1"
   348   "sbintrunc 0 (- numeral (Num.Bit0 w)) = 0"
   349   "sbintrunc 0 (- numeral (Num.Bit1 w)) = -1"
   350   by simp_all
   351 
   352 lemma sbintrunc_Suc_numeral:
   353   "sbintrunc (Suc n) 1 = 1"
   354   "sbintrunc (Suc n) (numeral (Num.Bit0 w)) =
   355     sbintrunc n (numeral w) BIT False"
   356   "sbintrunc (Suc n) (numeral (Num.Bit1 w)) =
   357     sbintrunc n (numeral w) BIT True"
   358   "sbintrunc (Suc n) (- numeral (Num.Bit0 w)) =
   359     sbintrunc n (- numeral w) BIT False"
   360   "sbintrunc (Suc n) (- numeral (Num.Bit1 w)) =
   361     sbintrunc n (- numeral (w + Num.One)) BIT True"
   362   by simp_all
   363 
   364 lemma bin_sign_lem: "(bin_sign (sbintrunc n bin) = -1) = bin_nth bin n"
   365   apply (induct n arbitrary: bin)
   366   apply (case_tac bin rule: bin_exhaust, case_tac b, auto)
   367   done
   368 
   369 lemma nth_bintr: "bin_nth (bintrunc m w) n = (n < m & bin_nth w n)"
   370   apply (induct n arbitrary: w m)
   371    apply (case_tac m, auto)[1]
   372   apply (case_tac m, auto)[1]
   373   done
   374 
   375 lemma nth_sbintr:
   376   "bin_nth (sbintrunc m w) n = 
   377           (if n < m then bin_nth w n else bin_nth w m)"
   378   apply (induct n arbitrary: w m)
   379   apply (case_tac m)
   380   apply simp_all
   381   apply (case_tac m)
   382   apply simp_all
   383   done
   384 
   385 lemma bin_nth_Bit:
   386   "bin_nth (w BIT b) n = (n = 0 & b | (EX m. n = Suc m & bin_nth w m))"
   387   by (cases n) auto
   388 
   389 lemma bin_nth_Bit0:
   390   "bin_nth (numeral (Num.Bit0 w)) n \<longleftrightarrow>
   391     (\<exists>m. n = Suc m \<and> bin_nth (numeral w) m)"
   392   using bin_nth_Bit [where w="numeral w" and b="False"] by simp
   393 
   394 lemma bin_nth_Bit1:
   395   "bin_nth (numeral (Num.Bit1 w)) n \<longleftrightarrow>
   396     n = 0 \<or> (\<exists>m. n = Suc m \<and> bin_nth (numeral w) m)"
   397   using bin_nth_Bit [where w="numeral w" and b="True"] by simp
   398 
   399 lemma bintrunc_bintrunc_l:
   400   "n <= m ==> (bintrunc m (bintrunc n w) = bintrunc n w)"
   401   by (rule bin_eqI) (auto simp add : nth_bintr)
   402 
   403 lemma sbintrunc_sbintrunc_l:
   404   "n <= m ==> (sbintrunc m (sbintrunc n w) = sbintrunc n w)"
   405   by (rule bin_eqI) (auto simp: nth_sbintr)
   406 
   407 lemma bintrunc_bintrunc_ge:
   408   "n <= m ==> (bintrunc n (bintrunc m w) = bintrunc n w)"
   409   by (rule bin_eqI) (auto simp: nth_bintr)
   410 
   411 lemma bintrunc_bintrunc_min [simp]:
   412   "bintrunc m (bintrunc n w) = bintrunc (min m n) w"
   413   apply (rule bin_eqI)
   414   apply (auto simp: nth_bintr)
   415   done
   416 
   417 lemma sbintrunc_sbintrunc_min [simp]:
   418   "sbintrunc m (sbintrunc n w) = sbintrunc (min m n) w"
   419   apply (rule bin_eqI)
   420   apply (auto simp: nth_sbintr min.absorb1 min.absorb2)
   421   done
   422 
   423 lemmas bintrunc_Pls = 
   424   bintrunc.Suc [where bin="0", simplified bin_last_numeral_simps bin_rest_numeral_simps]
   425 
   426 lemmas bintrunc_Min [simp] = 
   427   bintrunc.Suc [where bin="-1", simplified bin_last_numeral_simps bin_rest_numeral_simps]
   428 
   429 lemmas bintrunc_BIT  [simp] = 
   430   bintrunc.Suc [where bin="w BIT b", simplified bin_last_BIT bin_rest_BIT] for w b
   431 
   432 lemmas bintrunc_Sucs = bintrunc_Pls bintrunc_Min bintrunc_BIT
   433   bintrunc_Suc_numeral
   434 
   435 lemmas sbintrunc_Suc_Pls = 
   436   sbintrunc.Suc [where bin="0", simplified bin_last_numeral_simps bin_rest_numeral_simps]
   437 
   438 lemmas sbintrunc_Suc_Min = 
   439   sbintrunc.Suc [where bin="-1", simplified bin_last_numeral_simps bin_rest_numeral_simps]
   440 
   441 lemmas sbintrunc_Suc_BIT [simp] = 
   442   sbintrunc.Suc [where bin="w BIT b", simplified bin_last_BIT bin_rest_BIT] for w b
   443 
   444 lemmas sbintrunc_Sucs = sbintrunc_Suc_Pls sbintrunc_Suc_Min sbintrunc_Suc_BIT
   445   sbintrunc_Suc_numeral
   446 
   447 lemmas sbintrunc_Pls = 
   448   sbintrunc.Z [where bin="0", 
   449                simplified bin_last_numeral_simps bin_rest_numeral_simps]
   450 
   451 lemmas sbintrunc_Min = 
   452   sbintrunc.Z [where bin="-1",
   453                simplified bin_last_numeral_simps bin_rest_numeral_simps]
   454 
   455 lemmas sbintrunc_0_BIT_B0 [simp] = 
   456   sbintrunc.Z [where bin="w BIT False", 
   457                simplified bin_last_numeral_simps bin_rest_numeral_simps] for w
   458 
   459 lemmas sbintrunc_0_BIT_B1 [simp] = 
   460   sbintrunc.Z [where bin="w BIT True", 
   461                simplified bin_last_BIT bin_rest_numeral_simps] for w
   462 
   463 lemmas sbintrunc_0_simps =
   464   sbintrunc_Pls sbintrunc_Min sbintrunc_0_BIT_B0 sbintrunc_0_BIT_B1
   465 
   466 lemmas bintrunc_simps = bintrunc.Z bintrunc_Sucs
   467 lemmas sbintrunc_simps = sbintrunc_0_simps sbintrunc_Sucs
   468 
   469 lemma bintrunc_minus:
   470   "0 < n ==> bintrunc (Suc (n - 1)) w = bintrunc n w"
   471   by auto
   472 
   473 lemma sbintrunc_minus:
   474   "0 < n ==> sbintrunc (Suc (n - 1)) w = sbintrunc n w"
   475   by auto
   476 
   477 lemmas bintrunc_minus_simps = 
   478   bintrunc_Sucs [THEN [2] bintrunc_minus [symmetric, THEN trans]]
   479 lemmas sbintrunc_minus_simps = 
   480   sbintrunc_Sucs [THEN [2] sbintrunc_minus [symmetric, THEN trans]]
   481 
   482 lemmas thobini1 = arg_cong [where f = "%w. w BIT b"] for b
   483 
   484 lemmas bintrunc_BIT_I = trans [OF bintrunc_BIT thobini1]
   485 lemmas bintrunc_Min_I = trans [OF bintrunc_Min thobini1]
   486 
   487 lemmas bmsts = bintrunc_minus_simps(1-3) [THEN thobini1 [THEN [2] trans]]
   488 lemmas bintrunc_Pls_minus_I = bmsts(1)
   489 lemmas bintrunc_Min_minus_I = bmsts(2)
   490 lemmas bintrunc_BIT_minus_I = bmsts(3)
   491 
   492 lemma bintrunc_Suc_lem:
   493   "bintrunc (Suc n) x = y ==> m = Suc n ==> bintrunc m x = y"
   494   by auto
   495 
   496 lemmas bintrunc_Suc_Ialts = 
   497   bintrunc_Min_I [THEN bintrunc_Suc_lem]
   498   bintrunc_BIT_I [THEN bintrunc_Suc_lem]
   499 
   500 lemmas sbintrunc_BIT_I = trans [OF sbintrunc_Suc_BIT thobini1]
   501 
   502 lemmas sbintrunc_Suc_Is = 
   503   sbintrunc_Sucs(1-3) [THEN thobini1 [THEN [2] trans]]
   504 
   505 lemmas sbintrunc_Suc_minus_Is = 
   506   sbintrunc_minus_simps(1-3) [THEN thobini1 [THEN [2] trans]]
   507 
   508 lemma sbintrunc_Suc_lem:
   509   "sbintrunc (Suc n) x = y ==> m = Suc n ==> sbintrunc m x = y"
   510   by auto
   511 
   512 lemmas sbintrunc_Suc_Ialts = 
   513   sbintrunc_Suc_Is [THEN sbintrunc_Suc_lem]
   514 
   515 lemma sbintrunc_bintrunc_lt:
   516   "m > n ==> sbintrunc n (bintrunc m w) = sbintrunc n w"
   517   by (rule bin_eqI) (auto simp: nth_sbintr nth_bintr)
   518 
   519 lemma bintrunc_sbintrunc_le:
   520   "m <= Suc n ==> bintrunc m (sbintrunc n w) = bintrunc m w"
   521   apply (rule bin_eqI)
   522   apply (auto simp: nth_sbintr nth_bintr)
   523    apply (subgoal_tac "x=n", safe, arith+)[1]
   524   apply (subgoal_tac "x=n", safe, arith+)[1]
   525   done
   526 
   527 lemmas bintrunc_sbintrunc [simp] = order_refl [THEN bintrunc_sbintrunc_le]
   528 lemmas sbintrunc_bintrunc [simp] = lessI [THEN sbintrunc_bintrunc_lt]
   529 lemmas bintrunc_bintrunc [simp] = order_refl [THEN bintrunc_bintrunc_l]
   530 lemmas sbintrunc_sbintrunc [simp] = order_refl [THEN sbintrunc_sbintrunc_l] 
   531 
   532 lemma bintrunc_sbintrunc' [simp]:
   533   "0 < n \<Longrightarrow> bintrunc n (sbintrunc (n - 1) w) = bintrunc n w"
   534   by (cases n) (auto simp del: bintrunc.Suc)
   535 
   536 lemma sbintrunc_bintrunc' [simp]:
   537   "0 < n \<Longrightarrow> sbintrunc (n - 1) (bintrunc n w) = sbintrunc (n - 1) w"
   538   by (cases n) (auto simp del: bintrunc.Suc)
   539 
   540 lemma bin_sbin_eq_iff: 
   541   "bintrunc (Suc n) x = bintrunc (Suc n) y <-> 
   542    sbintrunc n x = sbintrunc n y"
   543   apply (rule iffI)
   544    apply (rule box_equals [OF _ sbintrunc_bintrunc sbintrunc_bintrunc])
   545    apply simp
   546   apply (rule box_equals [OF _ bintrunc_sbintrunc bintrunc_sbintrunc])
   547   apply simp
   548   done
   549 
   550 lemma bin_sbin_eq_iff':
   551   "0 < n \<Longrightarrow> bintrunc n x = bintrunc n y <-> 
   552             sbintrunc (n - 1) x = sbintrunc (n - 1) y"
   553   by (cases n) (simp_all add: bin_sbin_eq_iff del: bintrunc.Suc)
   554 
   555 lemmas bintrunc_sbintruncS0 [simp] = bintrunc_sbintrunc' [unfolded One_nat_def]
   556 lemmas sbintrunc_bintruncS0 [simp] = sbintrunc_bintrunc' [unfolded One_nat_def]
   557 
   558 lemmas bintrunc_bintrunc_l' = le_add1 [THEN bintrunc_bintrunc_l]
   559 lemmas sbintrunc_sbintrunc_l' = le_add1 [THEN sbintrunc_sbintrunc_l]
   560 
   561 (* although bintrunc_minus_simps, if added to default simpset,
   562   tends to get applied where it's not wanted in developing the theories,
   563   we get a version for when the word length is given literally *)
   564 
   565 lemmas nat_non0_gr = 
   566   trans [OF iszero_def [THEN Not_eq_iff [THEN iffD2]] refl]
   567 
   568 lemma bintrunc_numeral:
   569   "bintrunc (numeral k) x =
   570     bintrunc (pred_numeral k) (bin_rest x) BIT bin_last x"
   571   by (simp add: numeral_eq_Suc)
   572 
   573 lemma sbintrunc_numeral:
   574   "sbintrunc (numeral k) x =
   575     sbintrunc (pred_numeral k) (bin_rest x) BIT bin_last x"
   576   by (simp add: numeral_eq_Suc)
   577 
   578 lemma bintrunc_numeral_simps [simp]:
   579   "bintrunc (numeral k) (numeral (Num.Bit0 w)) =
   580     bintrunc (pred_numeral k) (numeral w) BIT False"
   581   "bintrunc (numeral k) (numeral (Num.Bit1 w)) =
   582     bintrunc (pred_numeral k) (numeral w) BIT True"
   583   "bintrunc (numeral k) (- numeral (Num.Bit0 w)) =
   584     bintrunc (pred_numeral k) (- numeral w) BIT False"
   585   "bintrunc (numeral k) (- numeral (Num.Bit1 w)) =
   586     bintrunc (pred_numeral k) (- numeral (w + Num.One)) BIT True"
   587   "bintrunc (numeral k) 1 = 1"
   588   by (simp_all add: bintrunc_numeral)
   589 
   590 lemma sbintrunc_numeral_simps [simp]:
   591   "sbintrunc (numeral k) (numeral (Num.Bit0 w)) =
   592     sbintrunc (pred_numeral k) (numeral w) BIT False"
   593   "sbintrunc (numeral k) (numeral (Num.Bit1 w)) =
   594     sbintrunc (pred_numeral k) (numeral w) BIT True"
   595   "sbintrunc (numeral k) (- numeral (Num.Bit0 w)) =
   596     sbintrunc (pred_numeral k) (- numeral w) BIT False"
   597   "sbintrunc (numeral k) (- numeral (Num.Bit1 w)) =
   598     sbintrunc (pred_numeral k) (- numeral (w + Num.One)) BIT True"
   599   "sbintrunc (numeral k) 1 = 1"
   600   by (simp_all add: sbintrunc_numeral)
   601 
   602 lemma no_bintr_alt1: "bintrunc n = (\<lambda>w. w mod 2 ^ n :: int)"
   603   by (rule ext) (rule bintrunc_mod2p)
   604 
   605 lemma range_bintrunc: "range (bintrunc n) = {i. 0 <= i & i < 2 ^ n}"
   606   apply (unfold no_bintr_alt1)
   607   apply (auto simp add: image_iff)
   608   apply (rule exI)
   609   apply (auto intro: int_mod_lem [THEN iffD1, symmetric])
   610   done
   611 
   612 lemma no_sbintr_alt2: 
   613   "sbintrunc n = (%w. (w + 2 ^ n) mod 2 ^ Suc n - 2 ^ n :: int)"
   614   by (rule ext) (simp add : sbintrunc_mod2p)
   615 
   616 lemma range_sbintrunc: 
   617   "range (sbintrunc n) = {i. - (2 ^ n) <= i & i < 2 ^ n}"
   618   apply (unfold no_sbintr_alt2)
   619   apply (auto simp add: image_iff eq_diff_eq)
   620   apply (rule exI)
   621   apply (auto intro: int_mod_lem [THEN iffD1, symmetric])
   622   done
   623 
   624 lemma sb_inc_lem:
   625   "(a::int) + 2^k < 0 \<Longrightarrow> a + 2^k + 2^(Suc k) <= (a + 2^k) mod 2^(Suc k)"
   626   apply (erule int_mod_ge' [where n = "2 ^ (Suc k)" and b = "a + 2 ^ k", simplified zless2p])
   627   apply (rule TrueI)
   628   done
   629 
   630 lemma sb_inc_lem':
   631   "(a::int) < - (2^k) \<Longrightarrow> a + 2^k + 2^(Suc k) <= (a + 2^k) mod 2^(Suc k)"
   632   by (rule sb_inc_lem) simp
   633 
   634 lemma sbintrunc_inc:
   635   "x < - (2^n) ==> x + 2^(Suc n) <= sbintrunc n x"
   636   unfolding no_sbintr_alt2 by (drule sb_inc_lem') simp
   637 
   638 lemma sb_dec_lem:
   639   "(0::int) \<le> - (2 ^ k) + a \<Longrightarrow> (a + 2 ^ k) mod (2 * 2 ^ k) \<le> - (2 ^ k) + a"
   640   using int_mod_le'[where n = "2 ^ (Suc k)" and b = "a + 2 ^ k"] by simp
   641 
   642 lemma sb_dec_lem':
   643   "(2::int) ^ k \<le> a \<Longrightarrow> (a + 2 ^ k) mod (2 * 2 ^ k) \<le> - (2 ^ k) + a"
   644   by (rule sb_dec_lem) simp
   645 
   646 lemma sbintrunc_dec:
   647   "x >= (2 ^ n) ==> x - 2 ^ (Suc n) >= sbintrunc n x"
   648   unfolding no_sbintr_alt2 by (drule sb_dec_lem') simp
   649 
   650 lemmas zmod_uminus' = zminus_zmod [where m=c] for c
   651 lemmas zpower_zmod' = power_mod [where b=c and n=k] for c k
   652 
   653 lemmas brdmod1s' [symmetric] =
   654   mod_add_left_eq mod_add_right_eq
   655   mod_diff_left_eq mod_diff_right_eq
   656   mod_mult_left_eq mod_mult_right_eq
   657 
   658 lemmas brdmods' [symmetric] = 
   659   zpower_zmod' [symmetric]
   660   trans [OF mod_add_left_eq mod_add_right_eq] 
   661   trans [OF mod_diff_left_eq mod_diff_right_eq] 
   662   trans [OF mod_mult_right_eq mod_mult_left_eq] 
   663   zmod_uminus' [symmetric]
   664   mod_add_left_eq [where b = "1::int"]
   665   mod_diff_left_eq [where b = "1::int"]
   666 
   667 lemmas bintr_arith1s =
   668   brdmod1s' [where c="2^n::int", folded bintrunc_mod2p] for n
   669 lemmas bintr_ariths =
   670   brdmods' [where c="2^n::int", folded bintrunc_mod2p] for n
   671 
   672 lemmas m2pths = pos_mod_sign pos_mod_bound [OF zless2p]
   673 
   674 lemma bintr_ge0: "0 \<le> bintrunc n w"
   675   by (simp add: bintrunc_mod2p)
   676 
   677 lemma bintr_lt2p: "bintrunc n w < 2 ^ n"
   678   by (simp add: bintrunc_mod2p)
   679 
   680 lemma bintr_Min: "bintrunc n (- 1) = 2 ^ n - 1"
   681   by (simp add: bintrunc_mod2p m1mod2k)
   682 
   683 lemma sbintr_ge: "- (2 ^ n) \<le> sbintrunc n w"
   684   by (simp add: sbintrunc_mod2p)
   685 
   686 lemma sbintr_lt: "sbintrunc n w < 2 ^ n"
   687   by (simp add: sbintrunc_mod2p)
   688 
   689 lemma sign_Pls_ge_0: 
   690   "(bin_sign bin = 0) = (bin >= (0 :: int))"
   691   unfolding bin_sign_def by simp
   692 
   693 lemma sign_Min_lt_0: 
   694   "(bin_sign bin = -1) = (bin < (0 :: int))"
   695   unfolding bin_sign_def by simp
   696 
   697 lemma bin_rest_trunc:
   698   "(bin_rest (bintrunc n bin)) = bintrunc (n - 1) (bin_rest bin)"
   699   by (induct n arbitrary: bin) auto
   700 
   701 lemma bin_rest_power_trunc:
   702   "(bin_rest ^^ k) (bintrunc n bin) = 
   703     bintrunc (n - k) ((bin_rest ^^ k) bin)"
   704   by (induct k) (auto simp: bin_rest_trunc)
   705 
   706 lemma bin_rest_trunc_i:
   707   "bintrunc n (bin_rest bin) = bin_rest (bintrunc (Suc n) bin)"
   708   by auto
   709 
   710 lemma bin_rest_strunc:
   711   "bin_rest (sbintrunc (Suc n) bin) = sbintrunc n (bin_rest bin)"
   712   by (induct n arbitrary: bin) auto
   713 
   714 lemma bintrunc_rest [simp]: 
   715   "bintrunc n (bin_rest (bintrunc n bin)) = bin_rest (bintrunc n bin)"
   716   apply (induct n arbitrary: bin, simp)
   717   apply (case_tac bin rule: bin_exhaust)
   718   apply (auto simp: bintrunc_bintrunc_l)
   719   done
   720 
   721 lemma sbintrunc_rest [simp]:
   722   "sbintrunc n (bin_rest (sbintrunc n bin)) = bin_rest (sbintrunc n bin)"
   723   apply (induct n arbitrary: bin, simp)
   724   apply (case_tac bin rule: bin_exhaust)
   725   apply (auto simp: bintrunc_bintrunc_l split: bool.splits)
   726   done
   727 
   728 lemma bintrunc_rest':
   729   "bintrunc n o bin_rest o bintrunc n = bin_rest o bintrunc n"
   730   by (rule ext) auto
   731 
   732 lemma sbintrunc_rest' :
   733   "sbintrunc n o bin_rest o sbintrunc n = bin_rest o sbintrunc n"
   734   by (rule ext) auto
   735 
   736 lemma rco_lem:
   737   "f o g o f = g o f ==> f o (g o f) ^^ n = g ^^ n o f"
   738   apply (rule ext)
   739   apply (induct_tac n)
   740    apply (simp_all (no_asm))
   741   apply (drule fun_cong)
   742   apply (unfold o_def)
   743   apply (erule trans)
   744   apply simp
   745   done
   746 
   747 lemmas rco_bintr = bintrunc_rest' 
   748   [THEN rco_lem [THEN fun_cong], unfolded o_def]
   749 lemmas rco_sbintr = sbintrunc_rest' 
   750   [THEN rco_lem [THEN fun_cong], unfolded o_def]
   751 
   752   
   753 subsection {* Splitting and concatenation *}
   754 
   755 primrec bin_split :: "nat \<Rightarrow> int \<Rightarrow> int \<times> int" where
   756   Z: "bin_split 0 w = (w, 0)"
   757   | Suc: "bin_split (Suc n) w = (let (w1, w2) = bin_split n (bin_rest w)
   758         in (w1, w2 BIT bin_last w))"
   759 
   760 lemma [code]:
   761   "bin_split (Suc n) w = (let (w1, w2) = bin_split n (bin_rest w) in (w1, w2 BIT bin_last w))"
   762   "bin_split 0 w = (w, 0)"
   763   by simp_all
   764 
   765 primrec bin_cat :: "int \<Rightarrow> nat \<Rightarrow> int \<Rightarrow> int" where
   766   Z: "bin_cat w 0 v = w"
   767   | Suc: "bin_cat w (Suc n) v = bin_cat w n (bin_rest v) BIT bin_last v"
   768 
   769 end
   770