src/HOL/Word/WordShift.thy
author nipkow
Mon, 20 Oct 2008 23:53:17 +0200
changeset 28643 caa1137d25dc
parent 27136 06a8f65e32f6
child 29631 3aa049e5f156
permissions -rw-r--r--
fixed proof
kleing@24333
     1
(* 
kleing@24333
     2
    ID:         $Id$
kleing@24333
     3
    Author:     Jeremy Dawson and Gerwin Klein, NICTA
kleing@24333
     4
kleing@24333
     5
  contains theorems to do with shifting, rotating, splitting words
kleing@24333
     6
*)
kleing@24333
     7
huffman@24350
     8
header {* Shifting, Rotating, and Splitting Words *}
huffman@24465
     9
haftmann@26558
    10
theory WordShift
haftmann@26558
    11
imports WordBitwise
haftmann@26558
    12
begin
kleing@24333
    13
huffman@24350
    14
subsection "Bit shifting"
kleing@24333
    15
kleing@24333
    16
lemma shiftl1_number [simp] :
kleing@24333
    17
  "shiftl1 (number_of w) = number_of (w BIT bit.B0)"
kleing@24333
    18
  apply (unfold shiftl1_def word_number_of_def)
huffman@26086
    19
  apply (simp add: word_ubin.norm_eq_iff [symmetric] word_ubin.eq_norm
huffman@26086
    20
              del: BIT_simps)
kleing@24333
    21
  apply (subst refl [THEN bintrunc_BIT_I, symmetric])
kleing@24333
    22
  apply (subst bintrunc_bintrunc_min)
kleing@24333
    23
  apply simp
kleing@24333
    24
  done
kleing@24333
    25
kleing@24333
    26
lemma shiftl1_0 [simp] : "shiftl1 0 = 0"
kleing@24333
    27
  unfolding word_0_no shiftl1_number by auto
kleing@24333
    28
kleing@24333
    29
lemmas shiftl1_def_u = shiftl1_def [folded word_number_of_def]
kleing@24333
    30
kleing@24333
    31
lemma shiftl1_def_s: "shiftl1 w = number_of (sint w BIT bit.B0)"
kleing@24333
    32
  by (rule trans [OF _ shiftl1_number]) simp
kleing@24333
    33
kleing@24333
    34
lemma shiftr1_0 [simp] : "shiftr1 0 = 0"
kleing@24333
    35
  unfolding shiftr1_def 
kleing@24333
    36
  by simp (simp add: word_0_wi)
kleing@24333
    37
kleing@24333
    38
lemma sshiftr1_0 [simp] : "sshiftr1 0 = 0"
kleing@24333
    39
  apply (unfold sshiftr1_def)
kleing@24333
    40
  apply simp
kleing@24333
    41
  apply (simp add : word_0_wi)
kleing@24333
    42
  done
kleing@24333
    43
kleing@24333
    44
lemma sshiftr1_n1 [simp] : "sshiftr1 -1 = -1"
kleing@24333
    45
  unfolding sshiftr1_def by auto
kleing@24333
    46
huffman@24465
    47
lemma shiftl_0 [simp] : "(0::'a::len0 word) << n = 0"
kleing@24333
    48
  unfolding shiftl_def by (induct n) auto
kleing@24333
    49
huffman@24465
    50
lemma shiftr_0 [simp] : "(0::'a::len0 word) >> n = 0"
kleing@24333
    51
  unfolding shiftr_def by (induct n) auto
kleing@24333
    52
kleing@24333
    53
lemma sshiftr_0 [simp] : "0 >>> n = 0"
kleing@24333
    54
  unfolding sshiftr_def by (induct n) auto
kleing@24333
    55
kleing@24333
    56
lemma sshiftr_n1 [simp] : "-1 >>> n = -1"
kleing@24333
    57
  unfolding sshiftr_def by (induct n) auto
kleing@24333
    58
kleing@24333
    59
lemma nth_shiftl1: "shiftl1 w !! n = (n < size w & n > 0 & w !! (n - 1))"
kleing@24333
    60
  apply (unfold shiftl1_def word_test_bit_def)
kleing@24333
    61
  apply (simp add: nth_bintr word_ubin.eq_norm word_size)
kleing@24333
    62
  apply (cases n)
kleing@24333
    63
   apply auto
kleing@24333
    64
  done
kleing@24333
    65
kleing@24333
    66
lemma nth_shiftl' [rule_format]:
huffman@24465
    67
  "ALL n. ((w::'a::len0 word) << m) !! n = (n < size w & n >= m & w !! (n - m))"
kleing@24333
    68
  apply (unfold shiftl_def)
kleing@24333
    69
  apply (induct "m")
kleing@24333
    70
   apply (force elim!: test_bit_size)
kleing@24333
    71
  apply (clarsimp simp add : nth_shiftl1 word_size)
kleing@24333
    72
  apply arith
kleing@24333
    73
  done
kleing@24333
    74
kleing@24333
    75
lemmas nth_shiftl = nth_shiftl' [unfolded word_size] 
kleing@24333
    76
kleing@24333
    77
lemma nth_shiftr1: "shiftr1 w !! n = w !! Suc n"
kleing@24333
    78
  apply (unfold shiftr1_def word_test_bit_def)
kleing@24333
    79
  apply (simp add: nth_bintr word_ubin.eq_norm)
kleing@24333
    80
  apply safe
kleing@24333
    81
  apply (drule bin_nth.Suc [THEN iffD2, THEN bin_nth_uint_imp])
kleing@24333
    82
  apply simp
kleing@24333
    83
  done
kleing@24333
    84
kleing@24333
    85
lemma nth_shiftr: 
huffman@24465
    86
  "\<And>n. ((w::'a::len0 word) >> m) !! n = w !! (n + m)"
kleing@24333
    87
  apply (unfold shiftr_def)
kleing@24333
    88
  apply (induct "m")
kleing@24333
    89
   apply (auto simp add : nth_shiftr1)
kleing@24333
    90
  done
kleing@24333
    91
   
kleing@24333
    92
(* see paper page 10, (1), (2), shiftr1_def is of the form of (1),
kleing@24333
    93
  where f (ie bin_rest) takes normal arguments to normal results,
kleing@24333
    94
  thus we get (2) from (1) *)
kleing@24333
    95
kleing@24333
    96
lemma uint_shiftr1: "uint (shiftr1 w) = bin_rest (uint w)" 
kleing@24333
    97
  apply (unfold shiftr1_def word_ubin.eq_norm bin_rest_trunc_i)
kleing@24333
    98
  apply (subst bintr_uint [symmetric, OF order_refl])
kleing@24333
    99
  apply (simp only : bintrunc_bintrunc_l)
kleing@24333
   100
  apply simp 
kleing@24333
   101
  done
kleing@24333
   102
kleing@24333
   103
lemma nth_sshiftr1: 
kleing@24333
   104
  "sshiftr1 w !! n = (if n = size w - 1 then w !! n else w !! Suc n)"
kleing@24333
   105
  apply (unfold sshiftr1_def word_test_bit_def)
kleing@24333
   106
  apply (simp add: nth_bintr word_ubin.eq_norm
kleing@24333
   107
                   bin_nth.Suc [symmetric] word_size 
kleing@24333
   108
             del: bin_nth.simps)
kleing@24333
   109
  apply (simp add: nth_bintr uint_sint del : bin_nth.simps)
kleing@24333
   110
  apply (auto simp add: bin_nth_sint)
kleing@24333
   111
  done
kleing@24333
   112
kleing@24333
   113
lemma nth_sshiftr [rule_format] : 
kleing@24333
   114
  "ALL n. sshiftr w m !! n = (n < size w & 
kleing@24333
   115
    (if n + m >= size w then w !! (size w - 1) else w !! (n + m)))"
kleing@24333
   116
  apply (unfold sshiftr_def)
kleing@24333
   117
  apply (induct_tac "m")
kleing@24333
   118
   apply (simp add: test_bit_bl)
kleing@24333
   119
  apply (clarsimp simp add: nth_sshiftr1 word_size)
kleing@24333
   120
  apply safe
kleing@24333
   121
       apply arith
kleing@24333
   122
      apply arith
kleing@24333
   123
     apply (erule thin_rl)
wenzelm@27136
   124
     apply (case_tac n)
kleing@24333
   125
      apply safe
kleing@24333
   126
      apply simp
kleing@24333
   127
     apply simp
kleing@24333
   128
    apply (erule thin_rl)
wenzelm@27136
   129
    apply (case_tac n)
kleing@24333
   130
     apply safe
kleing@24333
   131
     apply simp
kleing@24333
   132
    apply simp
kleing@24333
   133
   apply arith+
kleing@24333
   134
  done
kleing@24333
   135
    
kleing@24333
   136
lemma shiftr1_div_2: "uint (shiftr1 w) = uint w div 2"
kleing@24333
   137
  apply (unfold shiftr1_def bin_rest_div)
kleing@24333
   138
  apply (rule word_uint.Abs_inverse)
kleing@24333
   139
  apply (simp add: uints_num pos_imp_zdiv_nonneg_iff)
kleing@24333
   140
  apply (rule xtr7)
kleing@24333
   141
   prefer 2
kleing@24333
   142
   apply (rule zdiv_le_dividend)
kleing@24333
   143
    apply auto
kleing@24333
   144
  done
kleing@24333
   145
kleing@24333
   146
lemma sshiftr1_div_2: "sint (sshiftr1 w) = sint w div 2"
kleing@24333
   147
  apply (unfold sshiftr1_def bin_rest_div [symmetric])
kleing@24333
   148
  apply (simp add: word_sbin.eq_norm)
kleing@24333
   149
  apply (rule trans)
kleing@24333
   150
   defer
kleing@24333
   151
   apply (subst word_sbin.norm_Rep [symmetric])
kleing@24333
   152
   apply (rule refl)
kleing@24333
   153
  apply (subst word_sbin.norm_Rep [symmetric])
kleing@24333
   154
  apply (unfold One_nat_def)
kleing@24333
   155
  apply (rule sbintrunc_rest)
kleing@24333
   156
  done
kleing@24333
   157
kleing@24333
   158
lemma shiftr_div_2n: "uint (shiftr w n) = uint w div 2 ^ n"
kleing@24333
   159
  apply (unfold shiftr_def)
kleing@24333
   160
  apply (induct "n")
kleing@24333
   161
   apply simp
kleing@24333
   162
  apply (simp add: shiftr1_div_2 mult_commute
kleing@24333
   163
                   zdiv_zmult2_eq [symmetric])
kleing@24333
   164
  done
kleing@24333
   165
kleing@24333
   166
lemma sshiftr_div_2n: "sint (sshiftr w n) = sint w div 2 ^ n"
kleing@24333
   167
  apply (unfold sshiftr_def)
kleing@24333
   168
  apply (induct "n")
kleing@24333
   169
   apply simp
kleing@24333
   170
  apply (simp add: sshiftr1_div_2 mult_commute
kleing@24333
   171
                   zdiv_zmult2_eq [symmetric])
kleing@24333
   172
  done
kleing@24333
   173
huffman@24350
   174
subsubsection "shift functions in terms of lists of bools"
kleing@24333
   175
kleing@24333
   176
lemmas bshiftr1_no_bin [simp] = 
wenzelm@25350
   177
  bshiftr1_def [where w="number_of w", unfolded to_bl_no_bin, standard]
kleing@24333
   178
kleing@24333
   179
lemma bshiftr1_bl: "to_bl (bshiftr1 b w) = b # butlast (to_bl w)"
kleing@24333
   180
  unfolding bshiftr1_def by (rule word_bl.Abs_inverse) simp
kleing@24333
   181
kleing@24333
   182
lemma shiftl1_of_bl: "shiftl1 (of_bl bl) = of_bl (bl @ [False])"
kleing@24333
   183
  unfolding uint_bl of_bl_no 
kleing@24333
   184
  by (simp add: bl_to_bin_aux_append bl_to_bin_def)
kleing@24333
   185
wenzelm@25350
   186
lemma shiftl1_bl: "shiftl1 (w::'a::len0 word) = of_bl (to_bl w @ [False])"
wenzelm@25350
   187
proof -
wenzelm@25350
   188
  have "shiftl1 w = shiftl1 (of_bl (to_bl w))" by simp
wenzelm@25350
   189
  also have "\<dots> = of_bl (to_bl w @ [False])" by (rule shiftl1_of_bl)
wenzelm@25350
   190
  finally show ?thesis .
wenzelm@25350
   191
qed
kleing@24333
   192
kleing@24333
   193
lemma bl_shiftl1:
huffman@24465
   194
  "to_bl (shiftl1 (w :: 'a :: len word)) = tl (to_bl w) @ [False]"
