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