src/HOL/Word/BinOperations.thy
changeset 24364 31e359126ab6
parent 24353 9a7a9b19e925
child 24366 08b116049547
equal deleted inserted replaced
24363:c4dcc7408226 24364:31e359126ab6
    11 
    11 
    12 theory BinOperations imports BinGeneral BitSyntax
    12 theory BinOperations imports BinGeneral BitSyntax
    13 
    13 
    14 begin
    14 begin
    15 
    15 
    16 subsection {* NOT, AND, OR, XOR *}
    16 subsection {* Logical operations *}
    17 
    17 
    18 text "bit-wise logical operations on the int type"
    18 text "bit-wise logical operations on the int type"
    19 
    19 
    20 instance int :: bit
    20 instance int :: bit
    21   int_not_def: "bitNOT \<equiv> bin_rec Numeral.Min Numeral.Pls 
    21   int_not_def: "bitNOT \<equiv> bin_rec Numeral.Min Numeral.Pls 
    26     (\<lambda>w b s y. s (bin_rest y) BIT (b OR bin_last y))"
    26     (\<lambda>w b s y. s (bin_rest y) BIT (b OR bin_last y))"
    27   int_xor_def: "bitXOR \<equiv> bin_rec (\<lambda>x. x) bitNOT 
    27   int_xor_def: "bitXOR \<equiv> bin_rec (\<lambda>x. x) bitNOT 
    28     (\<lambda>w b s y. s (bin_rest y) BIT (b XOR bin_last y))"
    28     (\<lambda>w b s y. s (bin_rest y) BIT (b XOR bin_last y))"
    29   ..
    29   ..
    30 
    30 
       
    31 lemma int_not_simps [simp]:
       
    32   "NOT Numeral.Pls = Numeral.Min"
       
    33   "NOT Numeral.Min = Numeral.Pls"
       
    34   "NOT (w BIT b) = (NOT w) BIT (NOT b)"
       
    35   by (unfold int_not_def) (auto intro: bin_rec_simps)
       
    36 
       
    37 lemma bit_extra_simps [simp]: 
       
    38   "x AND bit.B0 = bit.B0"
       
    39   "x AND bit.B1 = x"
       
    40   "x OR bit.B1 = bit.B1"
       
    41   "x OR bit.B0 = x"
       
    42   "x XOR bit.B1 = NOT x"
       
    43   "x XOR bit.B0 = x"
       
    44   by (cases x, auto)+
       
    45 
       
    46 lemma bit_ops_comm: 
       
    47   "(x::bit) AND y = y AND x"
       
    48   "(x::bit) OR y = y OR x"
       
    49   "(x::bit) XOR y = y XOR x"
       
    50   by (cases y, auto)+
       
    51 
       
    52 lemma bit_ops_same [simp]: 
       
    53   "(x::bit) AND x = x"
       
    54   "(x::bit) OR x = x"
       
    55   "(x::bit) XOR x = bit.B0"
       
    56   by (cases x, auto)+
       
    57 
       
    58 lemma bit_not_not [simp]: "NOT (NOT (x::bit)) = x"
       
    59   by (cases x) auto
       
    60 
       
    61 lemma int_xor_Pls [simp]: 
       
    62   "Numeral.Pls XOR x = x"
       
    63   unfolding int_xor_def by (simp add: bin_rec_PM)
       
    64 
       
    65 lemma int_xor_Min [simp]: 
       
    66   "Numeral.Min XOR x = NOT x"
       
    67   unfolding int_xor_def by (simp add: bin_rec_PM)
       
    68 
       
    69 lemma int_xor_Bits [simp]: 
       
    70   "(x BIT b) XOR (y BIT c) = (x XOR y) BIT (b XOR c)"
       
    71   apply (unfold int_xor_def)
       
    72   apply (rule bin_rec_simps (1) [THEN fun_cong, THEN trans])
       
    73     apply (rule ext, simp)
       
    74    prefer 2
       
    75    apply simp
       
    76   apply (rule ext)
       
    77   apply (simp add: int_not_simps [symmetric])
       
    78   done
       
    79 
       
    80 lemma int_xor_x_simps':
       
    81   "w XOR (Numeral.Pls BIT bit.B0) = w"
       
    82   "w XOR (Numeral.Min BIT bit.B1) = NOT w"
       
    83   apply (induct w rule: bin_induct)
       
    84        apply simp_all[4]
       
    85    apply (unfold int_xor_Bits)
       
    86    apply clarsimp+
       
    87   done
       
    88 
       
    89 lemmas int_xor_extra_simps [simp] = int_xor_x_simps' [simplified arith_simps]
       
    90 
       
    91 lemma int_or_Pls [simp]: 
       
    92   "Numeral.Pls OR x = x"
       
    93   by (unfold int_or_def) (simp add: bin_rec_PM)
       
    94   
       
    95 lemma int_or_Min [simp]:
       
    96   "Numeral.Min OR x = Numeral.Min"
       
    97   by (unfold int_or_def) (simp add: bin_rec_PM)
       
    98 
       
    99 lemma int_or_Bits [simp]: 
       
   100   "(x BIT b) OR (y BIT c) = (x OR y) BIT (b OR c)"
       
   101   unfolding int_or_def by (simp add: bin_rec_simps)
       
   102 
       
   103 lemma int_or_x_simps': 
       
   104   "w OR (Numeral.Pls BIT bit.B0) = w"
       
   105   "w OR (Numeral.Min BIT bit.B1) = Numeral.Min"
       
   106   apply (induct w rule: bin_induct)
       
   107        apply simp_all[4]
       
   108    apply (unfold int_or_Bits)
       
   109    apply clarsimp+
       
   110   done
       
   111 
       
   112 lemmas int_or_extra_simps [simp] = int_or_x_simps' [simplified arith_simps]
       
   113 
       
   114 
       
   115 lemma int_and_Pls [simp]:
       
   116   "Numeral.Pls AND x = Numeral.Pls"
       
   117   unfolding int_and_def by (simp add: bin_rec_PM)
       
   118 
       
   119 lemma int_and_Min [simp]:
       
   120   "Numeral.Min AND x = x"
       
   121   unfolding int_and_def by (simp add: bin_rec_PM)
       
   122 
       
   123 lemma int_and_Bits [simp]: 
       
   124   "(x BIT b) AND (y BIT c) = (x AND y) BIT (b AND c)" 
       
   125   unfolding int_and_def by (simp add: bin_rec_simps)
       
   126 
       
   127 lemma int_and_x_simps': 
       
   128   "w AND (Numeral.Pls BIT bit.B0) = Numeral.Pls"
       
   129   "w AND (Numeral.Min BIT bit.B1) = w"
       
   130   apply (induct w rule: bin_induct)
       
   131        apply simp_all[4]
       
   132    apply (unfold int_and_Bits)
       
   133    apply clarsimp+
       
   134   done
       
   135 
       
   136 lemmas int_and_extra_simps [simp] = int_and_x_simps' [simplified arith_simps]
       
   137 
       
   138 (* commutativity of the above *)
       
   139 lemma bin_ops_comm:
       
   140   shows
       
   141   int_and_comm: "!!y::int. x AND y = y AND x" and
       
   142   int_or_comm:  "!!y::int. x OR y = y OR x" and
       
   143   int_xor_comm: "!!y::int. x XOR y = y XOR x"
       
   144   apply (induct x rule: bin_induct)
       
   145           apply simp_all[6]
       
   146     apply (case_tac y rule: bin_exhaust, simp add: bit_ops_comm)+
       
   147   done
       
   148 
       
   149 lemma bin_ops_same [simp]:
       
   150   "(x::int) AND x = x" 
       
   151   "(x::int) OR x = x" 
       
   152   "(x::int) XOR x = Numeral.Pls"
       
   153   by (induct x rule: bin_induct) auto
       
   154 
       
   155 lemma int_not_not [simp]: "NOT (NOT (x::int)) = x"
       
   156   by (induct x rule: bin_induct) auto
       
   157 
       
   158 lemmas bin_log_esimps = 
       
   159   int_and_extra_simps  int_or_extra_simps  int_xor_extra_simps
       
   160   int_and_Pls int_and_Min  int_or_Pls int_or_Min  int_xor_Pls int_xor_Min
       
   161 
       
   162 (* basic properties of logical (bit-wise) operations *)
       
   163 
       
   164 lemma bbw_ao_absorb: 
       
   165   "!!y::int. x AND (y OR x) = x & x OR (y AND x) = x"
       
   166   apply (induct x rule: bin_induct)
       
   167     apply auto 
       
   168    apply (case_tac [!] y rule: bin_exhaust)
       
   169    apply auto
       
   170    apply (case_tac [!] bit)
       
   171      apply auto
       
   172   done
       
   173 
       
   174 lemma bbw_ao_absorbs_other:
       
   175   "x AND (x OR y) = x \<and> (y AND x) OR x = (x::int)"
       
   176   "(y OR x) AND x = x \<and> x OR (x AND y) = (x::int)"
       
   177   "(x OR y) AND x = x \<and> (x AND y) OR x = (x::int)"
       
   178   apply (auto simp: bbw_ao_absorb int_or_comm)  
       
   179       apply (subst int_or_comm)
       
   180     apply (simp add: bbw_ao_absorb)
       
   181    apply (subst int_and_comm)
       
   182    apply (subst int_or_comm)
       
   183    apply (simp add: bbw_ao_absorb)
       
   184   apply (subst int_and_comm)
       
   185   apply (simp add: bbw_ao_absorb)
       
   186   done
       
   187 
       
   188 lemmas bbw_ao_absorbs [simp] = bbw_ao_absorb bbw_ao_absorbs_other
       
   189 
       
   190 lemma int_xor_not:
       
   191   "!!y::int. (NOT x) XOR y = NOT (x XOR y) & 
       
   192         x XOR (NOT y) = NOT (x XOR y)"
       
   193   apply (induct x rule: bin_induct)
       
   194     apply auto
       
   195    apply (case_tac y rule: bin_exhaust, auto, 
       
   196           case_tac b, auto)+
       
   197   done
       
   198 
       
   199 lemma bbw_assocs': 
       
   200   "!!y z::int. (x AND y) AND z = x AND (y AND z) & 
       
   201           (x OR y) OR z = x OR (y OR z) & 
       
   202           (x XOR y) XOR z = x XOR (y XOR z)"
       
   203   apply (induct x rule: bin_induct)
       
   204     apply (auto simp: int_xor_not)
       
   205     apply (case_tac [!] y rule: bin_exhaust)
       
   206     apply (case_tac [!] z rule: bin_exhaust)
       
   207     apply (case_tac [!] bit)
       
   208        apply (case_tac [!] b)
       
   209              apply auto
       
   210   done
       
   211 
       
   212 lemma int_and_assoc:
       
   213   "(x AND y) AND (z::int) = x AND (y AND z)"
       
   214   by (simp add: bbw_assocs')
       
   215 
       
   216 lemma int_or_assoc:
       
   217   "(x OR y) OR (z::int) = x OR (y OR z)"
       
   218   by (simp add: bbw_assocs')
       
   219 
       
   220 lemma int_xor_assoc:
       
   221   "(x XOR y) XOR (z::int) = x XOR (y XOR z)"
       
   222   by (simp add: bbw_assocs')
       
   223 
       
   224 lemmas bbw_assocs = int_and_assoc int_or_assoc int_xor_assoc
       
   225 
       
   226 lemma bbw_lcs [simp]: 
       
   227   "(y::int) AND (x AND z) = x AND (y AND z)"
       
   228   "(y::int) OR (x OR z) = x OR (y OR z)"
       
   229   "(y::int) XOR (x XOR z) = x XOR (y XOR z)" 
       
   230   apply (auto simp: bbw_assocs [symmetric])
       
   231   apply (auto simp: bin_ops_comm)
       
   232   done
       
   233 
       
   234 lemma bbw_not_dist: 
       
   235   "!!y::int. NOT (x OR y) = (NOT x) AND (NOT y)" 
       
   236   "!!y::int. NOT (x AND y) = (NOT x) OR (NOT y)"
       
   237   apply (induct x rule: bin_induct)
       
   238        apply auto
       
   239    apply (case_tac [!] y rule: bin_exhaust)
       
   240    apply (case_tac [!] bit, auto)
       
   241   done
       
   242 
       
   243 lemma bbw_oa_dist: 
       
   244   "!!y z::int. (x AND y) OR z = 
       
   245           (x OR z) AND (y OR z)"
       
   246   apply (induct x rule: bin_induct)
       
   247     apply auto
       
   248   apply (case_tac y rule: bin_exhaust)
       
   249   apply (case_tac z rule: bin_exhaust)
       
   250   apply (case_tac ba, auto)
       
   251   done
       
   252 
       
   253 lemma bbw_ao_dist: 
       
   254   "!!y z::int. (x OR y) AND z = 
       
   255           (x AND z) OR (y AND z)"
       
   256    apply (induct x rule: bin_induct)
       
   257     apply auto
       
   258   apply (case_tac y rule: bin_exhaust)
       
   259   apply (case_tac z rule: bin_exhaust)
       
   260   apply (case_tac ba, auto)
       
   261   done
       
   262 
       
   263 declare bin_ops_comm [simp] bbw_assocs [simp] 
       
   264 
       
   265 lemma plus_and_or [rule_format]:
       
   266   "ALL y::int. (x AND y) + (x OR y) = x + y"
       
   267   apply (induct x rule: bin_induct)
       
   268     apply clarsimp
       
   269    apply clarsimp
       
   270   apply clarsimp
       
   271   apply (case_tac y rule: bin_exhaust)
       
   272   apply clarsimp
       
   273   apply (unfold Bit_def)
       
   274   apply clarsimp
       
   275   apply (erule_tac x = "x" in allE)
       
   276   apply (simp split: bit.split)
       
   277   done
       
   278 
       
   279 lemma le_int_or:
       
   280   "!!x.  bin_sign y = Numeral.Pls ==> x <= x OR y"
       
   281   apply (induct y rule: bin_induct)
       
   282     apply clarsimp
       
   283    apply clarsimp
       
   284   apply (case_tac x rule: bin_exhaust)
       
   285   apply (case_tac b)
       
   286    apply (case_tac [!] bit)
       
   287      apply (auto simp: less_eq_numeral_code)
       
   288   done
       
   289 
       
   290 lemmas int_and_le =
       
   291   xtr3 [OF bbw_ao_absorbs (2) [THEN conjunct2, symmetric] le_int_or] ;
       
   292 
       
   293 lemma bin_nth_ops:
       
   294   "!!x y. bin_nth (x AND y) n = (bin_nth x n & bin_nth y n)" 
       
   295   "!!x y. bin_nth (x OR y) n = (bin_nth x n | bin_nth y n)"
       
   296   "!!x y. bin_nth (x XOR y) n = (bin_nth x n ~= bin_nth y n)" 
       
   297   "!!x. bin_nth (NOT x) n = (~ bin_nth x n)"
       
   298   apply (induct n)
       
   299          apply safe
       
   300                          apply (case_tac [!] x rule: bin_exhaust)
       
   301                          apply simp_all
       
   302                       apply (case_tac [!] y rule: bin_exhaust)
       
   303                       apply simp_all
       
   304         apply (auto dest: not_B1_is_B0 intro: B1_ass_B0)
       
   305   done
       
   306 
       
   307 (* interaction between bit-wise and arithmetic *)
       
   308 (* good example of bin_induction *)
       
   309 lemma bin_add_not: "x + NOT x = Numeral.Min"
       
   310   apply (induct x rule: bin_induct)
       
   311     apply clarsimp
       
   312    apply clarsimp
       
   313   apply (case_tac bit, auto)
       
   314   done
       
   315 
       
   316 (* truncating results of bit-wise operations *)
       
   317 lemma bin_trunc_ao: 
       
   318   "!!x y. (bintrunc n x) AND (bintrunc n y) = bintrunc n (x AND y)" 
       
   319   "!!x y. (bintrunc n x) OR (bintrunc n y) = bintrunc n (x OR y)"
       
   320   apply (induct n)
       
   321       apply auto
       
   322       apply (case_tac [!] x rule: bin_exhaust)
       
   323       apply (case_tac [!] y rule: bin_exhaust)
       
   324       apply auto
       
   325   done
       
   326 
       
   327 lemma bin_trunc_xor: 
       
   328   "!!x y. bintrunc n (bintrunc n x XOR bintrunc n y) = 
       
   329           bintrunc n (x XOR y)"
       
   330   apply (induct n)
       
   331    apply auto
       
   332    apply (case_tac [!] x rule: bin_exhaust)
       
   333    apply (case_tac [!] y rule: bin_exhaust)
       
   334    apply auto
       
   335   done
       
   336 
       
   337 lemma bin_trunc_not: 
       
   338   "!!x. bintrunc n (NOT (bintrunc n x)) = bintrunc n (NOT x)"
       
   339   apply (induct n)
       
   340    apply auto
       
   341    apply (case_tac [!] x rule: bin_exhaust)
       
   342    apply auto
       
   343   done
       
   344 
       
   345 (* want theorems of the form of bin_trunc_xor *)
       
   346 lemma bintr_bintr_i:
       
   347   "x = bintrunc n y ==> bintrunc n x = bintrunc n y"
       
   348   by auto
       
   349 
       
   350 lemmas bin_trunc_and = bin_trunc_ao(1) [THEN bintr_bintr_i]
       
   351 lemmas bin_trunc_or = bin_trunc_ao(2) [THEN bintr_bintr_i]
       
   352 
       
   353 subsection {* Setting and clearing bits *}
       
   354 
    31 consts
   355 consts
    32 (*
       
    33   int_and :: "int => int => int"
       
    34   int_or :: "int => int => int"
       
    35   bit_not :: "bit => bit"
       
    36   bit_and :: "bit => bit => bit"
       
    37   bit_or :: "bit => bit => bit"
       
    38   bit_xor :: "bit => bit => bit"
       
    39   int_not :: "int => int"
       
    40   int_xor :: "int => int => int"
       
    41 *)
       
    42   bin_sc :: "nat => bit => int => int"
   356   bin_sc :: "nat => bit => int => int"
    43 
       
    44 (*
       
    45 primrec
       
    46   B0 : "bit_not bit.B0 = bit.B1"
       
    47   B1 : "bit_not bit.B1 = bit.B0"
       
    48 
       
    49 primrec
       
    50   B1 : "bit_xor bit.B1 x = bit_not x"
       
    51   B0 : "bit_xor bit.B0 x = x"
       
    52 
       
    53 primrec
       
    54   B1 : "bit_or bit.B1 x = bit.B1"
       
    55   B0 : "bit_or bit.B0 x = x"
       
    56 
       
    57 primrec
       
    58   B0 : "bit_and bit.B0 x = bit.B0"
       
    59   B1 : "bit_and bit.B1 x = x"
       
    60 *)
       
    61 
   357 
    62 primrec
   358 primrec
    63   Z : "bin_sc 0 b w = bin_rest w BIT b"
   359   Z : "bin_sc 0 b w = bin_rest w BIT b"
    64   Suc :
   360   Suc :
    65     "bin_sc (Suc n) b w = bin_sc n b (bin_rest w) BIT bin_last w"
   361     "bin_sc (Suc n) b w = bin_sc n b (bin_rest w) BIT bin_last w"
    66 
   362 
    67 (*
   363 (** nth bit, set/clear **)
    68 defs (overloaded)
   364 
    69   int_not_def : "int_not == bin_rec Numeral.Min Numeral.Pls 
   365 lemma bin_nth_sc [simp]: 
    70     (%w b s. s BIT bit_not b)"
   366   "!!w. bin_nth (bin_sc n b w) n = (b = bit.B1)"
    71     int_and_def : "int_and == bin_rec (%x. Numeral.Pls) (%y. y) 
   367   by (induct n)  auto
    72     (%w b s y. s (bin_rest y) BIT (bit_and b (bin_last y)))"
   368 
    73   int_or_def : "int_or == bin_rec (%x. x) (%y. Numeral.Min) 
   369 lemma bin_sc_sc_same [simp]: 
    74     (%w b s y. s (bin_rest y) BIT (bit_or b (bin_last y)))"
   370   "!!w. bin_sc n c (bin_sc n b w) = bin_sc n c w"
    75   int_xor_def : "int_xor == bin_rec (%x. x) int_not 
   371   by (induct n) auto
    76     (%w b s y. s (bin_rest y) BIT (bit_xor b (bin_last y)))"
   372 
    77 *)
   373 lemma bin_sc_sc_diff:
       
   374   "!!w m. m ~= n ==> 
       
   375     bin_sc m c (bin_sc n b w) = bin_sc n b (bin_sc m c w)"
       
   376   apply (induct n)
       
   377    apply safe
       
   378    apply (case_tac [!] m)
       
   379      apply auto
       
   380   done
       
   381 
       
   382 lemma bin_nth_sc_gen: 
       
   383   "!!w m. bin_nth (bin_sc n b w) m = (if m = n then b = bit.B1 else bin_nth w m)"
       
   384   by (induct n) (case_tac [!] m, auto)
       
   385   
       
   386 lemma bin_sc_nth [simp]:
       
   387   "!!w. (bin_sc n (If (bin_nth w n) bit.B1 bit.B0) w) = w"
       
   388   by (induct n) auto
       
   389 
       
   390 lemma bin_sign_sc [simp]:
       
   391   "!!w. bin_sign (bin_sc n b w) = bin_sign w"
       
   392   by (induct n) auto
       
   393   
       
   394 lemma bin_sc_bintr [simp]: 
       
   395   "!!w m. bintrunc m (bin_sc n x (bintrunc m (w))) = bintrunc m (bin_sc n x w)"
       
   396   apply (induct n)
       
   397    apply (case_tac [!] w rule: bin_exhaust)
       
   398    apply (case_tac [!] m, auto)
       
   399   done
       
   400 
       
   401 lemma bin_clr_le:
       
   402   "!!w. bin_sc n bit.B0 w <= w"
       
   403   apply (induct n) 
       
   404    apply (case_tac [!] w rule: bin_exhaust)
       
   405    apply auto
       
   406    apply (unfold Bit_def)
       
   407    apply (simp_all split: bit.split)
       
   408   done
       
   409 
       
   410 lemma bin_set_ge:
       
   411   "!!w. bin_sc n bit.B1 w >= w"
       
   412   apply (induct n) 
       
   413    apply (case_tac [!] w rule: bin_exhaust)
       
   414    apply auto
       
   415    apply (unfold Bit_def)
       
   416    apply (simp_all split: bit.split)
       
   417   done
       
   418 
       
   419 lemma bintr_bin_clr_le:
       
   420   "!!w m. bintrunc n (bin_sc m bit.B0 w) <= bintrunc n w"
       
   421   apply (induct n)
       
   422    apply simp
       
   423   apply (case_tac w rule: bin_exhaust)
       
   424   apply (case_tac m)
       
   425    apply auto
       
   426    apply (unfold Bit_def)
       
   427    apply (simp_all split: bit.split)
       
   428   done
       
   429 
       
   430 lemma bintr_bin_set_ge:
       
   431   "!!w m. bintrunc n (bin_sc m bit.B1 w) >= bintrunc n w"
       
   432   apply (induct n)
       
   433    apply simp
       
   434   apply (case_tac w rule: bin_exhaust)
       
   435   apply (case_tac m)
       
   436    apply auto
       
   437    apply (unfold Bit_def)
       
   438    apply (simp_all split: bit.split)
       
   439   done
       
   440 
       
   441 lemma bin_sc_FP [simp]: "bin_sc n bit.B0 Numeral.Pls = Numeral.Pls"
       
   442   by (induct n) auto
       
   443 
       
   444 lemma bin_sc_TM [simp]: "bin_sc n bit.B1 Numeral.Min = Numeral.Min"
       
   445   by (induct n) auto
       
   446   
       
   447 lemmas bin_sc_simps = bin_sc.Z bin_sc.Suc bin_sc_TM bin_sc_FP
       
   448 
       
   449 lemma bin_sc_minus:
       
   450   "0 < n ==> bin_sc (Suc (n - 1)) b w = bin_sc n b w"
       
   451   by auto
       
   452 
       
   453 lemmas bin_sc_Suc_minus = 
       
   454   trans [OF bin_sc_minus [symmetric] bin_sc.Suc, standard]
       
   455 
       
   456 lemmas bin_sc_Suc_pred [simp] = 
       
   457   bin_sc_Suc_minus [of "number_of bin", simplified nobm1, standard]
       
   458 
       
   459 subsection {* Operations on lists of booleans *}
    78 
   460 
    79 consts
   461 consts
    80   bin_to_bl :: "nat => int => bool list"
   462   bin_to_bl :: "nat => int => bool list"
    81   bin_to_bl_aux :: "nat => int => bool list => bool list"
   463   bin_to_bl_aux :: "nat => int => bool list => bool list"
    82   bl_to_bin :: "bool list => int"
   464   bl_to_bin :: "bool list => int"
   114     case xs of [] => fill # takefill fill n xs
   496     case xs of [] => fill # takefill fill n xs
   115       | y # ys => y # takefill fill n ys)"
   497       | y # ys => y # takefill fill n ys)"
   116 
   498 
   117 defs
   499 defs
   118   app2_def : "app2 f as bs == map (split f) (zip as bs)"
   500   app2_def : "app2 f as bs == map (split f) (zip as bs)"
       
   501 
       
   502 subsection {* Splitting and concatenation *}
   119 
   503 
   120 -- "rcat and rsplit"
   504 -- "rcat and rsplit"
   121 consts
   505 consts
   122   bin_rcat :: "nat => int list => int"
   506   bin_rcat :: "nat => int list => int"
   123   bin_rsplit_aux :: "nat * int list * nat * int => int list"
   507   bin_rsplit_aux :: "nat * int list * nat * int => int list"
   141   bin_rcat_def : "bin_rcat n bs == foldl (%u v. bin_cat u n v) Numeral.Pls bs"
   525   bin_rcat_def : "bin_rcat n bs == foldl (%u v. bin_cat u n v) Numeral.Pls bs"
   142   bin_rsplit_def : "bin_rsplit n w == bin_rsplit_aux (n, [], w)"
   526   bin_rsplit_def : "bin_rsplit n w == bin_rsplit_aux (n, [], w)"
   143   bin_rsplitl_def : "bin_rsplitl n w == bin_rsplitl_aux (n, [], w)"
   527   bin_rsplitl_def : "bin_rsplitl n w == bin_rsplitl_aux (n, [], w)"
   144      
   528      
   145  
   529  
   146 lemma int_not_simps [simp]:
       
   147   "NOT Numeral.Pls = Numeral.Min"
       
   148   "NOT Numeral.Min = Numeral.Pls"
       
   149   "NOT (w BIT b) = (NOT w) BIT (NOT b)"
       
   150   by (unfold int_not_def) (auto intro: bin_rec_simps)
       
   151 
       
   152 lemma bit_extra_simps [simp]: 
       
   153   "x AND bit.B0 = bit.B0"
       
   154   "x AND bit.B1 = x"
       
   155   "x OR bit.B1 = bit.B1"
       
   156   "x OR bit.B0 = x"
       
   157   "x XOR bit.B1 = NOT x"
       
   158   "x XOR bit.B0 = x"
       
   159   by (cases x, auto)+
       
   160 
       
   161 lemma bit_ops_comm: 
       
   162   "(x::bit) AND y = y AND x"
       
   163   "(x::bit) OR y = y OR x"
       
   164   "(x::bit) XOR y = y XOR x"
       
   165   by (cases y, auto)+
       
   166 
       
   167 lemma bit_ops_same [simp]: 
       
   168   "(x::bit) AND x = x"
       
   169   "(x::bit) OR x = x"
       
   170   "(x::bit) XOR x = bit.B0"
       
   171   by (cases x, auto)+
       
   172 
       
   173 lemma bit_not_not [simp]: "NOT (NOT (x::bit)) = x"
       
   174   by (cases x) auto
       
   175 
       
   176 lemma int_xor_Pls [simp]: 
       
   177   "Numeral.Pls XOR x = x"
       
   178   unfolding int_xor_def by (simp add: bin_rec_PM)
       
   179 
       
   180 lemma int_xor_Min [simp]: 
       
   181   "Numeral.Min XOR x = NOT x"
       
   182   unfolding int_xor_def by (simp add: bin_rec_PM)
       
   183 
       
   184 lemma int_xor_Bits [simp]: 
       
   185   "(x BIT b) XOR (y BIT c) = (x XOR y) BIT (b XOR c)"
       
   186   apply (unfold int_xor_def)
       
   187   apply (rule bin_rec_simps (1) [THEN fun_cong, THEN trans])
       
   188     apply (rule ext, simp)
       
   189    prefer 2
       
   190    apply simp
       
   191   apply (rule ext)
       
   192   apply (simp add: int_not_simps [symmetric])
       
   193   done
       
   194 
       
   195 lemma int_xor_x_simps':
       
   196   "w XOR (Numeral.Pls BIT bit.B0) = w"
       
   197   "w XOR (Numeral.Min BIT bit.B1) = NOT w"
       
   198   apply (induct w rule: bin_induct)
       
   199        apply simp_all[4]
       
   200    apply (unfold int_xor_Bits)
       
   201    apply clarsimp+
       
   202   done
       
   203 
       
   204 lemmas int_xor_extra_simps [simp] = int_xor_x_simps' [simplified arith_simps]
       
   205 
       
   206 lemma int_or_Pls [simp]: 
       
   207   "Numeral.Pls OR x = x"
       
   208   by (unfold int_or_def) (simp add: bin_rec_PM)
       
   209   
       
   210 lemma int_or_Min [simp]:
       
   211   "Numeral.Min OR x = Numeral.Min"
       
   212   by (unfold int_or_def) (simp add: bin_rec_PM)
       
   213 
       
   214 lemma int_or_Bits [simp]: 
       
   215   "(x BIT b) OR (y BIT c) = (x OR y) BIT (b OR c)"
       
   216   unfolding int_or_def by (simp add: bin_rec_simps)
       
   217 
       
   218 lemma int_or_x_simps': 
       
   219   "w OR (Numeral.Pls BIT bit.B0) = w"
       
   220   "w OR (Numeral.Min BIT bit.B1) = Numeral.Min"
       
   221   apply (induct w rule: bin_induct)
       
   222        apply simp_all[4]
       
   223    apply (unfold int_or_Bits)
       
   224    apply clarsimp+
       
   225   done
       
   226 
       
   227 lemmas int_or_extra_simps [simp] = int_or_x_simps' [simplified arith_simps]
       
   228 
       
   229 
       
   230 lemma int_and_Pls [simp]:
       
   231   "Numeral.Pls AND x = Numeral.Pls"
       
   232   unfolding int_and_def by (simp add: bin_rec_PM)
       
   233 
       
   234 lemma int_and_Min [simp]:
       
   235   "Numeral.Min AND x = x"
       
   236   unfolding int_and_def by (simp add: bin_rec_PM)
       
   237 
       
   238 lemma int_and_Bits [simp]: 
       
   239   "(x BIT b) AND (y BIT c) = (x AND y) BIT (b AND c)" 
       
   240   unfolding int_and_def by (simp add: bin_rec_simps)
       
   241 
       
   242 lemma int_and_x_simps': 
       
   243   "w AND (Numeral.Pls BIT bit.B0) = Numeral.Pls"
       
   244   "w AND (Numeral.Min BIT bit.B1) = w"
       
   245   apply (induct w rule: bin_induct)
       
   246        apply simp_all[4]
       
   247    apply (unfold int_and_Bits)
       
   248    apply clarsimp+
       
   249   done
       
   250 
       
   251 lemmas int_and_extra_simps [simp] = int_and_x_simps' [simplified arith_simps]
       
   252 
       
   253 (* commutativity of the above *)
       
   254 lemma bin_ops_comm:
       
   255   shows
       
   256   int_and_comm: "!!y::int. x AND y = y AND x" and
       
   257   int_or_comm:  "!!y::int. x OR y = y OR x" and
       
   258   int_xor_comm: "!!y::int. x XOR y = y XOR x"
       
   259   apply (induct x rule: bin_induct)
       
   260           apply simp_all[6]
       
   261     apply (case_tac y rule: bin_exhaust, simp add: bit_ops_comm)+
       
   262   done
       
   263 
       
   264 lemma bin_ops_same [simp]:
       
   265   "(x::int) AND x = x" 
       
   266   "(x::int) OR x = x" 
       
   267   "(x::int) XOR x = Numeral.Pls"
       
   268   by (induct x rule: bin_induct) auto
       
   269 
       
   270 lemma int_not_not [simp]: "NOT (NOT (x::int)) = x"
       
   271   by (induct x rule: bin_induct) auto
       
   272 
       
   273 lemmas bin_log_esimps = 
       
   274   int_and_extra_simps  int_or_extra_simps  int_xor_extra_simps
       
   275   int_and_Pls int_and_Min  int_or_Pls int_or_Min  int_xor_Pls int_xor_Min
       
   276 
       
   277 (* potential for looping *)
   530 (* potential for looping *)
   278 declare bin_rsplit_aux.simps [simp del]
   531 declare bin_rsplit_aux.simps [simp del]
   279 declare bin_rsplitl_aux.simps [simp del]
   532 declare bin_rsplitl_aux.simps [simp del]
   280 
       
   281 
   533 
   282 lemma bin_sign_cat: 
   534 lemma bin_sign_cat: 
   283   "!!y. bin_sign (bin_cat x n y) = bin_sign x"
   535   "!!y. bin_sign (bin_cat x n y) = bin_sign x"
   284   by (induct n) auto
   536   by (induct n) auto
   285 
   537 
   389   apply (simp add: Bit_def zmod_zmult_zmult1 p1mod22k
   641   apply (simp add: Bit_def zmod_zmult_zmult1 p1mod22k
   390               split: bit.split 
   642               split: bit.split 
   391               cong: number_of_False_cong)
   643               cong: number_of_False_cong)
   392   done 
   644   done 
   393 
   645 
   394 
   646 subsection {* Miscellaneous lemmas *}
   395 (* basic properties of logical (bit-wise) operations *)
       
   396 
       
   397 lemma bbw_ao_absorb: 
       
   398   "!!y::int. x AND (y OR x) = x & x OR (y AND x) = x"
       
   399   apply (induct x rule: bin_induct)
       
   400     apply auto 
       
   401    apply (case_tac [!] y rule: bin_exhaust)
       
   402    apply auto
       
   403    apply (case_tac [!] bit)
       
   404      apply auto
       
   405   done
       
   406 
       
   407 lemma bbw_ao_absorbs_other:
       
   408   "x AND (x OR y) = x \<and> (y AND x) OR x = (x::int)"
       
   409   "(y OR x) AND x = x \<and> x OR (x AND y) = (x::int)"
       
   410   "(x OR y) AND x = x \<and> (x AND y) OR x = (x::int)"
       
   411   apply (auto simp: bbw_ao_absorb int_or_comm)  
       
   412       apply (subst int_or_comm)
       
   413     apply (simp add: bbw_ao_absorb)
       
   414    apply (subst int_and_comm)
       
   415    apply (subst int_or_comm)
       
   416    apply (simp add: bbw_ao_absorb)
       
   417   apply (subst int_and_comm)
       
   418   apply (simp add: bbw_ao_absorb)
       
   419   done
       
   420 
       
   421 lemmas bbw_ao_absorbs [simp] = bbw_ao_absorb bbw_ao_absorbs_other
       
   422 
       
   423 lemma int_xor_not:
       
   424   "!!y::int. (NOT x) XOR y = NOT (x XOR y) & 
       
   425         x XOR (NOT y) = NOT (x XOR y)"
       
   426   apply (induct x rule: bin_induct)
       
   427     apply auto
       
   428    apply (case_tac y rule: bin_exhaust, auto, 
       
   429           case_tac b, auto)+
       
   430   done
       
   431 
       
   432 lemma bbw_assocs': 
       
   433   "!!y z::int. (x AND y) AND z = x AND (y AND z) & 
       
   434           (x OR y) OR z = x OR (y OR z) & 
       
   435           (x XOR y) XOR z = x XOR (y XOR z)"
       
   436   apply (induct x rule: bin_induct)
       
   437     apply (auto simp: int_xor_not)
       
   438     apply (case_tac [!] y rule: bin_exhaust)
       
   439     apply (case_tac [!] z rule: bin_exhaust)
       
   440     apply (case_tac [!] bit)
       
   441        apply (case_tac [!] b)
       
   442              apply auto
       
   443   done
       
   444 
       
   445 lemma int_and_assoc:
       
   446   "(x AND y) AND (z::int) = x AND (y AND z)"
       
   447   by (simp add: bbw_assocs')
       
   448 
       
   449 lemma int_or_assoc:
       
   450   "(x OR y) OR (z::int) = x OR (y OR z)"
       
   451   by (simp add: bbw_assocs')
       
   452 
       
   453 lemma int_xor_assoc:
       
   454   "(x XOR y) XOR (z::int) = x XOR (y XOR z)"
       
   455   by (simp add: bbw_assocs')
       
   456 
       
   457 lemmas bbw_assocs = int_and_assoc int_or_assoc int_xor_assoc
       
   458 
       
   459 lemma bbw_lcs [simp]: 
       
   460   "(y::int) AND (x AND z) = x AND (y AND z)"
       
   461   "(y::int) OR (x OR z) = x OR (y OR z)"
       
   462   "(y::int) XOR (x XOR z) = x XOR (y XOR z)" 
       
   463   apply (auto simp: bbw_assocs [symmetric])
       
   464   apply (auto simp: bin_ops_comm)
       
   465   done
       
   466 
       
   467 lemma bbw_not_dist: 
       
   468   "!!y::int. NOT (x OR y) = (NOT x) AND (NOT y)" 
       
   469   "!!y::int. NOT (x AND y) = (NOT x) OR (NOT y)"
       
   470   apply (induct x rule: bin_induct)
       
   471        apply auto
       
   472    apply (case_tac [!] y rule: bin_exhaust)
       
   473    apply (case_tac [!] bit, auto)
       
   474   done
       
   475 
       
   476 lemma bbw_oa_dist: 
       
   477   "!!y z::int. (x AND y) OR z = 
       
   478           (x OR z) AND (y OR z)"
       
   479   apply (induct x rule: bin_induct)
       
   480     apply auto
       
   481   apply (case_tac y rule: bin_exhaust)
       
   482   apply (case_tac z rule: bin_exhaust)
       
   483   apply (case_tac ba, auto)
       
   484   done
       
   485 
       
   486 lemma bbw_ao_dist: 
       
   487   "!!y z::int. (x OR y) AND z = 
       
   488           (x AND z) OR (y AND z)"
       
   489    apply (induct x rule: bin_induct)
       
   490     apply auto
       
   491   apply (case_tac y rule: bin_exhaust)
       
   492   apply (case_tac z rule: bin_exhaust)
       
   493   apply (case_tac ba, auto)
       
   494   done
       
   495 
       
   496 declare bin_ops_comm [simp] bbw_assocs [simp] 
       
   497 
       
   498 lemma plus_and_or [rule_format]:
       
   499   "ALL y::int. (x AND y) + (x OR y) = x + y"
       
   500   apply (induct x rule: bin_induct)
       
   501     apply clarsimp
       
   502    apply clarsimp
       
   503   apply clarsimp
       
   504   apply (case_tac y rule: bin_exhaust)
       
   505   apply clarsimp
       
   506   apply (unfold Bit_def)
       
   507   apply clarsimp
       
   508   apply (erule_tac x = "x" in allE)
       
   509   apply (simp split: bit.split)
       
   510   done
       
   511 
       
   512 lemma le_int_or:
       
   513   "!!x.  bin_sign y = Numeral.Pls ==> x <= x OR y"
       
   514   apply (induct y rule: bin_induct)
       
   515     apply clarsimp
       
   516    apply clarsimp
       
   517   apply (case_tac x rule: bin_exhaust)
       
   518   apply (case_tac b)
       
   519    apply (case_tac [!] bit)
       
   520      apply (auto simp: less_eq_numeral_code)
       
   521   done
       
   522 
       
   523 lemmas int_and_le =
       
   524   xtr3 [OF bbw_ao_absorbs (2) [THEN conjunct2, symmetric] le_int_or] ;
       
   525 
       
   526 (** nth bit, set/clear **)
       
   527 
       
   528 lemma bin_nth_sc [simp]: 
       
   529   "!!w. bin_nth (bin_sc n b w) n = (b = bit.B1)"
       
   530   by (induct n)  auto
       
   531 
       
   532 lemma bin_sc_sc_same [simp]: 
       
   533   "!!w. bin_sc n c (bin_sc n b w) = bin_sc n c w"
       
   534   by (induct n) auto
       
   535 
       
   536 lemma bin_sc_sc_diff:
       
   537   "!!w m. m ~= n ==> 
       
   538     bin_sc m c (bin_sc n b w) = bin_sc n b (bin_sc m c w)"
       
   539   apply (induct n)
       
   540    apply safe
       
   541    apply (case_tac [!] m)
       
   542      apply auto
       
   543   done
       
   544 
       
   545 lemma bin_nth_sc_gen: 
       
   546   "!!w m. bin_nth (bin_sc n b w) m = (if m = n then b = bit.B1 else bin_nth w m)"
       
   547   by (induct n) (case_tac [!] m, auto)
       
   548   
       
   549 lemma bin_sc_nth [simp]:
       
   550   "!!w. (bin_sc n (If (bin_nth w n) bit.B1 bit.B0) w) = w"
       
   551   by (induct n) auto
       
   552 
       
   553 lemma bin_sign_sc [simp]:
       
   554   "!!w. bin_sign (bin_sc n b w) = bin_sign w"
       
   555   by (induct n) auto
       
   556   
       
   557 lemma bin_sc_bintr [simp]: 
       
   558   "!!w m. bintrunc m (bin_sc n x (bintrunc m (w))) = bintrunc m (bin_sc n x w)"
       
   559   apply (induct n)
       
   560    apply (case_tac [!] w rule: bin_exhaust)
       
   561    apply (case_tac [!] m, auto)
       
   562   done
       
   563 
       
   564 lemma bin_clr_le:
       
   565   "!!w. bin_sc n bit.B0 w <= w"
       
   566   apply (induct n) 
       
   567    apply (case_tac [!] w rule: bin_exhaust)
       
   568    apply auto
       
   569    apply (unfold Bit_def)
       
   570    apply (simp_all split: bit.split)
       
   571   done
       
   572 
       
   573 lemma bin_set_ge:
       
   574   "!!w. bin_sc n bit.B1 w >= w"
       
   575   apply (induct n) 
       
   576    apply (case_tac [!] w rule: bin_exhaust)
       
   577    apply auto
       
   578    apply (unfold Bit_def)
       
   579    apply (simp_all split: bit.split)
       
   580   done
       
   581 
       
   582 lemma bintr_bin_clr_le:
       
   583   "!!w m. bintrunc n (bin_sc m bit.B0 w) <= bintrunc n w"
       
   584   apply (induct n)
       
   585    apply simp
       
   586   apply (case_tac w rule: bin_exhaust)
       
   587   apply (case_tac m)
       
   588    apply auto
       
   589    apply (unfold Bit_def)
       
   590    apply (simp_all split: bit.split)
       
   591   done
       
   592 
       
   593 lemma bintr_bin_set_ge:
       
   594   "!!w m. bintrunc n (bin_sc m bit.B1 w) >= bintrunc n w"
       
   595   apply (induct n)
       
   596    apply simp
       
   597   apply (case_tac w rule: bin_exhaust)
       
   598   apply (case_tac m)
       
   599    apply auto
       
   600    apply (unfold Bit_def)
       
   601    apply (simp_all split: bit.split)
       
   602   done
       
   603 
       
   604 lemma bin_nth_ops:
       
   605   "!!x y. bin_nth (x AND y) n = (bin_nth x n & bin_nth y n)" 
       
   606   "!!x y. bin_nth (x OR y) n = (bin_nth x n | bin_nth y n)"
       
   607   "!!x y. bin_nth (x XOR y) n = (bin_nth x n ~= bin_nth y n)" 
       
   608   "!!x. bin_nth (NOT x) n = (~ bin_nth x n)"
       
   609   apply (induct n)
       
   610          apply safe
       
   611                          apply (case_tac [!] x rule: bin_exhaust)
       
   612                          apply simp_all
       
   613                       apply (case_tac [!] y rule: bin_exhaust)
       
   614                       apply simp_all
       
   615         apply (auto dest: not_B1_is_B0 intro: B1_ass_B0)
       
   616   done
       
   617 
       
   618 lemma bin_sc_FP [simp]: "bin_sc n bit.B0 Numeral.Pls = Numeral.Pls"
       
   619   by (induct n) auto
       
   620 
       
   621 lemma bin_sc_TM [simp]: "bin_sc n bit.B1 Numeral.Min = Numeral.Min"
       
   622   by (induct n) auto
       
   623   
       
   624 lemmas bin_sc_simps = bin_sc.Z bin_sc.Suc bin_sc_TM bin_sc_FP
       
   625 
       
   626 lemma bin_sc_minus:
       
   627   "0 < n ==> bin_sc (Suc (n - 1)) b w = bin_sc n b w"
       
   628   by auto
       
   629 
       
   630 lemmas bin_sc_Suc_minus = 
       
   631   trans [OF bin_sc_minus [symmetric] bin_sc.Suc, standard]
       
   632 
       
   633 lemmas bin_sc_Suc_pred [simp] = 
       
   634   bin_sc_Suc_minus [of "number_of bin", simplified nobm1, standard]
       
   635 
       
   636 (* interaction between bit-wise and arithmetic *)
       
   637 (* good example of bin_induction *)
       
   638 lemma bin_add_not: "x + NOT x = Numeral.Min"
       
   639   apply (induct x rule: bin_induct)
       
   640     apply clarsimp
       
   641    apply clarsimp
       
   642   apply (case_tac bit, auto)
       
   643   done
       
   644 
       
   645 (* truncating results of bit-wise operations *)
       
   646 lemma bin_trunc_ao: 
       
   647   "!!x y. (bintrunc n x) AND (bintrunc n y) = bintrunc n (x AND y)" 
       
   648   "!!x y. (bintrunc n x) OR (bintrunc n y) = bintrunc n (x OR y)"
       
   649   apply (induct n)
       
   650       apply auto
       
   651       apply (case_tac [!] x rule: bin_exhaust)
       
   652       apply (case_tac [!] y rule: bin_exhaust)
       
   653       apply auto
       
   654   done
       
   655 
       
   656 lemma bin_trunc_xor: 
       
   657   "!!x y. bintrunc n (bintrunc n x XOR bintrunc n y) = 
       
   658           bintrunc n (x XOR y)"
       
   659   apply (induct n)
       
   660    apply auto
       
   661    apply (case_tac [!] x rule: bin_exhaust)
       
   662    apply (case_tac [!] y rule: bin_exhaust)
       
   663    apply auto
       
   664   done
       
   665 
       
   666 lemma bin_trunc_not: 
       
   667   "!!x. bintrunc n (NOT (bintrunc n x)) = bintrunc n (NOT x)"
       
   668   apply (induct n)
       
   669    apply auto
       
   670    apply (case_tac [!] x rule: bin_exhaust)
       
   671    apply auto
       
   672   done
       
   673 
       
   674 (* want theorems of the form of bin_trunc_xor *)
       
   675 lemma bintr_bintr_i:
       
   676   "x = bintrunc n y ==> bintrunc n x = bintrunc n y"
       
   677   by auto
       
   678 
       
   679 lemmas bin_trunc_and = bin_trunc_ao(1) [THEN bintr_bintr_i]
       
   680 lemmas bin_trunc_or = bin_trunc_ao(2) [THEN bintr_bintr_i]
       
   681 
   647 
   682 lemma nth_2p_bin: 
   648 lemma nth_2p_bin: 
   683   "!!m. bin_nth (2 ^ n) m = (m = n)"
   649   "!!m. bin_nth (2 ^ n) m = (m = n)"
   684   apply (induct n)
   650   apply (induct n)
   685    apply clarsimp
   651    apply clarsimp