# HG changeset patch # User haftmann # Date 1555914497 0 # Node ID ff9efdc84289bc682df25f3007354bbf7731a214 # Parent 6d2effbbf8d4fc27edaf40c74a5fab93ed655797 clarified structure of theories diff -r 6d2effbbf8d4 -r ff9efdc84289 src/HOL/Word/Bit_Representation.thy --- a/src/HOL/Word/Bit_Representation.thy Sat Apr 20 18:02:22 2019 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,849 +0,0 @@ -(* Title: HOL/Word/Bit_Representation.thy - Author: Jeremy Dawson, NICTA -*) - -section \Integers as implicit bit strings\ - -theory Bit_Representation - imports Main -begin - -lemma int_mod_lem: "0 < n \ 0 \ b \ b < n \ b mod n = b" - for b n :: int - apply safe - apply (erule (1) mod_pos_pos_trivial) - apply (erule_tac [!] subst) - apply auto - done - -lemma int_mod_ge: "a < n \ 0 < n \ a \ a mod n" - for a n :: int - by (metis dual_order.trans le_cases mod_pos_pos_trivial pos_mod_conj) - -lemma int_mod_ge': "b < 0 \ 0 < n \ b + n \ b mod n" - for b n :: int - by (metis add_less_same_cancel2 int_mod_ge mod_add_self2) - -lemma int_mod_le': "0 \ b - n \ b mod n \ b - n" - for b n :: int - by (metis minus_mod_self2 zmod_le_nonneg_dividend) - -lemma emep1: "even n \ even d \ 0 \ d \ (n + 1) mod d = (n mod d) + 1" - for n d :: int - by (auto simp add: pos_zmod_mult_2 add.commute dvd_def) - -lemma m1mod2k: "- 1 mod 2 ^ n = (2 ^ n - 1 :: int)" - by (rule zmod_minus1) simp - - -subsection \Constructors and destructors for binary integers\ - -definition Bit :: "int \ bool \ int" (infixl "BIT" 90) - where "k BIT b = (if b then 1 else 0) + k + k" - -lemma Bit_B0: "k BIT False = k + k" - by (simp add: Bit_def) - -lemma Bit_B1: "k BIT True = k + k + 1" - by (simp add: Bit_def) - -lemma Bit_B0_2t: "k BIT False = 2 * k" - by (rule trans, rule Bit_B0) simp - -lemma Bit_B1_2t: "k BIT True = 2 * k + 1" - by (rule trans, rule Bit_B1) simp - -lemma power_BIT: "2 ^ Suc n - 1 = (2 ^ n - 1) BIT True" - by (simp add: Bit_B1) - -definition bin_last :: "int \ bool" - where "bin_last w \ w mod 2 = 1" - -lemma bin_last_odd: "bin_last = odd" - by (rule ext) (simp add: bin_last_def even_iff_mod_2_eq_zero) - -definition bin_rest :: "int \ int" - where "bin_rest w = w div 2" - -lemma bin_rl_simp [simp]: "bin_rest w BIT bin_last w = w" - unfolding bin_rest_def bin_last_def Bit_def - by (cases "w mod 2 = 0") (use div_mult_mod_eq [of w 2] in simp_all) - -lemma bin_rest_BIT [simp]: "bin_rest (x BIT b) = x" - unfolding bin_rest_def Bit_def - by (cases b) simp_all - -lemma bin_last_BIT [simp]: "bin_last (x BIT b) = b" - unfolding bin_last_def Bit_def - by (cases b) simp_all - -lemma BIT_eq_iff [iff]: "u BIT b = v BIT c \ u = v \ b = c" - by (auto simp: Bit_def) arith+ - -lemma BIT_bin_simps [simp]: - "numeral k BIT False = numeral (Num.Bit0 k)" - "numeral k BIT True = numeral (Num.Bit1 k)" - "(- numeral k) BIT False = - numeral (Num.Bit0 k)" - "(- numeral k) BIT True = - numeral (Num.BitM k)" - unfolding numeral.simps numeral_BitM - by (simp_all add: Bit_def del: arith_simps add_numeral_special diff_numeral_special) - -lemma BIT_special_simps [simp]: - shows "0 BIT False = 0" - and "0 BIT True = 1" - and "1 BIT False = 2" - and "1 BIT True = 3" - and "(- 1) BIT False = - 2" - and "(- 1) BIT True = - 1" - by (simp_all add: Bit_def) - -lemma Bit_eq_0_iff: "w BIT b = 0 \ w = 0 \ \ b" - by (auto simp: Bit_def) arith - -lemma Bit_eq_m1_iff: "w BIT b = -1 \ w = -1 \ b" - by (auto simp: Bit_def) arith - -lemma BitM_inc: "Num.BitM (Num.inc w) = Num.Bit1 w" - by (induct w) simp_all - -lemma expand_BIT: - "numeral (Num.Bit0 w) = numeral w BIT False" - "numeral (Num.Bit1 w) = numeral w BIT True" - "- numeral (Num.Bit0 w) = (- numeral w) BIT False" - "- numeral (Num.Bit1 w) = (- numeral (w + Num.One)) BIT True" - by (simp_all add: add_One BitM_inc) - -lemma bin_last_numeral_simps [simp]: - "\ bin_last 0" - "bin_last 1" - "bin_last (- 1)" - "bin_last Numeral1" - "\ bin_last (numeral (Num.Bit0 w))" - "bin_last (numeral (Num.Bit1 w))" - "\ bin_last (- numeral (Num.Bit0 w))" - "bin_last (- numeral (Num.Bit1 w))" - by (simp_all add: bin_last_def zmod_zminus1_eq_if) (auto simp add: divmod_def) - -lemma bin_rest_numeral_simps [simp]: - "bin_rest 0 = 0" - "bin_rest 1 = 0" - "bin_rest (- 1) = - 1" - "bin_rest Numeral1 = 0" - "bin_rest (numeral (Num.Bit0 w)) = numeral w" - "bin_rest (numeral (Num.Bit1 w)) = numeral w" - "bin_rest (- numeral (Num.Bit0 w)) = - numeral w" - "bin_rest (- numeral (Num.Bit1 w)) = - numeral (w + Num.One)" - by (simp_all add: bin_rest_def zdiv_zminus1_eq_if) (auto simp add: divmod_def) - -lemma less_Bits: "v BIT b < w BIT c \ v < w \ v \ w \ \ b \ c" - by (auto simp: Bit_def) - -lemma le_Bits: "v BIT b \ w BIT c \ v < w \ v \ w \ (\ b \ c)" - by (auto simp: Bit_def) - -lemma pred_BIT_simps [simp]: - "x BIT False - 1 = (x - 1) BIT True" - "x BIT True - 1 = x BIT False" - by (simp_all add: Bit_B0_2t Bit_B1_2t) - -lemma succ_BIT_simps [simp]: - "x BIT False + 1 = x BIT True" - "x BIT True + 1 = (x + 1) BIT False" - by (simp_all add: Bit_B0_2t Bit_B1_2t) - -lemma add_BIT_simps [simp]: - "x BIT False + y BIT False = (x + y) BIT False" - "x BIT False + y BIT True = (x + y) BIT True" - "x BIT True + y BIT False = (x + y) BIT True" - "x BIT True + y BIT True = (x + y + 1) BIT False" - by (simp_all add: Bit_B0_2t Bit_B1_2t) - -lemma mult_BIT_simps [simp]: - "x BIT False * y = (x * y) BIT False" - "x * y BIT False = (x * y) BIT False" - "x BIT True * y = (x * y) BIT False + y" - by (simp_all add: Bit_B0_2t Bit_B1_2t algebra_simps) - -lemma B_mod_2': "X = 2 \ (w BIT True) mod X = 1 \ (w BIT False) mod X = 0" - by (simp add: Bit_B0 Bit_B1) - -lemma bin_ex_rl: "\w b. w BIT b = bin" - by (metis bin_rl_simp) - -lemma bin_exhaust: "(\x b. bin = x BIT b \ Q) \ Q" -by (metis bin_ex_rl) - -primrec bin_nth :: "int \ nat \ bool" - where - Z: "bin_nth w 0 \ bin_last w" - | Suc: "bin_nth w (Suc n) \ bin_nth (bin_rest w) n" - -lemma bin_nth_eq_mod: - "bin_nth w n \ odd (w div 2 ^ n)" - by (induction n arbitrary: w) (simp_all add: bin_last_def bin_rest_def odd_iff_mod_2_eq_one zdiv_zmult2_eq) - -lemma bin_abs_lem: "bin = (w BIT b) \ bin \ -1 \ bin \ 0 \ nat \w\ < nat \bin\" - apply clarsimp - apply (unfold Bit_def) - apply (cases b) - apply (clarsimp, arith) - apply (clarsimp, arith) - done - -lemma bin_induct: - assumes PPls: "P 0" - and PMin: "P (- 1)" - and PBit: "\bin bit. P bin \ P (bin BIT bit)" - shows "P bin" - apply (rule_tac P=P and a=bin and f1="nat \ abs" in wf_measure [THEN wf_induct]) - apply (simp add: measure_def inv_image_def) - apply (case_tac x rule: bin_exhaust) - apply (frule bin_abs_lem) - apply (auto simp add : PPls PMin PBit) - done - -lemma Bit_div2 [simp]: "(w BIT b) div 2 = w" - unfolding bin_rest_def [symmetric] by (rule bin_rest_BIT) - -lemma bin_nth_eq_iff: "bin_nth x = bin_nth y \ x = y" -proof - - have bin_nth_lem [rule_format]: "\y. bin_nth x = bin_nth y \ x = y" - apply (induct x rule: bin_induct) - apply safe - apply (erule rev_mp) - apply (induct_tac y rule: bin_induct) - apply safe - apply (drule_tac x=0 in fun_cong, force) - apply (erule notE, rule ext, drule_tac x="Suc x" in fun_cong, force) - apply (drule_tac x=0 in fun_cong, force) - apply (erule rev_mp) - apply (induct_tac y rule: bin_induct) - apply safe - apply (drule_tac x=0 in fun_cong, force) - apply (erule notE, rule ext, drule_tac x="Suc x" in fun_cong, force) - apply (metis Bit_eq_m1_iff Z bin_last_BIT) - apply (case_tac y rule: bin_exhaust) - apply clarify - apply (erule allE) - apply (erule impE) - prefer 2 - apply (erule conjI) - apply (drule_tac x=0 in fun_cong, force) - apply (rule ext) - apply (drule_tac x="Suc x" for x in fun_cong, force) - done - show ?thesis - by (auto elim: bin_nth_lem) -qed - -lemmas bin_eqI = ext [THEN bin_nth_eq_iff [THEN iffD1]] - -lemma bin_eq_iff: "x = y \ (\n. bin_nth x n = bin_nth y n)" - using bin_nth_eq_iff by auto - -lemma bin_nth_zero [simp]: "\ bin_nth 0 n" - by (induct n) auto - -lemma bin_nth_1 [simp]: "bin_nth 1 n \ n = 0" - by (cases n) simp_all - -lemma bin_nth_minus1 [simp]: "bin_nth (- 1) n" - by (induct n) auto - -lemma bin_nth_0_BIT: "bin_nth (w BIT b) 0 \ b" - by auto - -lemma bin_nth_Suc_BIT: "bin_nth (w BIT b) (Suc n) = bin_nth w n" - by auto - -lemma bin_nth_minus [simp]: "0 < n \ bin_nth (w BIT b) n = bin_nth w (n - 1)" - by (cases n) auto - -lemma bin_nth_numeral: "bin_rest x = y \ bin_nth x (numeral n) = bin_nth y (pred_numeral n)" - by (simp add: numeral_eq_Suc) - -lemmas bin_nth_numeral_simps [simp] = - bin_nth_numeral [OF bin_rest_numeral_simps(2)] - bin_nth_numeral [OF bin_rest_numeral_simps(5)] - bin_nth_numeral [OF bin_rest_numeral_simps(6)] - bin_nth_numeral [OF bin_rest_numeral_simps(7)] - bin_nth_numeral [OF bin_rest_numeral_simps(8)] - -lemmas bin_nth_simps = - bin_nth.Z bin_nth.Suc bin_nth_zero bin_nth_minus1 - bin_nth_numeral_simps - -lemma nth_2p_bin: "bin_nth (2 ^ n) m = (m = n)" \ \for use when simplifying with \bin_nth_Bit\\ - apply (induct n arbitrary: m) - apply clarsimp - apply safe - apply (case_tac m) - apply (auto simp: Bit_B0_2t [symmetric]) - done - - -subsection \Truncating binary integers\ - -definition bin_sign :: "int \ int" - where "bin_sign k = (if k \ 0 then 0 else - 1)" - -lemma bin_sign_simps [simp]: - "bin_sign 0 = 0" - "bin_sign 1 = 0" - "bin_sign (- 1) = - 1" - "bin_sign (numeral k) = 0" - "bin_sign (- numeral k) = -1" - "bin_sign (w BIT b) = bin_sign w" - by (simp_all add: bin_sign_def Bit_def) - -lemma bin_sign_rest [simp]: "bin_sign (bin_rest w) = bin_sign w" - by (cases w rule: bin_exhaust) auto - -primrec bintrunc :: "nat \ int \ int" - where - Z : "bintrunc 0 bin = 0" - | Suc : "bintrunc (Suc n) bin = bintrunc n (bin_rest bin) BIT (bin_last bin)" - -primrec sbintrunc :: "nat \ int \ int" - where - Z : "sbintrunc 0 bin = (if bin_last bin then -1 else 0)" - | Suc : "sbintrunc (Suc n) bin = sbintrunc n (bin_rest bin) BIT (bin_last bin)" - -lemma bintrunc_mod2p: "bintrunc n w = w mod 2 ^ n" - by (induct n arbitrary: w) (auto simp add: bin_last_def bin_rest_def Bit_def zmod_zmult2_eq) - -lemma sbintrunc_mod2p: "sbintrunc n w = (w + 2 ^ n) mod 2 ^ Suc n - 2 ^ n" -proof (induction n arbitrary: w) - case 0 - then show ?case - by (auto simp add: bin_last_odd odd_iff_mod_2_eq_one) -next - case (Suc n) - moreover have "((bin_rest w + 2 ^ n) mod (2 * 2 ^ n) - 2 ^ n) BIT bin_last w = - (w + 2 * 2 ^ n) mod (4 * 2 ^ n) - 2 * 2 ^ n" - proof (cases w rule: parity_cases) - case even - then show ?thesis - by (simp add: bin_last_odd bin_rest_def Bit_B0_2t mult_mod_right) - next - case odd - then have "2 * (w div 2) = w - 1" - using minus_mod_eq_mult_div [of w 2] by simp - moreover have "(2 * 2 ^ n + w - 1) mod (2 * 2 * 2 ^ n) + 1 = (2 * 2 ^ n + w) mod (2 * 2 * 2 ^ n)" - using odd emep1 [of "2 * 2 ^ n + w - 1" "2 * 2 * 2 ^ n"] by simp - ultimately show ?thesis - using odd by (simp add: bin_last_odd bin_rest_def Bit_B1_2t mult_mod_right) (simp add: algebra_simps) - qed - ultimately show ?case - by simp -qed - - -subsection "Simplifications for (s)bintrunc" - -lemma sign_bintr: "bin_sign (bintrunc n w) = 0" - by (simp add: bintrunc_mod2p bin_sign_def) - -lemma bintrunc_n_0 [simp]: "bintrunc n 0 = 0" - by (simp add: bintrunc_mod2p) - -lemma sbintrunc_n_0 [simp]: "sbintrunc n 0 = 0" - by (simp add: sbintrunc_mod2p) - -lemma sbintrunc_n_minus1 [simp]: "sbintrunc n (- 1) = -1" - by (induct n) auto - -lemma bintrunc_Suc_numeral: - "bintrunc (Suc n) 1 = 1" - "bintrunc (Suc n) (- 1) = bintrunc n (- 1) BIT True" - "bintrunc (Suc n) (numeral (Num.Bit0 w)) = bintrunc n (numeral w) BIT False" - "bintrunc (Suc n) (numeral (Num.Bit1 w)) = bintrunc n (numeral w) BIT True" - "bintrunc (Suc n) (- numeral (Num.Bit0 w)) = bintrunc n (- numeral w) BIT False" - "bintrunc (Suc n) (- numeral (Num.Bit1 w)) = bintrunc n (- numeral (w + Num.One)) BIT True" - by simp_all - -lemma sbintrunc_0_numeral [simp]: - "sbintrunc 0 1 = -1" - "sbintrunc 0 (numeral (Num.Bit0 w)) = 0" - "sbintrunc 0 (numeral (Num.Bit1 w)) = -1" - "sbintrunc 0 (- numeral (Num.Bit0 w)) = 0" - "sbintrunc 0 (- numeral (Num.Bit1 w)) = -1" - by simp_all - -lemma sbintrunc_Suc_numeral: - "sbintrunc (Suc n) 1 = 1" - "sbintrunc (Suc n) (numeral (Num.Bit0 w)) = sbintrunc n (numeral w) BIT False" - "sbintrunc (Suc n) (numeral (Num.Bit1 w)) = sbintrunc n (numeral w) BIT True" - "sbintrunc (Suc n) (- numeral (Num.Bit0 w)) = sbintrunc n (- numeral w) BIT False" - "sbintrunc (Suc n) (- numeral (Num.Bit1 w)) = sbintrunc n (- numeral (w + Num.One)) BIT True" - by simp_all - -lemma bin_sign_lem: "(bin_sign (sbintrunc n bin) = -1) = bin_nth bin n" - apply (induct n arbitrary: bin) - apply (case_tac bin rule: bin_exhaust, case_tac b, auto) - done - -lemma nth_bintr: "bin_nth (bintrunc m w) n \ n < m \ bin_nth w n" - apply (induct n arbitrary: w m) - apply (case_tac m, auto)[1] - apply (case_tac m, auto)[1] - done - -lemma nth_sbintr: "bin_nth (sbintrunc m w) n = (if n < m then bin_nth w n else bin_nth w m)" - apply (induct n arbitrary: w m) - apply (case_tac m) - apply simp_all - apply (case_tac m) - apply simp_all - done - -lemma bin_nth_Bit: "bin_nth (w BIT b) n \ n = 0 \ b \ (\m. n = Suc m \ bin_nth w m)" - by (cases n) auto - -lemma bin_nth_Bit0: - "bin_nth (numeral (Num.Bit0 w)) n \ - (\m. n = Suc m \ bin_nth (numeral w) m)" - using bin_nth_Bit [where w="numeral w" and b="False"] by simp - -lemma bin_nth_Bit1: - "bin_nth (numeral (Num.Bit1 w)) n \ - n = 0 \ (\m. n = Suc m \ bin_nth (numeral w) m)" - using bin_nth_Bit [where w="numeral w" and b="True"] by simp - -lemma bintrunc_bintrunc_l: "n \ m \ bintrunc m (bintrunc n w) = bintrunc n w" - by (rule bin_eqI) (auto simp: nth_bintr) - -lemma sbintrunc_sbintrunc_l: "n \ m \ sbintrunc m (sbintrunc n w) = sbintrunc n w" - by (rule bin_eqI) (auto simp: nth_sbintr) - -lemma bintrunc_bintrunc_ge: "n \ m \ bintrunc n (bintrunc m w) = bintrunc n w" - by (rule bin_eqI) (auto simp: nth_bintr) - -lemma bintrunc_bintrunc_min [simp]: "bintrunc m (bintrunc n w) = bintrunc (min m n) w" - by (rule bin_eqI) (auto simp: nth_bintr) - -lemma sbintrunc_sbintrunc_min [simp]: "sbintrunc m (sbintrunc n w) = sbintrunc (min m n) w" - by (rule bin_eqI) (auto simp: nth_sbintr min.absorb1 min.absorb2) - -lemmas bintrunc_Pls = - bintrunc.Suc [where bin="0", simplified bin_last_numeral_simps bin_rest_numeral_simps] - -lemmas bintrunc_Min [simp] = - bintrunc.Suc [where bin="-1", simplified bin_last_numeral_simps bin_rest_numeral_simps] - -lemmas bintrunc_BIT [simp] = - bintrunc.Suc [where bin="w BIT b", simplified bin_last_BIT bin_rest_BIT] for w b - -lemmas bintrunc_Sucs = bintrunc_Pls bintrunc_Min bintrunc_BIT - bintrunc_Suc_numeral - -lemmas sbintrunc_Suc_Pls = - sbintrunc.Suc [where bin="0", simplified bin_last_numeral_simps bin_rest_numeral_simps] - -lemmas sbintrunc_Suc_Min = - sbintrunc.Suc [where bin="-1", simplified bin_last_numeral_simps bin_rest_numeral_simps] - -lemmas sbintrunc_Suc_BIT [simp] = - sbintrunc.Suc [where bin="w BIT b", simplified bin_last_BIT bin_rest_BIT] for w b - -lemmas sbintrunc_Sucs = sbintrunc_Suc_Pls sbintrunc_Suc_Min sbintrunc_Suc_BIT - sbintrunc_Suc_numeral - -lemmas sbintrunc_Pls = - sbintrunc.Z [where bin="0", simplified bin_last_numeral_simps bin_rest_numeral_simps] - -lemmas sbintrunc_Min = - sbintrunc.Z [where bin="-1", simplified bin_last_numeral_simps bin_rest_numeral_simps] - -lemmas sbintrunc_0_BIT_B0 [simp] = - sbintrunc.Z [where bin="w BIT False", simplified bin_last_numeral_simps bin_rest_numeral_simps] - for w - -lemmas sbintrunc_0_BIT_B1 [simp] = - sbintrunc.Z [where bin="w BIT True", simplified bin_last_BIT bin_rest_numeral_simps] - for w - -lemmas sbintrunc_0_simps = - sbintrunc_Pls sbintrunc_Min sbintrunc_0_BIT_B0 sbintrunc_0_BIT_B1 - -lemmas bintrunc_simps = bintrunc.Z bintrunc_Sucs -lemmas sbintrunc_simps = sbintrunc_0_simps sbintrunc_Sucs - -lemma bintrunc_minus: "0 < n \ bintrunc (Suc (n - 1)) w = bintrunc n w" - by auto - -lemma sbintrunc_minus: "0 < n \ sbintrunc (Suc (n - 1)) w = sbintrunc n w" - by auto - -lemmas bintrunc_minus_simps = - bintrunc_Sucs [THEN [2] bintrunc_minus [symmetric, THEN trans]] -lemmas sbintrunc_minus_simps = - sbintrunc_Sucs [THEN [2] sbintrunc_minus [symmetric, THEN trans]] - -lemmas thobini1 = arg_cong [where f = "\w. w BIT b"] for b - -lemmas bintrunc_BIT_I = trans [OF bintrunc_BIT thobini1] -lemmas bintrunc_Min_I = trans [OF bintrunc_Min thobini1] - -lemmas bmsts = bintrunc_minus_simps(1-3) [THEN thobini1 [THEN [2] trans]] -lemmas bintrunc_Pls_minus_I = bmsts(1) -lemmas bintrunc_Min_minus_I = bmsts(2) -lemmas bintrunc_BIT_minus_I = bmsts(3) - -lemma bintrunc_Suc_lem: "bintrunc (Suc n) x = y \ m = Suc n \ bintrunc m x = y" - by auto - -lemmas bintrunc_Suc_Ialts = - bintrunc_Min_I [THEN bintrunc_Suc_lem] - bintrunc_BIT_I [THEN bintrunc_Suc_lem] - -lemmas sbintrunc_BIT_I = trans [OF sbintrunc_Suc_BIT thobini1] - -lemmas sbintrunc_Suc_Is = - sbintrunc_Sucs(1-3) [THEN thobini1 [THEN [2] trans]] - -lemmas sbintrunc_Suc_minus_Is = - sbintrunc_minus_simps(1-3) [THEN thobini1 [THEN [2] trans]] - -lemma sbintrunc_Suc_lem: "sbintrunc (Suc n) x = y \ m = Suc n \ sbintrunc m x = y" - by auto - -lemmas sbintrunc_Suc_Ialts = - sbintrunc_Suc_Is [THEN sbintrunc_Suc_lem] - -lemma sbintrunc_bintrunc_lt: "m > n \ sbintrunc n (bintrunc m w) = sbintrunc n w" - by (rule bin_eqI) (auto simp: nth_sbintr nth_bintr) - -lemma bintrunc_sbintrunc_le: "m \ Suc n \ bintrunc m (sbintrunc n w) = bintrunc m w" - apply (rule bin_eqI) - apply (auto simp: nth_sbintr nth_bintr) - apply (subgoal_tac "x=n", safe, arith+)[1] - apply (subgoal_tac "x=n", safe, arith+)[1] - done - -lemmas bintrunc_sbintrunc [simp] = order_refl [THEN bintrunc_sbintrunc_le] -lemmas sbintrunc_bintrunc [simp] = lessI [THEN sbintrunc_bintrunc_lt] -lemmas bintrunc_bintrunc [simp] = order_refl [THEN bintrunc_bintrunc_l] -lemmas sbintrunc_sbintrunc [simp] = order_refl [THEN sbintrunc_sbintrunc_l] - -lemma bintrunc_sbintrunc' [simp]: "0 < n \ bintrunc n (sbintrunc (n - 1) w) = bintrunc n w" - by (cases n) (auto simp del: bintrunc.Suc) - -lemma sbintrunc_bintrunc' [simp]: "0 < n \ sbintrunc (n - 1) (bintrunc n w) = sbintrunc (n - 1) w" - by (cases n) (auto simp del: bintrunc.Suc) - -lemma bin_sbin_eq_iff: "bintrunc (Suc n) x = bintrunc (Suc n) y \ sbintrunc n x = sbintrunc n y" - apply (rule iffI) - apply (rule box_equals [OF _ sbintrunc_bintrunc sbintrunc_bintrunc]) - apply simp - apply (rule box_equals [OF _ bintrunc_sbintrunc bintrunc_sbintrunc]) - apply simp - done - -lemma bin_sbin_eq_iff': - "0 < n \ bintrunc n x = bintrunc n y \ sbintrunc (n - 1) x = sbintrunc (n - 1) y" - by (cases n) (simp_all add: bin_sbin_eq_iff del: bintrunc.Suc) - -lemmas bintrunc_sbintruncS0 [simp] = bintrunc_sbintrunc' [unfolded One_nat_def] -lemmas sbintrunc_bintruncS0 [simp] = sbintrunc_bintrunc' [unfolded One_nat_def] - -lemmas bintrunc_bintrunc_l' = le_add1 [THEN bintrunc_bintrunc_l] -lemmas sbintrunc_sbintrunc_l' = le_add1 [THEN sbintrunc_sbintrunc_l] - -(* although bintrunc_minus_simps, if added to default simpset, - tends to get applied where it's not wanted in developing the theories, - we get a version for when the word length is given literally *) - -lemmas nat_non0_gr = - trans [OF iszero_def [THEN Not_eq_iff [THEN iffD2]] refl] - -lemma bintrunc_numeral: - "bintrunc (numeral k) x = bintrunc (pred_numeral k) (bin_rest x) BIT bin_last x" - by (simp add: numeral_eq_Suc) - -lemma sbintrunc_numeral: - "sbintrunc (numeral k) x = sbintrunc (pred_numeral k) (bin_rest x) BIT bin_last x" - by (simp add: numeral_eq_Suc) - -lemma bintrunc_numeral_simps [simp]: - "bintrunc (numeral k) (numeral (Num.Bit0 w)) = bintrunc (pred_numeral k) (numeral w) BIT False" - "bintrunc (numeral k) (numeral (Num.Bit1 w)) = bintrunc (pred_numeral k) (numeral w) BIT True" - "bintrunc (numeral k) (- numeral (Num.Bit0 w)) = bintrunc (pred_numeral k) (- numeral w) BIT False" - "bintrunc (numeral k) (- numeral (Num.Bit1 w)) = - bintrunc (pred_numeral k) (- numeral (w + Num.One)) BIT True" - "bintrunc (numeral k) 1 = 1" - by (simp_all add: bintrunc_numeral) - -lemma sbintrunc_numeral_simps [simp]: - "sbintrunc (numeral k) (numeral (Num.Bit0 w)) = sbintrunc (pred_numeral k) (numeral w) BIT False" - "sbintrunc (numeral k) (numeral (Num.Bit1 w)) = sbintrunc (pred_numeral k) (numeral w) BIT True" - "sbintrunc (numeral k) (- numeral (Num.Bit0 w)) = - sbintrunc (pred_numeral k) (- numeral w) BIT False" - "sbintrunc (numeral k) (- numeral (Num.Bit1 w)) = - sbintrunc (pred_numeral k) (- numeral (w + Num.One)) BIT True" - "sbintrunc (numeral k) 1 = 1" - by (simp_all add: sbintrunc_numeral) - -lemma no_bintr_alt1: "bintrunc n = (\w. w mod 2 ^ n :: int)" - by (rule ext) (rule bintrunc_mod2p) - -lemma range_bintrunc: "range (bintrunc n) = {i. 0 \ i \ i < 2 ^ n}" - apply (unfold no_bintr_alt1) - apply (auto simp add: image_iff) - apply (rule exI) - apply (rule sym) - using int_mod_lem [symmetric, of "2 ^ n"] - apply auto - done - -lemma no_sbintr_alt2: "sbintrunc n = (\w. (w + 2 ^ n) mod 2 ^ Suc n - 2 ^ n :: int)" - by (rule ext) (simp add : sbintrunc_mod2p) - -lemma range_sbintrunc: "range (sbintrunc n) = {i. - (2 ^ n) \ i \ i < 2 ^ n}" - apply (unfold no_sbintr_alt2) - apply (auto simp add: image_iff eq_diff_eq) - - apply (rule exI) - apply (auto intro: int_mod_lem [THEN iffD1, symmetric]) - done - -lemma sb_inc_lem: "a + 2^k < 0 \ a + 2^k + 2^(Suc k) \ (a + 2^k) mod 2^(Suc k)" - for a :: int - using int_mod_ge' [where n = "2 ^ (Suc k)" and b = "a + 2 ^ k"] - by simp - -lemma sb_inc_lem': "a < - (2^k) \ a + 2^k + 2^(Suc k) \ (a + 2^k) mod 2^(Suc k)" - for a :: int - by (rule sb_inc_lem) simp - -lemma sbintrunc_inc: "x < - (2^n) \ x + 2^(Suc n) \ sbintrunc n x" - unfolding no_sbintr_alt2 by (drule sb_inc_lem') simp - -lemma sb_dec_lem: "0 \ - (2 ^ k) + a \ (a + 2 ^ k) mod (2 * 2 ^ k) \ - (2 ^ k) + a" - for a :: int - using int_mod_le'[where n = "2 ^ (Suc k)" and b = "a + 2 ^ k"] by simp - -lemma sb_dec_lem': "2 ^ k \ a \ (a + 2 ^ k) mod (2 * 2 ^ k) \ - (2 ^ k) + a" - for a :: int - by (rule sb_dec_lem) simp - -lemma sbintrunc_dec: "x \ (2 ^ n) \ x - 2 ^ (Suc n) >= sbintrunc n x" - unfolding no_sbintr_alt2 by (drule sb_dec_lem') simp - -lemma bintr_ge0: "0 \ bintrunc n w" - by (simp add: bintrunc_mod2p) - -lemma bintr_lt2p: "bintrunc n w < 2 ^ n" - by (simp add: bintrunc_mod2p) - -lemma bintr_Min: "bintrunc n (- 1) = 2 ^ n - 1" - by (simp add: bintrunc_mod2p m1mod2k) - -lemma sbintr_ge: "- (2 ^ n) \ sbintrunc n w" - by (simp add: sbintrunc_mod2p) - -lemma sbintr_lt: "sbintrunc n w < 2 ^ n" - by (simp add: sbintrunc_mod2p) - -lemma sign_Pls_ge_0: "bin_sign bin = 0 \ bin \ 0" - for bin :: int - by (simp add: bin_sign_def) - -lemma sign_Min_lt_0: "bin_sign bin = -1 \ bin < 0" - for bin :: int - by (simp add: bin_sign_def) - -lemma bin_rest_trunc: "bin_rest (bintrunc n bin) = bintrunc (n - 1) (bin_rest bin)" - by (induct n arbitrary: bin) auto - -lemma bin_rest_power_trunc: - "(bin_rest ^^ k) (bintrunc n bin) = bintrunc (n - k) ((bin_rest ^^ k) bin)" - by (induct k) (auto simp: bin_rest_trunc) - -lemma bin_rest_trunc_i: "bintrunc n (bin_rest bin) = bin_rest (bintrunc (Suc n) bin)" - by auto - -lemma bin_rest_strunc: "bin_rest (sbintrunc (Suc n) bin) = sbintrunc n (bin_rest bin)" - by (induct n arbitrary: bin) auto - -lemma bintrunc_rest [simp]: "bintrunc n (bin_rest (bintrunc n bin)) = bin_rest (bintrunc n bin)" - apply (induct n arbitrary: bin) - apply simp - apply (case_tac bin rule: bin_exhaust) - apply (auto simp: bintrunc_bintrunc_l) - done - -lemma sbintrunc_rest [simp]: "sbintrunc n (bin_rest (sbintrunc n bin)) = bin_rest (sbintrunc n bin)" - apply (induct n arbitrary: bin) - apply simp - apply (case_tac bin rule: bin_exhaust) - apply (auto simp: bintrunc_bintrunc_l split: bool.splits) - done - -lemma bintrunc_rest': "bintrunc n \ bin_rest \ bintrunc n = bin_rest \ bintrunc n" - by (rule ext) auto - -lemma sbintrunc_rest': "sbintrunc n \ bin_rest \ sbintrunc n = bin_rest \ sbintrunc n" - by (rule ext) auto - -lemma rco_lem: "f \ g \ f = g \ f \ f \ (g \ f) ^^ n = g ^^ n \ f" - apply (rule ext) - apply (induct_tac n) - apply (simp_all (no_asm)) - apply (drule fun_cong) - apply (unfold o_def) - apply (erule trans) - apply simp - done - -lemmas rco_bintr = bintrunc_rest' - [THEN rco_lem [THEN fun_cong], unfolded o_def] -lemmas rco_sbintr = sbintrunc_rest' - [THEN rco_lem [THEN fun_cong], unfolded o_def] - - -subsection \Splitting and concatenation\ - -primrec bin_split :: "nat \ int \ int \ int" - where - Z: "bin_split 0 w = (w, 0)" - | Suc: "bin_split (Suc n) w = - (let (w1, w2) = bin_split n (bin_rest w) - in (w1, w2 BIT bin_last w))" - -lemma [code]: - "bin_split (Suc n) w = (let (w1, w2) = bin_split n (bin_rest w) in (w1, w2 BIT bin_last w))" - "bin_split 0 w = (w, 0)" - by simp_all - -primrec bin_cat :: "int \ nat \ int \ int" - where - Z: "bin_cat w 0 v = w" - | Suc: "bin_cat w (Suc n) v = bin_cat w n (bin_rest v) BIT bin_last v" - -lemma bin_sign_cat: "bin_sign (bin_cat x n y) = bin_sign x" - by (induct n arbitrary: y) auto - -lemma bin_cat_Suc_Bit: "bin_cat w (Suc n) (v BIT b) = bin_cat w n v BIT b" - by auto - -lemma bin_cat_assoc: "bin_cat (bin_cat x m y) n z = bin_cat x (m + n) (bin_cat y n z)" - by (induct n arbitrary: z) auto - -lemma bin_cat_assoc_sym: "bin_cat x m (bin_cat y n z) = bin_cat (bin_cat x (m - n) y) (min m n) z" - apply (induct n arbitrary: z m) - apply clarsimp - apply (case_tac m, auto) - done - -definition bin_rcat :: "nat \ int list \ int" - where "bin_rcat n = foldl (\u v. bin_cat u n v) 0" - -fun bin_rsplit_aux :: "nat \ nat \ int \ int list \ int list" - where "bin_rsplit_aux n m c bs = - (if m = 0 \ n = 0 then bs - else - let (a, b) = bin_split n c - in bin_rsplit_aux n (m - n) a (b # bs))" - -definition bin_rsplit :: "nat \ nat \ int \ int list" - where "bin_rsplit n w = bin_rsplit_aux n (fst w) (snd w) []" - -fun bin_rsplitl_aux :: "nat \ nat \ int \ int list \ int list" - where "bin_rsplitl_aux n m c bs = - (if m = 0 \ n = 0 then bs - else - let (a, b) = bin_split (min m n) c - in bin_rsplitl_aux n (m - n) a (b # bs))" - -definition bin_rsplitl :: "nat \ nat \ int \ int list" - where "bin_rsplitl n w = bin_rsplitl_aux n (fst w) (snd w) []" - -declare bin_rsplit_aux.simps [simp del] -declare bin_rsplitl_aux.simps [simp del] - -lemma bin_nth_cat: - "bin_nth (bin_cat x k y) n = - (if n < k then bin_nth y n else bin_nth x (n - k))" - apply (induct k arbitrary: n y) - apply clarsimp - apply (case_tac n, auto) - done - -lemma bin_nth_split: - "bin_split n c = (a, b) \ - (\k. bin_nth a k = bin_nth c (n + k)) \ - (\k. bin_nth b k = (k < n \ bin_nth c k))" - apply (induct n arbitrary: b c) - apply clarsimp - apply (clarsimp simp: Let_def split: prod.split_asm) - apply (case_tac k) - apply auto - done - -lemma bin_cat_zero [simp]: "bin_cat 0 n w = bintrunc n w" - by (induct n arbitrary: w) auto - -lemma bintr_cat1: "bintrunc (k + n) (bin_cat a n b) = bin_cat (bintrunc k a) n b" - by (induct n arbitrary: b) auto - -lemma bintr_cat: "bintrunc m (bin_cat a n b) = - bin_cat (bintrunc (m - n) a) n (bintrunc (min m n) b)" - by (rule bin_eqI) (auto simp: bin_nth_cat nth_bintr) - -lemma bintr_cat_same [simp]: "bintrunc n (bin_cat a n b) = bintrunc n b" - by (auto simp add : bintr_cat) - -lemma cat_bintr [simp]: "bin_cat a n (bintrunc n b) = bin_cat a n b" - by (induct n arbitrary: b) auto - -lemma split_bintrunc: "bin_split n c = (a, b) \ b = bintrunc n c" - by (induct n arbitrary: b c) (auto simp: Let_def split: prod.split_asm) - -lemma bin_cat_split: "bin_split n w = (u, v) \ w = bin_cat u n v" - by (induct n arbitrary: v w) (auto simp: Let_def split: prod.split_asm) - -lemma bin_split_cat: "bin_split n (bin_cat v n w) = (v, bintrunc n w)" - by (induct n arbitrary: w) auto - -lemma bin_split_zero [simp]: "bin_split n 0 = (0, 0)" - by (induct n) auto - -lemma bin_split_minus1 [simp]: - "bin_split n (- 1) = (- 1, bintrunc n (- 1))" - by (induct n) auto - -lemma bin_split_trunc: - "bin_split (min m n) c = (a, b) \ - bin_split n (bintrunc m c) = (bintrunc (m - n) a, b)" - apply (induct n arbitrary: m b c, clarsimp) - apply (simp add: bin_rest_trunc Let_def split: prod.split_asm) - apply (case_tac m) - apply (auto simp: Let_def split: prod.split_asm) - done - -lemma bin_split_trunc1: - "bin_split n c = (a, b) \ - bin_split n (bintrunc m c) = (bintrunc (m - n) a, bintrunc m b)" - apply (induct n arbitrary: m b c, clarsimp) - apply (simp add: bin_rest_trunc Let_def split: prod.split_asm) - apply (case_tac m) - apply (auto simp: Let_def split: prod.split_asm) - done - -lemma bin_cat_num: "bin_cat a n b = a * 2 ^ n + bintrunc n b" - apply (induct n arbitrary: b) - apply clarsimp - apply (simp add: Bit_def) - done - -lemma bin_split_num: "bin_split n b = (b div 2 ^ n, b mod 2 ^ n)" - apply (induct n arbitrary: b) - apply simp - apply (simp add: bin_rest_def zdiv_zmult2_eq) - apply (case_tac b rule: bin_exhaust) - apply simp - apply (simp add: Bit_def mod_mult_mult1 pos_zmod_mult_2 add.commute) - done - -end diff -r 6d2effbbf8d4 -r ff9efdc84289 src/HOL/Word/Bits.thy --- a/src/HOL/Word/Bits.thy Sat Apr 20 18:02:22 2019 +0000 +++ b/src/HOL/Word/Bits.thy Mon Apr 22 06:28:17 2019 +0000 @@ -20,8 +20,6 @@ bind slightly stronger than \*\. \ -text \Testing and shifting operations.\ - class bits = bit + fixes test_bit :: "'a \ nat \ bool" (infixl "!!" 100) and lsb :: "'a \ bool" diff -r 6d2effbbf8d4 -r ff9efdc84289 src/HOL/Word/Bits_Int.thy --- a/src/HOL/Word/Bits_Int.thy Sat Apr 20 18:02:22 2019 +0000 +++ b/src/HOL/Word/Bits_Int.thy Mon Apr 22 06:28:17 2019 +0000 @@ -6,12 +6,1183 @@ and converting them to and from lists of bools. *) -section \Bitwise Operations on Binary Integers\ +section \Bitwise Operations on integers\ theory Bits_Int - imports Bits Bit_Representation Bool_List_Representation + imports Bits Misc_Auxiliary begin +subsection \Implicit bit representation of \<^typ>\int\\ + +definition Bit :: "int \ bool \ int" (infixl "BIT" 90) + where "k BIT b = (if b then 1 else 0) + k + k" + +lemma Bit_B0: "k BIT False = k + k" + by (simp add: Bit_def) + +lemma Bit_B1: "k BIT True = k + k + 1" + by (simp add: Bit_def) + +lemma Bit_B0_2t: "k BIT False = 2 * k" + by (rule trans, rule Bit_B0) simp + +lemma Bit_B1_2t: "k BIT True = 2 * k + 1" + by (rule trans, rule Bit_B1) simp + +lemma uminus_Bit_eq: + "- k BIT b = (- k - of_bool b) BIT b" + by (cases b) (simp_all add: Bit_def) + +lemma power_BIT: "2 ^ Suc n - 1 = (2 ^ n - 1) BIT True" + by (simp add: Bit_B1) + +definition bin_last :: "int \ bool" + where "bin_last w \ w mod 2 = 1" + +lemma bin_last_odd: "bin_last = odd" + by (rule ext) (simp add: bin_last_def even_iff_mod_2_eq_zero) + +definition bin_rest :: "int \ int" + where "bin_rest w = w div 2" + +lemma bin_rl_simp [simp]: "bin_rest w BIT bin_last w = w" + unfolding bin_rest_def bin_last_def Bit_def + by (cases "w mod 2 = 0") (use div_mult_mod_eq [of w 2] in simp_all) + +lemma bin_rest_BIT [simp]: "bin_rest (x BIT b) = x" + unfolding bin_rest_def Bit_def + by (cases b) simp_all + +lemma bin_last_BIT [simp]: "bin_last (x BIT b) = b" + unfolding bin_last_def Bit_def + by (cases b) simp_all + +lemma BIT_eq_iff [iff]: "u BIT b = v BIT c \ u = v \ b = c" + by (auto simp: Bit_def) arith+ + +lemma BIT_bin_simps [simp]: + "numeral k BIT False = numeral (Num.Bit0 k)" + "numeral k BIT True = numeral (Num.Bit1 k)" + "(- numeral k) BIT False = - numeral (Num.Bit0 k)" + "(- numeral k) BIT True = - numeral (Num.BitM k)" + unfolding numeral.simps numeral_BitM + by (simp_all add: Bit_def del: arith_simps add_numeral_special diff_numeral_special) + +lemma BIT_special_simps [simp]: + shows "0 BIT False = 0" + and "0 BIT True = 1" + and "1 BIT False = 2" + and "1 BIT True = 3" + and "(- 1) BIT False = - 2" + and "(- 1) BIT True = - 1" + by (simp_all add: Bit_def) + +lemma Bit_eq_0_iff: "w BIT b = 0 \ w = 0 \ \ b" + by (auto simp: Bit_def) arith + +lemma Bit_eq_m1_iff: "w BIT b = -1 \ w = -1 \ b" + by (auto simp: Bit_def) arith + +lemma BitM_inc: "Num.BitM (Num.inc w) = Num.Bit1 w" + by (induct w) simp_all + +lemma expand_BIT: + "numeral (Num.Bit0 w) = numeral w BIT False" + "numeral (Num.Bit1 w) = numeral w BIT True" + "- numeral (Num.Bit0 w) = (- numeral w) BIT False" + "- numeral (Num.Bit1 w) = (- numeral (w + Num.One)) BIT True" + by (simp_all add: add_One BitM_inc) + +lemma bin_last_numeral_simps [simp]: + "\ bin_last 0" + "bin_last 1" + "bin_last (- 1)" + "bin_last Numeral1" + "\ bin_last (numeral (Num.Bit0 w))" + "bin_last (numeral (Num.Bit1 w))" + "\ bin_last (- numeral (Num.Bit0 w))" + "bin_last (- numeral (Num.Bit1 w))" + by (simp_all add: bin_last_def zmod_zminus1_eq_if) (auto simp add: divmod_def) + +lemma bin_rest_numeral_simps [simp]: + "bin_rest 0 = 0" + "bin_rest 1 = 0" + "bin_rest (- 1) = - 1" + "bin_rest Numeral1 = 0" + "bin_rest (numeral (Num.Bit0 w)) = numeral w" + "bin_rest (numeral (Num.Bit1 w)) = numeral w" + "bin_rest (- numeral (Num.Bit0 w)) = - numeral w" + "bin_rest (- numeral (Num.Bit1 w)) = - numeral (w + Num.One)" + by (simp_all add: bin_rest_def zdiv_zminus1_eq_if) (auto simp add: divmod_def) + +lemma less_Bits: "v BIT b < w BIT c \ v < w \ v \ w \ \ b \ c" + by (auto simp: Bit_def) + +lemma le_Bits: "v BIT b \ w BIT c \ v < w \ v \ w \ (\ b \ c)" + by (auto simp: Bit_def) + +lemma pred_BIT_simps [simp]: + "x BIT False - 1 = (x - 1) BIT True" + "x BIT True - 1 = x BIT False" + by (simp_all add: Bit_B0_2t Bit_B1_2t) + +lemma succ_BIT_simps [simp]: + "x BIT False + 1 = x BIT True" + "x BIT True + 1 = (x + 1) BIT False" + by (simp_all add: Bit_B0_2t Bit_B1_2t) + +lemma add_BIT_simps [simp]: + "x BIT False + y BIT False = (x + y) BIT False" + "x BIT False + y BIT True = (x + y) BIT True" + "x BIT True + y BIT False = (x + y) BIT True" + "x BIT True + y BIT True = (x + y + 1) BIT False" + by (simp_all add: Bit_B0_2t Bit_B1_2t) + +lemma mult_BIT_simps [simp]: + "x BIT False * y = (x * y) BIT False" + "x * y BIT False = (x * y) BIT False" + "x BIT True * y = (x * y) BIT False + y" + by (simp_all add: Bit_B0_2t Bit_B1_2t algebra_simps) + +lemma B_mod_2': "X = 2 \ (w BIT True) mod X = 1 \ (w BIT False) mod X = 0" + by (simp add: Bit_B0 Bit_B1) + +lemma bin_ex_rl: "\w b. w BIT b = bin" + by (metis bin_rl_simp) + +lemma bin_exhaust: "(\x b. bin = x BIT b \ Q) \ Q" +by (metis bin_ex_rl) + +lemma bin_abs_lem: "bin = (w BIT b) \ bin \ -1 \ bin \ 0 \ nat \w\ < nat \bin\" + apply clarsimp + apply (unfold Bit_def) + apply (cases b) + apply (clarsimp, arith) + apply (clarsimp, arith) + done + +lemma bin_induct: + assumes PPls: "P 0" + and PMin: "P (- 1)" + and PBit: "\bin bit. P bin \ P (bin BIT bit)" + shows "P bin" + apply (rule_tac P=P and a=bin and f1="nat \ abs" in wf_measure [THEN wf_induct]) + apply (simp add: measure_def inv_image_def) + apply (case_tac x rule: bin_exhaust) + apply (frule bin_abs_lem) + apply (auto simp add : PPls PMin PBit) + done + +lemma Bit_div2 [simp]: "(w BIT b) div 2 = w" + unfolding bin_rest_def [symmetric] by (rule bin_rest_BIT) + +lemma bin_rl_eqI: "\bin_rest x = bin_rest y; bin_last x = bin_last y\ \ x = y" + by (metis (mono_tags) BIT_eq_iff bin_ex_rl bin_last_BIT bin_rest_BIT) + +lemma twice_conv_BIT: "2 * x = x BIT False" + by (rule bin_rl_eqI) (simp_all, simp_all add: bin_rest_def bin_last_def) + +lemma BIT_lt0 [simp]: "x BIT b < 0 \ x < 0" +by(cases b)(auto simp add: Bit_def) + +lemma BIT_ge0 [simp]: "x BIT b \ 0 \ x \ 0" +by(cases b)(auto simp add: Bit_def) + +lemma [simp]: + shows bin_rest_lt0: "bin_rest i < 0 \ i < 0" + and bin_rest_ge_0: "bin_rest i \ 0 \ i \ 0" +by(auto simp add: bin_rest_def) + +lemma bin_rest_gt_0 [simp]: "bin_rest x > 0 \ x > 1" +by(simp add: bin_rest_def add1_zle_eq pos_imp_zdiv_pos_iff) (metis add1_zle_eq one_add_one) + + +subsection \Explicit bit representation of \<^typ>\int\\ + +primrec bl_to_bin_aux :: "bool list \ int \ int" + where + Nil: "bl_to_bin_aux [] w = w" + | Cons: "bl_to_bin_aux (b # bs) w = bl_to_bin_aux bs (w BIT b)" + +definition bl_to_bin :: "bool list \ int" + where "bl_to_bin bs = bl_to_bin_aux bs 0" + +primrec bin_to_bl_aux :: "nat \ int \ bool list \ bool list" + where + Z: "bin_to_bl_aux 0 w bl = bl" + | Suc: "bin_to_bl_aux (Suc n) w bl = bin_to_bl_aux n (bin_rest w) ((bin_last w) # bl)" + +definition bin_to_bl :: "nat \ int \ bool list" + where "bin_to_bl n w = bin_to_bl_aux n w []" + +lemma bin_to_bl_aux_zero_minus_simp [simp]: + "0 < n \ bin_to_bl_aux n 0 bl = bin_to_bl_aux (n - 1) 0 (False # bl)" + by (cases n) auto + +lemma bin_to_bl_aux_minus1_minus_simp [simp]: + "0 < n \ bin_to_bl_aux n (- 1) bl = bin_to_bl_aux (n - 1) (- 1) (True # bl)" + by (cases n) auto + +lemma bin_to_bl_aux_one_minus_simp [simp]: + "0 < n \ bin_to_bl_aux n 1 bl = bin_to_bl_aux (n - 1) 0 (True # bl)" + by (cases n) auto + +lemma bin_to_bl_aux_Bit_minus_simp [simp]: + "0 < n \ bin_to_bl_aux n (w BIT b) bl = bin_to_bl_aux (n - 1) w (b # bl)" + by (cases n) auto + +lemma bin_to_bl_aux_Bit0_minus_simp [simp]: + "0 < n \ + bin_to_bl_aux n (numeral (Num.Bit0 w)) bl = bin_to_bl_aux (n - 1) (numeral w) (False # bl)" + by (cases n) auto + +lemma bin_to_bl_aux_Bit1_minus_simp [simp]: + "0 < n \ + bin_to_bl_aux n (numeral (Num.Bit1 w)) bl = bin_to_bl_aux (n - 1) (numeral w) (True # bl)" + by (cases n) auto + +lemma bl_to_bin_aux_append: "bl_to_bin_aux (bs @ cs) w = bl_to_bin_aux cs (bl_to_bin_aux bs w)" + by (induct bs arbitrary: w) auto + +lemma bin_to_bl_aux_append: "bin_to_bl_aux n w bs @ cs = bin_to_bl_aux n w (bs @ cs)" + by (induct n arbitrary: w bs) auto + +lemma bl_to_bin_append: "bl_to_bin (bs @ cs) = bl_to_bin_aux cs (bl_to_bin bs)" + unfolding bl_to_bin_def by (rule bl_to_bin_aux_append) + +lemma bin_to_bl_aux_alt: "bin_to_bl_aux n w bs = bin_to_bl n w @ bs" + by (simp add: bin_to_bl_def bin_to_bl_aux_append) + +lemma bin_to_bl_0 [simp]: "bin_to_bl 0 bs = []" + by (auto simp: bin_to_bl_def) + +lemma size_bin_to_bl_aux: "length (bin_to_bl_aux n w bs) = n + length bs" + by (induct n arbitrary: w bs) auto + +lemma size_bin_to_bl [simp]: "length (bin_to_bl n w) = n" + by (simp add: bin_to_bl_def size_bin_to_bl_aux) + +lemma bl_bin_bl': "bin_to_bl (n + length bs) (bl_to_bin_aux bs w) = bin_to_bl_aux n w bs" + apply (induct bs arbitrary: w n) + apply auto + apply (simp_all only: add_Suc [symmetric]) + apply (auto simp add: bin_to_bl_def) + done + +lemma bl_bin_bl [simp]: "bin_to_bl (length bs) (bl_to_bin bs) = bs" + unfolding bl_to_bin_def + apply (rule box_equals) + apply (rule bl_bin_bl') + prefer 2 + apply (rule bin_to_bl_aux.Z) + apply simp + done + +lemma bl_to_bin_inj: "bl_to_bin bs = bl_to_bin cs \ length bs = length cs \ bs = cs" + apply (rule_tac box_equals) + defer + apply (rule bl_bin_bl) + apply (rule bl_bin_bl) + apply simp + done + +lemma bl_to_bin_False [simp]: "bl_to_bin (False # bl) = bl_to_bin bl" + by (auto simp: bl_to_bin_def) + +lemma bl_to_bin_Nil [simp]: "bl_to_bin [] = 0" + by (auto simp: bl_to_bin_def) + +lemma bin_to_bl_zero_aux: "bin_to_bl_aux n 0 bl = replicate n False @ bl" + by (induct n arbitrary: bl) (auto simp: replicate_app_Cons_same) + +lemma bin_to_bl_zero: "bin_to_bl n 0 = replicate n False" + by (simp add: bin_to_bl_def bin_to_bl_zero_aux) + +lemma bin_to_bl_minus1_aux: "bin_to_bl_aux n (- 1) bl = replicate n True @ bl" + by (induct n arbitrary: bl) (auto simp: replicate_app_Cons_same) + +lemma bin_to_bl_minus1: "bin_to_bl n (- 1) = replicate n True" + by (simp add: bin_to_bl_def bin_to_bl_minus1_aux) + +lemma bl_to_bin_BIT: + "bl_to_bin bs BIT b = bl_to_bin (bs @ [b])" + by (simp add: bl_to_bin_append) + + +subsection \Bit projection\ + +primrec bin_nth :: "int \ nat \ bool" + where + Z: "bin_nth w 0 \ bin_last w" + | Suc: "bin_nth w (Suc n) \ bin_nth (bin_rest w) n" + +lemma bin_nth_eq_mod: + "bin_nth w n \ odd (w div 2 ^ n)" + by (induction n arbitrary: w) (simp_all add: bin_last_def bin_rest_def odd_iff_mod_2_eq_one zdiv_zmult2_eq) + +lemma bin_nth_eq_iff: "bin_nth x = bin_nth y \ x = y" +proof - + have bin_nth_lem [rule_format]: "\y. bin_nth x = bin_nth y \ x = y" + apply (induct x rule: bin_induct) + apply safe + apply (erule rev_mp) + apply (induct_tac y rule: bin_induct) + apply safe + apply (drule_tac x=0 in fun_cong, force) + apply (erule notE, rule ext, drule_tac x="Suc x" in fun_cong, force) + apply (drule_tac x=0 in fun_cong, force) + apply (erule rev_mp) + apply (induct_tac y rule: bin_induct) + apply safe + apply (drule_tac x=0 in fun_cong, force) + apply (erule notE, rule ext, drule_tac x="Suc x" in fun_cong, force) + apply (metis Bit_eq_m1_iff Z bin_last_BIT) + apply (case_tac y rule: bin_exhaust) + apply clarify + apply (erule allE) + apply (erule impE) + prefer 2 + apply (erule conjI) + apply (drule_tac x=0 in fun_cong, force) + apply (rule ext) + apply (drule_tac x="Suc x" for x in fun_cong, force) + done + show ?thesis + by (auto elim: bin_nth_lem) +qed + +lemma bin_eqI: + "x = y" if "\n. bin_nth x n \ bin_nth y n" + using that bin_nth_eq_iff [of x y] by (simp add: fun_eq_iff) + +lemma bin_eq_iff: "x = y \ (\n. bin_nth x n = bin_nth y n)" + using bin_nth_eq_iff by auto + +lemma bin_nth_zero [simp]: "\ bin_nth 0 n" + by (induct n) auto + +lemma bin_nth_1 [simp]: "bin_nth 1 n \ n = 0" + by (cases n) simp_all + +lemma bin_nth_minus1 [simp]: "bin_nth (- 1) n" + by (induct n) auto + +lemma bin_nth_0_BIT: "bin_nth (w BIT b) 0 \ b" + by auto + +lemma bin_nth_Suc_BIT: "bin_nth (w BIT b) (Suc n) = bin_nth w n" + by auto + +lemma bin_nth_minus [simp]: "0 < n \ bin_nth (w BIT b) n = bin_nth w (n - 1)" + by (cases n) auto + +lemma bin_nth_numeral: "bin_rest x = y \ bin_nth x (numeral n) = bin_nth y (pred_numeral n)" + by (simp add: numeral_eq_Suc) + +lemmas bin_nth_numeral_simps [simp] = + bin_nth_numeral [OF bin_rest_numeral_simps(2)] + bin_nth_numeral [OF bin_rest_numeral_simps(5)] + bin_nth_numeral [OF bin_rest_numeral_simps(6)] + bin_nth_numeral [OF bin_rest_numeral_simps(7)] + bin_nth_numeral [OF bin_rest_numeral_simps(8)] + +lemmas bin_nth_simps = + bin_nth.Z bin_nth.Suc bin_nth_zero bin_nth_minus1 + bin_nth_numeral_simps + +lemma nth_2p_bin: "bin_nth (2 ^ n) m = (m = n)" \ \for use when simplifying with \bin_nth_Bit\\ + apply (induct n arbitrary: m) + apply clarsimp + apply safe + apply (case_tac m) + apply (auto simp: Bit_B0_2t [symmetric]) + done + +lemma nth_rest_power_bin: "bin_nth ((bin_rest ^^ k) w) n = bin_nth w (n + k)" + apply (induct k arbitrary: n) + apply clarsimp + apply clarsimp + apply (simp only: bin_nth.Suc [symmetric] add_Suc) + done + +lemma bin_nth_numeral_unfold: + "bin_nth (numeral (num.Bit0 x)) n \ n > 0 \ bin_nth (numeral x) (n - 1)" + "bin_nth (numeral (num.Bit1 x)) n \ (n > 0 \ bin_nth (numeral x) (n - 1))" +by(case_tac [!] n) simp_all + + +subsection \Truncating\ + +definition bin_sign :: "int \ int" + where "bin_sign k = (if k \ 0 then 0 else - 1)" + +lemma bin_sign_simps [simp]: + "bin_sign 0 = 0" + "bin_sign 1 = 0" + "bin_sign (- 1) = - 1" + "bin_sign (numeral k) = 0" + "bin_sign (- numeral k) = -1" + "bin_sign (w BIT b) = bin_sign w" + by (simp_all add: bin_sign_def Bit_def) + +lemma bin_sign_rest [simp]: "bin_sign (bin_rest w) = bin_sign w" + by (cases w rule: bin_exhaust) auto + +primrec bintrunc :: "nat \ int \ int" + where + Z : "bintrunc 0 bin = 0" + | Suc : "bintrunc (Suc n) bin = bintrunc n (bin_rest bin) BIT (bin_last bin)" + +primrec sbintrunc :: "nat \ int \ int" + where + Z : "sbintrunc 0 bin = (if bin_last bin then -1 else 0)" + | Suc : "sbintrunc (Suc n) bin = sbintrunc n (bin_rest bin) BIT (bin_last bin)" + +lemma bintrunc_mod2p: "bintrunc n w = w mod 2 ^ n" + by (induct n arbitrary: w) (auto simp add: bin_last_def bin_rest_def Bit_def zmod_zmult2_eq) + +lemma sbintrunc_mod2p: "sbintrunc n w = (w + 2 ^ n) mod 2 ^ Suc n - 2 ^ n" +proof (induction n arbitrary: w) + case 0 + then show ?case + by (auto simp add: bin_last_odd odd_iff_mod_2_eq_one) +next + case (Suc n) + moreover have "((bin_rest w + 2 ^ n) mod (2 * 2 ^ n) - 2 ^ n) BIT bin_last w = + (w + 2 * 2 ^ n) mod (4 * 2 ^ n) - 2 * 2 ^ n" + proof (cases w rule: parity_cases) + case even + then show ?thesis + by (simp add: bin_last_odd bin_rest_def Bit_B0_2t mult_mod_right) + next + case odd + then have "2 * (w div 2) = w - 1" + using minus_mod_eq_mult_div [of w 2] by simp + moreover have "(2 * 2 ^ n + w - 1) mod (2 * 2 * 2 ^ n) + 1 = (2 * 2 ^ n + w) mod (2 * 2 * 2 ^ n)" + using odd emep1 [of "2 * 2 ^ n + w - 1" "2 * 2 * 2 ^ n"] by simp + ultimately show ?thesis + using odd by (simp add: bin_last_odd bin_rest_def Bit_B1_2t mult_mod_right) (simp add: algebra_simps) + qed + ultimately show ?case + by simp +qed + +lemma sign_bintr: "bin_sign (bintrunc n w) = 0" + by (simp add: bintrunc_mod2p bin_sign_def) + +lemma bintrunc_n_0 [simp]: "bintrunc n 0 = 0" + by (simp add: bintrunc_mod2p) + +lemma sbintrunc_n_0 [simp]: "sbintrunc n 0 = 0" + by (simp add: sbintrunc_mod2p) + +lemma sbintrunc_n_minus1 [simp]: "sbintrunc n (- 1) = -1" + by (induct n) auto + +lemma bintrunc_Suc_numeral: + "bintrunc (Suc n) 1 = 1" + "bintrunc (Suc n) (- 1) = bintrunc n (- 1) BIT True" + "bintrunc (Suc n) (numeral (Num.Bit0 w)) = bintrunc n (numeral w) BIT False" + "bintrunc (Suc n) (numeral (Num.Bit1 w)) = bintrunc n (numeral w) BIT True" + "bintrunc (Suc n) (- numeral (Num.Bit0 w)) = bintrunc n (- numeral w) BIT False" + "bintrunc (Suc n) (- numeral (Num.Bit1 w)) = bintrunc n (- numeral (w + Num.One)) BIT True" + by simp_all + +lemma sbintrunc_0_numeral [simp]: + "sbintrunc 0 1 = -1" + "sbintrunc 0 (numeral (Num.Bit0 w)) = 0" + "sbintrunc 0 (numeral (Num.Bit1 w)) = -1" + "sbintrunc 0 (- numeral (Num.Bit0 w)) = 0" + "sbintrunc 0 (- numeral (Num.Bit1 w)) = -1" + by simp_all + +lemma sbintrunc_Suc_numeral: + "sbintrunc (Suc n) 1 = 1" + "sbintrunc (Suc n) (numeral (Num.Bit0 w)) = sbintrunc n (numeral w) BIT False" + "sbintrunc (Suc n) (numeral (Num.Bit1 w)) = sbintrunc n (numeral w) BIT True" + "sbintrunc (Suc n) (- numeral (Num.Bit0 w)) = sbintrunc n (- numeral w) BIT False" + "sbintrunc (Suc n) (- numeral (Num.Bit1 w)) = sbintrunc n (- numeral (w + Num.One)) BIT True" + by simp_all + +lemma bin_sign_lem: "(bin_sign (sbintrunc n bin) = -1) = bin_nth bin n" + apply (induct n arbitrary: bin) + apply (case_tac bin rule: bin_exhaust, case_tac b, auto) + done + +lemma nth_bintr: "bin_nth (bintrunc m w) n \ n < m \ bin_nth w n" + apply (induct n arbitrary: w m) + apply (case_tac m, auto)[1] + apply (case_tac m, auto)[1] + done + +lemma nth_sbintr: "bin_nth (sbintrunc m w) n = (if n < m then bin_nth w n else bin_nth w m)" + apply (induct n arbitrary: w m) + apply (case_tac m) + apply simp_all + apply (case_tac m) + apply simp_all + done + +lemma bin_nth_Bit: "bin_nth (w BIT b) n \ n = 0 \ b \ (\m. n = Suc m \ bin_nth w m)" + by (cases n) auto + +lemma bin_nth_Bit0: + "bin_nth (numeral (Num.Bit0 w)) n \ + (\m. n = Suc m \ bin_nth (numeral w) m)" + using bin_nth_Bit [where w="numeral w" and b="False"] by simp + +lemma bin_nth_Bit1: + "bin_nth (numeral (Num.Bit1 w)) n \ + n = 0 \ (\m. n = Suc m \ bin_nth (numeral w) m)" + using bin_nth_Bit [where w="numeral w" and b="True"] by simp + +lemma bintrunc_bintrunc_l: "n \ m \ bintrunc m (bintrunc n w) = bintrunc n w" + by (rule bin_eqI) (auto simp: nth_bintr) + +lemma sbintrunc_sbintrunc_l: "n \ m \ sbintrunc m (sbintrunc n w) = sbintrunc n w" + by (rule bin_eqI) (auto simp: nth_sbintr) + +lemma bintrunc_bintrunc_ge: "n \ m \ bintrunc n (bintrunc m w) = bintrunc n w" + by (rule bin_eqI) (auto simp: nth_bintr) + +lemma bintrunc_bintrunc_min [simp]: "bintrunc m (bintrunc n w) = bintrunc (min m n) w" + by (rule bin_eqI) (auto simp: nth_bintr) + +lemma sbintrunc_sbintrunc_min [simp]: "sbintrunc m (sbintrunc n w) = sbintrunc (min m n) w" + by (rule bin_eqI) (auto simp: nth_sbintr min.absorb1 min.absorb2) + +lemmas bintrunc_Pls = + bintrunc.Suc [where bin="0", simplified bin_last_numeral_simps bin_rest_numeral_simps] + +lemmas bintrunc_Min [simp] = + bintrunc.Suc [where bin="-1", simplified bin_last_numeral_simps bin_rest_numeral_simps] + +lemmas bintrunc_BIT [simp] = + bintrunc.Suc [where bin="w BIT b", simplified bin_last_BIT bin_rest_BIT] for w b + +lemmas bintrunc_Sucs = bintrunc_Pls bintrunc_Min bintrunc_BIT + bintrunc_Suc_numeral + +lemmas sbintrunc_Suc_Pls = + sbintrunc.Suc [where bin="0", simplified bin_last_numeral_simps bin_rest_numeral_simps] + +lemmas sbintrunc_Suc_Min = + sbintrunc.Suc [where bin="-1", simplified bin_last_numeral_simps bin_rest_numeral_simps] + +lemmas sbintrunc_Suc_BIT [simp] = + sbintrunc.Suc [where bin="w BIT b", simplified bin_last_BIT bin_rest_BIT] for w b + +lemmas sbintrunc_Sucs = sbintrunc_Suc_Pls sbintrunc_Suc_Min sbintrunc_Suc_BIT + sbintrunc_Suc_numeral + +lemmas sbintrunc_Pls = + sbintrunc.Z [where bin="0", simplified bin_last_numeral_simps bin_rest_numeral_simps] + +lemmas sbintrunc_Min = + sbintrunc.Z [where bin="-1", simplified bin_last_numeral_simps bin_rest_numeral_simps] + +lemmas sbintrunc_0_BIT_B0 [simp] = + sbintrunc.Z [where bin="w BIT False", simplified bin_last_numeral_simps bin_rest_numeral_simps] + for w + +lemmas sbintrunc_0_BIT_B1 [simp] = + sbintrunc.Z [where bin="w BIT True", simplified bin_last_BIT bin_rest_numeral_simps] + for w + +lemmas sbintrunc_0_simps = + sbintrunc_Pls sbintrunc_Min sbintrunc_0_BIT_B0 sbintrunc_0_BIT_B1 + +lemmas bintrunc_simps = bintrunc.Z bintrunc_Sucs +lemmas sbintrunc_simps = sbintrunc_0_simps sbintrunc_Sucs + +lemma bintrunc_minus: "0 < n \ bintrunc (Suc (n - 1)) w = bintrunc n w" + by auto + +lemma sbintrunc_minus: "0 < n \ sbintrunc (Suc (n - 1)) w = sbintrunc n w" + by auto + +lemmas bintrunc_minus_simps = + bintrunc_Sucs [THEN [2] bintrunc_minus [symmetric, THEN trans]] +lemmas sbintrunc_minus_simps = + sbintrunc_Sucs [THEN [2] sbintrunc_minus [symmetric, THEN trans]] + +lemmas thobini1 = arg_cong [where f = "\w. w BIT b"] for b + +lemmas bintrunc_BIT_I = trans [OF bintrunc_BIT thobini1] +lemmas bintrunc_Min_I = trans [OF bintrunc_Min thobini1] + +lemmas bmsts = bintrunc_minus_simps(1-3) [THEN thobini1 [THEN [2] trans]] +lemmas bintrunc_Pls_minus_I = bmsts(1) +lemmas bintrunc_Min_minus_I = bmsts(2) +lemmas bintrunc_BIT_minus_I = bmsts(3) + +lemma bintrunc_Suc_lem: "bintrunc (Suc n) x = y \ m = Suc n \ bintrunc m x = y" + by auto + +lemmas bintrunc_Suc_Ialts = + bintrunc_Min_I [THEN bintrunc_Suc_lem] + bintrunc_BIT_I [THEN bintrunc_Suc_lem] + +lemmas sbintrunc_BIT_I = trans [OF sbintrunc_Suc_BIT thobini1] + +lemmas sbintrunc_Suc_Is = + sbintrunc_Sucs(1-3) [THEN thobini1 [THEN [2] trans]] + +lemmas sbintrunc_Suc_minus_Is = + sbintrunc_minus_simps(1-3) [THEN thobini1 [THEN [2] trans]] + +lemma sbintrunc_Suc_lem: "sbintrunc (Suc n) x = y \ m = Suc n \ sbintrunc m x = y" + by auto + +lemmas sbintrunc_Suc_Ialts = + sbintrunc_Suc_Is [THEN sbintrunc_Suc_lem] + +lemma sbintrunc_bintrunc_lt: "m > n \ sbintrunc n (bintrunc m w) = sbintrunc n w" + by (rule bin_eqI) (auto simp: nth_sbintr nth_bintr) + +lemma bintrunc_sbintrunc_le: "m \ Suc n \ bintrunc m (sbintrunc n w) = bintrunc m w" + apply (rule bin_eqI) + using le_Suc_eq less_Suc_eq_le apply (auto simp: nth_sbintr nth_bintr) + done + +lemmas bintrunc_sbintrunc [simp] = order_refl [THEN bintrunc_sbintrunc_le] +lemmas sbintrunc_bintrunc [simp] = lessI [THEN sbintrunc_bintrunc_lt] +lemmas bintrunc_bintrunc [simp] = order_refl [THEN bintrunc_bintrunc_l] +lemmas sbintrunc_sbintrunc [simp] = order_refl [THEN sbintrunc_sbintrunc_l] + +lemma bintrunc_sbintrunc' [simp]: "0 < n \ bintrunc n (sbintrunc (n - 1) w) = bintrunc n w" + by (cases n) (auto simp del: bintrunc.Suc) + +lemma sbintrunc_bintrunc' [simp]: "0 < n \ sbintrunc (n - 1) (bintrunc n w) = sbintrunc (n - 1) w" + by (cases n) (auto simp del: bintrunc.Suc) + +lemma bin_sbin_eq_iff: "bintrunc (Suc n) x = bintrunc (Suc n) y \ sbintrunc n x = sbintrunc n y" + apply (rule iffI) + apply (rule box_equals [OF _ sbintrunc_bintrunc sbintrunc_bintrunc]) + apply simp + apply (rule box_equals [OF _ bintrunc_sbintrunc bintrunc_sbintrunc]) + apply simp + done + +lemma bin_sbin_eq_iff': + "0 < n \ bintrunc n x = bintrunc n y \ sbintrunc (n - 1) x = sbintrunc (n - 1) y" + by (cases n) (simp_all add: bin_sbin_eq_iff del: bintrunc.Suc) + +lemmas bintrunc_sbintruncS0 [simp] = bintrunc_sbintrunc' [unfolded One_nat_def] +lemmas sbintrunc_bintruncS0 [simp] = sbintrunc_bintrunc' [unfolded One_nat_def] + +lemmas bintrunc_bintrunc_l' = le_add1 [THEN bintrunc_bintrunc_l] +lemmas sbintrunc_sbintrunc_l' = le_add1 [THEN sbintrunc_sbintrunc_l] + +(* although bintrunc_minus_simps, if added to default simpset, + tends to get applied where it's not wanted in developing the theories, + we get a version for when the word length is given literally *) + +lemmas nat_non0_gr = + trans [OF iszero_def [THEN Not_eq_iff [THEN iffD2]] refl] + +lemma bintrunc_numeral: + "bintrunc (numeral k) x = bintrunc (pred_numeral k) (bin_rest x) BIT bin_last x" + by (simp add: numeral_eq_Suc) + +lemma sbintrunc_numeral: + "sbintrunc (numeral k) x = sbintrunc (pred_numeral k) (bin_rest x) BIT bin_last x" + by (simp add: numeral_eq_Suc) + +lemma bintrunc_numeral_simps [simp]: + "bintrunc (numeral k) (numeral (Num.Bit0 w)) = bintrunc (pred_numeral k) (numeral w) BIT False" + "bintrunc (numeral k) (numeral (Num.Bit1 w)) = bintrunc (pred_numeral k) (numeral w) BIT True" + "bintrunc (numeral k) (- numeral (Num.Bit0 w)) = bintrunc (pred_numeral k) (- numeral w) BIT False" + "bintrunc (numeral k) (- numeral (Num.Bit1 w)) = + bintrunc (pred_numeral k) (- numeral (w + Num.One)) BIT True" + "bintrunc (numeral k) 1 = 1" + by (simp_all add: bintrunc_numeral) + +lemma sbintrunc_numeral_simps [simp]: + "sbintrunc (numeral k) (numeral (Num.Bit0 w)) = sbintrunc (pred_numeral k) (numeral w) BIT False" + "sbintrunc (numeral k) (numeral (Num.Bit1 w)) = sbintrunc (pred_numeral k) (numeral w) BIT True" + "sbintrunc (numeral k) (- numeral (Num.Bit0 w)) = + sbintrunc (pred_numeral k) (- numeral w) BIT False" + "sbintrunc (numeral k) (- numeral (Num.Bit1 w)) = + sbintrunc (pred_numeral k) (- numeral (w + Num.One)) BIT True" + "sbintrunc (numeral k) 1 = 1" + by (simp_all add: sbintrunc_numeral) + +lemma no_bintr_alt1: "bintrunc n = (\w. w mod 2 ^ n :: int)" + by (rule ext) (rule bintrunc_mod2p) + +lemma range_bintrunc: "range (bintrunc n) = {i. 0 \ i \ i < 2 ^ n}" + apply (unfold no_bintr_alt1) + apply (auto simp add: image_iff) + apply (rule exI) + apply (rule sym) + using int_mod_lem [symmetric, of "2 ^ n"] + apply auto + done + +lemma no_sbintr_alt2: "sbintrunc n = (\w. (w + 2 ^ n) mod 2 ^ Suc n - 2 ^ n :: int)" + by (rule ext) (simp add : sbintrunc_mod2p) + +lemma range_sbintrunc: "range (sbintrunc n) = {i. - (2 ^ n) \ i \ i < 2 ^ n}" + apply (unfold no_sbintr_alt2) + apply (auto simp add: image_iff eq_diff_eq) + + apply (rule exI) + apply (auto intro: int_mod_lem [THEN iffD1, symmetric]) + done + +lemma sb_inc_lem: "a + 2^k < 0 \ a + 2^k + 2^(Suc k) \ (a + 2^k) mod 2^(Suc k)" + for a :: int + using int_mod_ge' [where n = "2 ^ (Suc k)" and b = "a + 2 ^ k"] + by simp + +lemma sb_inc_lem': "a < - (2^k) \ a + 2^k + 2^(Suc k) \ (a + 2^k) mod 2^(Suc k)" + for a :: int + by (rule sb_inc_lem) simp + +lemma sbintrunc_inc: "x < - (2^n) \ x + 2^(Suc n) \ sbintrunc n x" + unfolding no_sbintr_alt2 by (drule sb_inc_lem') simp + +lemma sb_dec_lem: "0 \ - (2 ^ k) + a \ (a + 2 ^ k) mod (2 * 2 ^ k) \ - (2 ^ k) + a" + for a :: int + using int_mod_le'[where n = "2 ^ (Suc k)" and b = "a + 2 ^ k"] by simp + +lemma sb_dec_lem': "2 ^ k \ a \ (a + 2 ^ k) mod (2 * 2 ^ k) \ - (2 ^ k) + a" + for a :: int + by (rule sb_dec_lem) simp + +lemma sbintrunc_dec: "x \ (2 ^ n) \ x - 2 ^ (Suc n) >= sbintrunc n x" + unfolding no_sbintr_alt2 by (drule sb_dec_lem') simp + +lemma bintr_ge0: "0 \ bintrunc n w" + by (simp add: bintrunc_mod2p) + +lemma bintr_lt2p: "bintrunc n w < 2 ^ n" + by (simp add: bintrunc_mod2p) + +lemma bintr_Min: "bintrunc n (- 1) = 2 ^ n - 1" + by (simp add: bintrunc_mod2p m1mod2k) + +lemma sbintr_ge: "- (2 ^ n) \ sbintrunc n w" + by (simp add: sbintrunc_mod2p) + +lemma sbintr_lt: "sbintrunc n w < 2 ^ n" + by (simp add: sbintrunc_mod2p) + +lemma sign_Pls_ge_0: "bin_sign bin = 0 \ bin \ 0" + for bin :: int + by (simp add: bin_sign_def) + +lemma sign_Min_lt_0: "bin_sign bin = -1 \ bin < 0" + for bin :: int + by (simp add: bin_sign_def) + +lemma bin_rest_trunc: "bin_rest (bintrunc n bin) = bintrunc (n - 1) (bin_rest bin)" + by (induct n arbitrary: bin) auto + +lemma bin_rest_power_trunc: + "(bin_rest ^^ k) (bintrunc n bin) = bintrunc (n - k) ((bin_rest ^^ k) bin)" + by (induct k) (auto simp: bin_rest_trunc) + +lemma bin_rest_trunc_i: "bintrunc n (bin_rest bin) = bin_rest (bintrunc (Suc n) bin)" + by auto + +lemma bin_rest_strunc: "bin_rest (sbintrunc (Suc n) bin) = sbintrunc n (bin_rest bin)" + by (induct n arbitrary: bin) auto + +lemma bintrunc_rest [simp]: "bintrunc n (bin_rest (bintrunc n bin)) = bin_rest (bintrunc n bin)" + apply (induct n arbitrary: bin) + apply simp + apply (case_tac bin rule: bin_exhaust) + apply (auto simp: bintrunc_bintrunc_l) + done + +lemma sbintrunc_rest [simp]: "sbintrunc n (bin_rest (sbintrunc n bin)) = bin_rest (sbintrunc n bin)" + apply (induct n arbitrary: bin) + apply simp + apply (case_tac bin rule: bin_exhaust) + apply (auto simp: bintrunc_bintrunc_l split: bool.splits) + done + +lemma bintrunc_rest': "bintrunc n \ bin_rest \ bintrunc n = bin_rest \ bintrunc n" + by (rule ext) auto + +lemma sbintrunc_rest': "sbintrunc n \ bin_rest \ sbintrunc n = bin_rest \ sbintrunc n" + by (rule ext) auto + +lemma rco_lem: "f \ g \ f = g \ f \ f \ (g \ f) ^^ n = g ^^ n \ f" + apply (rule ext) + apply (induct_tac n) + apply (simp_all (no_asm)) + apply (drule fun_cong) + apply (unfold o_def) + apply (erule trans) + apply simp + done + +lemmas rco_bintr = bintrunc_rest' + [THEN rco_lem [THEN fun_cong], unfolded o_def] +lemmas rco_sbintr = sbintrunc_rest' + [THEN rco_lem [THEN fun_cong], unfolded o_def] + + +subsection \Splitting and concatenation\ + +primrec bin_split :: "nat \ int \ int \ int" + where + Z: "bin_split 0 w = (w, 0)" + | Suc: "bin_split (Suc n) w = + (let (w1, w2) = bin_split n (bin_rest w) + in (w1, w2 BIT bin_last w))" + +lemma [code]: + "bin_split (Suc n) w = (let (w1, w2) = bin_split n (bin_rest w) in (w1, w2 BIT bin_last w))" + "bin_split 0 w = (w, 0)" + by simp_all + +primrec bin_cat :: "int \ nat \ int \ int" + where + Z: "bin_cat w 0 v = w" + | Suc: "bin_cat w (Suc n) v = bin_cat w n (bin_rest v) BIT bin_last v" + +lemma bin_sign_cat: "bin_sign (bin_cat x n y) = bin_sign x" + by (induct n arbitrary: y) auto + +lemma bin_cat_Suc_Bit: "bin_cat w (Suc n) (v BIT b) = bin_cat w n v BIT b" + by auto + +lemma bin_cat_assoc: "bin_cat (bin_cat x m y) n z = bin_cat x (m + n) (bin_cat y n z)" + by (induct n arbitrary: z) auto + +lemma bin_cat_assoc_sym: "bin_cat x m (bin_cat y n z) = bin_cat (bin_cat x (m - n) y) (min m n) z" + apply (induct n arbitrary: z m) + apply clarsimp + apply (case_tac m, auto) + done + +definition bin_rcat :: "nat \ int list \ int" + where "bin_rcat n = foldl (\u v. bin_cat u n v) 0" + +fun bin_rsplit_aux :: "nat \ nat \ int \ int list \ int list" + where "bin_rsplit_aux n m c bs = + (if m = 0 \ n = 0 then bs + else + let (a, b) = bin_split n c + in bin_rsplit_aux n (m - n) a (b # bs))" + +definition bin_rsplit :: "nat \ nat \ int \ int list" + where "bin_rsplit n w = bin_rsplit_aux n (fst w) (snd w) []" + +fun bin_rsplitl_aux :: "nat \ nat \ int \ int list \ int list" + where "bin_rsplitl_aux n m c bs = + (if m = 0 \ n = 0 then bs + else + let (a, b) = bin_split (min m n) c + in bin_rsplitl_aux n (m - n) a (b # bs))" + +definition bin_rsplitl :: "nat \ nat \ int \ int list" + where "bin_rsplitl n w = bin_rsplitl_aux n (fst w) (snd w) []" + +declare bin_rsplit_aux.simps [simp del] +declare bin_rsplitl_aux.simps [simp del] + +lemma bin_nth_cat: + "bin_nth (bin_cat x k y) n = + (if n < k then bin_nth y n else bin_nth x (n - k))" + apply (induct k arbitrary: n y) + apply clarsimp + apply (case_tac n, auto) + done + +lemma bin_nth_split: + "bin_split n c = (a, b) \ + (\k. bin_nth a k = bin_nth c (n + k)) \ + (\k. bin_nth b k = (k < n \ bin_nth c k))" + apply (induct n arbitrary: b c) + apply clarsimp + apply (clarsimp simp: Let_def split: prod.split_asm) + apply (case_tac k) + apply auto + done + +lemma bin_cat_zero [simp]: "bin_cat 0 n w = bintrunc n w" + by (induct n arbitrary: w) auto + +lemma bintr_cat1: "bintrunc (k + n) (bin_cat a n b) = bin_cat (bintrunc k a) n b" + by (induct n arbitrary: b) auto + +lemma bintr_cat: "bintrunc m (bin_cat a n b) = + bin_cat (bintrunc (m - n) a) n (bintrunc (min m n) b)" + by (rule bin_eqI) (auto simp: bin_nth_cat nth_bintr) + +lemma bintr_cat_same [simp]: "bintrunc n (bin_cat a n b) = bintrunc n b" + by (auto simp add : bintr_cat) + +lemma cat_bintr [simp]: "bin_cat a n (bintrunc n b) = bin_cat a n b" + by (induct n arbitrary: b) auto + +lemma split_bintrunc: "bin_split n c = (a, b) \ b = bintrunc n c" + by (induct n arbitrary: b c) (auto simp: Let_def split: prod.split_asm) + +lemma bin_cat_split: "bin_split n w = (u, v) \ w = bin_cat u n v" + by (induct n arbitrary: v w) (auto simp: Let_def split: prod.split_asm) + +lemma bin_split_cat: "bin_split n (bin_cat v n w) = (v, bintrunc n w)" + by (induct n arbitrary: w) auto + +lemma bin_split_zero [simp]: "bin_split n 0 = (0, 0)" + by (induct n) auto + +lemma bin_split_minus1 [simp]: + "bin_split n (- 1) = (- 1, bintrunc n (- 1))" + by (induct n) auto + +lemma bin_split_trunc: + "bin_split (min m n) c = (a, b) \ + bin_split n (bintrunc m c) = (bintrunc (m - n) a, b)" + apply (induct n arbitrary: m b c, clarsimp) + apply (simp add: bin_rest_trunc Let_def split: prod.split_asm) + apply (case_tac m) + apply (auto simp: Let_def split: prod.split_asm) + done + +lemma bin_split_trunc1: + "bin_split n c = (a, b) \ + bin_split n (bintrunc m c) = (bintrunc (m - n) a, bintrunc m b)" + apply (induct n arbitrary: m b c, clarsimp) + apply (simp add: bin_rest_trunc Let_def split: prod.split_asm) + apply (case_tac m) + apply (auto simp: Let_def split: prod.split_asm) + done + +lemma bin_cat_num: "bin_cat a n b = a * 2 ^ n + bintrunc n b" + apply (induct n arbitrary: b) + apply clarsimp + apply (simp add: Bit_def) + done + +lemma bin_split_num: "bin_split n b = (b div 2 ^ n, b mod 2 ^ n)" + apply (induct n arbitrary: b) + apply simp + apply (simp add: bin_rest_def zdiv_zmult2_eq) + apply (case_tac b rule: bin_exhaust) + apply simp + apply (simp add: Bit_def mod_mult_mult1 pos_zmod_mult_2 add.commute) + done + +lemmas bin_rsplit_aux_simps = bin_rsplit_aux.simps bin_rsplitl_aux.simps +lemmas rsplit_aux_simps = bin_rsplit_aux_simps + +lemmas th_if_simp1 = if_split [where P = "(=) l", THEN iffD1, THEN conjunct1, THEN mp] for l +lemmas th_if_simp2 = if_split [where P = "(=) l", THEN iffD1, THEN conjunct2, THEN mp] for l + +lemmas rsplit_aux_simp1s = rsplit_aux_simps [THEN th_if_simp1] + +lemmas rsplit_aux_simp2ls = rsplit_aux_simps [THEN th_if_simp2] +\ \these safe to \[simp add]\ as require calculating \m - n\\ +lemmas bin_rsplit_aux_simp2s [simp] = rsplit_aux_simp2ls [unfolded Let_def] +lemmas rbscl = bin_rsplit_aux_simp2s (2) + +lemmas rsplit_aux_0_simps [simp] = + rsplit_aux_simp1s [OF disjI1] rsplit_aux_simp1s [OF disjI2] + +lemma bin_rsplit_aux_append: "bin_rsplit_aux n m c (bs @ cs) = bin_rsplit_aux n m c bs @ cs" + apply (induct n m c bs rule: bin_rsplit_aux.induct) + apply (subst bin_rsplit_aux.simps) + apply (subst bin_rsplit_aux.simps) + apply (clarsimp split: prod.split) + done + +lemma bin_rsplitl_aux_append: "bin_rsplitl_aux n m c (bs @ cs) = bin_rsplitl_aux n m c bs @ cs" + apply (induct n m c bs rule: bin_rsplitl_aux.induct) + apply (subst bin_rsplitl_aux.simps) + apply (subst bin_rsplitl_aux.simps) + apply (clarsimp split: prod.split) + done + +lemmas rsplit_aux_apps [where bs = "[]"] = + bin_rsplit_aux_append bin_rsplitl_aux_append + +lemmas rsplit_def_auxs = bin_rsplit_def bin_rsplitl_def + +lemmas rsplit_aux_alts = rsplit_aux_apps + [unfolded append_Nil rsplit_def_auxs [symmetric]] + +lemma bin_split_minus: "0 < n \ bin_split (Suc (n - 1)) w = bin_split n w" + by auto + +lemmas bin_split_minus_simp = + bin_split.Suc [THEN [2] bin_split_minus [symmetric, THEN trans]] + +lemma bin_split_pred_simp [simp]: + "(0::nat) < numeral bin \ + bin_split (numeral bin) w = + (let (w1, w2) = bin_split (numeral bin - 1) (bin_rest w) + in (w1, w2 BIT bin_last w))" + by (simp only: bin_split_minus_simp) + +lemma bin_rsplit_aux_simp_alt: + "bin_rsplit_aux n m c bs = + (if m = 0 \ n = 0 then bs + else let (a, b) = bin_split n c in bin_rsplit n (m - n, a) @ b # bs)" + apply (simp add: bin_rsplit_aux.simps [of n m c bs]) + apply (subst rsplit_aux_alts) + apply (simp add: bin_rsplit_def) + done + +lemmas bin_rsplit_simp_alt = + trans [OF bin_rsplit_def bin_rsplit_aux_simp_alt] + +lemmas bthrs = bin_rsplit_simp_alt [THEN [2] trans] + +lemma bin_rsplit_size_sign' [rule_format]: + "n > 0 \ rev sw = bin_rsplit n (nw, w) \ \v\set sw. bintrunc n v = v" + apply (induct sw arbitrary: nw w) + apply clarsimp + apply clarsimp + apply (drule bthrs) + apply (simp (no_asm_use) add: Let_def split: prod.split_asm if_split_asm) + apply clarify + apply (drule split_bintrunc) + apply simp + done + +lemmas bin_rsplit_size_sign = bin_rsplit_size_sign' [OF asm_rl + rev_rev_ident [THEN trans] set_rev [THEN equalityD2 [THEN subsetD]]] + +lemma bin_nth_rsplit [rule_format] : + "n > 0 \ m < n \ + \w k nw. + rev sw = bin_rsplit n (nw, w) \ + k < size sw \ bin_nth (sw ! k) m = bin_nth w (k * n + m)" + apply (induct sw) + apply clarsimp + apply clarsimp + apply (drule bthrs) + apply (simp (no_asm_use) add: Let_def split: prod.split_asm if_split_asm) + apply clarify + apply (erule allE, erule impE, erule exI) + apply (case_tac k) + apply clarsimp + prefer 2 + apply clarsimp + apply (erule allE) + apply (erule (1) impE) + apply (drule bin_nth_split, erule conjE, erule allE, erule trans, simp add: ac_simps)+ + done + +lemma bin_rsplit_all: "0 < nw \ nw \ n \ bin_rsplit n (nw, w) = [bintrunc n w]" + by (auto simp: bin_rsplit_def rsplit_aux_simp2ls split: prod.split dest!: split_bintrunc) + +lemma bin_rsplit_l [rule_format]: + "\bin. bin_rsplitl n (m, bin) = bin_rsplit n (m, bintrunc m bin)" + apply (rule_tac a = "m" in wf_less_than [THEN wf_induct]) + apply (simp (no_asm) add: bin_rsplitl_def bin_rsplit_def) + apply (rule allI) + apply (subst bin_rsplitl_aux.simps) + apply (subst bin_rsplit_aux.simps) + apply (clarsimp simp: Let_def split: prod.split) + apply (drule bin_split_trunc) + apply (drule sym [THEN trans], assumption) + apply (subst rsplit_aux_alts(1)) + apply (subst rsplit_aux_alts(2)) + apply clarsimp + unfolding bin_rsplit_def bin_rsplitl_def + apply simp + done + +lemma bin_rsplit_rcat [rule_format]: + "n > 0 \ bin_rsplit n (n * size ws, bin_rcat n ws) = map (bintrunc n) ws" + apply (unfold bin_rsplit_def bin_rcat_def) + apply (rule_tac xs = ws in rev_induct) + apply clarsimp + apply clarsimp + apply (subst rsplit_aux_alts) + unfolding bin_split_cat + apply simp + done + +lemma bin_rsplit_aux_len_le [rule_format] : + "\ws m. n \ 0 \ ws = bin_rsplit_aux n nw w bs \ + length ws \ m \ nw + length bs * n \ m * n" +proof - + have *: R + if d: "i \ j \ m < j'" + and R1: "i * k \ j * k \ R" + and R2: "Suc m * k' \ j' * k' \ R" + for i j j' k k' m :: nat and R + using d + apply safe + apply (rule R1, erule mult_le_mono1) + apply (rule R2, erule Suc_le_eq [THEN iffD2 [THEN mult_le_mono1]]) + done + have **: "0 < sc \ sc - n + (n + lb * n) \ m * n \ sc + lb * n \ m * n" + for sc m n lb :: nat + apply safe + apply arith + apply (case_tac "sc \ n") + apply arith + apply (insert linorder_le_less_linear [of m lb]) + apply (erule_tac k=n and k'=n in *) + apply arith + apply simp + done + show ?thesis + apply (induct n nw w bs rule: bin_rsplit_aux.induct) + apply (subst bin_rsplit_aux.simps) + apply (simp add: ** Let_def split: prod.split) + done +qed + +lemma bin_rsplit_len_le: "n \ 0 \ ws = bin_rsplit n (nw, w) \ length ws \ m \ nw \ m * n" + by (auto simp: bin_rsplit_def bin_rsplit_aux_len_le) + +lemma bin_rsplit_aux_len: + "n \ 0 \ length (bin_rsplit_aux n nw w cs) = (nw + n - 1) div n + length cs" + apply (induct n nw w cs rule: bin_rsplit_aux.induct) + apply (subst bin_rsplit_aux.simps) + apply (clarsimp simp: Let_def split: prod.split) + apply (erule thin_rl) + apply (case_tac m) + apply simp + apply (case_tac "m \ n") + apply (auto simp add: div_add_self2) + done + +lemma bin_rsplit_len: "n \ 0 \ length (bin_rsplit n (nw, w)) = (nw + n - 1) div n" + by (auto simp: bin_rsplit_def bin_rsplit_aux_len) + +lemma bin_rsplit_aux_len_indep: + "n \ 0 \ length bs = length cs \ + length (bin_rsplit_aux n nw v bs) = + length (bin_rsplit_aux n nw w cs)" +proof (induct n nw w cs arbitrary: v bs rule: bin_rsplit_aux.induct) + case (1 n m w cs v bs) + show ?case + proof (cases "m = 0") + case True + with \length bs = length cs\ show ?thesis by simp + next + case False + from "1.hyps" \m \ 0\ \n \ 0\ + have hyp: "\v bs. length bs = Suc (length cs) \ + length (bin_rsplit_aux n (m - n) v bs) = + length (bin_rsplit_aux n (m - n) (fst (bin_split n w)) (snd (bin_split n w) # cs))" + by auto + from \length bs = length cs\ \n \ 0\ show ?thesis + by (auto simp add: bin_rsplit_aux_simp_alt Let_def bin_rsplit_len split: prod.split) + qed +qed + +lemma bin_rsplit_len_indep: + "n \ 0 \ length (bin_rsplit n (nw, v)) = length (bin_rsplit n (nw, w))" + apply (unfold bin_rsplit_def) + apply (simp (no_asm)) + apply (erule bin_rsplit_aux_len_indep) + apply (rule refl) + done + + subsection \Logical operations\ text "bit-wise logical operations on the int type" @@ -232,9 +1403,6 @@ text \Cases for \0\ and \-1\ are already covered by other simp rules.\ -lemma bin_rl_eqI: "\bin_rest x = bin_rest y; bin_last x = bin_last y\ \ x = y" - by (metis (mono_tags) BIT_eq_iff bin_ex_rl bin_last_BIT bin_rest_BIT) - lemma bin_rest_neg_numeral_BitM [simp]: "bin_rest (- numeral (Num.BitM w)) = - numeral w" by (simp only: BIT_bin_simps [symmetric] bin_rest_BIT) @@ -423,7 +1591,7 @@ by (cases bit) (simp_all add: Bit_def) then have "0 \ bin AND bin'" by (rule 3) with 1 show ?thesis - by simp (simp add: Bit_def) + by simp qed qed @@ -443,7 +1611,7 @@ by (cases bit') (simp_all add: Bit_def) ultimately have "0 \ bin OR bin'" by (rule 3) with 1 show ?thesis - by simp (simp add: Bit_def) + by simp qed qed simp_all @@ -463,7 +1631,7 @@ by (cases bit') (simp_all add: Bit_def) ultimately have "0 \ bin XOR bin'" by (rule 3) with 1 show ?thesis - by simp (simp add: Bit_def) + by simp qed next case 2 @@ -534,7 +1702,8 @@ show ?thesis proof (cases n) case 0 - with 3 have "bin BIT bit = 0" by simp + with 3 have "bin BIT bit = 0" + by (simp add: Bit_def) then have "bin = 0" and "\ bit" by (auto simp add: Bit_def split: if_splits) arith then show ?thesis using 0 1 \y < 2 ^ n\ @@ -573,7 +1742,8 @@ show ?thesis proof (cases n) case 0 - with 3 have "bin BIT bit = 0" by simp + with 3 have "bin BIT bit = 0" + by (simp add: Bit_def) then have "bin = 0" and "\ bit" by (auto simp add: Bit_def split: if_splits) arith then show ?thesis using 0 1 \y < 2 ^ n\ @@ -615,58 +1785,92 @@ lemmas bin_trunc_and = bin_trunc_ao(1) [THEN bintr_bintr_i] lemmas bin_trunc_or = bin_trunc_ao(2) [THEN bintr_bintr_i] -lemma bl_xor_aux_bin: - "map2 (\x y. x \ y) (bin_to_bl_aux n v bs) (bin_to_bl_aux n w cs) = - bin_to_bl_aux n (v XOR w) (map2 (\x y. x \ y) bs cs)" - apply (induct n arbitrary: v w bs cs) - apply simp - apply (case_tac v rule: bin_exhaust) - apply (case_tac w rule: bin_exhaust) - apply clarsimp - apply (case_tac b) - apply auto - done - -lemma bl_or_aux_bin: - "map2 (\) (bin_to_bl_aux n v bs) (bin_to_bl_aux n w cs) = - bin_to_bl_aux n (v OR w) (map2 (\) bs cs)" - apply (induct n arbitrary: v w bs cs) - apply simp - apply (case_tac v rule: bin_exhaust) - apply (case_tac w rule: bin_exhaust) - apply clarsimp - done - -lemma bl_and_aux_bin: - "map2 (\) (bin_to_bl_aux n v bs) (bin_to_bl_aux n w cs) = - bin_to_bl_aux n (v AND w) (map2 (\) bs cs)" - apply (induct n arbitrary: v w bs cs) - apply simp - apply (case_tac v rule: bin_exhaust) - apply (case_tac w rule: bin_exhaust) - apply clarsimp - done - -lemma bl_not_aux_bin: "map Not (bin_to_bl_aux n w cs) = bin_to_bl_aux n (NOT w) (map Not cs)" - by (induct n arbitrary: w cs) auto - -lemma bl_not_bin: "map Not (bin_to_bl n w) = bin_to_bl n (NOT w)" - by (simp add: bin_to_bl_def bl_not_aux_bin) - -lemma bl_and_bin: "map2 (\) (bin_to_bl n v) (bin_to_bl n w) = bin_to_bl n (v AND w)" - by (simp add: bin_to_bl_def bl_and_aux_bin) - -lemma bl_or_bin: "map2 (\) (bin_to_bl n v) (bin_to_bl n w) = bin_to_bl n (v OR w)" - by (simp add: bin_to_bl_def bl_or_aux_bin) - -lemma bl_xor_bin: "map2 (\x y. x \ y) (bin_to_bl n v) (bin_to_bl n w) = bin_to_bl n (v XOR w)" - by (simp only: bin_to_bl_def bl_xor_aux_bin map2_Nil) + +subsubsection \More lemmas\ + +lemma not_int_cmp_0 [simp]: + fixes i :: int shows + "0 < NOT i \ i < -1" + "0 \ NOT i \ i < 0" + "NOT i < 0 \ i \ 0" + "NOT i \ 0 \ i \ -1" +by(simp_all add: int_not_def) arith+ + +lemma bbw_ao_dist2: "(x :: int) AND (y OR z) = x AND y OR x AND z" +by(metis int_and_comm bbw_ao_dist) + +lemmas int_and_ac = bbw_lcs(1) int_and_comm int_and_assoc + +lemma int_nand_same [simp]: fixes x :: int shows "x AND NOT x = 0" +by(induct x y\"NOT x" rule: bitAND_int.induct)(subst bitAND_int.simps, clarsimp) + +lemma int_nand_same_middle: fixes x :: int shows "x AND y AND NOT x = 0" +by (metis bbw_lcs(1) int_and_0 int_nand_same) + +lemma and_xor_dist: fixes x :: int shows + "x AND (y XOR z) = (x AND y) XOR (x AND z)" +by(simp add: int_xor_def bbw_ao_dist2 bbw_not_dist int_and_ac int_nand_same_middle) + +lemma int_and_lt0 [simp]: fixes x y :: int shows + "x AND y < 0 \ x < 0 \ y < 0" +by(induct x y rule: bitAND_int.induct)(subst bitAND_int.simps, simp) + +lemma int_and_ge0 [simp]: fixes x y :: int shows + "x AND y \ 0 \ x \ 0 \ y \ 0" +by (metis int_and_lt0 linorder_not_less) + +lemma int_and_1: fixes x :: int shows "x AND 1 = x mod 2" +by(subst bitAND_int.simps)(simp add: Bit_def bin_last_def zmod_minus1) + +lemma int_1_and: fixes x :: int shows "1 AND x = x mod 2" +by(subst int_and_comm)(simp add: int_and_1) + +lemma int_or_lt0 [simp]: fixes x y :: int shows + "x OR y < 0 \ x < 0 \ y < 0" +by(simp add: int_or_def) + +lemma int_xor_lt0 [simp]: fixes x y :: int shows + "x XOR y < 0 \ ((x < 0) \ (y < 0))" +by(auto simp add: int_xor_def) + +lemma int_xor_ge0 [simp]: fixes x y :: int shows + "x XOR y \ 0 \ ((x \ 0) \ (y \ 0))" +by (metis int_xor_lt0 linorder_not_le) + +lemma bin_last_conv_AND: + "bin_last i \ i AND 1 \ 0" +proof - + obtain x b where "i = x BIT b" by(cases i rule: bin_exhaust) + hence "i AND 1 = 0 BIT b" + by(simp add: BIT_special_simps(2)[symmetric] del: BIT_special_simps(2)) + thus ?thesis using \i = x BIT b\ by(cases b) simp_all +qed + +lemma bitval_bin_last: + "of_bool (bin_last i) = i AND 1" +proof - + obtain x b where "i = x BIT b" by(cases i rule: bin_exhaust) + hence "i AND 1 = 0 BIT b" + by(simp add: BIT_special_simps(2)[symmetric] del: BIT_special_simps(2)) + thus ?thesis by(cases b)(simp_all add: bin_last_conv_AND) +qed + +lemma bin_sign_and: + "bin_sign (i AND j) = - (bin_sign i * bin_sign j)" +by(simp add: bin_sign_def) + +lemma minus_BIT_0: fixes x y :: int shows "x BIT b - y BIT False = (x - y) BIT b" +by(simp add: Bit_def) + +lemma int_not_neg_numeral: "NOT (- numeral n) = (Num.sub n num.One :: int)" +by(simp add: int_not_def) + +lemma int_neg_numeral_pOne_conv_not: "- numeral (n + num.One) = (NOT (numeral n) :: int)" +by(simp add: int_not_def) subsection \Setting and clearing bits\ -text \nth bit, set/clear\ - primrec bin_sc :: "nat \ bool \ int \ int" where Z: "bin_sc 0 b w = bin_rest w BIT b" @@ -775,127 +1979,6 @@ end - -subsection \More lemmas\ - -lemma twice_conv_BIT: "2 * x = x BIT False" - by (rule bin_rl_eqI) (simp_all, simp_all add: bin_rest_def bin_last_def) - -lemma not_int_cmp_0 [simp]: - fixes i :: int shows - "0 < NOT i \ i < -1" - "0 \ NOT i \ i < 0" - "NOT i < 0 \ i \ 0" - "NOT i \ 0 \ i \ -1" -by(simp_all add: int_not_def) arith+ - -lemma bbw_ao_dist2: "(x :: int) AND (y OR z) = x AND y OR x AND z" -by(metis int_and_comm bbw_ao_dist) - -lemmas int_and_ac = bbw_lcs(1) int_and_comm int_and_assoc - -lemma int_nand_same [simp]: fixes x :: int shows "x AND NOT x = 0" -by(induct x y\"NOT x" rule: bitAND_int.induct)(subst bitAND_int.simps, clarsimp) - -lemma int_nand_same_middle: fixes x :: int shows "x AND y AND NOT x = 0" -by (metis bbw_lcs(1) int_and_0 int_nand_same) - -lemma and_xor_dist: fixes x :: int shows - "x AND (y XOR z) = (x AND y) XOR (x AND z)" -by(simp add: int_xor_def bbw_ao_dist2 bbw_ao_dist bbw_not_dist int_and_ac int_nand_same_middle) - -lemma BIT_lt0 [simp]: "x BIT b < 0 \ x < 0" -by(cases b)(auto simp add: Bit_def) - -lemma BIT_ge0 [simp]: "x BIT b \ 0 \ x \ 0" -by(cases b)(auto simp add: Bit_def) - -lemma [simp]: - shows bin_rest_lt0: "bin_rest i < 0 \ i < 0" - and bin_rest_ge_0: "bin_rest i \ 0 \ i \ 0" -by(auto simp add: bin_rest_def) - -lemma bin_rest_gt_0 [simp]: "bin_rest x > 0 \ x > 1" -by(simp add: bin_rest_def add1_zle_eq pos_imp_zdiv_pos_iff) (metis add1_zle_eq one_add_one) - -lemma int_and_lt0 [simp]: fixes x y :: int shows - "x AND y < 0 \ x < 0 \ y < 0" -by(induct x y rule: bitAND_int.induct)(subst bitAND_int.simps, simp) - -lemma int_and_ge0 [simp]: fixes x y :: int shows - "x AND y \ 0 \ x \ 0 \ y \ 0" -by (metis int_and_lt0 linorder_not_less) - -lemma int_and_1: fixes x :: int shows "x AND 1 = x mod 2" -by(subst bitAND_int.simps)(simp add: Bit_def bin_last_def zmod_minus1) - -lemma int_1_and: fixes x :: int shows "1 AND x = x mod 2" -by(subst int_and_comm)(simp add: int_and_1) - -lemma int_or_lt0 [simp]: fixes x y :: int shows - "x OR y < 0 \ x < 0 \ y < 0" -by(simp add: int_or_def) - -lemma int_xor_lt0 [simp]: fixes x y :: int shows - "x XOR y < 0 \ ((x < 0) \ (y < 0))" -by(auto simp add: int_xor_def) - -lemma int_xor_ge0 [simp]: fixes x y :: int shows - "x XOR y \ 0 \ ((x \ 0) \ (y \ 0))" -by (metis int_xor_lt0 linorder_not_le) - -lemma bin_last_conv_AND: - "bin_last i \ i AND 1 \ 0" -proof - - obtain x b where "i = x BIT b" by(cases i rule: bin_exhaust) - hence "i AND 1 = 0 BIT b" - by(simp add: BIT_special_simps(2)[symmetric] del: BIT_special_simps(2)) - thus ?thesis using \i = x BIT b\ by(cases b) simp_all -qed - -lemma bitval_bin_last: - "of_bool (bin_last i) = i AND 1" -proof - - obtain x b where "i = x BIT b" by(cases i rule: bin_exhaust) - hence "i AND 1 = 0 BIT b" - by(simp add: BIT_special_simps(2)[symmetric] del: BIT_special_simps(2)) - thus ?thesis by(cases b)(simp_all add: bin_last_conv_AND) -qed - -lemma bl_to_bin_BIT: - "bl_to_bin bs BIT b = bl_to_bin (bs @ [b])" -by(simp add: bl_to_bin_append) - -lemma bin_last_bl_to_bin: "bin_last (bl_to_bin bs) \ bs \ [] \ last bs" -by(cases "bs = []")(auto simp add: bl_to_bin_def last_bin_last'[where w=0]) - -lemma bin_rest_bl_to_bin: "bin_rest (bl_to_bin bs) = bl_to_bin (butlast bs)" -by(cases "bs = []")(simp_all add: bl_to_bin_def butlast_rest_bl2bin_aux) - -lemma bin_nth_numeral_unfold: - "bin_nth (numeral (num.Bit0 x)) n \ n > 0 \ bin_nth (numeral x) (n - 1)" - "bin_nth (numeral (num.Bit1 x)) n \ (n > 0 \ bin_nth (numeral x) (n - 1))" -by(case_tac [!] n) simp_all - -lemma bin_sign_and: - "bin_sign (i AND j) = - (bin_sign i * bin_sign j)" -by(simp add: bin_sign_def) - -lemma minus_BIT_0: fixes x y :: int shows "x BIT b - y BIT False = (x - y) BIT b" -by(simp add: Bit_def) - -lemma int_not_neg_numeral: "NOT (- numeral n) = (Num.sub n num.One :: int)" -by(simp add: int_not_def) - -lemma sub_inc_One: "Num.sub (Num.inc n) num.One = numeral n" -by (metis add_diff_cancel diff_minus_eq_add diff_numeral_special(2) diff_numeral_special(6)) - -lemma inc_BitM: "Num.inc (Num.BitM n) = num.Bit0 n" -by(simp add: BitM_plus_one[symmetric] add_One) - -lemma int_neg_numeral_pOne_conv_not: "- numeral (n + num.One) = (NOT (numeral n) :: int)" -by(simp add: int_not_def) - lemma int_lsb_BIT [simp]: fixes x :: int shows "lsb (x BIT b) \ b" by(simp add: lsb_int_def) @@ -1047,10 +2130,6 @@ lemma int_shiftr_lt_0 [simp]: fixes i :: int shows "i >> n < 0 \ i < 0" by (metis int_shiftr_ge_0 not_less) -lemma uminus_Bit_eq: - "- k BIT b = (- k - of_bool b) BIT b" - by (cases b) (simp_all add: Bit_def) - lemma int_shiftr_numeral [simp]: "(1 :: int) >> numeral w' = 0" "(numeral num.One :: int) >> numeral w' = 0" @@ -1103,10 +2182,10 @@ by(induct n arbitrary: i)(auto intro: bin_rl_eqI) lemma int_set_bits_K_True [simp]: "(BITS _. True) = (-1 :: int)" -by(auto simp add: set_bits_int_def bin_last_bl_to_bin) + by (auto simp add: set_bits_int_def bl_to_bin_def) lemma int_set_bits_K_False [simp]: "(BITS _. False) = (0 :: int)" -by(auto simp add: set_bits_int_def) + by (simp add: set_bits_int_def) lemma msb_conv_bin_sign: "msb x \ bin_sign x = -1" by(simp add: bin_sign_def not_le msb_int_def) @@ -1152,4 +2231,551 @@ "msb (- numeral n :: int) = True" by(simp_all add: msb_int_def) + +subsection \Semantic interpretation of \<^typ>\bool list\ as \<^typ>\int\\ + +lemma bin_bl_bin': "bl_to_bin (bin_to_bl_aux n w bs) = bl_to_bin_aux bs (bintrunc n w)" + by (induct n arbitrary: w bs) (auto simp: bl_to_bin_def) + +lemma bin_bl_bin [simp]: "bl_to_bin (bin_to_bl n w) = bintrunc n w" + by (auto simp: bin_to_bl_def bin_bl_bin') + +lemma bl_to_bin_rep_F: "bl_to_bin (replicate n False @ bl) = bl_to_bin bl" + by (simp add: bin_to_bl_zero_aux [symmetric] bin_bl_bin') (simp add: bl_to_bin_def) + +lemma bin_to_bl_trunc [simp]: "n \ m \ bin_to_bl n (bintrunc m w) = bin_to_bl n w" + by (auto intro: bl_to_bin_inj) + +lemma bin_to_bl_aux_bintr: + "bin_to_bl_aux n (bintrunc m bin) bl = + replicate (n - m) False @ bin_to_bl_aux (min n m) bin bl" + apply (induct n arbitrary: m bin bl) + apply clarsimp + apply clarsimp + apply (case_tac "m") + apply (clarsimp simp: bin_to_bl_zero_aux) + apply (erule thin_rl) + apply (induct_tac n) + apply auto + done + +lemma bin_to_bl_bintr: + "bin_to_bl n (bintrunc m bin) = replicate (n - m) False @ bin_to_bl (min n m) bin" + unfolding bin_to_bl_def by (rule bin_to_bl_aux_bintr) + +lemma bl_to_bin_rep_False: "bl_to_bin (replicate n False) = 0" + by (induct n) auto + +lemma len_bin_to_bl_aux: "length (bin_to_bl_aux n w bs) = n + length bs" + by (fact size_bin_to_bl_aux) + +lemma len_bin_to_bl: "length (bin_to_bl n w) = n" + by (fact size_bin_to_bl) (* FIXME: duplicate *) + +lemma sign_bl_bin': "bin_sign (bl_to_bin_aux bs w) = bin_sign w" + by (induct bs arbitrary: w) auto + +lemma sign_bl_bin: "bin_sign (bl_to_bin bs) = 0" + by (simp add: bl_to_bin_def sign_bl_bin') + +lemma bl_sbin_sign_aux: "hd (bin_to_bl_aux (Suc n) w bs) = (bin_sign (sbintrunc n w) = -1)" + apply (induct n arbitrary: w bs) + apply clarsimp + apply (cases w rule: bin_exhaust) + apply simp + done + +lemma bl_sbin_sign: "hd (bin_to_bl (Suc n) w) = (bin_sign (sbintrunc n w) = -1)" + unfolding bin_to_bl_def by (rule bl_sbin_sign_aux) + +lemma bin_nth_of_bl_aux: + "bin_nth (bl_to_bin_aux bl w) n = + (n < size bl \ rev bl ! n \ n \ length bl \ bin_nth w (n - size bl))" + apply (induct bl arbitrary: w) + apply clarsimp + apply clarsimp + apply (cut_tac x=n and y="size bl" in linorder_less_linear) + apply (erule disjE, simp add: nth_append)+ + apply auto + done + +lemma bin_nth_of_bl: "bin_nth (bl_to_bin bl) n = (n < length bl \ rev bl ! n)" + by (simp add: bl_to_bin_def bin_nth_of_bl_aux) + +lemma bin_nth_bl: "n < m \ bin_nth w n = nth (rev (bin_to_bl m w)) n" + apply (induct n arbitrary: m w) + apply clarsimp + apply (case_tac m, clarsimp) + apply (clarsimp simp: bin_to_bl_def) + apply (simp add: bin_to_bl_aux_alt) + apply clarsimp + apply (case_tac m, clarsimp) + apply (clarsimp simp: bin_to_bl_def) + apply (simp add: bin_to_bl_aux_alt) + done + +lemma nth_bin_to_bl_aux: + "n < m + length bl \ (bin_to_bl_aux m w bl) ! n = + (if n < m then bin_nth w (m - 1 - n) else bl ! (n - m))" + apply (induct m arbitrary: w n bl) + apply clarsimp + apply clarsimp + apply (case_tac w rule: bin_exhaust) + apply simp + done + +lemma nth_bin_to_bl: "n < m \ (bin_to_bl m w) ! n = bin_nth w (m - Suc n)" + by (simp add: bin_to_bl_def nth_bin_to_bl_aux) + +lemma bl_to_bin_lt2p_aux: "bl_to_bin_aux bs w < (w + 1) * (2 ^ length bs)" + apply (induct bs arbitrary: w) + apply clarsimp + apply clarsimp + apply (drule meta_spec, erule xtrans(8) [rotated], simp add: Bit_def)+ + done + +lemma bl_to_bin_lt2p_drop: "bl_to_bin bs < 2 ^ length (dropWhile Not bs)" +proof (induct bs) + case Nil + then show ?case by simp +next + case (Cons b bs) + with bl_to_bin_lt2p_aux[where w=1] show ?case + by (simp add: bl_to_bin_def) +qed + +lemma bl_to_bin_lt2p: "bl_to_bin bs < 2 ^ length bs" + by (metis bin_bl_bin bintr_lt2p bl_bin_bl) + +lemma bl_to_bin_ge2p_aux: "bl_to_bin_aux bs w \ w * (2 ^ length bs)" + apply (induct bs arbitrary: w) + apply clarsimp + apply clarsimp + apply (drule meta_spec, erule order_trans [rotated], + simp add: Bit_B0_2t Bit_B1_2t algebra_simps)+ + apply (simp add: Bit_def) + done + +lemma bl_to_bin_ge0: "bl_to_bin bs \ 0" + apply (unfold bl_to_bin_def) + apply (rule xtrans(4)) + apply (rule bl_to_bin_ge2p_aux) + apply simp + done + +lemma butlast_rest_bin: "butlast (bin_to_bl n w) = bin_to_bl (n - 1) (bin_rest w)" + apply (unfold bin_to_bl_def) + apply (cases w rule: bin_exhaust) + apply (cases n, clarsimp) + apply clarsimp + apply (auto simp add: bin_to_bl_aux_alt) + done + +lemma butlast_bin_rest: "butlast bl = bin_to_bl (length bl - Suc 0) (bin_rest (bl_to_bin bl))" + using butlast_rest_bin [where w="bl_to_bin bl" and n="length bl"] by simp + +lemma butlast_rest_bl2bin_aux: + "bl \ [] \ bl_to_bin_aux (butlast bl) w = bin_rest (bl_to_bin_aux bl w)" + by (induct bl arbitrary: w) auto + +lemma butlast_rest_bl2bin: "bl_to_bin (butlast bl) = bin_rest (bl_to_bin bl)" + by (cases bl) (auto simp: bl_to_bin_def butlast_rest_bl2bin_aux) + +lemma trunc_bl2bin_aux: + "bintrunc m (bl_to_bin_aux bl w) = + bl_to_bin_aux (drop (length bl - m) bl) (bintrunc (m - length bl) w)" +proof (induct bl arbitrary: w) + case Nil + show ?case by simp +next + case (Cons b bl) + show ?case + proof (cases "m - length bl") + case 0 + then have "Suc (length bl) - m = Suc (length bl - m)" by simp + with Cons show ?thesis by simp + next + case (Suc n) + then have "m - Suc (length bl) = n" by simp + with Cons Suc show ?thesis by simp + qed +qed + +lemma trunc_bl2bin: "bintrunc m (bl_to_bin bl) = bl_to_bin (drop (length bl - m) bl)" + by (simp add: bl_to_bin_def trunc_bl2bin_aux) + +lemma trunc_bl2bin_len [simp]: "bintrunc (length bl) (bl_to_bin bl) = bl_to_bin bl" + by (simp add: trunc_bl2bin) + +lemma bl2bin_drop: "bl_to_bin (drop k bl) = bintrunc (length bl - k) (bl_to_bin bl)" + apply (rule trans) + prefer 2 + apply (rule trunc_bl2bin [symmetric]) + apply (cases "k \ length bl") + apply auto + done + +lemma take_rest_power_bin: "m \ n \ take m (bin_to_bl n w) = bin_to_bl m ((bin_rest ^^ (n - m)) w)" + apply (rule nth_equalityI) + apply simp + apply (clarsimp simp add: nth_bin_to_bl nth_rest_power_bin) + done + +lemma last_bin_last': "size xs > 0 \ last xs \ bin_last (bl_to_bin_aux xs w)" + by (induct xs arbitrary: w) auto + +lemma last_bin_last: "size xs > 0 \ last xs \ bin_last (bl_to_bin xs)" + unfolding bl_to_bin_def by (erule last_bin_last') + +lemma bin_last_last: "bin_last w \ last (bin_to_bl (Suc n) w)" + by (simp add: bin_to_bl_def) (auto simp: bin_to_bl_aux_alt) + +lemma drop_bin2bl_aux: + "drop m (bin_to_bl_aux n bin bs) = + bin_to_bl_aux (n - m) bin (drop (m - n) bs)" + apply (induct n arbitrary: m bin bs, clarsimp) + apply clarsimp + apply (case_tac bin rule: bin_exhaust) + apply (case_tac "m \ n", simp) + apply (case_tac "m - n", simp) + apply simp + apply (rule_tac f = "\nat. drop nat bs" in arg_cong) + apply simp + done + +lemma drop_bin2bl: "drop m (bin_to_bl n bin) = bin_to_bl (n - m) bin" + by (simp add: bin_to_bl_def drop_bin2bl_aux) + +lemma take_bin2bl_lem1: "take m (bin_to_bl_aux m w bs) = bin_to_bl m w" + apply (induct m arbitrary: w bs) + apply clarsimp + apply clarsimp + apply (simp add: bin_to_bl_aux_alt) + apply (simp add: bin_to_bl_def) + apply (simp add: bin_to_bl_aux_alt) + done + +lemma take_bin2bl_lem: "take m (bin_to_bl_aux (m + n) w bs) = take m (bin_to_bl (m + n) w)" + by (induct n arbitrary: w bs) (simp_all (no_asm) add: bin_to_bl_def take_bin2bl_lem1, simp) + +lemma bin_split_take: "bin_split n c = (a, b) \ bin_to_bl m a = take m (bin_to_bl (m + n) c)" + apply (induct n arbitrary: b c) + apply clarsimp + apply (clarsimp simp: Let_def split: prod.split_asm) + apply (simp add: bin_to_bl_def) + apply (simp add: take_bin2bl_lem) + done + +lemma bin_split_take1: + "k = m + n \ bin_split n c = (a, b) \ bin_to_bl m a = take m (bin_to_bl k c)" + by (auto elim: bin_split_take) + +lemma takefill_bintrunc: "takefill False n bl = rev (bin_to_bl n (bl_to_bin (rev bl)))" + apply (rule nth_equalityI) + apply simp + apply (clarsimp simp: nth_takefill nth_rev nth_bin_to_bl bin_nth_of_bl) + done + +lemma bl_bin_bl_rtf: "bin_to_bl n (bl_to_bin bl) = rev (takefill False n (rev bl))" + by (simp add: takefill_bintrunc) + +lemma bl_bin_bl_rep_drop: + "bin_to_bl n (bl_to_bin bl) = + replicate (n - length bl) False @ drop (length bl - n) bl" + by (simp add: bl_bin_bl_rtf takefill_alt rev_take) + +lemma bl_to_bin_aux_cat: + "\nv v. bl_to_bin_aux bs (bin_cat w nv v) = + bin_cat w (nv + length bs) (bl_to_bin_aux bs v)" + by (induct bs) (simp, simp add: bin_cat_Suc_Bit [symmetric] del: bin_cat.simps) + +lemma bin_to_bl_aux_cat: + "\w bs. bin_to_bl_aux (nv + nw) (bin_cat v nw w) bs = + bin_to_bl_aux nv v (bin_to_bl_aux nw w bs)" + by (induct nw) auto + +lemma bl_to_bin_aux_alt: "bl_to_bin_aux bs w = bin_cat w (length bs) (bl_to_bin bs)" + using bl_to_bin_aux_cat [where nv = "0" and v = "0"] + by (simp add: bl_to_bin_def [symmetric]) + +lemma bin_to_bl_cat: + "bin_to_bl (nv + nw) (bin_cat v nw w) = + bin_to_bl_aux nv v (bin_to_bl nw w)" + by (simp add: bin_to_bl_def bin_to_bl_aux_cat) + +lemmas bl_to_bin_aux_app_cat = + trans [OF bl_to_bin_aux_append bl_to_bin_aux_alt] + +lemmas bin_to_bl_aux_cat_app = + trans [OF bin_to_bl_aux_cat bin_to_bl_aux_alt] + +lemma bl_to_bin_app_cat: + "bl_to_bin (bsa @ bs) = bin_cat (bl_to_bin bsa) (length bs) (bl_to_bin bs)" + by (simp only: bl_to_bin_aux_app_cat bl_to_bin_def) + +lemma bin_to_bl_cat_app: + "bin_to_bl (n + nw) (bin_cat w nw wa) = bin_to_bl n w @ bin_to_bl nw wa" + by (simp only: bin_to_bl_def bin_to_bl_aux_cat_app) + +text \\bl_to_bin_app_cat_alt\ and \bl_to_bin_app_cat\ are easily interderivable.\ +lemma bl_to_bin_app_cat_alt: "bin_cat (bl_to_bin cs) n w = bl_to_bin (cs @ bin_to_bl n w)" + by (simp add: bl_to_bin_app_cat) + +lemma mask_lem: "(bl_to_bin (True # replicate n False)) = bl_to_bin (replicate n True) + 1" + apply (unfold bl_to_bin_def) + apply (induct n) + apply simp + apply (simp only: Suc_eq_plus1 replicate_add append_Cons [symmetric] bl_to_bin_aux_append) + apply (simp add: Bit_B0_2t Bit_B1_2t) + done + +primrec rbl_succ :: "bool list \ bool list" + where + Nil: "rbl_succ Nil = Nil" + | Cons: "rbl_succ (x # xs) = (if x then False # rbl_succ xs else True # xs)" + +primrec rbl_pred :: "bool list \ bool list" + where + Nil: "rbl_pred Nil = Nil" + | Cons: "rbl_pred (x # xs) = (if x then False # xs else True # rbl_pred xs)" + +primrec rbl_add :: "bool list \ bool list \ bool list" + where \ \result is length of first arg, second arg may be longer\ + Nil: "rbl_add Nil x = Nil" + | Cons: "rbl_add (y # ys) x = + (let ws = rbl_add ys (tl x) + in (y \ hd x) # (if hd x \ y then rbl_succ ws else ws))" + +primrec rbl_mult :: "bool list \ bool list \ bool list" + where \ \result is length of first arg, second arg may be longer\ + Nil: "rbl_mult Nil x = Nil" + | Cons: "rbl_mult (y # ys) x = + (let ws = False # rbl_mult ys x + in if y then rbl_add ws x else ws)" + +lemma size_rbl_pred: "length (rbl_pred bl) = length bl" + by (induct bl) auto + +lemma size_rbl_succ: "length (rbl_succ bl) = length bl" + by (induct bl) auto + +lemma size_rbl_add: "length (rbl_add bl cl) = length bl" + by (induct bl arbitrary: cl) (auto simp: Let_def size_rbl_succ) + +lemma size_rbl_mult: "length (rbl_mult bl cl) = length bl" + by (induct bl arbitrary: cl) (auto simp add: Let_def size_rbl_add) + +lemmas rbl_sizes [simp] = + size_rbl_pred size_rbl_succ size_rbl_add size_rbl_mult + +lemmas rbl_Nils = + rbl_pred.Nil rbl_succ.Nil rbl_add.Nil rbl_mult.Nil + +lemma rbl_add_app2: "length blb \ length bla \ rbl_add bla (blb @ blc) = rbl_add bla blb" + apply (induct bla arbitrary: blb) + apply simp + apply clarsimp + apply (case_tac blb, clarsimp) + apply (clarsimp simp: Let_def) + done + +lemma rbl_add_take2: + "length blb \ length bla \ rbl_add bla (take (length bla) blb) = rbl_add bla blb" + apply (induct bla arbitrary: blb) + apply simp + apply clarsimp + apply (case_tac blb, clarsimp) + apply (clarsimp simp: Let_def) + done + +lemma rbl_mult_app2: "length blb \ length bla \ rbl_mult bla (blb @ blc) = rbl_mult bla blb" + apply (induct bla arbitrary: blb) + apply simp + apply clarsimp + apply (case_tac blb, clarsimp) + apply (clarsimp simp: Let_def rbl_add_app2) + done + +lemma rbl_mult_take2: + "length blb \ length bla \ rbl_mult bla (take (length bla) blb) = rbl_mult bla blb" + apply (rule trans) + apply (rule rbl_mult_app2 [symmetric]) + apply simp + apply (rule_tac f = "rbl_mult bla" in arg_cong) + apply (rule append_take_drop_id) + done + +lemma rbl_add_split: + "P (rbl_add (y # ys) (x # xs)) = + (\ws. length ws = length ys \ ws = rbl_add ys xs \ + (y \ ((x \ P (False # rbl_succ ws)) \ (\ x \ P (True # ws)))) \ + (\ y \ P (x # ws)))" + by (cases y) (auto simp: Let_def) + +lemma rbl_mult_split: + "P (rbl_mult (y # ys) xs) = + (\ws. length ws = Suc (length ys) \ ws = False # rbl_mult ys xs \ + (y \ P (rbl_add ws xs)) \ (\ y \ P ws))" + by (auto simp: Let_def) + +lemma rbl_pred: "rbl_pred (rev (bin_to_bl n bin)) = rev (bin_to_bl n (bin - 1))" + apply (unfold bin_to_bl_def) + apply (induct n arbitrary: bin) + apply simp + apply clarsimp + apply (case_tac bin rule: bin_exhaust) + apply (case_tac b) + apply (clarsimp simp: bin_to_bl_aux_alt)+ + done + +lemma rbl_succ: "rbl_succ (rev (bin_to_bl n bin)) = rev (bin_to_bl n (bin + 1))" + apply (unfold bin_to_bl_def) + apply (induct n arbitrary: bin) + apply simp + apply clarsimp + apply (case_tac bin rule: bin_exhaust) + apply (case_tac b) + apply (clarsimp simp: bin_to_bl_aux_alt)+ + done + +lemma rbl_add: + "\bina binb. rbl_add (rev (bin_to_bl n bina)) (rev (bin_to_bl n binb)) = + rev (bin_to_bl n (bina + binb))" + apply (unfold bin_to_bl_def) + apply (induct n) + apply simp + apply clarsimp + apply (case_tac bina rule: bin_exhaust) + apply (case_tac binb rule: bin_exhaust) + apply (case_tac b) + apply (case_tac [!] "ba") + apply (auto simp: rbl_succ bin_to_bl_aux_alt Let_def ac_simps) + done + +lemma rbl_add_long: + "m \ n \ rbl_add (rev (bin_to_bl n bina)) (rev (bin_to_bl m binb)) = + rev (bin_to_bl n (bina + binb))" + apply (rule box_equals [OF _ rbl_add_take2 rbl_add]) + apply (rule_tac f = "rbl_add (rev (bin_to_bl n bina))" in arg_cong) + apply (rule rev_swap [THEN iffD1]) + apply (simp add: rev_take drop_bin2bl) + apply simp + done + +lemma rbl_mult_gt1: + "m \ length bl \ + rbl_mult bl (rev (bin_to_bl m binb)) = + rbl_mult bl (rev (bin_to_bl (length bl) binb))" + apply (rule trans) + apply (rule rbl_mult_take2 [symmetric]) + apply simp_all + apply (rule_tac f = "rbl_mult bl" in arg_cong) + apply (rule rev_swap [THEN iffD1]) + apply (simp add: rev_take drop_bin2bl) + done + +lemma rbl_mult_gt: + "m > n \ + rbl_mult (rev (bin_to_bl n bina)) (rev (bin_to_bl m binb)) = + rbl_mult (rev (bin_to_bl n bina)) (rev (bin_to_bl n binb))" + by (auto intro: trans [OF rbl_mult_gt1]) + +lemmas rbl_mult_Suc = lessI [THEN rbl_mult_gt] + +lemma rbbl_Cons: "b # rev (bin_to_bl n x) = rev (bin_to_bl (Suc n) (x BIT b))" + by (simp add: bin_to_bl_def) (simp add: bin_to_bl_aux_alt) + +lemma rbl_mult: + "rbl_mult (rev (bin_to_bl n bina)) (rev (bin_to_bl n binb)) = + rev (bin_to_bl n (bina * binb))" + apply (induct n arbitrary: bina binb) + apply simp + apply (unfold bin_to_bl_def) + apply clarsimp + apply (case_tac bina rule: bin_exhaust) + apply (case_tac binb rule: bin_exhaust) + apply (case_tac b) + apply (case_tac [!] "ba") + apply (auto simp: bin_to_bl_aux_alt Let_def) + apply (auto simp: rbbl_Cons rbl_mult_Suc rbl_add) + done + +lemma sclem: "size (concat (map (bin_to_bl n) xs)) = length xs * n" + by (induct xs) auto + +lemma bin_cat_foldl_lem: + "foldl (\u. bin_cat u n) x xs = + bin_cat x (size xs * n) (foldl (\u. bin_cat u n) y xs)" + apply (induct xs arbitrary: x) + apply simp + apply (simp (no_asm)) + apply (frule asm_rl) + apply (drule meta_spec) + apply (erule trans) + apply (drule_tac x = "bin_cat y n a" in meta_spec) + apply (simp add: bin_cat_assoc_sym min.absorb2) + done + +lemma bin_rcat_bl: "bin_rcat n wl = bl_to_bin (concat (map (bin_to_bl n) wl))" + apply (unfold bin_rcat_def) + apply (rule sym) + apply (induct wl) + apply (auto simp add: bl_to_bin_append) + apply (simp add: bl_to_bin_aux_alt sclem) + apply (simp add: bin_cat_foldl_lem [symmetric]) + done + +lemma bin_last_bl_to_bin: "bin_last (bl_to_bin bs) \ bs \ [] \ last bs" +by(cases "bs = []")(auto simp add: bl_to_bin_def last_bin_last'[where w=0]) + +lemma bin_rest_bl_to_bin: "bin_rest (bl_to_bin bs) = bl_to_bin (butlast bs)" +by(cases "bs = []")(simp_all add: bl_to_bin_def butlast_rest_bl2bin_aux) + +lemma bl_xor_aux_bin: + "map2 (\x y. x \ y) (bin_to_bl_aux n v bs) (bin_to_bl_aux n w cs) = + bin_to_bl_aux n (v XOR w) (map2 (\x y. x \ y) bs cs)" + apply (induct n arbitrary: v w bs cs) + apply simp + apply (case_tac v rule: bin_exhaust) + apply (case_tac w rule: bin_exhaust) + apply clarsimp + apply (case_tac b) + apply auto + done + +lemma bl_or_aux_bin: + "map2 (\) (bin_to_bl_aux n v bs) (bin_to_bl_aux n w cs) = + bin_to_bl_aux n (v OR w) (map2 (\) bs cs)" + apply (induct n arbitrary: v w bs cs) + apply simp + apply (case_tac v rule: bin_exhaust) + apply (case_tac w rule: bin_exhaust) + apply clarsimp + done + +lemma bl_and_aux_bin: + "map2 (\) (bin_to_bl_aux n v bs) (bin_to_bl_aux n w cs) = + bin_to_bl_aux n (v AND w) (map2 (\) bs cs)" + apply (induct n arbitrary: v w bs cs) + apply simp + apply (case_tac v rule: bin_exhaust) + apply (case_tac w rule: bin_exhaust) + apply clarsimp + done + +lemma bl_not_aux_bin: "map Not (bin_to_bl_aux n w cs) = bin_to_bl_aux n (NOT w) (map Not cs)" + by (induct n arbitrary: w cs) auto + +lemma bl_not_bin: "map Not (bin_to_bl n w) = bin_to_bl n (NOT w)" + by (simp add: bin_to_bl_def bl_not_aux_bin) + +lemma bl_and_bin: "map2 (\) (bin_to_bl n v) (bin_to_bl n w) = bin_to_bl n (v AND w)" + by (simp add: bin_to_bl_def bl_and_aux_bin) + +lemma bl_or_bin: "map2 (\) (bin_to_bl n v) (bin_to_bl n w) = bin_to_bl n (v OR w)" + by (simp add: bin_to_bl_def bl_or_aux_bin) + +lemma bl_xor_bin: "map2 (\x y. x \ y) (bin_to_bl n v) (bin_to_bl n w) = bin_to_bl n (v XOR w)" + by (simp only: bin_to_bl_def bl_xor_aux_bin map2_Nil) + end diff -r 6d2effbbf8d4 -r ff9efdc84289 src/HOL/Word/Bool_List_Representation.thy --- a/src/HOL/Word/Bool_List_Representation.thy Sat Apr 20 18:02:22 2019 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,996 +0,0 @@ -(* Title: HOL/Word/Bool_List_Representation.thy - Author: Jeremy Dawson, NICTA - -Theorems to do with integers, expressed using Pls, Min, BIT, -theorems linking them to lists of booleans, and repeated splitting -and concatenation. -*) - -section \Bool lists and integers\ - -theory Bool_List_Representation - imports Bit_Representation -begin - -definition map2 :: "('a \ 'b \ 'c) \ 'a list \ 'b list \ 'c list" - where "map2 f as bs = map (case_prod f) (zip as bs)" - -lemma map2_Nil [simp, code]: "map2 f [] ys = []" - by (auto simp: map2_def) - -lemma map2_Nil2 [simp, code]: "map2 f xs [] = []" - by (auto simp: map2_def) - -lemma map2_Cons [simp, code]: "map2 f (x # xs) (y # ys) = f x y # map2 f xs ys" - by (auto simp: map2_def) - - -subsection \Operations on lists of booleans\ - -primrec bl_to_bin_aux :: "bool list \ int \ int" - where - Nil: "bl_to_bin_aux [] w = w" - | Cons: "bl_to_bin_aux (b # bs) w = bl_to_bin_aux bs (w BIT b)" - -definition bl_to_bin :: "bool list \ int" - where "bl_to_bin bs = bl_to_bin_aux bs 0" - -primrec bin_to_bl_aux :: "nat \ int \ bool list \ bool list" - where - Z: "bin_to_bl_aux 0 w bl = bl" - | Suc: "bin_to_bl_aux (Suc n) w bl = bin_to_bl_aux n (bin_rest w) ((bin_last w) # bl)" - -definition bin_to_bl :: "nat \ int \ bool list" - where "bin_to_bl n w = bin_to_bl_aux n w []" - -primrec bl_of_nth :: "nat \ (nat \ bool) \ bool list" - where - Suc: "bl_of_nth (Suc n) f = f n # bl_of_nth n f" - | Z: "bl_of_nth 0 f = []" - -primrec takefill :: "'a \ nat \ 'a list \ 'a list" -where - Z: "takefill fill 0 xs = []" - | Suc: "takefill fill (Suc n) xs = - (case xs of - [] \ fill # takefill fill n xs - | y # ys \ y # takefill fill n ys)" - - -subsection "Arithmetic in terms of bool lists" - -text \ - Arithmetic operations in terms of the reversed bool list, - assuming input list(s) the same length, and don't extend them. -\ - -primrec rbl_succ :: "bool list \ bool list" - where - Nil: "rbl_succ Nil = Nil" - | Cons: "rbl_succ (x # xs) = (if x then False # rbl_succ xs else True # xs)" - -primrec rbl_pred :: "bool list \ bool list" - where - Nil: "rbl_pred Nil = Nil" - | Cons: "rbl_pred (x # xs) = (if x then False # xs else True # rbl_pred xs)" - -primrec rbl_add :: "bool list \ bool list \ bool list" - where \ \result is length of first arg, second arg may be longer\ - Nil: "rbl_add Nil x = Nil" - | Cons: "rbl_add (y # ys) x = - (let ws = rbl_add ys (tl x) - in (y \ hd x) # (if hd x \ y then rbl_succ ws else ws))" - -primrec rbl_mult :: "bool list \ bool list \ bool list" - where \ \result is length of first arg, second arg may be longer\ - Nil: "rbl_mult Nil x = Nil" - | Cons: "rbl_mult (y # ys) x = - (let ws = False # rbl_mult ys x - in if y then rbl_add ws x else ws)" - -lemma butlast_power: "(butlast ^^ n) bl = take (length bl - n) bl" - by (induct n) (auto simp: butlast_take) - -lemma bin_to_bl_aux_zero_minus_simp [simp]: - "0 < n \ bin_to_bl_aux n 0 bl = bin_to_bl_aux (n - 1) 0 (False # bl)" - by (cases n) auto - -lemma bin_to_bl_aux_minus1_minus_simp [simp]: - "0 < n \ bin_to_bl_aux n (- 1) bl = bin_to_bl_aux (n - 1) (- 1) (True # bl)" - by (cases n) auto - -lemma bin_to_bl_aux_one_minus_simp [simp]: - "0 < n \ bin_to_bl_aux n 1 bl = bin_to_bl_aux (n - 1) 0 (True # bl)" - by (cases n) auto - -lemma bin_to_bl_aux_Bit_minus_simp [simp]: - "0 < n \ bin_to_bl_aux n (w BIT b) bl = bin_to_bl_aux (n - 1) w (b # bl)" - by (cases n) auto - -lemma bin_to_bl_aux_Bit0_minus_simp [simp]: - "0 < n \ - bin_to_bl_aux n (numeral (Num.Bit0 w)) bl = bin_to_bl_aux (n - 1) (numeral w) (False # bl)" - by (cases n) auto - -lemma bin_to_bl_aux_Bit1_minus_simp [simp]: - "0 < n \ - bin_to_bl_aux n (numeral (Num.Bit1 w)) bl = bin_to_bl_aux (n - 1) (numeral w) (True # bl)" - by (cases n) auto - -text \Link between \bin\ and \bool list\.\ - -lemma bl_to_bin_aux_append: "bl_to_bin_aux (bs @ cs) w = bl_to_bin_aux cs (bl_to_bin_aux bs w)" - by (induct bs arbitrary: w) auto - -lemma bin_to_bl_aux_append: "bin_to_bl_aux n w bs @ cs = bin_to_bl_aux n w (bs @ cs)" - by (induct n arbitrary: w bs) auto - -lemma bl_to_bin_append: "bl_to_bin (bs @ cs) = bl_to_bin_aux cs (bl_to_bin bs)" - unfolding bl_to_bin_def by (rule bl_to_bin_aux_append) - -lemma bin_to_bl_aux_alt: "bin_to_bl_aux n w bs = bin_to_bl n w @ bs" - by (simp add: bin_to_bl_def bin_to_bl_aux_append) - -lemma bin_to_bl_0 [simp]: "bin_to_bl 0 bs = []" - by (auto simp: bin_to_bl_def) - -lemma size_bin_to_bl_aux: "size (bin_to_bl_aux n w bs) = n + length bs" - by (induct n arbitrary: w bs) auto - -lemma size_bin_to_bl [simp]: "size (bin_to_bl n w) = n" - by (simp add: bin_to_bl_def size_bin_to_bl_aux) - -lemma bin_bl_bin': "bl_to_bin (bin_to_bl_aux n w bs) = bl_to_bin_aux bs (bintrunc n w)" - by (induct n arbitrary: w bs) (auto simp: bl_to_bin_def) - -lemma bin_bl_bin [simp]: "bl_to_bin (bin_to_bl n w) = bintrunc n w" - by (auto simp: bin_to_bl_def bin_bl_bin') - -lemma bl_bin_bl': "bin_to_bl (n + length bs) (bl_to_bin_aux bs w) = bin_to_bl_aux n w bs" - apply (induct bs arbitrary: w n) - apply auto - apply (simp_all only: add_Suc [symmetric]) - apply (auto simp add: bin_to_bl_def) - done - -lemma bl_bin_bl [simp]: "bin_to_bl (length bs) (bl_to_bin bs) = bs" - unfolding bl_to_bin_def - apply (rule box_equals) - apply (rule bl_bin_bl') - prefer 2 - apply (rule bin_to_bl_aux.Z) - apply simp - done - -lemma bl_to_bin_inj: "bl_to_bin bs = bl_to_bin cs \ length bs = length cs \ bs = cs" - apply (rule_tac box_equals) - defer - apply (rule bl_bin_bl) - apply (rule bl_bin_bl) - apply simp - done - -lemma bl_to_bin_False [simp]: "bl_to_bin (False # bl) = bl_to_bin bl" - by (auto simp: bl_to_bin_def) - -lemma bl_to_bin_Nil [simp]: "bl_to_bin [] = 0" - by (auto simp: bl_to_bin_def) - -lemma bin_to_bl_zero_aux: "bin_to_bl_aux n 0 bl = replicate n False @ bl" - by (induct n arbitrary: bl) (auto simp: replicate_app_Cons_same) - -lemma bin_to_bl_zero: "bin_to_bl n 0 = replicate n False" - by (simp add: bin_to_bl_def bin_to_bl_zero_aux) - -lemma bin_to_bl_minus1_aux: "bin_to_bl_aux n (- 1) bl = replicate n True @ bl" - by (induct n arbitrary: bl) (auto simp: replicate_app_Cons_same) - -lemma bin_to_bl_minus1: "bin_to_bl n (- 1) = replicate n True" - by (simp add: bin_to_bl_def bin_to_bl_minus1_aux) - -lemma bl_to_bin_rep_F: "bl_to_bin (replicate n False @ bl) = bl_to_bin bl" - by (simp add: bin_to_bl_zero_aux [symmetric] bin_bl_bin') (simp add: bl_to_bin_def) - -lemma bin_to_bl_trunc [simp]: "n \ m \ bin_to_bl n (bintrunc m w) = bin_to_bl n w" - by (auto intro: bl_to_bin_inj) - -lemma bin_to_bl_aux_bintr: - "bin_to_bl_aux n (bintrunc m bin) bl = - replicate (n - m) False @ bin_to_bl_aux (min n m) bin bl" - apply (induct n arbitrary: m bin bl) - apply clarsimp - apply clarsimp - apply (case_tac "m") - apply (clarsimp simp: bin_to_bl_zero_aux) - apply (erule thin_rl) - apply (induct_tac n) - apply auto - done - -lemma bin_to_bl_bintr: - "bin_to_bl n (bintrunc m bin) = replicate (n - m) False @ bin_to_bl (min n m) bin" - unfolding bin_to_bl_def by (rule bin_to_bl_aux_bintr) - -lemma bl_to_bin_rep_False: "bl_to_bin (replicate n False) = 0" - by (induct n) auto - -lemma len_bin_to_bl_aux: "length (bin_to_bl_aux n w bs) = n + length bs" - by (fact size_bin_to_bl_aux) - -lemma len_bin_to_bl: "length (bin_to_bl n w) = n" - by (fact size_bin_to_bl) (* FIXME: duplicate *) - -lemma sign_bl_bin': "bin_sign (bl_to_bin_aux bs w) = bin_sign w" - by (induct bs arbitrary: w) auto - -lemma sign_bl_bin: "bin_sign (bl_to_bin bs) = 0" - by (simp add: bl_to_bin_def sign_bl_bin') - -lemma bl_sbin_sign_aux: "hd (bin_to_bl_aux (Suc n) w bs) = (bin_sign (sbintrunc n w) = -1)" - apply (induct n arbitrary: w bs) - apply clarsimp - apply (cases w rule: bin_exhaust) - apply simp - done - -lemma bl_sbin_sign: "hd (bin_to_bl (Suc n) w) = (bin_sign (sbintrunc n w) = -1)" - unfolding bin_to_bl_def by (rule bl_sbin_sign_aux) - -lemma bin_nth_of_bl_aux: - "bin_nth (bl_to_bin_aux bl w) n = - (n < size bl \ rev bl ! n \ n \ length bl \ bin_nth w (n - size bl))" - apply (induct bl arbitrary: w) - apply clarsimp - apply clarsimp - apply (cut_tac x=n and y="size bl" in linorder_less_linear) - apply (erule disjE, simp add: nth_append)+ - apply auto - done - -lemma bin_nth_of_bl: "bin_nth (bl_to_bin bl) n = (n < length bl \ rev bl ! n)" - by (simp add: bl_to_bin_def bin_nth_of_bl_aux) - -lemma bin_nth_bl: "n < m \ bin_nth w n = nth (rev (bin_to_bl m w)) n" - apply (induct n arbitrary: m w) - apply clarsimp - apply (case_tac m, clarsimp) - apply (clarsimp simp: bin_to_bl_def) - apply (simp add: bin_to_bl_aux_alt) - apply clarsimp - apply (case_tac m, clarsimp) - apply (clarsimp simp: bin_to_bl_def) - apply (simp add: bin_to_bl_aux_alt) - done - -lemma nth_rev: "n < length xs \ rev xs ! n = xs ! (length xs - 1 - n)" - apply (induct xs) - apply simp - apply (clarsimp simp add: nth_append nth.simps split: nat.split) - apply (rule_tac f = "\n. xs ! n" in arg_cong) - apply arith - done - -lemma nth_rev_alt: "n < length ys \ ys ! n = rev ys ! (length ys - Suc n)" - by (simp add: nth_rev) - -lemma nth_bin_to_bl_aux: - "n < m + length bl \ (bin_to_bl_aux m w bl) ! n = - (if n < m then bin_nth w (m - 1 - n) else bl ! (n - m))" - apply (induct m arbitrary: w n bl) - apply clarsimp - apply clarsimp - apply (case_tac w rule: bin_exhaust) - apply simp - done - -lemma nth_bin_to_bl: "n < m \ (bin_to_bl m w) ! n = bin_nth w (m - Suc n)" - by (simp add: bin_to_bl_def nth_bin_to_bl_aux) - -lemma bl_to_bin_lt2p_aux: "bl_to_bin_aux bs w < (w + 1) * (2 ^ length bs)" - apply (induct bs arbitrary: w) - apply clarsimp - apply clarsimp - apply (drule meta_spec, erule xtrans(8) [rotated], simp add: Bit_def)+ - done - -lemma bl_to_bin_lt2p_drop: "bl_to_bin bs < 2 ^ length (dropWhile Not bs)" -proof (induct bs) - case Nil - then show ?case by simp -next - case (Cons b bs) - with bl_to_bin_lt2p_aux[where w=1] show ?case - by (simp add: bl_to_bin_def) -qed - -lemma bl_to_bin_lt2p: "bl_to_bin bs < 2 ^ length bs" - by (metis bin_bl_bin bintr_lt2p bl_bin_bl) - -lemma bl_to_bin_ge2p_aux: "bl_to_bin_aux bs w \ w * (2 ^ length bs)" - apply (induct bs arbitrary: w) - apply clarsimp - apply clarsimp - apply (drule meta_spec, erule order_trans [rotated], - simp add: Bit_B0_2t Bit_B1_2t algebra_simps)+ - apply (simp add: Bit_def) - done - -lemma bl_to_bin_ge0: "bl_to_bin bs \ 0" - apply (unfold bl_to_bin_def) - apply (rule xtrans(4)) - apply (rule bl_to_bin_ge2p_aux) - apply simp - done - -lemma butlast_rest_bin: "butlast (bin_to_bl n w) = bin_to_bl (n - 1) (bin_rest w)" - apply (unfold bin_to_bl_def) - apply (cases w rule: bin_exhaust) - apply (cases n, clarsimp) - apply clarsimp - apply (auto simp add: bin_to_bl_aux_alt) - done - -lemma butlast_bin_rest: "butlast bl = bin_to_bl (length bl - Suc 0) (bin_rest (bl_to_bin bl))" - using butlast_rest_bin [where w="bl_to_bin bl" and n="length bl"] by simp - -lemma butlast_rest_bl2bin_aux: - "bl \ [] \ bl_to_bin_aux (butlast bl) w = bin_rest (bl_to_bin_aux bl w)" - by (induct bl arbitrary: w) auto - -lemma butlast_rest_bl2bin: "bl_to_bin (butlast bl) = bin_rest (bl_to_bin bl)" - by (cases bl) (auto simp: bl_to_bin_def butlast_rest_bl2bin_aux) - -lemma trunc_bl2bin_aux: - "bintrunc m (bl_to_bin_aux bl w) = - bl_to_bin_aux (drop (length bl - m) bl) (bintrunc (m - length bl) w)" -proof (induct bl arbitrary: w) - case Nil - show ?case by simp -next - case (Cons b bl) - show ?case - proof (cases "m - length bl") - case 0 - then have "Suc (length bl) - m = Suc (length bl - m)" by simp - with Cons show ?thesis by simp - next - case (Suc n) - then have "m - Suc (length bl) = n" by simp - with Cons Suc show ?thesis by simp - qed -qed - -lemma trunc_bl2bin: "bintrunc m (bl_to_bin bl) = bl_to_bin (drop (length bl - m) bl)" - by (simp add: bl_to_bin_def trunc_bl2bin_aux) - -lemma trunc_bl2bin_len [simp]: "bintrunc (length bl) (bl_to_bin bl) = bl_to_bin bl" - by (simp add: trunc_bl2bin) - -lemma bl2bin_drop: "bl_to_bin (drop k bl) = bintrunc (length bl - k) (bl_to_bin bl)" - apply (rule trans) - prefer 2 - apply (rule trunc_bl2bin [symmetric]) - apply (cases "k \ length bl") - apply auto - done - -lemma nth_rest_power_bin: "bin_nth ((bin_rest ^^ k) w) n = bin_nth w (n + k)" - apply (induct k arbitrary: n) - apply clarsimp - apply clarsimp - apply (simp only: bin_nth.Suc [symmetric] add_Suc) - done - -lemma take_rest_power_bin: "m \ n \ take m (bin_to_bl n w) = bin_to_bl m ((bin_rest ^^ (n - m)) w)" - apply (rule nth_equalityI) - apply simp - apply (clarsimp simp add: nth_bin_to_bl nth_rest_power_bin) - done - -lemma hd_butlast: "size xs > 1 \ hd (butlast xs) = hd xs" - by (cases xs) auto - -lemma last_bin_last': "size xs > 0 \ last xs \ bin_last (bl_to_bin_aux xs w)" - by (induct xs arbitrary: w) auto - -lemma last_bin_last: "size xs > 0 \ last xs \ bin_last (bl_to_bin xs)" - unfolding bl_to_bin_def by (erule last_bin_last') - -lemma bin_last_last: "bin_last w \ last (bin_to_bl (Suc n) w)" - by (simp add: bin_to_bl_def) (auto simp: bin_to_bl_aux_alt) - - -lemma drop_bin2bl_aux: - "drop m (bin_to_bl_aux n bin bs) = - bin_to_bl_aux (n - m) bin (drop (m - n) bs)" - apply (induct n arbitrary: m bin bs, clarsimp) - apply clarsimp - apply (case_tac bin rule: bin_exhaust) - apply (case_tac "m \ n", simp) - apply (case_tac "m - n", simp) - apply simp - apply (rule_tac f = "\nat. drop nat bs" in arg_cong) - apply simp - done - -lemma drop_bin2bl: "drop m (bin_to_bl n bin) = bin_to_bl (n - m) bin" - by (simp add: bin_to_bl_def drop_bin2bl_aux) - -lemma take_bin2bl_lem1: "take m (bin_to_bl_aux m w bs) = bin_to_bl m w" - apply (induct m arbitrary: w bs) - apply clarsimp - apply clarsimp - apply (simp add: bin_to_bl_aux_alt) - apply (simp add: bin_to_bl_def) - apply (simp add: bin_to_bl_aux_alt) - done - -lemma take_bin2bl_lem: "take m (bin_to_bl_aux (m + n) w bs) = take m (bin_to_bl (m + n) w)" - by (induct n arbitrary: w bs) (simp_all (no_asm) add: bin_to_bl_def take_bin2bl_lem1, simp) - -lemma bin_split_take: "bin_split n c = (a, b) \ bin_to_bl m a = take m (bin_to_bl (m + n) c)" - apply (induct n arbitrary: b c) - apply clarsimp - apply (clarsimp simp: Let_def split: prod.split_asm) - apply (simp add: bin_to_bl_def) - apply (simp add: take_bin2bl_lem) - done - -lemma bin_split_take1: - "k = m + n \ bin_split n c = (a, b) \ bin_to_bl m a = take m (bin_to_bl k c)" - by (auto elim: bin_split_take) - -lemma nth_takefill: "m < n \ takefill fill n l ! m = (if m < length l then l ! m else fill)" - apply (induct n arbitrary: m l) - apply clarsimp - apply clarsimp - apply (case_tac m) - apply (simp split: list.split) - apply (simp split: list.split) - done - -lemma takefill_alt: "takefill fill n l = take n l @ replicate (n - length l) fill" - by (induct n arbitrary: l) (auto split: list.split) - -lemma takefill_replicate [simp]: "takefill fill n (replicate m fill) = replicate n fill" - by (simp add: takefill_alt replicate_add [symmetric]) - -lemma takefill_le': "n = m + k \ takefill x m (takefill x n l) = takefill x m l" - by (induct m arbitrary: l n) (auto split: list.split) - -lemma length_takefill [simp]: "length (takefill fill n l) = n" - by (simp add: takefill_alt) - -lemma take_takefill': "n = k + m \ take k (takefill fill n w) = takefill fill k w" - by (induct k arbitrary: w n) (auto split: list.split) - -lemma drop_takefill: "drop k (takefill fill (m + k) w) = takefill fill m (drop k w)" - by (induct k arbitrary: w) (auto split: list.split) - -lemma takefill_le [simp]: "m \ n \ takefill x m (takefill x n l) = takefill x m l" - by (auto simp: le_iff_add takefill_le') - -lemma take_takefill [simp]: "m \ n \ take m (takefill fill n w) = takefill fill m w" - by (auto simp: le_iff_add take_takefill') - -lemma takefill_append: "takefill fill (m + length xs) (xs @ w) = xs @ (takefill fill m w)" - by (induct xs) auto - -lemma takefill_same': "l = length xs \ takefill fill l xs = xs" - by (induct xs arbitrary: l) auto - -lemmas takefill_same [simp] = takefill_same' [OF refl] - -lemma takefill_bintrunc: "takefill False n bl = rev (bin_to_bl n (bl_to_bin (rev bl)))" - apply (rule nth_equalityI) - apply simp - apply (clarsimp simp: nth_takefill nth_rev nth_bin_to_bl bin_nth_of_bl) - done - -lemma bl_bin_bl_rtf: "bin_to_bl n (bl_to_bin bl) = rev (takefill False n (rev bl))" - by (simp add: takefill_bintrunc) - -lemma bl_bin_bl_rep_drop: - "bin_to_bl n (bl_to_bin bl) = - replicate (n - length bl) False @ drop (length bl - n) bl" - by (simp add: bl_bin_bl_rtf takefill_alt rev_take) - -lemma tf_rev: - "n + k = m + length bl \ takefill x m (rev (takefill y n bl)) = - rev (takefill y m (rev (takefill x k (rev bl))))" - apply (rule nth_equalityI) - apply (auto simp add: nth_takefill nth_rev) - apply (rule_tac f = "\n. bl ! n" in arg_cong) - apply arith - done - -lemma takefill_minus: "0 < n \ takefill fill (Suc (n - 1)) w = takefill fill n w" - by auto - -lemmas takefill_Suc_cases = - list.cases [THEN takefill.Suc [THEN trans]] - -lemmas takefill_Suc_Nil = takefill_Suc_cases (1) -lemmas takefill_Suc_Cons = takefill_Suc_cases (2) - -lemmas takefill_minus_simps = takefill_Suc_cases [THEN [2] - takefill_minus [symmetric, THEN trans]] - -lemma takefill_numeral_Nil [simp]: - "takefill fill (numeral k) [] = fill # takefill fill (pred_numeral k) []" - by (simp add: numeral_eq_Suc) - -lemma takefill_numeral_Cons [simp]: - "takefill fill (numeral k) (x # xs) = x # takefill fill (pred_numeral k) xs" - by (simp add: numeral_eq_Suc) - - -subsection \Links with function \bl_to_bin\\ - -lemma bl_to_bin_aux_cat: - "\nv v. bl_to_bin_aux bs (bin_cat w nv v) = - bin_cat w (nv + length bs) (bl_to_bin_aux bs v)" - by (induct bs) (simp, simp add: bin_cat_Suc_Bit [symmetric] del: bin_cat.simps) - -lemma bin_to_bl_aux_cat: - "\w bs. bin_to_bl_aux (nv + nw) (bin_cat v nw w) bs = - bin_to_bl_aux nv v (bin_to_bl_aux nw w bs)" - by (induct nw) auto - -lemma bl_to_bin_aux_alt: "bl_to_bin_aux bs w = bin_cat w (length bs) (bl_to_bin bs)" - using bl_to_bin_aux_cat [where nv = "0" and v = "0"] - by (simp add: bl_to_bin_def [symmetric]) - -lemma bin_to_bl_cat: - "bin_to_bl (nv + nw) (bin_cat v nw w) = - bin_to_bl_aux nv v (bin_to_bl nw w)" - by (simp add: bin_to_bl_def bin_to_bl_aux_cat) - -lemmas bl_to_bin_aux_app_cat = - trans [OF bl_to_bin_aux_append bl_to_bin_aux_alt] - -lemmas bin_to_bl_aux_cat_app = - trans [OF bin_to_bl_aux_cat bin_to_bl_aux_alt] - -lemma bl_to_bin_app_cat: - "bl_to_bin (bsa @ bs) = bin_cat (bl_to_bin bsa) (length bs) (bl_to_bin bs)" - by (simp only: bl_to_bin_aux_app_cat bl_to_bin_def) - -lemma bin_to_bl_cat_app: - "bin_to_bl (n + nw) (bin_cat w nw wa) = bin_to_bl n w @ bin_to_bl nw wa" - by (simp only: bin_to_bl_def bin_to_bl_aux_cat_app) - -text \\bl_to_bin_app_cat_alt\ and \bl_to_bin_app_cat\ are easily interderivable.\ -lemma bl_to_bin_app_cat_alt: "bin_cat (bl_to_bin cs) n w = bl_to_bin (cs @ bin_to_bl n w)" - by (simp add: bl_to_bin_app_cat) - -lemma mask_lem: "(bl_to_bin (True # replicate n False)) = bl_to_bin (replicate n True) + 1" - apply (unfold bl_to_bin_def) - apply (induct n) - apply simp - apply (simp only: Suc_eq_plus1 replicate_add append_Cons [symmetric] bl_to_bin_aux_append) - apply (simp add: Bit_B0_2t Bit_B1_2t) - done - - -subsection \Function \bl_of_nth\\ - -lemma length_bl_of_nth [simp]: "length (bl_of_nth n f) = n" - by (induct n) auto - -lemma nth_bl_of_nth [simp]: "m < n \ rev (bl_of_nth n f) ! m = f m" - apply (induct n) - apply simp - apply (clarsimp simp add: nth_append) - apply (rule_tac f = "f" in arg_cong) - apply simp - done - -lemma bl_of_nth_inj: "(\k. k < n \ f k = g k) \ bl_of_nth n f = bl_of_nth n g" - by (induct n) auto - -lemma bl_of_nth_nth_le: "n \ length xs \ bl_of_nth n (nth (rev xs)) = drop (length xs - n) xs" - apply (induct n arbitrary: xs) - apply clarsimp - apply clarsimp - apply (rule trans [OF _ hd_Cons_tl]) - apply (frule Suc_le_lessD) - apply (simp add: nth_rev trans [OF drop_Suc drop_tl, symmetric]) - apply (subst hd_drop_conv_nth) - apply force - apply simp_all - apply (rule_tac f = "\n. drop n xs" in arg_cong) - apply simp - done - -lemma bl_of_nth_nth [simp]: "bl_of_nth (length xs) ((!) (rev xs)) = xs" - by (simp add: bl_of_nth_nth_le) - -lemma size_rbl_pred: "length (rbl_pred bl) = length bl" - by (induct bl) auto - -lemma size_rbl_succ: "length (rbl_succ bl) = length bl" - by (induct bl) auto - -lemma size_rbl_add: "length (rbl_add bl cl) = length bl" - by (induct bl arbitrary: cl) (auto simp: Let_def size_rbl_succ) - -lemma size_rbl_mult: "length (rbl_mult bl cl) = length bl" - by (induct bl arbitrary: cl) (auto simp add: Let_def size_rbl_add) - -lemmas rbl_sizes [simp] = - size_rbl_pred size_rbl_succ size_rbl_add size_rbl_mult - -lemmas rbl_Nils = - rbl_pred.Nil rbl_succ.Nil rbl_add.Nil rbl_mult.Nil - -lemma rbl_pred: "rbl_pred (rev (bin_to_bl n bin)) = rev (bin_to_bl n (bin - 1))" - apply (unfold bin_to_bl_def) - apply (induct n arbitrary: bin) - apply simp - apply clarsimp - apply (case_tac bin rule: bin_exhaust) - apply (case_tac b) - apply (clarsimp simp: bin_to_bl_aux_alt)+ - done - -lemma rbl_succ: "rbl_succ (rev (bin_to_bl n bin)) = rev (bin_to_bl n (bin + 1))" - apply (unfold bin_to_bl_def) - apply (induct n arbitrary: bin) - apply simp - apply clarsimp - apply (case_tac bin rule: bin_exhaust) - apply (case_tac b) - apply (clarsimp simp: bin_to_bl_aux_alt)+ - done - -lemma rbl_add: - "\bina binb. rbl_add (rev (bin_to_bl n bina)) (rev (bin_to_bl n binb)) = - rev (bin_to_bl n (bina + binb))" - apply (unfold bin_to_bl_def) - apply (induct n) - apply simp - apply clarsimp - apply (case_tac bina rule: bin_exhaust) - apply (case_tac binb rule: bin_exhaust) - apply (case_tac b) - apply (case_tac [!] "ba") - apply (auto simp: rbl_succ bin_to_bl_aux_alt Let_def ac_simps) - done - -lemma rbl_add_app2: "length blb \ length bla \ rbl_add bla (blb @ blc) = rbl_add bla blb" - apply (induct bla arbitrary: blb) - apply simp - apply clarsimp - apply (case_tac blb, clarsimp) - apply (clarsimp simp: Let_def) - done - -lemma rbl_add_take2: - "length blb \ length bla \ rbl_add bla (take (length bla) blb) = rbl_add bla blb" - apply (induct bla arbitrary: blb) - apply simp - apply clarsimp - apply (case_tac blb, clarsimp) - apply (clarsimp simp: Let_def) - done - -lemma rbl_add_long: - "m \ n \ rbl_add (rev (bin_to_bl n bina)) (rev (bin_to_bl m binb)) = - rev (bin_to_bl n (bina + binb))" - apply (rule box_equals [OF _ rbl_add_take2 rbl_add]) - apply (rule_tac f = "rbl_add (rev (bin_to_bl n bina))" in arg_cong) - apply (rule rev_swap [THEN iffD1]) - apply (simp add: rev_take drop_bin2bl) - apply simp - done - -lemma rbl_mult_app2: "length blb \ length bla \ rbl_mult bla (blb @ blc) = rbl_mult bla blb" - apply (induct bla arbitrary: blb) - apply simp - apply clarsimp - apply (case_tac blb, clarsimp) - apply (clarsimp simp: Let_def rbl_add_app2) - done - -lemma rbl_mult_take2: - "length blb \ length bla \ rbl_mult bla (take (length bla) blb) = rbl_mult bla blb" - apply (rule trans) - apply (rule rbl_mult_app2 [symmetric]) - apply simp - apply (rule_tac f = "rbl_mult bla" in arg_cong) - apply (rule append_take_drop_id) - done - -lemma rbl_mult_gt1: - "m \ length bl \ - rbl_mult bl (rev (bin_to_bl m binb)) = - rbl_mult bl (rev (bin_to_bl (length bl) binb))" - apply (rule trans) - apply (rule rbl_mult_take2 [symmetric]) - apply simp_all - apply (rule_tac f = "rbl_mult bl" in arg_cong) - apply (rule rev_swap [THEN iffD1]) - apply (simp add: rev_take drop_bin2bl) - done - -lemma rbl_mult_gt: - "m > n \ - rbl_mult (rev (bin_to_bl n bina)) (rev (bin_to_bl m binb)) = - rbl_mult (rev (bin_to_bl n bina)) (rev (bin_to_bl n binb))" - by (auto intro: trans [OF rbl_mult_gt1]) - -lemmas rbl_mult_Suc = lessI [THEN rbl_mult_gt] - -lemma rbbl_Cons: "b # rev (bin_to_bl n x) = rev (bin_to_bl (Suc n) (x BIT b))" - by (simp add: bin_to_bl_def) (simp add: bin_to_bl_aux_alt) - -lemma rbl_mult: - "rbl_mult (rev (bin_to_bl n bina)) (rev (bin_to_bl n binb)) = - rev (bin_to_bl n (bina * binb))" - apply (induct n arbitrary: bina binb) - apply simp - apply (unfold bin_to_bl_def) - apply clarsimp - apply (case_tac bina rule: bin_exhaust) - apply (case_tac binb rule: bin_exhaust) - apply (case_tac b) - apply (case_tac [!] "ba") - apply (auto simp: bin_to_bl_aux_alt Let_def) - apply (auto simp: rbbl_Cons rbl_mult_Suc rbl_add) - done - -lemma rbl_add_split: - "P (rbl_add (y # ys) (x # xs)) = - (\ws. length ws = length ys \ ws = rbl_add ys xs \ - (y \ ((x \ P (False # rbl_succ ws)) \ (\ x \ P (True # ws)))) \ - (\ y \ P (x # ws)))" - by (cases y) (auto simp: Let_def) - -lemma rbl_mult_split: - "P (rbl_mult (y # ys) xs) = - (\ws. length ws = Suc (length ys) \ ws = False # rbl_mult ys xs \ - (y \ P (rbl_add ws xs)) \ (\ y \ P ws))" - by (auto simp: Let_def) - - -subsection \Repeated splitting or concatenation\ - -lemma sclem: "size (concat (map (bin_to_bl n) xs)) = length xs * n" - by (induct xs) auto - -lemma bin_cat_foldl_lem: - "foldl (\u. bin_cat u n) x xs = - bin_cat x (size xs * n) (foldl (\u. bin_cat u n) y xs)" - apply (induct xs arbitrary: x) - apply simp - apply (simp (no_asm)) - apply (frule asm_rl) - apply (drule meta_spec) - apply (erule trans) - apply (drule_tac x = "bin_cat y n a" in meta_spec) - apply (simp add: bin_cat_assoc_sym min.absorb2) - done - -lemma bin_rcat_bl: "bin_rcat n wl = bl_to_bin (concat (map (bin_to_bl n) wl))" - apply (unfold bin_rcat_def) - apply (rule sym) - apply (induct wl) - apply (auto simp add: bl_to_bin_append) - apply (simp add: bl_to_bin_aux_alt sclem) - apply (simp add: bin_cat_foldl_lem [symmetric]) - done - -lemmas bin_rsplit_aux_simps = bin_rsplit_aux.simps bin_rsplitl_aux.simps -lemmas rsplit_aux_simps = bin_rsplit_aux_simps - -lemmas th_if_simp1 = if_split [where P = "(=) l", THEN iffD1, THEN conjunct1, THEN mp] for l -lemmas th_if_simp2 = if_split [where P = "(=) l", THEN iffD1, THEN conjunct2, THEN mp] for l - -lemmas rsplit_aux_simp1s = rsplit_aux_simps [THEN th_if_simp1] - -lemmas rsplit_aux_simp2ls = rsplit_aux_simps [THEN th_if_simp2] -\ \these safe to \[simp add]\ as require calculating \m - n\\ -lemmas bin_rsplit_aux_simp2s [simp] = rsplit_aux_simp2ls [unfolded Let_def] -lemmas rbscl = bin_rsplit_aux_simp2s (2) - -lemmas rsplit_aux_0_simps [simp] = - rsplit_aux_simp1s [OF disjI1] rsplit_aux_simp1s [OF disjI2] - -lemma bin_rsplit_aux_append: "bin_rsplit_aux n m c (bs @ cs) = bin_rsplit_aux n m c bs @ cs" - apply (induct n m c bs rule: bin_rsplit_aux.induct) - apply (subst bin_rsplit_aux.simps) - apply (subst bin_rsplit_aux.simps) - apply (clarsimp split: prod.split) - done - -lemma bin_rsplitl_aux_append: "bin_rsplitl_aux n m c (bs @ cs) = bin_rsplitl_aux n m c bs @ cs" - apply (induct n m c bs rule: bin_rsplitl_aux.induct) - apply (subst bin_rsplitl_aux.simps) - apply (subst bin_rsplitl_aux.simps) - apply (clarsimp split: prod.split) - done - -lemmas rsplit_aux_apps [where bs = "[]"] = - bin_rsplit_aux_append bin_rsplitl_aux_append - -lemmas rsplit_def_auxs = bin_rsplit_def bin_rsplitl_def - -lemmas rsplit_aux_alts = rsplit_aux_apps - [unfolded append_Nil rsplit_def_auxs [symmetric]] - -lemma bin_split_minus: "0 < n \ bin_split (Suc (n - 1)) w = bin_split n w" - by auto - -lemmas bin_split_minus_simp = - bin_split.Suc [THEN [2] bin_split_minus [symmetric, THEN trans]] - -lemma bin_split_pred_simp [simp]: - "(0::nat) < numeral bin \ - bin_split (numeral bin) w = - (let (w1, w2) = bin_split (numeral bin - 1) (bin_rest w) - in (w1, w2 BIT bin_last w))" - by (simp only: bin_split_minus_simp) - -lemma bin_rsplit_aux_simp_alt: - "bin_rsplit_aux n m c bs = - (if m = 0 \ n = 0 then bs - else let (a, b) = bin_split n c in bin_rsplit n (m - n, a) @ b # bs)" - apply (simp add: bin_rsplit_aux.simps [of n m c bs]) - apply (subst rsplit_aux_alts) - apply (simp add: bin_rsplit_def) - done - -lemmas bin_rsplit_simp_alt = - trans [OF bin_rsplit_def bin_rsplit_aux_simp_alt] - -lemmas bthrs = bin_rsplit_simp_alt [THEN [2] trans] - -lemma bin_rsplit_size_sign' [rule_format]: - "n > 0 \ rev sw = bin_rsplit n (nw, w) \ \v\set sw. bintrunc n v = v" - apply (induct sw arbitrary: nw w) - apply clarsimp - apply clarsimp - apply (drule bthrs) - apply (simp (no_asm_use) add: Let_def split: prod.split_asm if_split_asm) - apply clarify - apply (drule split_bintrunc) - apply simp - done - -lemmas bin_rsplit_size_sign = bin_rsplit_size_sign' [OF asm_rl - rev_rev_ident [THEN trans] set_rev [THEN equalityD2 [THEN subsetD]]] - -lemma bin_nth_rsplit [rule_format] : - "n > 0 \ m < n \ - \w k nw. - rev sw = bin_rsplit n (nw, w) \ - k < size sw \ bin_nth (sw ! k) m = bin_nth w (k * n + m)" - apply (induct sw) - apply clarsimp - apply clarsimp - apply (drule bthrs) - apply (simp (no_asm_use) add: Let_def split: prod.split_asm if_split_asm) - apply clarify - apply (erule allE, erule impE, erule exI) - apply (case_tac k) - apply clarsimp - prefer 2 - apply clarsimp - apply (erule allE) - apply (erule (1) impE) - apply (drule bin_nth_split, erule conjE, erule allE, erule trans, simp add: ac_simps)+ - done - -lemma bin_rsplit_all: "0 < nw \ nw \ n \ bin_rsplit n (nw, w) = [bintrunc n w]" - by (auto simp: bin_rsplit_def rsplit_aux_simp2ls split: prod.split dest!: split_bintrunc) - -lemma bin_rsplit_l [rule_format]: - "\bin. bin_rsplitl n (m, bin) = bin_rsplit n (m, bintrunc m bin)" - apply (rule_tac a = "m" in wf_less_than [THEN wf_induct]) - apply (simp (no_asm) add: bin_rsplitl_def bin_rsplit_def) - apply (rule allI) - apply (subst bin_rsplitl_aux.simps) - apply (subst bin_rsplit_aux.simps) - apply (clarsimp simp: Let_def split: prod.split) - apply (drule bin_split_trunc) - apply (drule sym [THEN trans], assumption) - apply (subst rsplit_aux_alts(1)) - apply (subst rsplit_aux_alts(2)) - apply clarsimp - unfolding bin_rsplit_def bin_rsplitl_def - apply simp - done - -lemma bin_rsplit_rcat [rule_format]: - "n > 0 \ bin_rsplit n (n * size ws, bin_rcat n ws) = map (bintrunc n) ws" - apply (unfold bin_rsplit_def bin_rcat_def) - apply (rule_tac xs = ws in rev_induct) - apply clarsimp - apply clarsimp - apply (subst rsplit_aux_alts) - unfolding bin_split_cat - apply simp - done - -lemma bin_rsplit_aux_len_le [rule_format] : - "\ws m. n \ 0 \ ws = bin_rsplit_aux n nw w bs \ - length ws \ m \ nw + length bs * n \ m * n" -proof - - have *: R - if d: "i \ j \ m < j'" - and R1: "i * k \ j * k \ R" - and R2: "Suc m * k' \ j' * k' \ R" - for i j j' k k' m :: nat and R - using d - apply safe - apply (rule R1, erule mult_le_mono1) - apply (rule R2, erule Suc_le_eq [THEN iffD2 [THEN mult_le_mono1]]) - done - have **: "0 < sc \ sc - n + (n + lb * n) \ m * n \ sc + lb * n \ m * n" - for sc m n lb :: nat - apply safe - apply arith - apply (case_tac "sc \ n") - apply arith - apply (insert linorder_le_less_linear [of m lb]) - apply (erule_tac k=n and k'=n in *) - apply arith - apply simp - done - show ?thesis - apply (induct n nw w bs rule: bin_rsplit_aux.induct) - apply (subst bin_rsplit_aux.simps) - apply (simp add: ** Let_def split: prod.split) - done -qed - -lemma bin_rsplit_len_le: "n \ 0 \ ws = bin_rsplit n (nw, w) \ length ws \ m \ nw \ m * n" - by (auto simp: bin_rsplit_def bin_rsplit_aux_len_le) - -lemma bin_rsplit_aux_len: - "n \ 0 \ length (bin_rsplit_aux n nw w cs) = (nw + n - 1) div n + length cs" - apply (induct n nw w cs rule: bin_rsplit_aux.induct) - apply (subst bin_rsplit_aux.simps) - apply (clarsimp simp: Let_def split: prod.split) - apply (erule thin_rl) - apply (case_tac m) - apply simp - apply (case_tac "m \ n") - apply (auto simp add: div_add_self2) - done - -lemma bin_rsplit_len: "n \ 0 \ length (bin_rsplit n (nw, w)) = (nw + n - 1) div n" - by (auto simp: bin_rsplit_def bin_rsplit_aux_len) - -lemma bin_rsplit_aux_len_indep: - "n \ 0 \ length bs = length cs \ - length (bin_rsplit_aux n nw v bs) = - length (bin_rsplit_aux n nw w cs)" -proof (induct n nw w cs arbitrary: v bs rule: bin_rsplit_aux.induct) - case (1 n m w cs v bs) - show ?case - proof (cases "m = 0") - case True - with \length bs = length cs\ show ?thesis by simp - next - case False - from "1.hyps" \m \ 0\ \n \ 0\ - have hyp: "\v bs. length bs = Suc (length cs) \ - length (bin_rsplit_aux n (m - n) v bs) = - length (bin_rsplit_aux n (m - n) (fst (bin_split n w)) (snd (bin_split n w) # cs))" - by auto - from \length bs = length cs\ \n \ 0\ show ?thesis - by (auto simp add: bin_rsplit_aux_simp_alt Let_def bin_rsplit_len split: prod.split) - qed -qed - -lemma bin_rsplit_len_indep: - "n \ 0 \ length (bin_rsplit n (nw, v)) = length (bin_rsplit n (nw, w))" - apply (unfold bin_rsplit_def) - apply (simp (no_asm)) - apply (erule bin_rsplit_aux_len_indep) - apply (rule refl) - done - -end diff -r 6d2effbbf8d4 -r ff9efdc84289 src/HOL/Word/Misc_Arithmetic.thy --- a/src/HOL/Word/Misc_Arithmetic.thy Sat Apr 20 18:02:22 2019 +0000 +++ b/src/HOL/Word/Misc_Arithmetic.thy Mon Apr 22 06:28:17 2019 +0000 @@ -3,7 +3,7 @@ section \Miscellaneous lemmas, mostly for arithmetic\ theory Misc_Arithmetic - imports "HOL-Library.Bit" Bit_Representation + imports Misc_Auxiliary "HOL-Library.Bit" begin lemma one_mod_exp_eq_one [simp]: @@ -168,7 +168,9 @@ for n :: int by arith -lemmas eme1p = emep1 [simplified add.commute] +lemma eme1p: + "even n \ even d \ 0 \ d \ (1 + n) mod d = 1 + n mod d" for n d :: int + using emep1 [of n d] by (simp add: ac_simps) lemma le_diff_eq': "a \ c - b \ b + a \ c" for a b c :: int diff -r 6d2effbbf8d4 -r ff9efdc84289 src/HOL/Word/Misc_Auxiliary.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/HOL/Word/Misc_Auxiliary.thy Mon Apr 22 06:28:17 2019 +0000 @@ -0,0 +1,194 @@ +(* Title: HOL/Word/Misc_Auxiliary.thy + Author: Jeremy Dawson, NICTA +*) + +section \Generic auxiliary\ + +theory Misc_Auxiliary + imports Main +begin + +subsection \Arithmetic lemmas\ + +lemma int_mod_lem: "0 < n \ 0 \ b \ b < n \ b mod n = b" + for b n :: int + apply safe + apply (erule (1) mod_pos_pos_trivial) + apply (erule_tac [!] subst) + apply auto + done + +lemma int_mod_ge: "a < n \ 0 < n \ a \ a mod n" + for a n :: int + by (metis dual_order.trans le_cases mod_pos_pos_trivial pos_mod_conj) + +lemma int_mod_ge': "b < 0 \ 0 < n \ b + n \ b mod n" + for b n :: int + by (metis add_less_same_cancel2 int_mod_ge mod_add_self2) + +lemma int_mod_le': "0 \ b - n \ b mod n \ b - n" + for b n :: int + by (metis minus_mod_self2 zmod_le_nonneg_dividend) + +lemma emep1: "even n \ even d \ 0 \ d \ (n + 1) mod d = (n mod d) + 1" + for n d :: int + by (auto simp add: pos_zmod_mult_2 add.commute dvd_def) + +lemma m1mod2k: "- 1 mod 2 ^ n = (2 ^ n - 1 :: int)" + by (rule zmod_minus1) simp + +lemma sub_inc_One: "Num.sub (Num.inc n) num.One = numeral n" + by (metis add_diff_cancel add_neg_numeral_special(3) add_uminus_conv_diff numeral_inc) + +lemma inc_BitM: "Num.inc (Num.BitM n) = num.Bit0 n" + by (simp add: BitM_plus_one[symmetric] add_One) + + +subsection \Lemmas on list operations\ + +lemma butlast_power: "(butlast ^^ n) bl = take (length bl - n) bl" + by (induct n) (auto simp: butlast_take) + +lemma nth_rev: "n < length xs \ rev xs ! n = xs ! (length xs - 1 - n)" + using rev_nth by simp + +lemma nth_rev_alt: "n < length ys \ ys ! n = rev ys ! (length ys - Suc n)" + by (simp add: nth_rev) + +lemma hd_butlast: "length xs > 1 \ hd (butlast xs) = hd xs" + by (cases xs) auto + + +subsection \Implicit augmentation of list prefixes\ + +primrec takefill :: "'a \ nat \ 'a list \ 'a list" +where + Z: "takefill fill 0 xs = []" + | Suc: "takefill fill (Suc n) xs = + (case xs of + [] \ fill # takefill fill n xs + | y # ys \ y # takefill fill n ys)" + +lemma nth_takefill: "m < n \ takefill fill n l ! m = (if m < length l then l ! m else fill)" + apply (induct n arbitrary: m l) + apply clarsimp + apply clarsimp + apply (case_tac m) + apply (simp split: list.split) + apply (simp split: list.split) + done + +lemma takefill_alt: "takefill fill n l = take n l @ replicate (n - length l) fill" + by (induct n arbitrary: l) (auto split: list.split) + +lemma takefill_replicate [simp]: "takefill fill n (replicate m fill) = replicate n fill" + by (simp add: takefill_alt replicate_add [symmetric]) + +lemma takefill_le': "n = m + k \ takefill x m (takefill x n l) = takefill x m l" + by (induct m arbitrary: l n) (auto split: list.split) + +lemma length_takefill [simp]: "length (takefill fill n l) = n" + by (simp add: takefill_alt) + +lemma take_takefill': "n = k + m \ take k (takefill fill n w) = takefill fill k w" + by (induct k arbitrary: w n) (auto split: list.split) + +lemma drop_takefill: "drop k (takefill fill (m + k) w) = takefill fill m (drop k w)" + by (induct k arbitrary: w) (auto split: list.split) + +lemma takefill_le [simp]: "m \ n \ takefill x m (takefill x n l) = takefill x m l" + by (auto simp: le_iff_add takefill_le') + +lemma take_takefill [simp]: "m \ n \ take m (takefill fill n w) = takefill fill m w" + by (auto simp: le_iff_add take_takefill') + +lemma takefill_append: "takefill fill (m + length xs) (xs @ w) = xs @ (takefill fill m w)" + by (induct xs) auto + +lemma takefill_same': "l = length xs \ takefill fill l xs = xs" + by (induct xs arbitrary: l) auto + +lemmas takefill_same [simp] = takefill_same' [OF refl] + +lemma tf_rev: + "n + k = m + length bl \ takefill x m (rev (takefill y n bl)) = + rev (takefill y m (rev (takefill x k (rev bl))))" + apply (rule nth_equalityI) + apply (auto simp add: nth_takefill nth_rev) + apply (rule_tac f = "\n. bl ! n" in arg_cong) + apply arith + done + +lemma takefill_minus: "0 < n \ takefill fill (Suc (n - 1)) w = takefill fill n w" + by auto + +lemmas takefill_Suc_cases = + list.cases [THEN takefill.Suc [THEN trans]] + +lemmas takefill_Suc_Nil = takefill_Suc_cases (1) +lemmas takefill_Suc_Cons = takefill_Suc_cases (2) + +lemmas takefill_minus_simps = takefill_Suc_cases [THEN [2] + takefill_minus [symmetric, THEN trans]] + +lemma takefill_numeral_Nil [simp]: + "takefill fill (numeral k) [] = fill # takefill fill (pred_numeral k) []" + by (simp add: numeral_eq_Suc) + +lemma takefill_numeral_Cons [simp]: + "takefill fill (numeral k) (x # xs) = x # takefill fill (pred_numeral k) xs" + by (simp add: numeral_eq_Suc) + + +subsection \Simultaneous map\ + +definition map2 :: "('a \ 'b \ 'c) \ 'a list \ 'b list \ 'c list" + where "map2 f as bs = map (case_prod f) (zip as bs)" + +lemma map2_Nil [simp, code]: "map2 f [] ys = []" + by (auto simp: map2_def) + +lemma map2_Nil2 [simp, code]: "map2 f xs [] = []" + by (auto simp: map2_def) + +lemma map2_Cons [simp, code]: "map2 f (x # xs) (y # ys) = f x y # map2 f xs ys" + by (auto simp: map2_def) + + +subsection \Auxiliary: Range projection\ + +definition bl_of_nth :: "nat \ (nat \ 'a) \ 'a list" + where "bl_of_nth n f = map f (rev [0.. rev (bl_of_nth n f) ! m = f m" + by (simp add: bl_of_nth_def rev_map) + +lemma bl_of_nth_inj: "(\k. k < n \ f k = g k) \ bl_of_nth n f = bl_of_nth n g" + by (simp add: bl_of_nth_def) + +lemma bl_of_nth_nth_le: "n \ length xs \ bl_of_nth n (nth (rev xs)) = drop (length xs - n) xs" + apply (induct n arbitrary: xs) + apply clarsimp + apply clarsimp + apply (rule trans [OF _ hd_Cons_tl]) + apply (frule Suc_le_lessD) + apply (simp add: nth_rev trans [OF drop_Suc drop_tl, symmetric]) + apply (subst hd_drop_conv_nth) + apply force + apply simp_all + apply (rule_tac f = "\n. drop n xs" in arg_cong) + apply simp + done + +lemma bl_of_nth_nth [simp]: "bl_of_nth (length xs) ((!) (rev xs)) = xs" + by (simp add: bl_of_nth_nth_le) + +end diff -r 6d2effbbf8d4 -r ff9efdc84289 src/HOL/Word/Word.thy --- a/src/HOL/Word/Word.thy Sat Apr 20 18:02:22 2019 +0000 +++ b/src/HOL/Word/Word.thy Mon Apr 22 06:28:17 2019 +0000 @@ -8,8 +8,8 @@ imports "HOL-Library.Type_Length" "HOL-Library.Boolean_Algebra" + Bits_Int Bits_Bit - Bits_Int Misc_Typedef Misc_Arithmetic begin @@ -2084,6 +2084,9 @@ subsection \Bitwise Operations on Words\ +lemma word_eq_rbl_eq: "x = y \ rev (to_bl x) = rev (to_bl y)" + by simp + lemmas bin_log_bintrs = bin_trunc_not bin_trunc_xor bin_trunc_and bin_trunc_or \ \following definitions require both arithmetic and bit-wise word operations\ @@ -2590,6 +2593,18 @@ "size x \ n \ set_bit x n b = x" for x :: "'a :: len0 word" by (auto intro: word_eqI simp add: test_bit_set_gen word_size) +lemma rbl_word_or: "rev (to_bl (x OR y)) = map2 (\) (rev (to_bl x)) (rev (to_bl y))" + by (simp add: map2_def zip_rev bl_word_or rev_map) + +lemma rbl_word_and: "rev (to_bl (x AND y)) = map2 (\) (rev (to_bl x)) (rev (to_bl y))" + by (simp add: map2_def zip_rev bl_word_and rev_map) + +lemma rbl_word_xor: "rev (to_bl (x XOR y)) = map2 (\) (rev (to_bl x)) (rev (to_bl y))" + by (simp add: map2_def zip_rev bl_word_xor rev_map) + +lemma rbl_word_not: "rev (to_bl (NOT x)) = map Not (rev (to_bl x))" + by (simp add: bl_word_not rev_map) + subsection \Shifting, Rotating, and Splitting Words\ diff -r 6d2effbbf8d4 -r ff9efdc84289 src/HOL/Word/Word_Bitwise.thy --- a/src/HOL/Word/Word_Bitwise.thy Sat Apr 20 18:02:22 2019 +0000 +++ b/src/HOL/Word/Word_Bitwise.thy Mon Apr 22 06:28:17 2019 +0000 @@ -36,21 +36,6 @@ bit lists. Equalities are generated and manipulated in the reverse order to \<^const>\to_bl\.\ -lemma word_eq_rbl_eq: "x = y \ rev (to_bl x) = rev (to_bl y)" - by simp - -lemma rbl_word_or: "rev (to_bl (x OR y)) = map2 (\) (rev (to_bl x)) (rev (to_bl y))" - by (simp add: map2_def zip_rev bl_word_or rev_map) - -lemma rbl_word_and: "rev (to_bl (x AND y)) = map2 (\) (rev (to_bl x)) (rev (to_bl y))" - by (simp add: map2_def zip_rev bl_word_and rev_map) - -lemma rbl_word_xor: "rev (to_bl (x XOR y)) = map2 (\) (rev (to_bl x)) (rev (to_bl y))" - by (simp add: map2_def zip_rev bl_word_xor rev_map) - -lemma rbl_word_not: "rev (to_bl (NOT x)) = map Not (rev (to_bl x))" - by (simp add: bl_word_not rev_map) - lemma bl_word_sub: "to_bl (x - y) = to_bl (x + (- y))" by simp