318 primrec bin_nth :: "int \<Rightarrow> nat \<Rightarrow> bool" |
318 primrec bin_nth :: "int \<Rightarrow> nat \<Rightarrow> bool" |
319 where |
319 where |
320 Z: "bin_nth w 0 \<longleftrightarrow> bin_last w" |
320 Z: "bin_nth w 0 \<longleftrightarrow> bin_last w" |
321 | Suc: "bin_nth w (Suc n) \<longleftrightarrow> bin_nth (bin_rest w) n" |
321 | Suc: "bin_nth w (Suc n) \<longleftrightarrow> bin_nth (bin_rest w) n" |
322 |
322 |
323 lemma bin_nth_eq_mod: |
323 lemma bin_nth_iff: |
324 "bin_nth w n \<longleftrightarrow> odd (w div 2 ^ n)" |
324 \<open>bin_nth = bit\<close> |
325 by (induction n arbitrary: w) (simp_all add: bin_last_def bin_rest_def odd_iff_mod_2_eq_one zdiv_zmult2_eq) |
325 proof (rule ext)+ |
|
326 fix k and n |
|
327 show \<open>bin_nth k n \<longleftrightarrow> bit k n\<close> |
|
328 by (induction n arbitrary: k) (simp_all add: bit_Suc bin_rest_def) |
|
329 qed |
326 |
330 |
327 lemma bin_nth_eq_iff: "bin_nth x = bin_nth y \<longleftrightarrow> x = y" |
331 lemma bin_nth_eq_iff: "bin_nth x = bin_nth y \<longleftrightarrow> x = y" |
328 proof - |
332 by (simp add: bin_nth_iff bit_eq_iff fun_eq_iff) |
329 have bin_nth_lem [rule_format]: "\<forall>y. bin_nth x = bin_nth y \<longrightarrow> x = y" |
|
330 apply (induct x rule: bin_induct) |
|
331 apply safe |
|
332 apply (erule rev_mp) |
|
333 apply (induct_tac y rule: bin_induct) |
|
334 apply safe |
|
335 apply (drule_tac x=0 in fun_cong, force) |
|
336 apply (erule notE, rule ext, drule_tac x="Suc x" in fun_cong, force) |
|
337 apply (drule_tac x=0 in fun_cong, force) |
|
338 apply (erule rev_mp) |
|
339 apply (induct_tac y rule: bin_induct) |
|
340 apply safe |
|
341 apply (drule_tac x=0 in fun_cong, force) |
|
342 apply (erule notE, rule ext, drule_tac x="Suc x" in fun_cong, force) |
|
343 apply (metis Bit_eq_m1_iff Z bin_last_BIT) |
|
344 apply (case_tac y rule: bin_exhaust) |
|
345 apply clarify |
|
346 apply (erule allE) |
|
347 apply (erule impE) |
|
348 prefer 2 |
|
349 apply (erule conjI) |
|
350 apply (drule_tac x=0 in fun_cong, force) |
|
351 apply (rule ext) |
|
352 apply (drule_tac x="Suc x" for x in fun_cong, force) |
|
353 done |
|
354 show ?thesis |
|
355 by (auto elim: bin_nth_lem) |
|
356 qed |
|
357 |
333 |
358 lemma bin_eqI: |
334 lemma bin_eqI: |
359 "x = y" if "\<And>n. bin_nth x n \<longleftrightarrow> bin_nth y n" |
335 "x = y" if "\<And>n. bin_nth x n \<longleftrightarrow> bin_nth y n" |
360 using that bin_nth_eq_iff [of x y] by (simp add: fun_eq_iff) |
336 using that bin_nth_eq_iff [of x y] by (simp add: fun_eq_iff) |
361 |
337 |
440 primrec sbintrunc :: "nat \<Rightarrow> int \<Rightarrow> int" |
416 primrec sbintrunc :: "nat \<Rightarrow> int \<Rightarrow> int" |
441 where |
417 where |
442 Z : "sbintrunc 0 bin = (if bin_last bin then -1 else 0)" |
418 Z : "sbintrunc 0 bin = (if bin_last bin then -1 else 0)" |
443 | Suc : "sbintrunc (Suc n) bin = sbintrunc n (bin_rest bin) BIT (bin_last bin)" |
419 | Suc : "sbintrunc (Suc n) bin = sbintrunc n (bin_rest bin) BIT (bin_last bin)" |
444 |
420 |
|
421 lemma bintrunc_eq_take_bit: |
|
422 \<open>bintrunc = take_bit\<close> |
|
423 proof (rule ext)+ |
|
424 fix n and k |
|
425 show \<open>bintrunc n k = take_bit n k\<close> |
|
426 by (induction n arbitrary: k) (simp_all add: take_bit_Suc bin_rest_def Bit_def) |
|
427 qed |
|
428 |
445 lemma bintrunc_mod2p: "bintrunc n w = w mod 2 ^ n" |
429 lemma bintrunc_mod2p: "bintrunc n w = w mod 2 ^ n" |
446 by (induct n arbitrary: w) (auto simp add: bin_last_def bin_rest_def Bit_def zmod_zmult2_eq) |
430 by (simp add: bintrunc_eq_take_bit take_bit_eq_mod) |
447 |
431 |
448 lemma sbintrunc_mod2p: "sbintrunc n w = (w + 2 ^ n) mod 2 ^ Suc n - 2 ^ n" |
432 lemma sbintrunc_mod2p: "sbintrunc n w = (w + 2 ^ n) mod 2 ^ Suc n - 2 ^ n" |
449 proof (induction n arbitrary: w) |
433 proof (induction n arbitrary: w) |
450 case 0 |
434 case 0 |
451 then show ?case |
435 then show ?case |
837 Z: "bin_split 0 w = (w, 0)" |
821 Z: "bin_split 0 w = (w, 0)" |
838 | Suc: "bin_split (Suc n) w = |
822 | Suc: "bin_split (Suc n) w = |
839 (let (w1, w2) = bin_split n (bin_rest w) |
823 (let (w1, w2) = bin_split n (bin_rest w) |
840 in (w1, w2 BIT bin_last w))" |
824 in (w1, w2 BIT bin_last w))" |
841 |
825 |
|
826 lemma bin_split_eq_drop_bit_take_bit: |
|
827 \<open>bin_split n k = (drop_bit n k, take_bit n k)\<close> |
|
828 by (induction n arbitrary: k) |
|
829 (simp_all add: bin_rest_def Bit_def drop_bit_Suc take_bit_Suc) |
|
830 |
842 lemma [code]: |
831 lemma [code]: |
843 "bin_split (Suc n) w = (let (w1, w2) = bin_split n (bin_rest w) in (w1, w2 BIT bin_last w))" |
832 "bin_split (Suc n) w = (let (w1, w2) = bin_split n (bin_rest w) in (w1, w2 BIT bin_last w))" |
844 "bin_split 0 w = (w, 0)" |
833 "bin_split 0 w = (w, 0)" |
845 by simp_all |
834 by simp_all |
846 |
835 |
847 primrec bin_cat :: "int \<Rightarrow> nat \<Rightarrow> int \<Rightarrow> int" |
836 primrec bin_cat :: "int \<Rightarrow> nat \<Rightarrow> int \<Rightarrow> int" |
848 where |
837 where |
849 Z: "bin_cat w 0 v = w" |
838 Z: "bin_cat w 0 v = w" |
850 | Suc: "bin_cat w (Suc n) v = bin_cat w n (bin_rest v) BIT bin_last v" |
839 | Suc: "bin_cat w (Suc n) v = bin_cat w n (bin_rest v) BIT bin_last v" |
|
840 |
|
841 lemma bin_cat_eq_push_bit_add_take_bit: |
|
842 \<open>bin_cat k n l = push_bit n k + take_bit n l\<close> |
|
843 by (induction n arbitrary: k l) |
|
844 (simp_all add: bin_rest_def Bit_def take_bit_Suc push_bit_double) |
851 |
845 |
852 lemma bin_sign_cat: "bin_sign (bin_cat x n y) = bin_sign x" |
846 lemma bin_sign_cat: "bin_sign (bin_cat x n y) = bin_sign x" |
853 by (induct n arbitrary: y) auto |
847 by (induct n arbitrary: y) auto |
854 |
848 |
855 lemma bin_cat_Suc_Bit: "bin_cat w (Suc n) (v BIT b) = bin_cat w n v BIT b" |
849 lemma bin_cat_Suc_Bit: "bin_cat w (Suc n) (v BIT b) = bin_cat w n v BIT b" |
1301 definition "msb x \<longleftrightarrow> x < 0" for x :: int |
1295 definition "msb x \<longleftrightarrow> x < 0" for x :: int |
1302 |
1296 |
1303 instance .. |
1297 instance .. |
1304 |
1298 |
1305 end |
1299 end |
|
1300 |
|
1301 lemma shiftl_eq_push_bit: |
|
1302 \<open>k << n = push_bit n k\<close> for k :: int |
|
1303 by (simp add: shiftl_int_def push_bit_eq_mult) |
|
1304 |
|
1305 lemma shiftr_eq_drop_bit: |
|
1306 \<open>k >> n = drop_bit n k\<close> for k :: int |
|
1307 by (simp add: shiftr_int_def drop_bit_eq_div) |
1306 |
1308 |
1307 |
1309 |
1308 subsubsection \<open>Basic simplification rules\<close> |
1310 subsubsection \<open>Basic simplification rules\<close> |
1309 |
1311 |
1310 lemma int_not_BIT [simp]: "NOT (w BIT b) = (NOT w) BIT (\<not> b)" |
1312 lemma int_not_BIT [simp]: "NOT (w BIT b) = (NOT w) BIT (\<not> b)" |