src/HOL/Word/Misc_set_bit.thy
author haftmann
Tue, 04 Aug 2020 09:33:05 +0000
changeset 72082 41393ecb57ac
parent 72000 379d0c207c29
permissions -rw-r--r--
uniform mask operation
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
72000
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
     1
(*  Author:     Jeremy Dawson, NICTA
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
     2
*)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
     3
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
     4
section \<open>Operation variant for setting and unsetting bits\<close>
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
     5
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
     6
theory Misc_set_bit
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
     7
  imports Word Misc_msb
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
     8
begin
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
     9
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    10
class set_bit = ring_bit_operations +
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    11
  fixes set_bit :: \<open>'a \<Rightarrow> nat \<Rightarrow> bool \<Rightarrow> 'a\<close>
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    12
  assumes set_bit_eq: \<open>set_bit a n b = (if b then Bit_Operations.set_bit else unset_bit) n a\<close>
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    13
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    14
instantiation int :: set_bit
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    15
begin
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    16
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    17
definition set_bit_int :: \<open>int \<Rightarrow> nat \<Rightarrow> bool \<Rightarrow> int\<close>
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    18
  where \<open>set_bit i n b = bin_sc n b i\<close>
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    19
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    20
instance
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    21
  by standard (simp add: set_bit_int_def bin_sc_eq)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    22
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    23
end
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    24
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    25
lemma int_set_bit_0 [simp]: fixes x :: int shows
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    26
  "set_bit x 0 b = of_bool b + 2 * (x div 2)"
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    27
  by (auto simp add: set_bit_int_def intro: bin_rl_eqI)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    28
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    29
lemma int_set_bit_Suc: fixes x :: int shows
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    30
  "set_bit x (Suc n) b = of_bool (odd x) + 2 * set_bit (x div 2) n b"
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    31
  by (auto simp add: set_bit_int_def intro: bin_rl_eqI)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    32
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    33
lemma bin_last_set_bit:
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    34
  "bin_last (set_bit x n b) = (if n > 0 then bin_last x else b)"
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    35
  by (cases n) (simp_all add: int_set_bit_Suc)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    36
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    37
lemma bin_rest_set_bit: 
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    38
  "bin_rest (set_bit x n b) = (if n > 0 then set_bit (x div 2) (n - 1) b else x div 2)"
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    39
  by (cases n) (simp_all add: int_set_bit_Suc)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    40
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    41
lemma int_set_bit_numeral: fixes x :: int shows
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    42
  "set_bit x (numeral w) b = of_bool (odd x) + 2 * set_bit (x div 2) (pred_numeral w) b"
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    43
  by (simp add: set_bit_int_def)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    44
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    45
lemmas int_set_bit_numerals [simp] =
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    46
  int_set_bit_numeral[where x="numeral w'"] 
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    47
  int_set_bit_numeral[where x="- numeral w'"]
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    48
  int_set_bit_numeral[where x="Numeral1"]
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    49
  int_set_bit_numeral[where x="1"]
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    50
  int_set_bit_numeral[where x="0"]
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    51
  int_set_bit_Suc[where x="numeral w'"]
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    52
  int_set_bit_Suc[where x="- numeral w'"]
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    53
  int_set_bit_Suc[where x="Numeral1"]
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    54
  int_set_bit_Suc[where x="1"]
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    55
  int_set_bit_Suc[where x="0"]
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    56
  for w'
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    57
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    58
lemma msb_set_bit [simp]: "msb (set_bit (x :: int) n b) \<longleftrightarrow> msb x"
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    59
by(simp add: msb_conv_bin_sign set_bit_int_def)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    60
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    61
instantiation word :: (len) set_bit
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    62
begin
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    63
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    64
definition set_bit_word :: \<open>'a word \<Rightarrow> nat \<Rightarrow> bool \<Rightarrow> 'a word\<close>
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    65
  where word_set_bit_def: \<open>set_bit a n x = word_of_int (bin_sc n x (uint a))\<close>
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    66
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    67
instance
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    68
  apply standard
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    69
  apply (simp add: word_set_bit_def bin_sc_eq Bit_Operations.set_bit_def unset_bit_def)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    70
  apply transfer
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    71
  apply simp
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    72
  done
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    73
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    74
end
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    75
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    76
lemma set_bit_unfold:
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    77
  \<open>set_bit w n b = (if b then Bit_Operations.set_bit n w else unset_bit n w)\<close>
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    78
  for w :: \<open>'a::len word\<close>
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    79
  by (simp add: set_bit_eq)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    80
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    81
lemma bit_set_bit_word_iff:
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    82
  \<open>bit (set_bit w m b) n \<longleftrightarrow> (if m = n then n < LENGTH('a) \<and> b else bit w n)\<close>
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    83
  for w :: \<open>'a::len word\<close>
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    84
  by (auto simp add: set_bit_unfold bit_unset_bit_iff bit_set_bit_iff exp_eq_zero_iff not_le bit_imp_le_length)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    85
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    86
lemma word_set_nth [simp]: "set_bit w n (test_bit w n) = w"
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    87
  for w :: "'a::len word"
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    88
  by (auto simp: word_test_bit_def word_set_bit_def)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    89
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    90
lemma test_bit_set: "(set_bit w n x) !! n \<longleftrightarrow> n < size w \<and> x"
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    91
  for w :: "'a::len word"
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    92
  by (auto simp: word_size word_test_bit_def word_set_bit_def word_ubin.eq_norm nth_bintr)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    93
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    94
lemma test_bit_set_gen:
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    95
  "test_bit (set_bit w n x) m = (if m = n then n < size w \<and> x else test_bit w m)"
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    96
  for w :: "'a::len word"
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    97
  apply (unfold word_size word_test_bit_def word_set_bit_def)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    98
  apply (clarsimp simp add: word_ubin.eq_norm nth_bintr bin_nth_sc_gen)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
    99
  apply (auto elim!: test_bit_size [unfolded word_size]
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   100
      simp add: word_test_bit_def [symmetric])
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   101
  done
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   102
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   103
lemma word_set_set_same [simp]: "set_bit (set_bit w n x) n y = set_bit w n y"
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   104
  for w :: "'a::len word"
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   105
  by (rule word_eqI) (simp add : test_bit_set_gen word_size)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   106
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   107
lemma word_set_set_diff:
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   108
  fixes w :: "'a::len word"
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   109
  assumes "m \<noteq> n"
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   110
  shows "set_bit (set_bit w m x) n y = set_bit (set_bit w n y) m x"
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   111
  by (rule word_eqI) (auto simp: test_bit_set_gen word_size assms)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   112
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   113
lemma set_bit_word_of_int: "set_bit (word_of_int x) n b = word_of_int (bin_sc n b x)"
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   114
  unfolding word_set_bit_def
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   115
  by (rule word_eqI)(simp add: word_size bin_nth_sc_gen word_ubin.eq_norm nth_bintr)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   116
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   117
lemma word_set_numeral [simp]:
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   118
  "set_bit (numeral bin::'a::len word) n b =
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   119
    word_of_int (bin_sc n b (numeral bin))"
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   120
  unfolding word_numeral_alt by (rule set_bit_word_of_int)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   121
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   122
lemma word_set_neg_numeral [simp]:
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   123
  "set_bit (- numeral bin::'a::len word) n b =
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   124
    word_of_int (bin_sc n b (- numeral bin))"
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   125
  unfolding word_neg_numeral_alt by (rule set_bit_word_of_int)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   126
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   127
lemma word_set_bit_0 [simp]: "set_bit 0 n b = word_of_int (bin_sc n b 0)"
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   128
  unfolding word_0_wi by (rule set_bit_word_of_int)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   129
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   130
lemma word_set_bit_1 [simp]: "set_bit 1 n b = word_of_int (bin_sc n b 1)"
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   131
  unfolding word_1_wi by (rule set_bit_word_of_int)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   132
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   133
lemma word_set_nth_iff: "set_bit w n b = w \<longleftrightarrow> w !! n = b \<or> n \<ge> size w"
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   134
  for w :: "'a::len word"
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   135
  apply (rule iffI)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   136
   apply (rule disjCI)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   137
   apply (drule word_eqD)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   138
   apply (erule sym [THEN trans])
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   139
   apply (simp add: test_bit_set)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   140
  apply (erule disjE)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   141
   apply clarsimp
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   142
  apply (rule word_eqI)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   143
  apply (clarsimp simp add : test_bit_set_gen)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   144
  apply (drule test_bit_size)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   145
  apply force
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   146
  done
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   147
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   148
lemma word_clr_le: "w \<ge> set_bit w n False"
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   149
  for w :: "'a::len word"
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   150
  apply (unfold word_set_bit_def word_le_def word_ubin.eq_norm)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   151
  apply (rule order_trans)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   152
   apply (rule bintr_bin_clr_le)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   153
  apply simp
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   154
  done
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   155
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   156
lemma word_set_ge: "w \<le> set_bit w n True"
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   157
  for w :: "'a::len word"
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   158
  apply (unfold word_set_bit_def word_le_def word_ubin.eq_norm)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   159
  apply (rule order_trans [OF _ bintr_bin_set_ge])
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   160
  apply simp
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   161
  done
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   162
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   163
lemma set_bit_beyond:
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   164
  "size x \<le> n \<Longrightarrow> set_bit x n b = x" for x :: "'a :: len word"
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   165
  by (auto intro: word_eqI simp add: test_bit_set_gen word_size)
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   166
379d0c207c29 separation of traditional bit operations
haftmann
parents:
diff changeset
   167
end