huffman@24465
   195
  apply (simp add: shiftl1_bl word_rep_drop drop_Suc drop_Cons')
huffman@24465
   196
  apply (fast intro!: Suc_leI)
huffman@24465
   197
  done
kleing@24333
   198
kleing@24333
   199
lemma shiftr1_bl: "shiftr1 w = of_bl (butlast (to_bl w))"
kleing@24333
   200
  apply (unfold shiftr1_def uint_bl of_bl_def)
kleing@24333
   201
  apply (simp add: butlast_rest_bin word_size)
kleing@24333
   202
  apply (simp add: bin_rest_trunc [symmetric, unfolded One_nat_def])
kleing@24333
   203
  done
kleing@24333
   204
kleing@24333
   205
lemma bl_shiftr1: 
huffman@24465
   206
  "to_bl (shiftr1 (w :: 'a :: len word)) = False # butlast (to_bl w)"
kleing@24333
   207
  unfolding shiftr1_bl
huffman@24465
   208
  by (simp add : word_rep_drop len_gt_0 [THEN Suc_leI])
kleing@24333
   209
kleing@24333
   210
huffman@24465
   211
(* relate the two above : TODO - remove the :: len restriction on
kleing@24333
   212
  this theorem and others depending on it *)
kleing@24333
   213
lemma shiftl1_rev: 
huffman@24465
   214
  "shiftl1 (w :: 'a :: len word) = word_reverse (shiftr1 (word_reverse w))"
kleing@24333
   215
  apply (unfold word_reverse_def)
kleing@24333
   216
  apply (rule word_bl.Rep_inverse' [symmetric])
kleing@24333
   217
  apply (simp add: bl_shiftl1 bl_shiftr1 word_bl.Abs_inverse)
kleing@24333
   218
  apply (cases "to_bl w")
kleing@24333
   219
   apply auto
kleing@24333
   220
  done
kleing@24333
   221
kleing@24333
   222
lemma shiftl_rev: 
huffman@24465
   223
  "shiftl (w :: 'a :: len word) n = word_reverse (shiftr (word_reverse w) n)"
kleing@24333
   224
  apply (unfold shiftl_def shiftr_def)
kleing@24333
   225
  apply (induct "n")
kleing@24333
   226
   apply (auto simp add : shiftl1_rev)
kleing@24333
   227
  done
kleing@24333
   228
kleing@24333
   229
lemmas rev_shiftl =
wenzelm@25350
   230
  shiftl_rev [where w = "word_reverse w", simplified, standard]
kleing@24333
   231
kleing@24333
   232
lemmas shiftr_rev = rev_shiftl [THEN word_rev_gal', standard]
kleing@24333
   233
lemmas rev_shiftr = shiftl_rev [THEN word_rev_gal', standard]
kleing@24333
   234
kleing@24333
   235
lemma bl_sshiftr1:
huffman@24465
   236
  "to_bl (sshiftr1 (w :: 'a :: len word)) = hd (to_bl w) # butlast (to_bl w)"
kleing@24333
   237
  apply (unfold sshiftr1_def uint_bl word_size)
kleing@24333
   238
  apply (simp add: butlast_rest_bin word_ubin.eq_norm)
kleing@24333
   239
  apply (simp add: sint_uint)
kleing@24333
   240
  apply (rule nth_equalityI)
kleing@24333
   241
   apply clarsimp
kleing@24333
   242
  apply clarsimp
kleing@24333
   243
  apply (case_tac i)
kleing@24333
   244
   apply (simp_all add: hd_conv_nth length_0_conv [symmetric]
kleing@24333
   245
                        nth_bin_to_bl bin_nth.Suc [symmetric] 
kleing@24333
   246
                        nth_sbintr 
kleing@24333
   247
                   del: bin_nth.Suc)
huffman@24465
   248
   apply force
kleing@24333
   249
  apply (rule impI)
kleing@24333
   250
  apply (rule_tac f = "bin_nth (uint w)" in arg_cong)
kleing@24333
   251
  apply simp
kleing@24333
   252
  done
kleing@24333
   253
kleing@24333
   254
lemma drop_shiftr: 
huffman@24465
   255
  "drop n (to_bl ((w :: 'a :: len word) >> n)) = take (size w - n) (to_bl w)" 
kleing@24333
   256
  apply (unfold shiftr_def)
kleing@24333
   257
  apply (induct n)
kleing@24333
   258
   prefer 2
kleing@24333
   259
   apply (simp add: drop_Suc bl_shiftr1 butlast_drop [symmetric])
kleing@24333
   260
   apply (rule butlast_take [THEN trans])
kleing@24333
   261
  apply (auto simp: word_size)
kleing@24333
   262
  done
kleing@24333
   263
kleing@24333
   264
lemma drop_sshiftr: 
huffman@24465
   265
  "drop n (to_bl ((w :: 'a :: len word) >>> n)) = take (size w - n) (to_bl w)"
kleing@24333
   266
  apply (unfold sshiftr_def)
kleing@24333
   267
  apply (induct n)
kleing@24333
   268
   prefer 2
kleing@24333
   269
   apply (simp add: drop_Suc bl_sshiftr1 butlast_drop [symmetric])
kleing@24333
   270
   apply (rule butlast_take [THEN trans])
kleing@24333
   271
  apply (auto simp: word_size)
kleing@24333
   272
  done
kleing@24333
   273
kleing@24333
   274
lemma take_shiftr [rule_format] :
huffman@24465
   275
  "n <= size (w :: 'a :: len word) --> take n (to_bl (w >> n)) = 
kleing@24333
   276
    replicate n False" 
kleing@24333
   277
  apply (unfold shiftr_def)
kleing@24333
   278
  apply (induct n)
kleing@24333
   279
   prefer 2
kleing@24333
   280
   apply (simp add: bl_shiftr1)
kleing@24333
   281
   apply (rule impI)
kleing@24333
   282
   apply (rule take_butlast [THEN trans])
kleing@24333
   283
  apply (auto simp: word_size)
kleing@24333
   284
  done
kleing@24333
   285
kleing@24333
   286
lemma take_sshiftr' [rule_format] :
huffman@24465
   287
  "n <= size (w :: 'a :: len word) --> hd (to_bl (w >>> n)) = hd (to_bl w) & 
kleing@24333
   288
    take n (to_bl (w >>> n)) = replicate n (hd (to_bl w))" 
kleing@24333
   289
  apply (unfold sshiftr_def)
kleing@24333
   290
  apply (induct n)
kleing@24333
   291
   prefer 2
kleing@24333
   292
   apply (simp add: bl_sshiftr1)
kleing@24333
   293
   apply (rule impI)
kleing@24333
   294
   apply (rule take_butlast [THEN trans])
kleing@24333
   295
  apply (auto simp: word_size)
kleing@24333
   296
  done
kleing@24333
   297
kleing@24333
   298
lemmas hd_sshiftr = take_sshiftr' [THEN conjunct1, standard]
kleing@24333
   299
lemmas take_sshiftr = take_sshiftr' [THEN conjunct2, standard]
kleing@24333
   300
kleing@24333
   301
lemma atd_lem: "take n xs = t ==> drop n xs = d ==> xs = t @ d"
kleing@24333
   302
  by (auto intro: append_take_drop_id [symmetric])
kleing@24333
   303
kleing@24333
   304
lemmas bl_shiftr = atd_lem [OF take_shiftr drop_shiftr]
kleing@24333
   305
lemmas bl_sshiftr = atd_lem [OF take_sshiftr drop_sshiftr]
kleing@24333
   306
kleing@24333
   307
lemma shiftl_of_bl: "of_bl bl << n = of_bl (bl @ replicate n False)"
kleing@24333
   308
  unfolding shiftl_def
kleing@24333
   309
  by (induct n) (auto simp: shiftl1_of_bl replicate_app_Cons_same)
kleing@24333
   310
wenzelm@25350
   311
lemma shiftl_bl:
wenzelm@25350
   312
  "(w::'a::len0 word) << (n::nat) = of_bl (to_bl w @ replicate n False)"
wenzelm@25350
   313
proof -
wenzelm@25350
   314
  have "w << n = of_bl (to_bl w) << n" by simp
wenzelm@25350
   315
  also have "\<dots> = of_bl (to_bl w @ replicate n False)" by (rule shiftl_of_bl)
wenzelm@25350
   316
  finally show ?thesis .
wenzelm@25350
   317
qed
kleing@24333
   318
wenzelm@25350
   319
lemmas shiftl_number [simp] = shiftl_def [where w="number_of w", standard]
kleing@24333
   320
kleing@24333
   321
lemma bl_shiftl:
kleing@24333
   322
  "to_bl (w << n) = drop n (to_bl w) @ replicate (min (size w) n) False"
kleing@24333
   323
  by (simp add: shiftl_bl word_rep_drop word_size min_def)
kleing@24333
   324
kleing@24333
   325
lemma shiftl_zero_size: 
huffman@24465
   326
  fixes x :: "'a::len0 word"
kleing@24333
   327
  shows "size x <= n ==> x << n = 0"
kleing@24333
   328
  apply (unfold word_size)
kleing@24333
   329
  apply (rule word_eqI)
kleing@24333
   330
  apply (clarsimp simp add: shiftl_bl word_size test_bit_of_bl nth_append)
kleing@24333
   331
  done
kleing@24333
   332
huffman@24465
   333
(* note - the following results use 'a :: len word < number_ring *)
kleing@24333
   334
huffman@24465
   335
lemma shiftl1_2t: "shiftl1 (w :: 'a :: len word) = 2 * w"
kleing@24333
   336
  apply (simp add: shiftl1_def_u)
huffman@26086
   337
  apply (simp only:  double_number_of_Bit0 [symmetric])
kleing@24333
   338
  apply simp
kleing@24333
   339
  done
kleing@24333
   340
huffman@24465
   341
lemma shiftl1_p: "shiftl1 (w :: 'a :: len word) = w + w"
kleing@24333
   342
  apply (simp add: shiftl1_def_u)
huffman@26086
   343
  apply (simp only: double_number_of_Bit0 [symmetric])
kleing@24333
   344
  apply simp
kleing@24333
   345
  done
kleing@24333
   346
huffman@24465
   347
lemma shiftl_t2n: "shiftl (w :: 'a :: len word) n = 2 ^ n * w"
kleing@24333
   348
  unfolding shiftl_def 
kleing@24333
   349
  by (induct n) (auto simp: shiftl1_2t power_Suc)
kleing@24333
   350
kleing@24333
   351
lemma shiftr1_bintr [simp]:
huffman@24465
   352
  "(shiftr1 (number_of w) :: 'a :: len0 word) = 
huffman@24465
   353
    number_of (bin_rest (bintrunc (len_of TYPE ('a)) w))" 
kleing@24333
   354
  unfolding shiftr1_def word_number_of_def
kleing@24333
   355
  by (simp add : word_ubin.eq_norm)
kleing@24333
   356
kleing@24333
   357
lemma sshiftr1_sbintr [simp] :
huffman@24465
   358
  "(sshiftr1 (number_of w) :: 'a :: len word) = 
huffman@24465
   359
    number_of (bin_rest (sbintrunc (len_of TYPE ('a) - 1) w))" 
kleing@24333
   360
  unfolding sshiftr1_def word_number_of_def
kleing@24333
   361
  by (simp add : word_sbin.eq_norm)
kleing@24333
   362
kleing@24333
   363
lemma shiftr_no': 
kleing@24333
   364
  "w = number_of bin ==> 
huffman@24465
   365
  (w::'a::len0 word) >> n = number_of ((bin_rest ^ n) (bintrunc (size w) bin))"
kleing@24333
   366
  apply clarsimp
kleing@24333
   367
  apply (rule word_eqI)
kleing@24333
   368
  apply (auto simp: nth_shiftr nth_rest_power_bin nth_bintr word_size)
kleing@24333
   369
  done
kleing@24333
   370
kleing@24333
   371
lemma sshiftr_no': 
kleing@24333
   372
  "w = number_of bin ==> w >>> n = number_of ((bin_rest ^ n) 
kleing@24333
   373
    (sbintrunc (size w - 1) bin))"
kleing@24333
   374
  apply clarsimp
kleing@24333
   375
  apply (rule word_eqI)
kleing@24333
   376
  apply (auto simp: nth_sshiftr nth_rest_power_bin nth_sbintr word_size)
huffman@24465
   377
   apply (subgoal_tac "na + n = len_of TYPE('a) - Suc 0", simp, simp)+
kleing@24333
   378
  done
kleing@24333
   379
kleing@24333
   380
lemmas sshiftr_no [simp] = 
wenzelm@25350
   381
  sshiftr_no' [where w = "number_of w", OF refl, unfolded word_size, standard]
kleing@24333
   382
kleing@24333
   383
lemmas shiftr_no [simp] = 
wenzelm@25350
   384
  shiftr_no' [where w = "number_of w", OF refl, unfolded word_size, standard]
kleing@24333
   385
kleing@24333
   386
lemma shiftr1_bl_of': 
kleing@24333
   387
  "us = shiftr1 (of_bl bl) ==> length bl <= size us ==> 
kleing@24333
   388
    us = of_bl (butlast bl)"
kleing@24333
   389
  by (clarsimp simp: shiftr1_def of_bl_def word_size butlast_rest_bl2bin 
kleing@24333
   390
                     word_ubin.eq_norm trunc_bl2bin)
kleing@24333
   391
kleing@24333
   392
lemmas shiftr1_bl_of = refl [THEN shiftr1_bl_of', unfolded word_size]
kleing@24333
   393
kleing@24333
   394
lemma shiftr_bl_of' [rule_format]: 
kleing@24333
   395
  "us = of_bl bl >> n ==> length bl <= size us --> 
kleing@24333
   396
   us = of_bl (take (length bl - n) bl)"
kleing@24333
   397
  apply (unfold shiftr_def)
kleing@24333
   398
  apply hypsubst
kleing@24333
   399
  apply (unfold word_size)
kleing@24333
   400
  apply (induct n)
kleing@24333
   401
   apply clarsimp
kleing@24333
   402
  apply clarsimp
kleing@24333
   403
  apply (subst shiftr1_bl_of)
kleing@24333
   404
   apply simp
kleing@24333
   405
  apply (simp add: butlast_take)
kleing@24333
   406
  done
kleing@24333
   407
kleing@24333
   408
lemmas shiftr_bl_of = refl [THEN shiftr_bl_of', unfolded word_size]
kleing@24333
   409
kleing@24333
   410
lemmas shiftr_bl = word_bl.Rep' [THEN eq_imp_le, THEN shiftr_bl_of,
kleing@24333
   411
  simplified word_size, simplified, THEN eq_reflection, standard]
kleing@24333
   412
huffman@24465
   413
lemma msb_shift': "msb (w::'a::len word) <-> (w >> (size w - 1)) ~= 0"
kleing@24333
   414
  apply (unfold shiftr_bl word_msb_alt)
kleing@24333
   415
  apply (simp add: word_size Suc_le_eq take_Suc)
kleing@24333
   416
  apply (cases "hd (to_bl w)")
kleing@24333
   417
   apply (auto simp: word_1_bl word_0_bl 
kleing@24333
   418
                     of_bl_rep_False [where n=1 and bs="[]", simplified])
kleing@24333
   419
  done
kleing@24333
   420
kleing@24333
   421
lemmas msb_shift = msb_shift' [unfolded word_size]
kleing@24333
   422
kleing@24333
   423
lemma align_lem_or [rule_format] :
kleing@24333
   424
  "ALL x m. length x = n + m --> length y = n + m --> 
kleing@24333
   425
    drop m x = replicate n False --> take m y = replicate m False --> 
haftmann@26558
   426
    map2 op | x y = take m x @ drop m y"
kleing@24333
   427
  apply (induct_tac y)
kleing@24333
   428
   apply force
kleing@24333
   429
  apply clarsimp
kleing@24333
   430
  apply (case_tac x, force)
kleing@24333
   431
  apply (case_tac m, auto)
kleing@24333
   432
  apply (drule sym)
kleing@24333
   433
  apply auto
kleing@24333
   434
  apply (induct_tac list, auto)
kleing@24333
   435
  done
kleing@24333
   436
kleing@24333
   437
lemma align_lem_and [rule_format] :
kleing@24333
   438
  "ALL x m. length x = n + m --> length y = n + m --> 
kleing@24333
   439
    drop m x = replicate n False --> take m y = replicate m False --> 
haftmann@26558
   440
    map2 op & x y = replicate (n + m) False"
kleing@24333
   441
  apply (induct_tac y)
kleing@24333
   442
   apply force
kleing@24333
   443
  apply clarsimp
kleing@24333
   444
  apply (case_tac x, force)
kleing@24333
   445
  apply (case_tac m, auto)
kleing@24333
   446
  apply (drule sym)
kleing@24333
   447
  apply auto
kleing@24333
   448
  apply (induct_tac list, auto)
kleing@24333
   449
  done
kleing@24333
   450
kleing@24333
   451
lemma aligned_bl_add_size':
kleing@24333
   452
  "size x - n = m ==> n <= size x ==> drop m (to_bl x) = replicate n False ==>
kleing@24333
   453
    take m (to_bl y) = replicate m False ==> 
kleing@24333
   454
    to_bl (x + y) = take m (to_bl x) @ drop m (to_bl y)"
kleing@24333
   455
  apply (subgoal_tac "x AND y = 0")
kleing@24333
   456
   prefer 2
kleing@24333
   457
   apply (rule word_bl.Rep_eqD)
kleing@24333
   458
   apply (simp add: bl_word_and to_bl_0)
kleing@24333
   459
   apply (rule align_lem_and [THEN trans])
kleing@24333
   460
       apply (simp_all add: word_size)[5]
kleing@24333
   461
   apply simp
kleing@24333
   462
  apply (subst word_plus_and_or [symmetric])
kleing@24333
   463
  apply (simp add : bl_word_or)
kleing@24333
   464
  apply (rule align_lem_or)
kleing@24333
   465
     apply (simp_all add: word_size)
kleing@24333
   466
  done
kleing@24333
   467
kleing@24333
   468
lemmas aligned_bl_add_size = refl [THEN aligned_bl_add_size']
kleing@24333
   469
huffman@24350
   470
subsubsection "Mask"
kleing@24333
   471
kleing@24333
   472
lemma nth_mask': "m = mask n ==> test_bit m i = (i < n & i < size m)"
kleing@24333
   473
  apply (unfold mask_def test_bit_bl)
kleing@24333
   474
  apply (simp only: word_1_bl [symmetric] shiftl_of_bl)
kleing@24333
   475
  apply (clarsimp simp add: word_size)
kleing@24333
   476
  apply (simp only: of_bl_no mask_lem number_of_succ add_diff_cancel2)
kleing@24333
   477
  apply (fold of_bl_no)
kleing@24333
   478
  apply (simp add: word_1_bl)
kleing@24333
   479
  apply (rule test_bit_of_bl [THEN trans, unfolded test_bit_bl word_size])
kleing@24333
   480
  apply auto
kleing@24333
   481
  done
kleing@24333
   482
kleing@24333
   483
lemmas nth_mask [simp] = refl [THEN nth_mask']
kleing@24333
   484
kleing@24333
   485
lemma mask_bl: "mask n = of_bl (replicate n True)"
kleing@24333
   486
  by (auto simp add : test_bit_of_bl word_size intro: word_eqI)
kleing@24333
   487
haftmann@25919
   488
lemma mask_bin: "mask n = number_of (bintrunc n Int.Min)"
kleing@24333
   489
  by (auto simp add: nth_bintr word_size intro: word_eqI)
kleing@24333
   490
kleing@24333
   491
lemma and_mask_bintr: "w AND mask n = number_of (bintrunc n (uint w))"
kleing@24333
   492
  apply (rule word_eqI)
kleing@24333
   493
  apply (simp add: nth_bintr word_size word_ops_nth_size)
kleing@24333
   494
  apply (auto simp add: test_bit_bin)
kleing@24333
   495
  done
kleing@24333
   496
kleing@24333
   497
lemma and_mask_no: "number_of i AND mask n = number_of (bintrunc n i)" 
kleing@24333
   498
  by (auto simp add : nth_bintr word_size word_ops_nth_size intro: word_eqI)
kleing@24333
   499
kleing@24333
   500
lemmas and_mask_wi = and_mask_no [unfolded word_number_of_def] 
kleing@24333
   501
kleing@24333
   502
lemma bl_and_mask:
huffman@24465
   503
  "to_bl (w AND mask n :: 'a :: len word) = 
huffman@24465
   504
    replicate (len_of TYPE('a) - n) False @ 
huffman@24465
   505
    drop (len_of TYPE('a) - n) (to_bl w)"
kleing@24333
   506
  apply (rule nth_equalityI)
kleing@24333
   507
   apply simp
kleing@24333
   508
  apply (clarsimp simp add: to_bl_nth word_size)
kleing@24333
   509
  apply (simp add: word_size word_ops_nth_size)
kleing@24333
   510
  apply (auto simp add: word_size test_bit_bl nth_append nth_rev)
kleing@24333
   511
  done
kleing@24333
   512
kleing@24333
   513
lemmas and_mask_mod_2p = 
kleing@24333
   514
  and_mask_bintr [unfolded word_number_of_alt no_bintr_alt]
kleing@24333
   515
kleing@24333
   516
lemma and_mask_lt_2p: "uint (w AND mask n) < 2 ^ n"
kleing@24333
   517
  apply (simp add : and_mask_bintr no_bintr_alt)
kleing@24333
   518
  apply (rule xtr8)
kleing@24333
   519
   prefer 2
kleing@24333
   520
   apply (rule pos_mod_bound)
kleing@24333
   521
  apply auto
kleing@24333
   522
  done
kleing@24333
   523
kleing@24333
   524
lemmas eq_mod_iff = trans [symmetric, OF int_mod_lem eq_sym_conv]
kleing@24333
   525
kleing@24333
   526
lemma mask_eq_iff: "(w AND mask n) = w <-> uint w < 2 ^ n"
kleing@24333
   527
  apply (simp add: and_mask_bintr word_number_of_def)
kleing@24333
   528
  apply (simp add: word_ubin.inverse_norm)
kleing@24333
   529
  apply (simp add: eq_mod_iff bintrunc_mod2p min_def)
kleing@24333
   530
  apply (fast intro!: lt2p_lem)
kleing@24333
   531
  done
kleing@24333
   532
kleing@24333
   533
lemma and_mask_dvd: "2 ^ n dvd uint w = (w AND mask n = 0)"
kleing@24333
   534
  apply (simp add: zdvd_iff_zmod_eq_0 and_mask_mod_2p)
kleing@24333
   535
  apply (simp add: word_uint.norm_eq_iff [symmetric] word_of_int_homs)
kleing@24333
   536
  apply (subst word_uint.norm_Rep [symmetric])
kleing@24333
   537
  apply (simp only: bintrunc_bintrunc_min bintrunc_mod2p [symmetric] min_def)
kleing@24333
   538
  apply auto
kleing@24333
   539
  done
kleing@24333
   540
kleing@24333
   541
lemma and_mask_dvd_nat: "2 ^ n dvd unat w = (w AND mask n = 0)"
kleing@24333
   542
  apply (unfold unat_def)
kleing@24333
   543
  apply (rule trans [OF _ and_mask_dvd])
kleing@24333
   544
  apply (unfold dvd_def) 
kleing@24333
   545
  apply auto 
kleing@24333
   546
  apply (drule uint_ge_0 [THEN nat_int.Abs_inverse' [simplified], symmetric])
kleing@24333
   547
  apply (simp add : int_mult int_power)
kleing@24333
   548
  apply (simp add : nat_mult_distrib nat_power_eq)
kleing@24333
   549
  done
kleing@24333
   550
kleing@24333
   551
lemma word_2p_lem: 
huffman@24465
   552
  "n < size w ==> w < 2 ^ n = (uint (w :: 'a :: len word) < 2 ^ n)"
kleing@24333
   553
  apply (unfold word_size word_less_alt word_number_of_alt)
kleing@24333
   554
  apply (clarsimp simp add: word_of_int_power_hom word_uint.eq_norm 
kleing@24333
   555
                            int_mod_eq'
kleing@24333
   556
                  simp del: word_of_int_bin)
kleing@24333
   557
  done
kleing@24333
   558
huffman@24465
   559
lemma less_mask_eq: "x < 2 ^ n ==> x AND mask n = (x :: 'a :: len word)"
kleing@24333
   560
  apply (unfold word_less_alt word_number_of_alt)
kleing@24333
   561
  apply (clarsimp simp add: and_mask_mod_2p word_of_int_power_hom 
kleing@24333
   562
                            word_uint.eq_norm
kleing@24333
   563
                  simp del: word_of_int_bin)
kleing@24333
   564
  apply (drule xtr8 [rotated])
kleing@24333
   565
  apply (rule int_mod_le)
kleing@24333
   566
  apply (auto simp add : mod_pos_pos_trivial)
kleing@24333
   567
  done
kleing@24333
   568
kleing@24333
   569
lemmas mask_eq_iff_w2p =
kleing@24333
   570
  trans [OF mask_eq_iff word_2p_lem [symmetric], standard]
kleing@24333
   571
kleing@24333
   572
lemmas and_mask_less' = 
kleing@24333
   573
  iffD2 [OF word_2p_lem and_mask_lt_2p, simplified word_size, standard]
kleing@24333
   574
kleing@24333
   575
lemma and_mask_less_size: "n < size x ==> x AND mask n < 2^n"
kleing@24333
   576
  unfolding word_size by (erule and_mask_less')
kleing@24333
   577
kleing@24333
   578
lemma word_mod_2p_is_mask':
huffman@24465
   579
  "c = 2 ^ n ==> c > 0 ==> x mod c = (x :: 'a :: len word) AND mask n" 
kleing@24333
   580
  by (clarsimp simp add: word_mod_def uint_2p and_mask_mod_2p) 
kleing@24333
   581
kleing@24333
   582
lemmas word_mod_2p_is_mask = refl [THEN word_mod_2p_is_mask'] 
kleing@24333
   583
kleing@24333
   584
lemma mask_eqs:
kleing@24333
   585
  "(a AND mask n) + b AND mask n = a + b AND mask n"
kleing@24333
   586
  "a + (b AND mask n) AND mask n = a + b AND mask n"
kleing@24333
   587
  "(a AND mask n) - b AND mask n = a - b AND mask n"
kleing@24333
   588
  "a - (b AND mask n) AND mask n = a - b AND mask n"
kleing@24333
   589
  "a * (b AND mask n) AND mask n = a * b AND mask n"
kleing@24333
   590
  "(b AND mask n) * a AND mask n = b * a AND mask n"
kleing@24333
   591
  "(a AND mask n) + (b AND mask n) AND mask n = a + b AND mask n"
kleing@24333
   592
  "(a AND mask n) - (b AND mask n) AND mask n = a - b AND mask n"
kleing@24333
   593
  "(a AND mask n) * (b AND mask n) AND mask n = a * b AND mask n"
kleing@24333
   594
  "- (a AND mask n) AND mask n = - a AND mask n"
kleing@24333
   595
  "word_succ (a AND mask n) AND mask n = word_succ a AND mask n"
kleing@24333
   596
  "word_pred (a AND mask n) AND mask n = word_pred a AND mask n"
kleing@24333
   597
  using word_of_int_Ex [where x=a] word_of_int_Ex [where x=b]
kleing@24333
   598
  by (auto simp: and_mask_wi bintr_ariths bintr_arith1s new_word_of_int_homs)
kleing@24333
   599
kleing@24333
   600
lemma mask_power_eq:
kleing@24333
   601
  "(x AND mask n) ^ k AND mask n = x ^ k AND mask n"
kleing@24333
   602
  using word_of_int_Ex [where x=x]
kleing@24333
   603
  by (clarsimp simp: and_mask_wi word_of_int_power_hom bintr_ariths)
kleing@24333
   604
kleing@24333
   605
huffman@24350
   606
subsubsection "Revcast"
kleing@24333
   607
kleing@24333
   608
lemmas revcast_def' = revcast_def [simplified]
kleing@24333
   609
lemmas revcast_def'' = revcast_def' [simplified word_size]
kleing@24333
   610
lemmas revcast_no_def [simp] =
wenzelm@25350
   611
  revcast_def' [where w="number_of w", unfolded word_size, standard]
kleing@24333
   612
kleing@24333
   613
lemma to_bl_revcast: 
huffman@24465
   614
  "to_bl (revcast w :: 'a :: len0 word) = 
huffman@24465
   615
   takefill False (len_of TYPE ('a)) (to_bl w)"
kleing@24333
   616
  apply (unfold revcast_def' word_size)
kleing@24333
   617
  apply (rule word_bl.Abs_inverse)
kleing@24333
   618
  apply simp
kleing@24333
   619
  done
kleing@24333
   620
kleing@24333
   621
lemma revcast_rev_ucast': 
kleing@24333
   622
  "cs = [rc, uc] ==> rc = revcast (word_reverse w) ==> uc = ucast w ==> 
kleing@24333
   623
    rc = word_reverse uc"
kleing@24333
   624
  apply (unfold ucast_def revcast_def' Let_def word_reverse_def)
kleing@24333
   625
  apply (clarsimp simp add : to_bl_of_bin takefill_bintrunc)
kleing@24333
   626
  apply (simp add : word_bl.Abs_inverse word_size)
kleing@24333
   627
  done
kleing@24333
   628
kleing@24333
   629
lemmas revcast_rev_ucast = revcast_rev_ucast' [OF refl refl refl]
kleing@24333
   630
kleing@24333
   631
lemmas revcast_ucast = revcast_rev_ucast
wenzelm@25350
   632
  [where w = "word_reverse w", simplified word_rev_rev, standard]
kleing@24333
   633
kleing@24333
   634
lemmas ucast_revcast = revcast_rev_ucast [THEN word_rev_gal', standard]
kleing@24333
   635
lemmas ucast_rev_revcast = revcast_ucast [THEN word_rev_gal', standard]
kleing@24333
   636
kleing@24333
   637
kleing@24333
   638
-- "linking revcast and cast via shift"
kleing@24333
   639
kleing@24333
   640
lemmas wsst_TYs = source_size target_size word_size
kleing@24333
   641
kleing@24333
   642
lemma revcast_down_uu': 
kleing@24333
   643
  "rc = revcast ==> source_size rc = target_size rc + n ==> 
huffman@24465
   644
    rc (w :: 'a :: len word) = ucast (w >> n)"
kleing@24333
   645
  apply (simp add: revcast_def')
kleing@24333
   646
  apply (rule word_bl.Rep_inverse')
kleing@24333
   647
  apply (rule trans, rule ucast_down_drop)
kleing@24333
   648
   prefer 2
kleing@24333
   649
   apply (rule trans, rule drop_shiftr)
kleing@24333
   650
   apply (auto simp: takefill_alt wsst_TYs)
kleing@24333
   651
  done
kleing@24333
   652
kleing@24333
   653
lemma revcast_down_us': 
kleing@24333
   654
  "rc = revcast ==> source_size rc = target_size rc + n ==> 
huffman@24465
   655
    rc (w :: 'a :: len word) = ucast (w >>> n)"
kleing@24333
   656
  apply (simp add: revcast_def')
kleing@24333
   657
  apply (rule word_bl.Rep_inverse')
kleing@24333
   658
  apply (rule trans, rule ucast_down_drop)
kleing@24333
   659
   prefer 2
kleing@24333
   660
   apply (rule trans, rule drop_sshiftr)
kleing@24333
   661
   apply (auto simp: takefill_alt wsst_TYs)
kleing@24333
   662
  done
kleing@24333
   663
kleing@24333
   664
lemma revcast_down_su': 
kleing@24333
   665
  "rc = revcast ==> source_size rc = target_size rc + n ==> 
huffman@24465
   666
    rc (w :: 'a :: len word) = scast (w >> n)"
kleing@24333
   667
  apply (simp add: revcast_def')
kleing@24333
   668
  apply (rule word_bl.Rep_inverse')
kleing@24333
   669
  apply (rule trans, rule scast_down_drop)
kleing@24333
   670
   prefer 2
kleing@24333
   671
   apply (rule trans, rule drop_shiftr)
kleing@24333
   672
   apply (auto simp: takefill_alt wsst_TYs)
kleing@24333
   673
  done
kleing@24333
   674
kleing@24333
   675
lemma revcast_down_ss': 
kleing@24333
   676
  "rc = revcast ==> source_size rc = target_size rc + n ==> 
huffman@24465
   677
    rc (w :: 'a :: len word) = scast (w >>> n)"
kleing@24333
   678
  apply (simp add: revcast_def')
kleing@24333
   679
  apply (rule word_bl.Rep_inverse')
kleing@24333
   680
  apply (rule trans, rule scast_down_drop)
kleing@24333
   681
   prefer 2
kleing@24333
   682
   apply (rule trans, rule drop_sshiftr)
kleing@24333
   683
   apply (auto simp: takefill_alt wsst_TYs)
kleing@24333
   684
  done
kleing@24333
   685
kleing@24333
   686
lemmas revcast_down_uu = refl [THEN revcast_down_uu']
kleing@24333
   687
lemmas revcast_down_us = refl [THEN revcast_down_us']
kleing@24333
   688
lemmas revcast_down_su = refl [THEN revcast_down_su']
kleing@24333
   689
lemmas revcast_down_ss = refl [THEN revcast_down_ss']
kleing@24333
   690
kleing@24333
   691
lemma cast_down_rev: 
kleing@24333
   692
  "uc = ucast ==> source_size uc = target_size uc + n ==> 
huffman@24465
   693
    uc w = revcast ((w :: 'a :: len word) << n)"
kleing@24333
   694
  apply (unfold shiftl_rev)
kleing@24333
   695
  apply clarify
kleing@24333
   696
  apply (simp add: revcast_rev_ucast)
kleing@24333
   697
  apply (rule word_rev_gal')
kleing@24333
   698
  apply (rule trans [OF _ revcast_rev_ucast])
kleing@24333
   699
  apply (rule revcast_down_uu [symmetric])
kleing@24333
   700
  apply (auto simp add: wsst_TYs)
kleing@24333
   701
  done
kleing@24333
   702
kleing@24333
   703
lemma revcast_up': 
kleing@24333
   704
  "rc = revcast ==> source_size rc + n = target_size rc ==> 
huffman@24465
   705
    rc w = (ucast w :: 'a :: len word) << n" 
kleing@24333
   706
  apply (simp add: revcast_def')
kleing@24333
   707
  apply (rule word_bl.Rep_inverse')
kleing@24333
   708
  apply (simp add: takefill_alt)
kleing@24333
   709
  apply (rule bl_shiftl [THEN trans])
kleing@24333
   710
  apply (subst ucast_up_app)
kleing@24333
   711
  apply (auto simp add: wsst_TYs)
kleing@24333
   712
  done
kleing@24333
   713
kleing@24333
   714
lemmas revcast_up = refl [THEN revcast_up']
kleing@24333
   715
kleing@24333
   716
lemmas rc1 = revcast_up [THEN 
kleing@24333
   717
  revcast_rev_ucast [symmetric, THEN trans, THEN word_rev_gal, symmetric]]
kleing@24333
   718
lemmas rc2 = revcast_down_uu [THEN 
kleing@24333
   719
  revcast_rev_ucast [symmetric, THEN trans, THEN word_rev_gal, symmetric]]
kleing@24333
   720
kleing@24333
   721
lemmas ucast_up =
kleing@24333
   722
 rc1 [simplified rev_shiftr [symmetric] revcast_ucast [symmetric]]
kleing@24333
   723
lemmas ucast_down = 
kleing@24333
   724
  rc2 [simplified rev_shiftr revcast_ucast [symmetric]]
kleing@24333
   725
kleing@24333
   726
huffman@24350
   727
subsubsection "Slices"
kleing@24333
   728
kleing@24333
   729
lemmas slice1_no_bin [simp] =
wenzelm@25350
   730
  slice1_def [where w="number_of w", unfolded to_bl_no_bin, standard]
kleing@24333
   731
kleing@24333
   732
lemmas slice_no_bin [simp] = 
kleing@24333
   733
   trans [OF slice_def [THEN meta_eq_to_obj_eq] 
kleing@24333
   734
             slice1_no_bin [THEN meta_eq_to_obj_eq], 
kleing@24333
   735
          unfolded word_size, standard]
kleing@24333
   736
kleing@24333
   737
lemma slice1_0 [simp] : "slice1 n 0 = 0"
kleing@24333
   738
  unfolding slice1_def by (simp add : to_bl_0)
kleing@24333
   739
kleing@24333
   740
lemma slice_0 [simp] : "slice n 0 = 0"
kleing@24333
   741
  unfolding slice_def by auto
kleing@24333
   742
kleing@24333
   743
lemma slice_take': "slice n w = of_bl (take (size w - n) (to_bl w))"
kleing@24333
   744
  unfolding slice_def' slice1_def
kleing@24333
   745
  by (simp add : takefill_alt word_size)
kleing@24333
   746
kleing@24333
   747
lemmas slice_take = slice_take' [unfolded word_size]
kleing@24333
   748
kleing@24333
   749
-- "shiftr to a word of the same size is just slice, 
kleing@24333
   750
    slice is just shiftr then ucast"
kleing@24333
   751
lemmas shiftr_slice = trans
kleing@24333
   752
  [OF shiftr_bl [THEN meta_eq_to_obj_eq] slice_take [symmetric], standard]
kleing@24333
   753
kleing@24333
   754
lemma slice_shiftr: "slice n w = ucast (w >> n)"
kleing@24333
   755
  apply (unfold slice_take shiftr_bl)
kleing@24333
   756
  apply (rule ucast_of_bl_up [symmetric])
kleing@24333
   757
  apply (simp add: word_size)
kleing@24333
   758
  done
kleing@24333
   759
kleing@24333
   760
lemma nth_slice: 
huffman@24465
   761
  "(slice n w :: 'a :: len0 word) !! m = 
huffman@24465
   762
   (w !! (m + n) & m < len_of TYPE ('a))"
kleing@24333
   763
  unfolding slice_shiftr 
kleing@24333
   764
  by (simp add : nth_ucast nth_shiftr)
kleing@24333
   765
kleing@24333
   766
lemma slice1_down_alt': 
kleing@24333
   767
  "sl = slice1 n w ==> fs = size sl ==> fs + k = n ==> 
kleing@24333
   768
    to_bl sl = takefill False fs (drop k (to_bl w))"
kleing@24333
   769
  unfolding slice1_def word_size of_bl_def uint_bl
kleing@24333
   770
  by (clarsimp simp: word_ubin.eq_norm bl_bin_bl_rep_drop drop_takefill)
kleing@24333
   771
kleing@24333
   772
lemma slice1_up_alt': 
kleing@24333
   773
  "sl = slice1 n w ==> fs = size sl ==> fs = n + k ==> 
kleing@24333
   774
    to_bl sl = takefill False fs (replicate k False @ (to_bl w))"
kleing@24333
   775
  apply (unfold slice1_def word_size of_bl_def uint_bl)
kleing@24333
   776
  apply (clarsimp simp: word_ubin.eq_norm bl_bin_bl_rep_drop 
kleing@24333
   777
                        takefill_append [symmetric])
huffman@24465
   778
  apply (rule_tac f = "%k. takefill False (len_of TYPE('a))
huffman@24465
   779
    (replicate k False @ bin_to_bl (len_of TYPE('b)) (uint w))" in arg_cong)
kleing@24333
   780
  apply arith
kleing@24333
   781
  done
kleing@24333
   782
    
kleing@24333
   783
lemmas sd1 = slice1_down_alt' [OF refl refl, unfolded word_size]
kleing@24333
   784
lemmas su1 = slice1_up_alt' [OF refl refl, unfolded word_size]
kleing@24333
   785
lemmas slice1_down_alt = le_add_diff_inverse [THEN sd1]
kleing@24333
   786
lemmas slice1_up_alts = 
kleing@24333
   787
  le_add_diff_inverse [symmetric, THEN su1] 
kleing@24333
   788
  le_add_diff_inverse2 [symmetric, THEN su1]
kleing@24333
   789
kleing@24333
   790
lemma ucast_slice1: "ucast w = slice1 (size w) w"
kleing@24333
   791
  unfolding slice1_def ucast_bl
kleing@24333
   792
  by (simp add : takefill_same' word_size)
kleing@24333
   793
kleing@24333
   794
lemma ucast_slice: "ucast w = slice 0 w"
kleing@24333
   795
  unfolding slice_def by (simp add : ucast_slice1)
kleing@24333
   796
kleing@24333
   797
lemmas slice_id = trans [OF ucast_slice [symmetric] ucast_id]
kleing@24333
   798
kleing@24333
   799
lemma revcast_slice1': 
kleing@24333
   800
  "rc = revcast w ==> slice1 (size rc) w = rc"
kleing@24333
   801
  unfolding slice1_def revcast_def' by (simp add : word_size)
kleing@24333
   802
kleing@24333
   803
lemmas revcast_slice1 = refl [THEN revcast_slice1']
kleing@24333
   804
kleing@24333
   805
lemma slice1_tf_tf': 
huffman@24465
   806
  "to_bl (slice1 n w :: 'a :: len0 word) = 
huffman@24465
   807
   rev (takefill False (len_of TYPE('a)) (rev (takefill False n (to_bl w))))"
kleing@24333
   808
  unfolding slice1_def by (rule word_rev_tf)
kleing@24333
   809
kleing@24333
   810
lemmas slice1_tf_tf = slice1_tf_tf'
kleing@24333
   811
  [THEN word_bl.Rep_inverse', symmetric, standard]
kleing@24333
   812
kleing@24333
   813
lemma rev_slice1:
huffman@24465
   814
  "n + k = len_of TYPE('a) + len_of TYPE('b) \<Longrightarrow> 
huffman@24465
   815
  slice1 n (word_reverse w :: 'b :: len0 word) = 
huffman@24465
   816
  word_reverse (slice1 k w :: 'a :: len0 word)"
kleing@24333
   817
  apply (unfold word_reverse_def slice1_tf_tf)
kleing@24333
   818
  apply (rule word_bl.Rep_inverse')
kleing@24333
   819
  apply (rule rev_swap [THEN iffD1])
kleing@24333
   820
  apply (rule trans [symmetric])
kleing@24333
   821
  apply (rule tf_rev)
kleing@24333
   822
   apply (simp add: word_bl.Abs_inverse)
kleing@24333
   823
  apply (simp add: word_bl.Abs_inverse)
kleing@24333
   824
  done
kleing@24333
   825
kleing@24333
   826
lemma rev_slice': 
kleing@24333
   827
  "res = slice n (word_reverse w) ==> n + k + size res = size w ==> 
kleing@24333
   828
    res = word_reverse (slice k w)"
kleing@24333
   829
  apply (unfold slice_def word_size)
kleing@24333
   830
  apply clarify
kleing@24333
   831
  apply (rule rev_slice1)
kleing@24333
   832
  apply arith
kleing@24333
   833
  done
kleing@24333
   834
kleing@24333
   835
lemmas rev_slice = refl [THEN rev_slice', unfolded word_size]
kleing@24333
   836
kleing@24333
   837
lemmas sym_notr = 
kleing@24333
   838
  not_iff [THEN iffD2, THEN not_sym, THEN not_iff [THEN iffD1]]
kleing@24333
   839
kleing@24333
   840
-- {* problem posed by TPHOLs referee:
kleing@24333
   841
      criterion for overflow of addition of signed integers *}
kleing@24333
   842
kleing@24333
   843
lemma sofl_test:
huffman@24465
   844
  "(sint (x :: 'a :: len word) + sint y = sint (x + y)) = 
kleing@24333
   845
     ((((x+y) XOR x) AND ((x+y) XOR y)) >> (size x - 1) = 0)"
kleing@24333
   846
  apply (unfold word_size)
huffman@24465
   847
  apply (cases "len_of TYPE('a)", simp) 
kleing@24333
   848
  apply (subst msb_shift [THEN sym_notr])
kleing@24333
   849
  apply (simp add: word_ops_msb)
kleing@24333
   850
  apply (simp add: word_msb_sint)
kleing@24333
   851
  apply safe
kleing@24333
   852
       apply simp_all
kleing@24333
   853
     apply (unfold sint_word_ariths)
kleing@24333
   854
     apply (unfold word_sbin.set_iff_norm [symmetric] sints_num)
kleing@24333
   855
     apply safe
kleing@24333
   856
        apply (insert sint_range' [where x=x])
kleing@24333
   857
        apply (insert sint_range' [where x=y])
kleing@24333
   858
        defer 
kleing@24333
   859
        apply (simp (no_asm), arith)
kleing@24333
   860
       apply (simp (no_asm), arith)
kleing@24333
   861
      defer
kleing@24333
   862
      defer
kleing@24333
   863
      apply (simp (no_asm), arith)
kleing@24333
   864
     apply (simp (no_asm), arith)
kleing@24333
   865
    apply (rule notI [THEN notnotD],
kleing@24333
   866
           drule leI not_leE,
kleing@24333
   867
           drule sbintrunc_inc sbintrunc_dec,      
kleing@24333
   868
           simp)+
kleing@24333
   869
  done
kleing@24333
   870
kleing@24333
   871
huffman@24350
   872
subsection "Split and cat"
kleing@24333
   873
kleing@24333
   874
lemmas word_split_bin' = word_split_def [THEN meta_eq_to_obj_eq, standard]
kleing@24333
   875
lemmas word_cat_bin' = word_cat_def [THEN meta_eq_to_obj_eq, standard]
kleing@24333
   876
kleing@24333
   877
lemma word_rsplit_no:
huffman@24465
   878
  "(word_rsplit (number_of bin :: 'b :: len0 word) :: 'a word list) = 
huffman@24465
   879
    map number_of (bin_rsplit (len_of TYPE('a :: len)) 
huffman@24465
   880
      (len_of TYPE('b), bintrunc (len_of TYPE('b)) bin))"
kleing@24333
   881
  apply (unfold word_rsplit_def word_no_wi)
kleing@24333
   882
  apply (simp add: word_ubin.eq_norm)
kleing@24333
   883
  done
kleing@24333
   884
kleing@24333
   885
lemmas word_rsplit_no_cl [simp] = word_rsplit_no
kleing@24333
   886
  [unfolded bin_rsplitl_def bin_rsplit_l [symmetric]]
kleing@24333
   887
kleing@24333
   888
lemma test_bit_cat:
kleing@24333
   889
  "wc = word_cat a b ==> wc !! n = (n < size wc & 
kleing@24333
   890
    (if n < size b then b !! n else a !! (n - size b)))"
kleing@24333
   891
  apply (unfold word_cat_bin' test_bit_bin)
kleing@24333
   892
  apply (auto simp add : word_ubin.eq_norm nth_bintr bin_nth_cat word_size)
kleing@24333
   893
  apply (erule bin_nth_uint_imp)
kleing@24333
   894
  done
kleing@24333
   895
kleing@24333
   896
lemma word_cat_bl: "word_cat a b = of_bl (to_bl a @ to_bl b)"
kleing@24333
   897
  apply (unfold of_bl_def to_bl_def word_cat_bin')
kleing@24333
   898
  apply (simp add: bl_to_bin_app_cat)
kleing@24333
   899
  done
kleing@24333
   900
kleing@24333
   901
lemma of_bl_append:
huffman@24465
   902
  "(of_bl (xs @ ys) :: 'a :: len word) = of_bl xs * 2^(length ys) + of_bl ys"
kleing@24333
   903
  apply (unfold of_bl_def)
kleing@24333
   904
  apply (simp add: bl_to_bin_app_cat bin_cat_num)
kleing@24333
   905
  apply (simp add: word_of_int_power_hom [symmetric] new_word_of_int_hom_syms)
kleing@24333
   906
  done
kleing@24333
   907
kleing@24333
   908
lemma of_bl_False [simp]:
kleing@24333
   909
  "of_bl (False#xs) = of_bl xs"
kleing@24333
   910
  by (rule word_eqI)
kleing@24333
   911
     (auto simp add: test_bit_of_bl nth_append)
kleing@24333
   912
kleing@24333
   913
lemma of_bl_True: 
huffman@24465
   914
  "(of_bl (True#xs)::'a::len word) = 2^length xs + of_bl xs"
kleing@24333
   915
  by (subst of_bl_append [where xs="[True]", simplified])
kleing@24333
   916
     (simp add: word_1_bl)
kleing@24333
   917
kleing@24333
   918
lemma of_bl_Cons:
kleing@24333
   919
  "of_bl (x#xs) = of_bool x * 2^length xs + of_bl xs"
kleing@24333
   920
  by (cases x) (simp_all add: of_bl_True)
kleing@24333
   921
huffman@24465
   922
lemma split_uint_lem: "bin_split n (uint (w :: 'a :: len0 word)) = (a, b) ==> 
huffman@24465
   923
  a = bintrunc (len_of TYPE('a) - n) a & b = bintrunc (len_of TYPE('a)) b"
kleing@24333
   924
  apply (frule word_ubin.norm_Rep [THEN ssubst])
kleing@24333
   925
  apply (drule bin_split_trunc1)
kleing@24333
   926
  apply (drule sym [THEN trans])
kleing@24333
   927
  apply assumption
kleing@24333
   928
  apply safe
kleing@24333
   929
  done
kleing@24333
   930
kleing@24333
   931
lemma word_split_bl': 
kleing@24333
   932
  "std = size c - size b ==> (word_split c = (a, b)) ==> 
kleing@24333
   933
    (a = of_bl (take std (to_bl c)) & b = of_bl (drop std (to_bl c)))"
kleing@24333
   934
  apply (unfold word_split_bin')
kleing@24333
   935
  apply safe
kleing@24333
   936
   defer
kleing@24333
   937
   apply (clarsimp split: prod.splits)
kleing@24333
   938
   apply (drule word_ubin.norm_Rep [THEN ssubst])
kleing@24333
   939
   apply (drule split_bintrunc)
kleing@24333
   940
   apply (simp add : of_bl_def bl2bin_drop word_size
kleing@24333
   941
       word_ubin.norm_eq_iff [symmetric] min_def del : word_ubin.norm_Rep)    
kleing@24333
   942
  apply (clarsimp split: prod.splits)
kleing@24333
   943
  apply (frule split_uint_lem [THEN conjunct1])
kleing@24333
   944
  apply (unfold word_size)
huffman@24465
   945
  apply (cases "len_of TYPE('a) >= len_of TYPE('b)")
kleing@24333
   946
   defer
kleing@24333
   947
   apply (simp add: word_0_bl word_0_wi_Pls)
kleing@24333
   948
  apply (simp add : of_bl_def to_bl_def)
kleing@24333
   949
  apply (subst bin_split_take1 [symmetric])
kleing@24333
   950
    prefer 2
kleing@24333
   951
    apply assumption
kleing@24333
   952
   apply simp
kleing@24333
   953
  apply (erule thin_rl)
kleing@24333
   954
  apply (erule arg_cong [THEN trans])
kleing@24333
   955
  apply (simp add : word_ubin.norm_eq_iff [symmetric])
kleing@24333
   956
  done
kleing@24333
   957
kleing@24333
   958
lemma word_split_bl: "std = size c - size b ==> 
kleing@24333
   959
    (a = of_bl (take std (to_bl c)) & b = of_bl (drop std (to_bl c))) <-> 
kleing@24333
   960
    word_split c = (a, b)"
kleing@24333
   961
  apply (rule iffI)
kleing@24333
   962
   defer
kleing@24333
   963
   apply (erule (1) word_split_bl')
kleing@24333
   964
  apply (case_tac "word_split c")
kleing@24333
   965
  apply (auto simp add : word_size)
kleing@24333
   966
  apply (frule word_split_bl' [rotated])
kleing@24333
   967
  apply (auto simp add : word_size)
kleing@24333
   968
  done
kleing@24333
   969
kleing@24333
   970
lemma word_split_bl_eq:
huffman@24465
   971
   "(word_split (c::'a::len word) :: ('c :: len0 word * 'd :: len0 word)) =
huffman@24465
   972
      (of_bl (take (len_of TYPE('a::len) - len_of TYPE('d::len0)) (to_bl c)),
huffman@24465
   973
       of_bl (drop (len_of TYPE('a) - len_of TYPE('d)) (to_bl c)))"
kleing@24333
   974
  apply (rule word_split_bl [THEN iffD1])
kleing@24333
   975
  apply (unfold word_size)
kleing@24333
   976
  apply (rule refl conjI)+
kleing@24333
   977
  done
kleing@24333
   978
kleing@24333
   979
-- "keep quantifiers for use in simplification"
kleing@24333
   980
lemma test_bit_split':
kleing@24333
   981
  "word_split c = (a, b) --> (ALL n m. b !! n = (n < size b & c !! n) & 
kleing@24333
   982
    a !! m = (m < size a & c !! (m + size b)))"
kleing@24333
   983
  apply (unfold word_split_bin' test_bit_bin)
kleing@24333
   984
  apply (clarify)
kleing@24333
   985
  apply (clarsimp simp: word_ubin.eq_norm nth_bintr word_size split: prod.splits)
kleing@24333
   986
  apply (drule bin_nth_split)
kleing@24333
   987
  apply safe
kleing@24333
   988
       apply (simp_all add: add_commute)
kleing@24333
   989
   apply (erule bin_nth_uint_imp)+
kleing@24333
   990
  done
kleing@24333
   991
kleing@24333
   992
lemmas test_bit_split = 
kleing@24333
   993
  test_bit_split' [THEN mp, simplified all_simps, standard]
kleing@24333
   994
kleing@24333
   995
lemma test_bit_split_eq: "word_split c = (a, b) <-> 
kleing@24333
   996
  ((ALL n::nat. b !! n = (n < size b & c !! n)) &
kleing@24333
   997
    (ALL m::nat. a !! m = (m < size a & c !! (m + size b))))"
kleing@24333
   998
  apply (rule_tac iffI)
kleing@24333
   999
   apply (rule_tac conjI)
kleing@24333
  1000
    apply (erule test_bit_split [THEN conjunct1])
kleing@24333
  1001
   apply (erule test_bit_split [THEN conjunct2])
kleing@24333
  1002
  apply (case_tac "word_split c")
kleing@24333
  1003
  apply (frule test_bit_split)
kleing@24333
  1004
  apply (erule trans)
kleing@24333
  1005
  apply (fastsimp intro ! : word_eqI simp add : word_size)
kleing@24333
  1006
  done
kleing@24333
  1007
wenzelm@26008
  1008
-- {* this odd result is analogous to @{text "ucast_id"}, 
kleing@24333
  1009
      result to the length given by the result type *}
kleing@24333
  1010
kleing@24333
  1011
lemma word_cat_id: "word_cat a b = b"
kleing@24333
  1012
  unfolding word_cat_bin' by (simp add: word_ubin.inverse_norm)
kleing@24333
  1013
kleing@24333
  1014
-- "limited hom result"
kleing@24333
  1015
lemma word_cat_hom:
huffman@24465
  1016
  "len_of TYPE('a::len0) <= len_of TYPE('b::len0) + len_of TYPE ('c::len0)
kleing@24333
  1017
  ==>
kleing@24333
  1018
  (word_cat (word_of_int w :: 'b word) (b :: 'c word) :: 'a word) = 
kleing@24333
  1019
  word_of_int (bin_cat w (size b) (uint b))"
kleing@24333
  1020
  apply (unfold word_cat_def word_size) 
kleing@24333
  1021
  apply (clarsimp simp add : word_ubin.norm_eq_iff [symmetric]
kleing@24333
  1022
      word_ubin.eq_norm bintr_cat min_def)
huffman@24465
  1023
  apply arith
kleing@24333
  1024
  done
kleing@24333
  1025
kleing@24333
  1026
lemma word_cat_split_alt:
kleing@24333
  1027
  "size w <= size u + size v ==> word_split w = (u, v) ==> word_cat u v = w"
kleing@24333
  1028
  apply (rule word_eqI)
kleing@24333
  1029
  apply (drule test_bit_split)
kleing@24333
  1030
  apply (clarsimp simp add : test_bit_cat word_size)
kleing@24333
  1031
  apply safe
kleing@24333
  1032
  apply arith
kleing@24333
  1033
  done
kleing@24333
  1034
kleing@24333
  1035
lemmas word_cat_split_size = 
kleing@24333
  1036
  sym [THEN [2] word_cat_split_alt [symmetric], standard]
kleing@24333
  1037
kleing@24333
  1038
huffman@24350
  1039
subsubsection "Split and slice"
kleing@24333
  1040
kleing@24333
  1041
lemma split_slices: 
kleing@24333
  1042
  "word_split w = (u, v) ==> u = slice (size v) w & v = slice 0 w"
kleing@24333
  1043
  apply (drule test_bit_split)
kleing@24333
  1044
  apply (rule conjI)
kleing@24333
  1045
   apply (rule word_eqI, clarsimp simp: nth_slice word_size)+
kleing@24333
  1046
  done
kleing@24333
  1047
kleing@24333
  1048
lemma slice_cat1':
kleing@24333
  1049
  "wc = word_cat a b ==> size wc >= size a + size b ==> slice (size b) wc = a"
kleing@24333
  1050
  apply safe
kleing@24333
  1051
  apply (rule word_eqI)
kleing@24333
  1052
  apply (simp add: nth_slice test_bit_cat word_size)
kleing@24333
  1053
  done
kleing@24333
  1054
kleing@24333
  1055
lemmas slice_cat1 = refl [THEN slice_cat1']
kleing@24333
  1056
lemmas slice_cat2 = trans [OF slice_id word_cat_id]
kleing@24333
  1057
kleing@24333
  1058
lemma cat_slices:
wenzelm@26008
  1059
  "a = slice n c ==> b = slice 0 c ==> n = size b ==>
kleing@24333
  1060
    size a + size b >= size c ==> word_cat a b = c"
kleing@24333
  1061
  apply safe
kleing@24333
  1062
  apply (rule word_eqI)
kleing@24333
  1063
  apply (simp add: nth_slice test_bit_cat word_size)
kleing@24333
  1064
  apply safe
kleing@24333
  1065
  apply arith
kleing@24333
  1066
  done
kleing@24333
  1067
kleing@24333
  1068
lemma word_split_cat_alt:
kleing@24333
  1069
  "w = word_cat u v ==> size u + size v <= size w ==> word_split w = (u, v)"
kleing@24333
  1070
  apply (case_tac "word_split ?w")
kleing@24333
  1071
  apply (rule trans, assumption)
kleing@24333
  1072
  apply (drule test_bit_split)
kleing@24333
  1073
  apply safe
kleing@24333
  1074
   apply (rule word_eqI, clarsimp simp: test_bit_cat word_size)+
kleing@24333
  1075
  done
kleing@24333
  1076
kleing@24333
  1077
lemmas word_cat_bl_no_bin [simp] =
wenzelm@25350
  1078
  word_cat_bl [where a="number_of a" 
wenzelm@25350
  1079
                 and b="number_of b", 
wenzelm@25350
  1080
               unfolded to_bl_no_bin, standard]
kleing@24333
  1081
kleing@24333
  1082
lemmas word_split_bl_no_bin [simp] =
wenzelm@25350
  1083
  word_split_bl_eq [where c="number_of c", unfolded to_bl_no_bin, standard]
kleing@24333
  1084
kleing@24333
  1085
-- {* this odd result arises from the fact that the statement of the
kleing@24333
  1086
      result implies that the decoded words are of the same type, 
kleing@24333
  1087
      and therefore of the same length, as the original word *}
kleing@24333
  1088
kleing@24333
  1089
lemma word_rsplit_same: "word_rsplit w = [w]"
kleing@24333
  1090
  unfolding word_rsplit_def by (simp add : bin_rsplit_all)
kleing@24333
  1091
kleing@24333
  1092
lemma word_rsplit_empty_iff_size:
kleing@24333
  1093
  "(word_rsplit w = []) = (size w = 0)" 
kleing@24333
  1094
  unfolding word_rsplit_def bin_rsplit_def word_size
wenzelm@26289
  1095
  by (simp add: bin_rsplit_aux_simp_alt Let_def split: Product_Type.split_split)
kleing@24333
  1096
kleing@24333
  1097
lemma test_bit_rsplit:
huffman@24465
  1098
  "sw = word_rsplit w ==> m < size (hd sw :: 'a :: len word) ==> 
kleing@24333
  1099
    k < length sw ==> (rev sw ! k) !! m = (w !! (k * size (hd sw) + m))"
kleing@24333
  1100
  apply (unfold word_rsplit_def word_test_bit_def)
kleing@24333
  1101
  apply (rule trans)
kleing@24333
  1102
   apply (rule_tac f = "%x. bin_nth x m" in arg_cong)
kleing@24333
  1103
   apply (rule nth_map [symmetric])
kleing@24333
  1104
   apply simp
kleing@24333
  1105
  apply (rule bin_nth_rsplit)
kleing@24333
  1106
     apply simp_all
kleing@24333
  1107
  apply (simp add : word_size rev_map map_compose [symmetric])
kleing@24333
  1108
  apply (rule trans)
kleing@24333
  1109
   defer
kleing@24333
  1110
   apply (rule map_ident [THEN fun_cong])
kleing@24333
  1111
  apply (rule refl [THEN map_cong])
kleing@24333
  1112
  apply (simp add : word_ubin.eq_norm)
huffman@24465
  1113
  apply (erule bin_rsplit_size_sign [OF len_gt_0 refl])
kleing@24333
  1114
  done
kleing@24333
  1115
kleing@24333
  1116
lemma word_rcat_bl: "word_rcat wl == of_bl (concat (map to_bl wl))"
kleing@24333
  1117
  unfolding word_rcat_def to_bl_def' of_bl_def
kleing@24333
  1118
  by (clarsimp simp add : bin_rcat_bl map_compose)
kleing@24333
  1119
kleing@24333
  1120
lemma size_rcat_lem':
kleing@24333
  1121
  "size (concat (map to_bl wl)) = length wl * size (hd wl)"
kleing@24333
  1122
  unfolding word_size by (induct wl) auto
kleing@24333
  1123
kleing@24333
  1124
lemmas size_rcat_lem = size_rcat_lem' [unfolded word_size]
kleing@24333
  1125
huffman@24465
  1126
lemmas td_gal_lt_len = len_gt_0 [THEN td_gal_lt, standard]
kleing@24333
  1127
kleing@24333
  1128
lemma nth_rcat_lem' [rule_format] :
huffman@24465
  1129
  "sw = size (hd wl  :: 'a :: len word) ==> (ALL n. n < size wl * sw --> 
kleing@24333
  1130
    rev (concat (map to_bl wl)) ! n = 
kleing@24333
  1131
    rev (to_bl (rev wl ! (n div sw))) ! (n mod sw))"
kleing@24333
  1132
  apply (unfold word_size)
kleing@24333
  1133
  apply (induct "wl")
kleing@24333
  1134
   apply clarsimp
kleing@24333
  1135
  apply (clarsimp simp add : nth_append size_rcat_lem)
kleing@24333
  1136
  apply (simp (no_asm_use) only:  mult_Suc [symmetric] 
kleing@24333
  1137
         td_gal_lt_len less_Suc_eq_le mod_div_equality')
kleing@24333
  1138
  apply clarsimp
kleing@24333
  1139
  done
kleing@24333
  1140
kleing@24333
  1141
lemmas nth_rcat_lem = refl [THEN nth_rcat_lem', unfolded word_size]
kleing@24333
  1142
kleing@24333
  1143
lemma test_bit_rcat:
huffman@24465
  1144
  "sw = size (hd wl :: 'a :: len word) ==> rc = word_rcat wl ==> rc !! n = 
kleing@24333
  1145
    (n < size rc & n div sw < size wl & (rev wl) ! (n div sw) !! (n mod sw))"
kleing@24333
  1146
  apply (unfold word_rcat_bl word_size)
kleing@24333
  1147
  apply (clarsimp simp add : 
kleing@24333
  1148
    test_bit_of_bl size_rcat_lem word_size td_gal_lt_len)
kleing@24333
  1149
  apply safe
kleing@24333
  1150
   apply (auto simp add : 
kleing@24333
  1151
    test_bit_bl word_size td_gal_lt_len [THEN iffD2, THEN nth_rcat_lem])
kleing@24333
  1152
  done
kleing@24333
  1153
kleing@24333
  1154
lemma foldl_eq_foldr [rule_format] :
kleing@24333
  1155
  "ALL x. foldl op + x xs = foldr op + (x # xs) (0 :: 'a :: comm_monoid_add)" 
kleing@24333
  1156
  by (induct xs) (auto simp add : add_assoc)
kleing@24333
  1157
kleing@24333
  1158
lemmas test_bit_cong = arg_cong [where f = "test_bit", THEN fun_cong]
kleing@24333
  1159
kleing@24333
  1160
lemmas test_bit_rsplit_alt = 
kleing@24333
  1161
  trans [OF nth_rev_alt [THEN test_bit_cong] 
kleing@24333
  1162
  test_bit_rsplit [OF refl asm_rl diff_Suc_less]]
kleing@24333
  1163
kleing@24333
  1164
-- "lazy way of expressing that u and v, and su and sv, have same types"
kleing@24333
  1165
lemma word_rsplit_len_indep':
kleing@24333
  1166
  "[u,v] = p ==> [su,sv] = q ==> word_rsplit u = su ==> 
kleing@24333
  1167
    word_rsplit v = sv ==> length su = length sv"
kleing@24333
  1168
  apply (unfold word_rsplit_def)
kleing@24333
  1169
  apply (auto simp add : bin_rsplit_len_indep)
kleing@24333
  1170
  done
kleing@24333
  1171
kleing@24333
  1172
lemmas word_rsplit_len_indep = word_rsplit_len_indep' [OF refl refl refl refl]
kleing@24333
  1173
kleing@24333
  1174
lemma length_word_rsplit_size: 
huffman@24465
  1175
  "n = len_of TYPE ('a :: len) ==> 
kleing@24333
  1176
    (length (word_rsplit w :: 'a word list) <= m) = (size w <= m * n)"
kleing@24333
  1177
  apply (unfold word_rsplit_def word_size)
kleing@24333
  1178
  apply (clarsimp simp add : bin_rsplit_len_le)
kleing@24333
  1179
  done
kleing@24333
  1180
kleing@24333
  1181
lemmas length_word_rsplit_lt_size = 
kleing@24333
  1182
  length_word_rsplit_size [unfolded Not_eq_iff linorder_not_less [symmetric]]
kleing@24333
  1183
kleing@24333
  1184
lemma length_word_rsplit_exp_size: 
huffman@24465
  1185
  "n = len_of TYPE ('a :: len) ==> 
kleing@24333
  1186
    length (word_rsplit w :: 'a word list) = (size w + n - 1) div n"
kleing@24333
  1187
  unfolding word_rsplit_def by (clarsimp simp add : word_size bin_rsplit_len)
kleing@24333
  1188
kleing@24333
  1189
lemma length_word_rsplit_even_size: 
huffman@24465
  1190
  "n = len_of TYPE ('a :: len) ==> size w = m * n ==> 
kleing@24333
  1191
    length (word_rsplit w :: 'a word list) = m"
kleing@24333
  1192
  by (clarsimp simp add : length_word_rsplit_exp_size given_quot_alt)
kleing@24333
  1193
kleing@24333
  1194
lemmas length_word_rsplit_exp_size' = refl [THEN length_word_rsplit_exp_size]
kleing@24333
  1195
kleing@24333
  1196
(* alternative proof of word_rcat_rsplit *)
kleing@24333
  1197
lemmas tdle = iffD2 [OF split_div_lemma refl, THEN conjunct1] 
kleing@24333
  1198
lemmas dtle = xtr4 [OF tdle mult_commute]
kleing@24333
  1199
kleing@24333
  1200
lemma word_rcat_rsplit: "word_rcat (word_rsplit w) = w"
kleing@24333
  1201
  apply (rule word_eqI)
kleing@24333
  1202
  apply (clarsimp simp add : test_bit_rcat word_size)
kleing@24333
  1203
  apply (subst refl [THEN test_bit_rsplit])
kleing@24333
  1204
    apply (simp_all add: word_size 
haftmann@26072
  1205
      refl [THEN length_word_rsplit_size [simplified not_less [symmetric], simplified]])
kleing@24333
  1206
   apply safe
huffman@24465
  1207
   apply (erule xtr7, rule len_gt_0 [THEN dtle])+
kleing@24333
  1208
  done
kleing@24333
  1209
kleing@24333
  1210
lemma size_word_rsplit_rcat_size':
huffman@24465
  1211
  "word_rcat (ws :: 'a :: len word list) = frcw ==> 
huffman@24465
  1212
    size frcw = length ws * len_of TYPE ('a) ==> 
kleing@24333
  1213
    size (hd [word_rsplit frcw, ws]) = size ws" 
kleing@24333
  1214
  apply (clarsimp simp add : word_size length_word_rsplit_exp_size')
huffman@24465
  1215
  apply (fast intro: given_quot_alt)
kleing@24333
  1216
  done
kleing@24333
  1217
kleing@24333
  1218
lemmas size_word_rsplit_rcat_size = 
kleing@24333
  1219
  size_word_rsplit_rcat_size' [simplified]
kleing@24333
  1220
kleing@24333
  1221
lemma msrevs:
kleing@24333
  1222
  fixes n::nat
kleing@24333
  1223
  shows "0 < n \<Longrightarrow> (k * n + m) div n = m div n + k"
kleing@24333
  1224
  and   "(k * n + m) mod n = m mod n"
kleing@24333
  1225
  by (auto simp: add_commute)
kleing@24333
  1226
kleing@24333
  1227
lemma word_rsplit_rcat_size':
huffman@24465
  1228
  "word_rcat (ws :: 'a :: len word list) = frcw ==> 
huffman@24465
  1229
    size frcw = length ws * len_of TYPE ('a) ==> word_rsplit frcw = ws" 
kleing@24333
  1230
  apply (frule size_word_rsplit_rcat_size, assumption)
kleing@24333
  1231
  apply (clarsimp simp add : word_size)
kleing@24333
  1232
  apply (rule nth_equalityI, assumption)
kleing@24333
  1233
  apply clarsimp
kleing@24333
  1234
  apply (rule word_eqI)
kleing@24333
  1235
  apply (rule trans)
kleing@24333
  1236
   apply (rule test_bit_rsplit_alt)
kleing@24333
  1237
     apply (clarsimp simp: word_size)+
kleing@24333
  1238
  apply (rule trans)
kleing@24333
  1239
  apply (rule test_bit_rcat [OF refl refl])
kleing@24333
  1240
  apply (simp add : word_size msrevs)
kleing@24333
  1241
  apply (subst nth_rev)
kleing@24333
  1242
   apply arith
kleing@24333
  1243
  apply (simp add : le0 [THEN [2] xtr7, THEN diff_Suc_less])
kleing@24333
  1244
  apply safe
kleing@24333
  1245
  apply (simp add : diff_mult_distrib)
kleing@24333
  1246
  apply (rule mpl_lem)
kleing@24333
  1247
  apply (cases "size ws")
kleing@24333
  1248
   apply simp_all
kleing@24333
  1249
  done
kleing@24333
  1250
kleing@24333
  1251
lemmas word_rsplit_rcat_size = refl [THEN word_rsplit_rcat_size']
kleing@24333
  1252
kleing@24333
  1253
huffman@24350
  1254
subsection "Rotation"
kleing@24333
  1255
kleing@24333
  1256
lemmas rotater_0' [simp] = rotater_def [where n = "0", simplified]
kleing@24333
  1257
kleing@24333
  1258
lemmas word_rot_defs = word_roti_def word_rotr_def word_rotl_def
kleing@24333
  1259
kleing@24333
  1260
lemma rotate_eq_mod: 
kleing@24333
  1261
  "m mod length xs = n mod length xs ==> rotate m xs = rotate n xs"
kleing@24333
  1262
  apply (rule box_equals)
kleing@24333
  1263
    defer
kleing@24333
  1264
    apply (rule rotate_conv_mod [symmetric])+
kleing@24333
  1265
  apply simp
kleing@24333
  1266
  done
kleing@24333
  1267
kleing@24333
  1268
lemmas rotate_eqs [standard] = 
kleing@24333
  1269
  trans [OF rotate0 [THEN fun_cong] id_apply]
kleing@24333
  1270
  rotate_rotate [symmetric] 
kleing@24333
  1271
  rotate_id 
kleing@24333
  1272
  rotate_conv_mod 
kleing@24333
  1273
  rotate_eq_mod
kleing@24333
  1274
kleing@24333
  1275
huffman@24350
  1276
subsubsection "Rotation of list to right"
kleing@24333
  1277
kleing@24333
  1278
lemma rotate1_rl': "rotater1 (l @ [a]) = a # l"
kleing@24333
  1279
  unfolding rotater1_def by (cases l) auto
kleing@24333
  1280
kleing@24333
  1281
lemma rotate1_rl [simp] : "rotater1 (rotate1 l) = l"
kleing@24333
  1282
  apply (unfold rotater1_def)
kleing@24333
  1283
  apply (cases "l")
kleing@24333
  1284
  apply (case_tac [2] "list")
kleing@24333
  1285
  apply auto
kleing@24333
  1286
  done
kleing@24333
  1287
kleing@24333
  1288
lemma rotate1_lr [simp] : "rotate1 (rotater1 l) = l"
kleing@24333
  1289
  unfolding rotater1_def by (cases l) auto
kleing@24333
  1290
kleing@24333
  1291
lemma rotater1_rev': "rotater1 (rev xs) = rev (rotate1 xs)"
kleing@24333
  1292
  apply (cases "xs")
kleing@24333
  1293
  apply (simp add : rotater1_def)
kleing@24333
  1294
  apply (simp add : rotate1_rl')
kleing@24333
  1295
  done
kleing@24333
  1296
  
kleing@24333
  1297
lemma rotater_rev': "rotater n (rev xs) = rev (rotate n xs)"
kleing@24333
  1298
  unfolding rotater_def by (induct n) (auto intro: rotater1_rev')
kleing@24333
  1299
wenzelm@25350
  1300
lemmas rotater_rev = rotater_rev' [where xs = "rev ys", simplified, standard]
kleing@24333
  1301
kleing@24333
  1302
lemma rotater_drop_take: 
kleing@24333
  1303
  "rotater n xs = 
kleing@24333
  1304
   drop (length xs - n mod length xs) xs @
kleing@24333
  1305
   take (length xs - n mod length xs) xs"
kleing@24333
  1306
  by (clarsimp simp add : rotater_rev rotate_drop_take rev_take rev_drop)
kleing@24333
  1307
kleing@24333
  1308
lemma rotater_Suc [simp] : 
kleing@24333
  1309
  "rotater (Suc n) xs = rotater1 (rotater n xs)"
kleing@24333
  1310
  unfolding rotater_def by auto
kleing@24333
  1311
kleing@24333
  1312
lemma rotate_inv_plus [rule_format] :
kleing@24333
  1313
  "ALL k. k = m + n --> rotater k (rotate n xs) = rotater m xs & 
kleing@24333
  1314
    rotate k (rotater n xs) = rotate m xs & 
kleing@24333
  1315
    rotater n (rotate k xs) = rotate m xs & 
kleing@24333
  1316
    rotate n (rotater k xs) = rotater m xs"
kleing@24333
  1317
  unfolding rotater_def rotate_def
kleing@24333
  1318
  by (induct n) (auto intro: funpow_swap1 [THEN trans])
kleing@24333
  1319
  
kleing@24333
  1320
lemmas rotate_inv_rel = le_add_diff_inverse2 [symmetric, THEN rotate_inv_plus]
kleing@24333
  1321
kleing@24333
  1322
lemmas rotate_inv_eq = order_refl [THEN rotate_inv_rel, simplified]
kleing@24333
  1323
kleing@24333
  1324
lemmas rotate_lr [simp] = rotate_inv_eq [THEN conjunct1, standard]
kleing@24333
  1325
lemmas rotate_rl [simp] =
kleing@24333
  1326
  rotate_inv_eq [THEN conjunct2, THEN conjunct1, standard]
kleing@24333
  1327
kleing@24333
  1328
lemma rotate_gal: "(rotater n xs = ys) = (rotate n ys = xs)"
kleing@24333
  1329
  by auto
kleing@24333
  1330
kleing@24333
  1331
lemma rotate_gal': "(ys = rotater n xs) = (xs = rotate n ys)"
kleing@24333
  1332
  by auto
kleing@24333
  1333
kleing@24333
  1334
lemma length_rotater [simp]: 
kleing@24333
  1335
  "length (rotater n xs) = length xs"
kleing@24333
  1336
  by (simp add : rotater_rev)
kleing@24333
  1337
kleing@24333
  1338
lemmas rrs0 = rotate_eqs [THEN restrict_to_left, 
kleing@24333
  1339
  simplified rotate_gal [symmetric] rotate_gal' [symmetric], standard]
kleing@24333
  1340
lemmas rrs1 = rrs0 [THEN refl [THEN rev_iffD1]]
kleing@24333
  1341
lemmas rotater_eqs = rrs1 [simplified length_rotater, standard]
kleing@24333
  1342
lemmas rotater_0 = rotater_eqs (1)
kleing@24333
  1343
lemmas rotater_add = rotater_eqs (2)
kleing@24333
  1344
kleing@24333
  1345
haftmann@26558
  1346
subsubsection "map, map2, commuting with rotate(r)"
kleing@24333
  1347
kleing@24333
  1348
lemma last_map: "xs ~= [] ==> last (map f xs) = f (last xs)"
kleing@24333
  1349
  by (induct xs) auto
kleing@24333
  1350
kleing@24333
  1351
lemma butlast_map:
kleing@24333
  1352
  "xs ~= [] ==> butlast (map f xs) = map f (butlast xs)"
kleing@24333
  1353
  by (induct xs) auto
kleing@24333
  1354
kleing@24333
  1355
lemma rotater1_map: "rotater1 (map f xs) = map f (rotater1 xs)" 
kleing@24333
  1356
  unfolding rotater1_def
kleing@24333
  1357
  by (cases xs) (auto simp add: last_map butlast_map)
kleing@24333
  1358
kleing@24333
  1359
lemma rotater_map:
kleing@24333
  1360
  "rotater n (map f xs) = map f (rotater n xs)" 
kleing@24333
  1361
  unfolding rotater_def
kleing@24333
  1362
  by (induct n) (auto simp add : rotater1_map)
kleing@24333
  1363
kleing@24333
  1364
lemma but_last_zip [rule_format] :
kleing@24333
  1365
  "ALL ys. length xs = length ys --> xs ~= [] --> 
kleing@24333
  1366
    last (zip xs ys) = (last xs, last ys) & 
kleing@24333
  1367
    butlast (zip xs ys) = zip (butlast xs) (butlast ys)" 
kleing@24333
  1368
  apply (induct "xs")
kleing@24333
  1369
  apply auto
kleing@24333
  1370
     apply ((case_tac ys, auto simp: neq_Nil_conv)[1])+
kleing@24333
  1371
  done
kleing@24333
  1372
haftmann@26558
  1373
lemma but_last_map2 [rule_format] :
kleing@24333
  1374
  "ALL ys. length xs = length ys --> xs ~= [] --> 
haftmann@26558
  1375
    last (map2 f xs ys) = f (last xs) (last ys) & 
haftmann@26558
  1376
    butlast (map2 f xs ys) = map2 f (butlast xs) (butlast ys)" 
kleing@24333
  1377
  apply (induct "xs")
kleing@24333
  1378
  apply auto
haftmann@26558
  1379
     apply (unfold map2_def)
kleing@24333
  1380
     apply ((case_tac ys, auto simp: neq_Nil_conv)[1])+
kleing@24333
  1381
  done
kleing@24333
  1382
kleing@24333
  1383
lemma rotater1_zip:
kleing@24333
  1384
  "length xs = length ys ==> 
kleing@24333
  1385
    rotater1 (zip xs ys) = zip (rotater1 xs) (rotater1 ys)" 
kleing@24333
  1386
  apply (unfold rotater1_def)
kleing@24333
  1387
  apply (cases "xs")
kleing@24333
  1388
   apply auto
kleing@24333
  1389
   apply ((case_tac ys, auto simp: neq_Nil_conv but_last_zip)[1])+
kleing@24333
  1390
  done
kleing@24333
  1391
haftmann@26558
  1392
lemma rotater1_map2:
kleing@24333
  1393
  "length xs = length ys ==> 
haftmann@26558
  1394
    rotater1 (map2 f xs ys) = map2 f (rotater1 xs) (rotater1 ys)" 
haftmann@26558
  1395
  unfolding map2_def by (simp add: rotater1_map rotater1_zip)
kleing@24333
  1396
kleing@24333
  1397
lemmas lrth = 
kleing@24333
  1398
  box_equals [OF asm_rl length_rotater [symmetric] 
kleing@24333
  1399
                 length_rotater [symmetric], 
haftmann@26558
  1400
              THEN rotater1_map2]
kleing@24333
  1401
haftmann@26558
  1402
lemma rotater_map2: 
kleing@24333
  1403
  "length xs = length ys ==> 
haftmann@26558
  1404
    rotater n (map2 f xs ys) = map2 f (rotater n xs) (rotater n ys)" 
kleing@24333
  1405
  by (induct n) (auto intro!: lrth)
kleing@24333
  1406
haftmann@26558
  1407
lemma rotate1_map2:
kleing@24333
  1408
  "length xs = length ys ==> 
haftmann@26558
  1409
    rotate1 (map2 f xs ys) = map2 f (rotate1 xs) (rotate1 ys)" 
haftmann@26558
  1410
  apply (unfold map2_def)
kleing@24333
  1411
  apply (cases xs)
kleing@24333
  1412
   apply (cases ys, auto simp add : rotate1_def)+
kleing@24333
  1413
  done
kleing@24333
  1414
kleing@24333
  1415
lemmas lth = box_equals [OF asm_rl length_rotate [symmetric] 
haftmann@26558
  1416
  length_rotate [symmetric], THEN rotate1_map2]
kleing@24333
  1417
haftmann@26558
  1418
lemma rotate_map2: 
kleing@24333
  1419
  "length xs = length ys ==> 
haftmann@26558
  1420
    rotate n (map2 f xs ys) = map2 f (rotate n xs) (rotate n ys)" 
kleing@24333
  1421
  by (induct n) (auto intro!: lth)
kleing@24333
  1422
kleing@24333
  1423
kleing@24333
  1424
-- "corresponding equalities for word rotation"
kleing@24333
  1425
kleing@24333
  1426
lemma to_bl_rotl: 
kleing@24333
  1427
  "to_bl (word_rotl n w) = rotate n (to_bl w)"
kleing@24333
  1428
  by (simp add: word_bl.Abs_inverse' word_rotl_def)
kleing@24333
  1429
kleing@24333
  1430
lemmas blrs0 = rotate_eqs [THEN to_bl_rotl [THEN trans]]
kleing@24333
  1431
kleing@24333
  1432
lemmas word_rotl_eqs =
kleing@24333
  1433
  blrs0 [simplified word_bl.Rep' word_bl.Rep_inject to_bl_rotl [symmetric]]
kleing@24333
  1434
kleing@24333
  1435
lemma to_bl_rotr: 
kleing@24333
  1436
  "to_bl (word_rotr n w) = rotater n (to_bl w)"
kleing@24333
  1437
  by (simp add: word_bl.Abs_inverse' word_rotr_def)
kleing@24333
  1438
kleing@24333
  1439
lemmas brrs0 = rotater_eqs [THEN to_bl_rotr [THEN trans]]
kleing@24333
  1440
kleing@24333
  1441
lemmas word_rotr_eqs =
kleing@24333
  1442
  brrs0 [simplified word_bl.Rep' word_bl.Rep_inject to_bl_rotr [symmetric]]
kleing@24333
  1443
kleing@24333
  1444
declare word_rotr_eqs (1) [simp]
kleing@24333
  1445
declare word_rotl_eqs (1) [simp]
kleing@24333
  1446
kleing@24333
  1447
lemma
kleing@24333
  1448
  word_rot_rl [simp]:
kleing@24333
  1449
  "word_rotl k (word_rotr k v) = v" and
kleing@24333
  1450
  word_rot_lr [simp]:
kleing@24333
  1451
  "word_rotr k (word_rotl k v) = v"
kleing@24333
  1452
  by (auto simp add: to_bl_rotr to_bl_rotl word_bl.Rep_inject [symmetric])
kleing@24333
  1453
kleing@24333
  1454
lemma
kleing@24333
  1455
  word_rot_gal:
kleing@24333
  1456
  "(word_rotr n v = w) = (word_rotl n w = v)" and
kleing@24333
  1457
  word_rot_gal':
kleing@24333
  1458
  "(w = word_rotr n v) = (v = word_rotl n w)"
kleing@24333
  1459
  by (auto simp: to_bl_rotr to_bl_rotl word_bl.Rep_inject [symmetric] 
kleing@24333
  1460
           dest: sym)
kleing@24333
  1461
kleing@24333
  1462
lemma word_rotr_rev:
kleing@24333
  1463
  "word_rotr n w = word_reverse (word_rotl n (word_reverse w))"
kleing@24333
  1464
  by (simp add: word_bl.Rep_inject [symmetric] to_bl_word_rev
kleing@24333
  1465
                to_bl_rotr to_bl_rotl rotater_rev)
kleing@24333
  1466
  
kleing@24333
  1467
lemma word_roti_0 [simp]: "word_roti 0 w = w"
kleing@24333
  1468
  by (unfold word_rot_defs) auto
kleing@24333
  1469
kleing@24333
  1470
lemmas abl_cong = arg_cong [where f = "of_bl"]
kleing@24333
  1471
kleing@24333
  1472
lemma word_roti_add: 
kleing@24333
  1473
  "word_roti (m + n) w = word_roti m (word_roti n w)"
kleing@24333
  1474
proof -
kleing@24333
  1475
  have rotater_eq_lem: 
kleing@24333
  1476
    "\<And>m n xs. m = n ==> rotater m xs = rotater n xs"
kleing@24333
  1477
    by auto
kleing@24333
  1478
kleing@24333
  1479
  have rotate_eq_lem: 
kleing@24333
  1480
    "\<And>m n xs. m = n ==> rotate m xs = rotate n xs"
kleing@24333
  1481
    by auto
kleing@24333
  1482
kleing@24333
  1483
  note rpts [symmetric, standard] = 
kleing@24333
  1484
    rotate_inv_plus [THEN conjunct1]
kleing@24333
  1485
    rotate_inv_plus [THEN conjunct2, THEN conjunct1]
kleing@24333
  1486
    rotate_inv_plus [THEN conjunct2, THEN conjunct2, THEN conjunct1]
kleing@24333
  1487
    rotate_inv_plus [THEN conjunct2, THEN conjunct2, THEN conjunct2]
kleing@24333
  1488
kleing@24333
  1489
  note rrp = trans [symmetric, OF rotate_rotate rotate_eq_lem]
kleing@24333
  1490
  note rrrp = trans [symmetric, OF rotater_add [symmetric] rotater_eq_lem]
kleing@24333
  1491
kleing@24333
  1492
  show ?thesis
kleing@24333
  1493
  apply (unfold word_rot_defs)
kleing@24333
  1494
  apply (simp only: split: split_if)
kleing@24333
  1495
  apply (safe intro!: abl_cong)
kleing@24333
  1496
  apply (simp_all only: to_bl_rotl [THEN word_bl.Rep_inverse'] 
kleing@24333
  1497
                    to_bl_rotl
kleing@24333
  1498
                    to_bl_rotr [THEN word_bl.Rep_inverse']
kleing@24333
  1499
                    to_bl_rotr)
kleing@24333
  1500
  apply (rule rrp rrrp rpts,
kleing@24333
  1501
         simp add: nat_add_distrib [symmetric] 
kleing@24333
  1502
                   nat_diff_distrib [symmetric])+
kleing@24333
  1503
  done
kleing@24333
  1504
qed
kleing@24333
  1505
    
kleing@24333
  1506
lemma word_roti_conv_mod': "word_roti n w = word_roti (n mod int (size w)) w"
kleing@24333
  1507
  apply (unfold word_rot_defs)
kleing@24333
  1508
  apply (cut_tac y="size w" in gt_or_eq_0)
kleing@24333
  1509
  apply (erule disjE)
kleing@24333
  1510
   apply simp_all
kleing@24333
  1511
  apply (safe intro!: abl_cong)
kleing@24333
  1512
   apply (rule rotater_eqs)
kleing@24333
  1513
   apply (simp add: word_size nat_mod_distrib)
kleing@24333
  1514
  apply (simp add: rotater_add [symmetric] rotate_gal [symmetric])
kleing@24333
  1515
  apply (rule rotater_eqs)
kleing@24333
  1516
  apply (simp add: word_size nat_mod_distrib)
kleing@24333
  1517
  apply (rule int_eq_0_conv [THEN iffD1])
kleing@24333
  1518
  apply (simp only: zmod_int zadd_int [symmetric])
kleing@24333
  1519
  apply (simp add: rdmods)
kleing@24333
  1520
  done
kleing@24333
  1521
kleing@24333
  1522
lemmas word_roti_conv_mod = word_roti_conv_mod' [unfolded word_size]
kleing@24333
  1523
kleing@24333
  1524
huffman@24350
  1525
subsubsection "Word rotation commutes with bit-wise operations"
kleing@24333
  1526
kleing@24333
  1527
(* using locale to not pollute lemma namespace *)
kleing@24333
  1528
locale word_rotate 
kleing@24333
  1529
kleing@24333
  1530
context word_rotate
kleing@24333
  1531
begin
kleing@24333
  1532
kleing@24333
  1533
lemmas word_rot_defs' = to_bl_rotl to_bl_rotr
kleing@24333
  1534
kleing@24333
  1535
lemmas blwl_syms [symmetric] = bl_word_not bl_word_and bl_word_or bl_word_xor
kleing@24333
  1536
kleing@24333
  1537
lemmas lbl_lbl = trans [OF word_bl.Rep' word_bl.Rep' [symmetric]]
kleing@24333
  1538
haftmann@26558
  1539
lemmas ths_map2 [OF lbl_lbl] = rotate_map2 rotater_map2
kleing@24333
  1540
wenzelm@26936
  1541
lemmas ths_map [where xs = "to_bl v", standard] = rotate_map rotater_map
kleing@24333
  1542
haftmann@26558
  1543
lemmas th1s [simplified word_rot_defs' [symmetric]] = ths_map2 ths_map
kleing@24333
  1544
kleing@24333
  1545
lemma word_rot_logs:
kleing@24333
  1546
  "word_rotl n (NOT v) = NOT word_rotl n v"
kleing@24333
  1547
  "word_rotr n (NOT v) = NOT word_rotr n v"
kleing@24333
  1548
  "word_rotl n (x AND y) = word_rotl n x AND word_rotl n y"
kleing@24333
  1549
  "word_rotr n (x AND y) = word_rotr n x AND word_rotr n y"
kleing@24333
  1550
  "word_rotl n (x OR y) = word_rotl n x OR word_rotl n y"
kleing@24333
  1551
  "word_rotr n (x OR y) = word_rotr n x OR word_rotr n y"
kleing@24333
  1552
  "word_rotl n (x XOR y) = word_rotl n x XOR word_rotl n y"
kleing@24333
  1553
  "word_rotr n (x XOR y) = word_rotr n x XOR word_rotr n y"  
kleing@24333
  1554
  by (rule word_bl.Rep_eqD,
kleing@24333
  1555
      rule word_rot_defs' [THEN trans],
kleing@24333
  1556
      simp only: blwl_syms [symmetric],
kleing@24333
  1557
      rule th1s [THEN trans], 
kleing@24333
  1558
      rule refl)+
kleing@24333
  1559
end
kleing@24333
  1560
kleing@24333
  1561
lemmas word_rot_logs = word_rotate.word_rot_logs
kleing@24333
  1562
kleing@24333
  1563
lemmas bl_word_rotl_dt = trans [OF to_bl_rotl rotate_drop_take,
kleing@24333
  1564
  simplified word_bl.Rep', standard]
kleing@24333
  1565
kleing@24333
  1566
lemmas bl_word_rotr_dt = trans [OF to_bl_rotr rotater_drop_take,
kleing@24333
  1567
  simplified word_bl.Rep', standard]
kleing@24333
  1568
kleing@24333
  1569
lemma bl_word_roti_dt': 
huffman@24465
  1570
  "n = nat ((- i) mod int (size (w :: 'a :: len word))) ==> 
kleing@24333
  1571
    to_bl (word_roti i w) = drop n (to_bl w) @ take n (to_bl w)"
kleing@24333
  1572
  apply (unfold word_roti_def)
kleing@24333
  1573
  apply (simp add: bl_word_rotl_dt bl_word_rotr_dt word_size)
kleing@24333
  1574
  apply safe
kleing@24333
  1575
   apply (simp add: zmod_zminus1_eq_if)
kleing@24333
  1576
   apply safe
kleing@24333
  1577
    apply (simp add: nat_mult_distrib)
kleing@24333
  1578
   apply (simp add: nat_diff_distrib [OF pos_mod_sign pos_mod_conj 
kleing@24333
  1579
                                      [THEN conjunct2, THEN order_less_imp_le]]
kleing@24333
  1580
                    nat_mod_distrib)
kleing@24333
  1581
  apply (simp add: nat_mod_distrib)
kleing@24333
  1582
  done
kleing@24333
  1583
kleing@24333
  1584
lemmas bl_word_roti_dt = bl_word_roti_dt' [unfolded word_size]
kleing@24333
  1585
kleing@24333
  1586
lemmas word_rotl_dt = bl_word_rotl_dt 
kleing@24333
  1587
  [THEN word_bl.Rep_inverse' [symmetric], standard] 
kleing@24333
  1588
lemmas word_rotr_dt = bl_word_rotr_dt 
kleing@24333
  1589
  [THEN word_bl.Rep_inverse' [symmetric], standard]
kleing@24333
  1590
lemmas word_roti_dt = bl_word_roti_dt 
kleing@24333
  1591
  [THEN word_bl.Rep_inverse' [symmetric], standard]
kleing@24333
  1592
kleing@24333
  1593
lemma word_rotx_0 [simp] : "word_rotr i 0 = 0 & word_rotl i 0 = 0"
kleing@24333
  1594
  by (simp add : word_rotr_dt word_rotl_dt to_bl_0 replicate_add [symmetric])
kleing@24333
  1595
kleing@24333
  1596
lemma word_roti_0' [simp] : "word_roti n 0 = 0"
kleing@24333
  1597
  unfolding word_roti_def by auto
kleing@24333
  1598
kleing@24333
  1599
lemmas word_rotr_dt_no_bin' [simp] = 
wenzelm@25350
  1600
  word_rotr_dt [where w="number_of w", unfolded to_bl_no_bin, standard]
kleing@24333
  1601
kleing@24333
  1602
lemmas word_rotl_dt_no_bin' [simp] = 
wenzelm@25350
  1603
  word_rotl_dt [where w="number_of w", unfolded to_bl_no_bin, standard]
kleing@24333
  1604
kleing@24333
  1605
declare word_roti_def [simp]
kleing@24333
  1606
kleing@24333
  1607
end
kleing@24333
  1608