9 header "Bool lists and integers" |
9 header "Bool lists and integers" |
10 |
10 |
11 theory Bool_List_Representation |
11 theory Bool_List_Representation |
12 imports Bit_Int |
12 imports Bit_Int |
13 begin |
13 begin |
|
14 |
|
15 definition map2 :: "('a \<Rightarrow> 'b \<Rightarrow> 'c) \<Rightarrow> 'a list \<Rightarrow> 'b list \<Rightarrow> 'c list" |
|
16 where |
|
17 "map2 f as bs = map (split f) (zip as bs)" |
|
18 |
|
19 lemma map2_Nil [simp, code]: |
|
20 "map2 f [] ys = []" |
|
21 unfolding map2_def by auto |
|
22 |
|
23 lemma map2_Nil2 [simp, code]: |
|
24 "map2 f xs [] = []" |
|
25 unfolding map2_def by auto |
|
26 |
|
27 lemma map2_Cons [simp, code]: |
|
28 "map2 f (x # xs) (y # ys) = f x y # map2 f xs ys" |
|
29 unfolding map2_def by auto |
|
30 |
14 |
31 |
15 subsection {* Operations on lists of booleans *} |
32 subsection {* Operations on lists of booleans *} |
16 |
33 |
17 primrec bl_to_bin_aux :: "bool list \<Rightarrow> int \<Rightarrow> int" where |
34 primrec bl_to_bin_aux :: "bool list \<Rightarrow> int \<Rightarrow> int" where |
18 Nil: "bl_to_bin_aux [] w = w" |
35 Nil: "bl_to_bin_aux [] w = w" |
37 primrec takefill :: "'a \<Rightarrow> nat \<Rightarrow> 'a list \<Rightarrow> 'a list" where |
54 primrec takefill :: "'a \<Rightarrow> nat \<Rightarrow> 'a list \<Rightarrow> 'a list" where |
38 Z: "takefill fill 0 xs = []" |
55 Z: "takefill fill 0 xs = []" |
39 | Suc: "takefill fill (Suc n) xs = ( |
56 | Suc: "takefill fill (Suc n) xs = ( |
40 case xs of [] => fill # takefill fill n xs |
57 case xs of [] => fill # takefill fill n xs |
41 | y # ys => y # takefill fill n ys)" |
58 | y # ys => y # takefill fill n ys)" |
42 |
|
43 definition map2 :: "('a \<Rightarrow> 'b \<Rightarrow> 'c) \<Rightarrow> 'a list \<Rightarrow> 'b list \<Rightarrow> 'c list" where |
|
44 "map2 f as bs = map (split f) (zip as bs)" |
|
45 |
|
46 lemma map2_Nil [simp]: "map2 f [] ys = []" |
|
47 unfolding map2_def by auto |
|
48 |
|
49 lemma map2_Nil2 [simp]: "map2 f xs [] = []" |
|
50 unfolding map2_def by auto |
|
51 |
|
52 lemma map2_Cons [simp]: |
|
53 "map2 f (x # xs) (y # ys) = f x y # map2 f xs ys" |
|
54 unfolding map2_def by auto |
|
55 |
59 |
56 |
60 |
57 subsection "Arithmetic in terms of bool lists" |
61 subsection "Arithmetic in terms of bool lists" |
58 |
62 |
59 text {* |
63 text {* |
312 "bl_to_bin_aux bs w < (w + 1) * (2 ^ length bs)" |
316 "bl_to_bin_aux bs w < (w + 1) * (2 ^ length bs)" |
313 apply (induct bs arbitrary: w) |
317 apply (induct bs arbitrary: w) |
314 apply clarsimp |
318 apply clarsimp |
315 apply clarsimp |
319 apply clarsimp |
316 apply safe |
320 apply safe |
317 apply (drule meta_spec, erule xtr8 [rotated], simp add: Bit_def)+ |
321 apply (drule meta_spec, erule xtrans(8) [rotated], simp add: Bit_def)+ |
318 done |
322 done |
319 |
323 |
320 lemma bl_to_bin_lt2p: "bl_to_bin bs < (2 ^ length bs)" |
324 lemma bl_to_bin_lt2p: "bl_to_bin bs < (2 ^ length bs)" |
321 apply (unfold bl_to_bin_def) |
325 apply (unfold bl_to_bin_def) |
322 apply (rule xtr1) |
326 apply (rule xtrans(1)) |
323 prefer 2 |
327 prefer 2 |
324 apply (rule bl_to_bin_lt2p_aux) |
328 apply (rule bl_to_bin_lt2p_aux) |
325 apply simp |
329 apply simp |
326 done |
330 done |
327 |
331 |
335 simp add: Bit_B0_2t Bit_B1_2t algebra_simps)+ |
339 simp add: Bit_B0_2t Bit_B1_2t algebra_simps)+ |
336 done |
340 done |
337 |
341 |
338 lemma bl_to_bin_ge0: "bl_to_bin bs >= 0" |
342 lemma bl_to_bin_ge0: "bl_to_bin bs >= 0" |
339 apply (unfold bl_to_bin_def) |
343 apply (unfold bl_to_bin_def) |
340 apply (rule xtr4) |
344 apply (rule xtrans(4)) |
341 apply (rule bl_to_bin_ge2p_aux) |
345 apply (rule bl_to_bin_ge2p_aux) |
342 apply simp |
346 apply simp |
343 done |
347 done |
344 |
348 |
345 lemma butlast_rest_bin: |
349 lemma butlast_rest_bin: |
532 lemma bin_split_take: |
536 lemma bin_split_take: |
533 "bin_split n c = (a, b) \<Longrightarrow> |
537 "bin_split n c = (a, b) \<Longrightarrow> |
534 bin_to_bl m a = take m (bin_to_bl (m + n) c)" |
538 bin_to_bl m a = take m (bin_to_bl (m + n) c)" |
535 apply (induct n arbitrary: b c) |
539 apply (induct n arbitrary: b c) |
536 apply clarsimp |
540 apply clarsimp |
537 apply (clarsimp simp: Let_def split: ls_splits) |
541 apply (clarsimp simp: Let_def split: prod.split_asm) |
538 apply (simp add: bin_to_bl_def) |
542 apply (simp add: bin_to_bl_def) |
539 apply (simp add: take_bin2bl_lem) |
543 apply (simp add: take_bin2bl_lem) |
540 done |
544 done |
541 |
545 |
542 lemma bin_split_take1: |
546 lemma bin_split_take1: |
746 size_rbl_pred size_rbl_succ size_rbl_add size_rbl_mult |
750 size_rbl_pred size_rbl_succ size_rbl_add size_rbl_mult |
747 |
751 |
748 lemmas rbl_Nils = |
752 lemmas rbl_Nils = |
749 rbl_pred.Nil rbl_succ.Nil rbl_add.Nil rbl_mult.Nil |
753 rbl_pred.Nil rbl_succ.Nil rbl_add.Nil rbl_mult.Nil |
750 |
754 |
751 lemma pred_BIT_simps [simp]: |
|
752 "x BIT 0 - 1 = (x - 1) BIT 1" |
|
753 "x BIT 1 - 1 = x BIT 0" |
|
754 by (simp_all add: Bit_B0_2t Bit_B1_2t) |
|
755 |
|
756 lemma rbl_pred: |
755 lemma rbl_pred: |
757 "rbl_pred (rev (bin_to_bl n bin)) = rev (bin_to_bl n (bin - 1))" |
756 "rbl_pred (rev (bin_to_bl n bin)) = rev (bin_to_bl n (bin - 1))" |
758 apply (induct n arbitrary: bin, simp) |
757 apply (induct n arbitrary: bin, simp) |
759 apply (unfold bin_to_bl_def) |
758 apply (unfold bin_to_bl_def) |
760 apply clarsimp |
759 apply clarsimp |
761 apply (case_tac bin rule: bin_exhaust) |
760 apply (case_tac bin rule: bin_exhaust) |
762 apply (case_tac b) |
761 apply (case_tac b) |
763 apply (clarsimp simp: bin_to_bl_aux_alt)+ |
762 apply (clarsimp simp: bin_to_bl_aux_alt)+ |
764 done |
763 done |
765 |
764 |
766 lemma succ_BIT_simps [simp]: |
|
767 "x BIT 0 + 1 = x BIT 1" |
|
768 "x BIT 1 + 1 = (x + 1) BIT 0" |
|
769 by (simp_all add: Bit_B0_2t Bit_B1_2t) |
|
770 |
|
771 lemma rbl_succ: |
765 lemma rbl_succ: |
772 "rbl_succ (rev (bin_to_bl n bin)) = rev (bin_to_bl n (bin + 1))" |
766 "rbl_succ (rev (bin_to_bl n bin)) = rev (bin_to_bl n (bin + 1))" |
773 apply (induct n arbitrary: bin, simp) |
767 apply (induct n arbitrary: bin, simp) |
774 apply (unfold bin_to_bl_def) |
768 apply (unfold bin_to_bl_def) |
775 apply clarsimp |
769 apply clarsimp |
776 apply (case_tac bin rule: bin_exhaust) |
770 apply (case_tac bin rule: bin_exhaust) |
777 apply (case_tac b) |
771 apply (case_tac b) |
778 apply (clarsimp simp: bin_to_bl_aux_alt)+ |
772 apply (clarsimp simp: bin_to_bl_aux_alt)+ |
779 done |
773 done |
780 |
|
781 lemma add_BIT_simps [simp]: (* FIXME: move *) |
|
782 "x BIT 0 + y BIT 0 = (x + y) BIT 0" |
|
783 "x BIT 0 + y BIT 1 = (x + y) BIT 1" |
|
784 "x BIT 1 + y BIT 0 = (x + y) BIT 1" |
|
785 "x BIT 1 + y BIT 1 = (x + y + 1) BIT 0" |
|
786 by (simp_all add: Bit_B0_2t Bit_B1_2t) |
|
787 |
774 |
788 lemma rbl_add: |
775 lemma rbl_add: |
789 "!!bina binb. rbl_add (rev (bin_to_bl n bina)) (rev (bin_to_bl n binb)) = |
776 "!!bina binb. rbl_add (rev (bin_to_bl n bina)) (rev (bin_to_bl n binb)) = |
790 rev (bin_to_bl n (bina + binb))" |
777 rev (bin_to_bl n (bina + binb))" |
791 apply (induct n, simp) |
778 apply (induct n, simp) |
868 apply (unfold bin_to_bl_def) |
855 apply (unfold bin_to_bl_def) |
869 apply simp |
856 apply simp |
870 apply (simp add: bin_to_bl_aux_alt) |
857 apply (simp add: bin_to_bl_aux_alt) |
871 done |
858 done |
872 |
859 |
873 lemma mult_BIT_simps [simp]: |
|
874 "x BIT 0 * y = (x * y) BIT 0" |
|
875 "x * y BIT 0 = (x * y) BIT 0" |
|
876 "x BIT 1 * y = (x * y) BIT 0 + y" |
|
877 by (simp_all add: Bit_B0_2t Bit_B1_2t algebra_simps) |
|
878 |
|
879 lemma rbl_mult: "!!bina binb. |
860 lemma rbl_mult: "!!bina binb. |
880 rbl_mult (rev (bin_to_bl n bina)) (rev (bin_to_bl n binb)) = |
861 rbl_mult (rev (bin_to_bl n bina)) (rev (bin_to_bl n binb)) = |
881 rev (bin_to_bl n (bina * binb))" |
862 rev (bin_to_bl n (bina * binb))" |
882 apply (induct n) |
863 apply (induct n) |
883 apply simp |
864 apply simp |
905 "P (rbl_mult (y # ys) xs) = |
886 "P (rbl_mult (y # ys) xs) = |
906 (ALL ws. length ws = Suc (length ys) --> ws = False # rbl_mult ys xs --> |
887 (ALL ws. length ws = Suc (length ys) --> ws = False # rbl_mult ys xs --> |
907 (y --> P (rbl_add ws xs)) & (~ y --> P ws))" |
888 (y --> P (rbl_add ws xs)) & (~ y --> P ws))" |
908 by (clarsimp simp add : Let_def) |
889 by (clarsimp simp add : Let_def) |
909 |
890 |
910 lemma and_len: "xs = ys ==> xs = ys & length xs = length ys" |
|
911 by auto |
|
912 |
|
913 lemma size_if: "size (if p then xs else ys) = (if p then size xs else size ys)" |
|
914 by auto |
|
915 |
|
916 lemma tl_if: "tl (if p then xs else ys) = (if p then tl xs else tl ys)" |
|
917 by auto |
|
918 |
|
919 lemma hd_if: "hd (if p then xs else ys) = (if p then hd xs else hd ys)" |
|
920 by auto |
|
921 |
|
922 lemma if_Not_x: "(if p then ~ x else x) = (p = (~ x))" |
|
923 by auto |
|
924 |
|
925 lemma if_x_Not: "(if p then x else ~ x) = (p = x)" |
|
926 by auto |
|
927 |
|
928 lemma if_same_and: "(If p x y & If p u v) = (if p then x & u else y & v)" |
|
929 by auto |
|
930 |
|
931 lemma if_same_eq: "(If p x y = (If p u v)) = (if p then x = (u) else y = (v))" |
|
932 by auto |
|
933 |
|
934 lemma if_same_eq_not: |
|
935 "(If p x y = (~ If p u v)) = (if p then x = (~u) else y = (~v))" |
|
936 by auto |
|
937 |
|
938 (* note - if_Cons can cause blowup in the size, if p is complex, |
|
939 so make a simproc *) |
|
940 lemma if_Cons: "(if p then x # xs else y # ys) = If p x y # If p xs ys" |
|
941 by auto |
|
942 |
|
943 lemma if_single: |
|
944 "(if xc then [xab] else [an]) = [if xc then xab else an]" |
|
945 by auto |
|
946 |
|
947 lemma if_bool_simps: |
|
948 "If p True y = (p | y) & If p False y = (~p & y) & |
|
949 If p y True = (p --> y) & If p y False = (p & y)" |
|
950 by auto |
|
951 |
|
952 lemmas if_simps = if_x_Not if_Not_x if_cancel if_True if_False if_bool_simps |
|
953 |
|
954 lemmas seqr = eq_reflection [where x = "size w"] for w (* FIXME: delete *) |
|
955 |
|
956 (* TODO: move name bindings to List.thy *) |
|
957 lemmas tl_Nil = tl.simps (1) |
|
958 lemmas tl_Cons = tl.simps (2) |
|
959 |
|
960 |
891 |
961 subsection "Repeated splitting or concatenation" |
892 subsection "Repeated splitting or concatenation" |
962 |
893 |
963 lemma sclem: |
894 lemma sclem: |
964 "size (concat (map (bin_to_bl n) xs)) = length xs * n" |
895 "size (concat (map (bin_to_bl n) xs)) = length xs * n" |
1006 lemma bin_rsplit_aux_append: |
937 lemma bin_rsplit_aux_append: |
1007 "bin_rsplit_aux n m c (bs @ cs) = bin_rsplit_aux n m c bs @ cs" |
938 "bin_rsplit_aux n m c (bs @ cs) = bin_rsplit_aux n m c bs @ cs" |
1008 apply (induct n m c bs rule: bin_rsplit_aux.induct) |
939 apply (induct n m c bs rule: bin_rsplit_aux.induct) |
1009 apply (subst bin_rsplit_aux.simps) |
940 apply (subst bin_rsplit_aux.simps) |
1010 apply (subst bin_rsplit_aux.simps) |
941 apply (subst bin_rsplit_aux.simps) |
1011 apply (clarsimp split: ls_splits) |
942 apply (clarsimp split: prod.split) |
1012 apply auto |
943 apply auto |
1013 done |
944 done |
1014 |
945 |
1015 lemma bin_rsplitl_aux_append: |
946 lemma bin_rsplitl_aux_append: |
1016 "bin_rsplitl_aux n m c (bs @ cs) = bin_rsplitl_aux n m c bs @ cs" |
947 "bin_rsplitl_aux n m c (bs @ cs) = bin_rsplitl_aux n m c bs @ cs" |
1017 apply (induct n m c bs rule: bin_rsplitl_aux.induct) |
948 apply (induct n m c bs rule: bin_rsplitl_aux.induct) |
1018 apply (subst bin_rsplitl_aux.simps) |
949 apply (subst bin_rsplitl_aux.simps) |
1019 apply (subst bin_rsplitl_aux.simps) |
950 apply (subst bin_rsplitl_aux.simps) |
1020 apply (clarsimp split: ls_splits) |
951 apply (clarsimp split: prod.split) |
1021 apply auto |
952 apply auto |
1022 done |
953 done |
1023 |
954 |
1024 lemmas rsplit_aux_apps [where bs = "[]"] = |
955 lemmas rsplit_aux_apps [where bs = "[]"] = |
1025 bin_rsplit_aux_append bin_rsplitl_aux_append |
956 bin_rsplit_aux_append bin_rsplitl_aux_append |
1095 done |
1026 done |
1096 |
1027 |
1097 lemma bin_rsplit_all: |
1028 lemma bin_rsplit_all: |
1098 "0 < nw ==> nw <= n ==> bin_rsplit n (nw, w) = [bintrunc n w]" |
1029 "0 < nw ==> nw <= n ==> bin_rsplit n (nw, w) = [bintrunc n w]" |
1099 unfolding bin_rsplit_def |
1030 unfolding bin_rsplit_def |
1100 by (clarsimp dest!: split_bintrunc simp: rsplit_aux_simp2ls split: ls_splits) |
1031 by (clarsimp dest!: split_bintrunc simp: rsplit_aux_simp2ls split: prod.split) |
1101 |
1032 |
1102 lemma bin_rsplit_l [rule_format] : |
1033 lemma bin_rsplit_l [rule_format] : |
1103 "ALL bin. bin_rsplitl n (m, bin) = bin_rsplit n (m, bintrunc m bin)" |
1034 "ALL bin. bin_rsplitl n (m, bin) = bin_rsplit n (m, bintrunc m bin)" |
1104 apply (rule_tac a = "m" in wf_less_than [THEN wf_induct]) |
1035 apply (rule_tac a = "m" in wf_less_than [THEN wf_induct]) |
1105 apply (simp (no_asm) add : bin_rsplitl_def bin_rsplit_def) |
1036 apply (simp (no_asm) add : bin_rsplitl_def bin_rsplit_def) |
1106 apply (rule allI) |
1037 apply (rule allI) |
1107 apply (subst bin_rsplitl_aux.simps) |
1038 apply (subst bin_rsplitl_aux.simps) |
1108 apply (subst bin_rsplit_aux.simps) |
1039 apply (subst bin_rsplit_aux.simps) |
1109 apply (clarsimp simp: Let_def split: ls_splits) |
1040 apply (clarsimp simp: Let_def split: prod.split) |
1110 apply (drule bin_split_trunc) |
1041 apply (drule bin_split_trunc) |
1111 apply (drule sym [THEN trans], assumption) |
1042 apply (drule sym [THEN trans], assumption) |
1112 apply (subst rsplit_aux_alts(1)) |
1043 apply (subst rsplit_aux_alts(1)) |
1113 apply (subst rsplit_aux_alts(2)) |
1044 apply (subst rsplit_aux_alts(2)) |
1114 apply clarsimp |
1045 apply clarsimp |
1130 lemma bin_rsplit_aux_len_le [rule_format] : |
1061 lemma bin_rsplit_aux_len_le [rule_format] : |
1131 "\<forall>ws m. n \<noteq> 0 \<longrightarrow> ws = bin_rsplit_aux n nw w bs \<longrightarrow> |
1062 "\<forall>ws m. n \<noteq> 0 \<longrightarrow> ws = bin_rsplit_aux n nw w bs \<longrightarrow> |
1132 length ws \<le> m \<longleftrightarrow> nw + length bs * n \<le> m * n" |
1063 length ws \<le> m \<longleftrightarrow> nw + length bs * n \<le> m * n" |
1133 apply (induct n nw w bs rule: bin_rsplit_aux.induct) |
1064 apply (induct n nw w bs rule: bin_rsplit_aux.induct) |
1134 apply (subst bin_rsplit_aux.simps) |
1065 apply (subst bin_rsplit_aux.simps) |
1135 apply (simp add: lrlem Let_def split: ls_splits) |
1066 apply (simp add: lrlem Let_def split: prod.split) |
1136 done |
1067 done |
1137 |
1068 |
1138 lemma bin_rsplit_len_le: |
1069 lemma bin_rsplit_len_le: |
1139 "n \<noteq> 0 --> ws = bin_rsplit n (nw, w) --> (length ws <= m) = (nw <= m * n)" |
1070 "n \<noteq> 0 --> ws = bin_rsplit n (nw, w) --> (length ws <= m) = (nw <= m * n)" |
1140 unfolding bin_rsplit_def by (clarsimp simp add : bin_rsplit_aux_len_le) |
1071 unfolding bin_rsplit_def by (clarsimp simp add : bin_rsplit_aux_len_le) |
1142 lemma bin_rsplit_aux_len: |
1073 lemma bin_rsplit_aux_len: |
1143 "n \<noteq> 0 \<Longrightarrow> length (bin_rsplit_aux n nw w cs) = |
1074 "n \<noteq> 0 \<Longrightarrow> length (bin_rsplit_aux n nw w cs) = |
1144 (nw + n - 1) div n + length cs" |
1075 (nw + n - 1) div n + length cs" |
1145 apply (induct n nw w cs rule: bin_rsplit_aux.induct) |
1076 apply (induct n nw w cs rule: bin_rsplit_aux.induct) |
1146 apply (subst bin_rsplit_aux.simps) |
1077 apply (subst bin_rsplit_aux.simps) |
1147 apply (clarsimp simp: Let_def split: ls_splits) |
1078 apply (clarsimp simp: Let_def split: prod.split) |
1148 apply (erule thin_rl) |
1079 apply (erule thin_rl) |
1149 apply (case_tac m) |
1080 apply (case_tac m) |
1150 apply simp |
1081 apply simp |
1151 apply (case_tac "m <= n") |
1082 apply (case_tac "m <= n") |
1152 apply auto |
1083 apply auto |
1170 length (bin_rsplit_aux n (m - n) v bs) = |
1101 length (bin_rsplit_aux n (m - n) v bs) = |
1171 length (bin_rsplit_aux n (m - n) (fst (bin_split n w)) (snd (bin_split n w) # cs))" |
1102 length (bin_rsplit_aux n (m - n) (fst (bin_split n w)) (snd (bin_split n w) # cs))" |
1172 by auto |
1103 by auto |
1173 show ?thesis using `length bs = length cs` `n \<noteq> 0` |
1104 show ?thesis using `length bs = length cs` `n \<noteq> 0` |
1174 by (auto simp add: bin_rsplit_aux_simp_alt Let_def bin_rsplit_len |
1105 by (auto simp add: bin_rsplit_aux_simp_alt Let_def bin_rsplit_len |
1175 split: ls_splits) |
1106 split: prod.split) |
1176 qed |
1107 qed |
1177 qed |
1108 qed |
1178 |
1109 |
1179 lemma bin_rsplit_len_indep: |
1110 lemma bin_rsplit_len_indep: |
1180 "n\<noteq>0 ==> length (bin_rsplit n (nw, v)) = length (bin_rsplit n (nw, w))" |
1111 "n\<noteq>0 ==> length (bin_rsplit n (nw, v)) = length (bin_rsplit n (nw, w))" |