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