theory Bitwise imports "HOL-Library.Word"
More_Arithmetic
Reversed_Bit_Lists
Bit_Shifts_Infix_Syntax
begin
text‹Helper constants used in defining addition›
definition xor3 :: "bool ==> bool ==> bool ==> bool" where"xor3 a b c = (a = (b = c))"
definition carry :: "bool ==> bool ==> bool ==> bool" where"carry a b c = ((a ∧ (b ∨ c)) ∨ (b ∧ c))"
lemma carry_simps: "carry True a b = (a ∨ b)" "carry a True b = (a ∨ b)" "carry a b True = (a ∨ b)" "carry False a b = (a ∧ b)" "carry a False b = (a ∧ b)" "carry a b False = (a ∧ b)" by (auto simp add: carry_def)
lemma xor3_simps: "xor3 True a b = (a = b)" "xor3 a True b = (a = b)" "xor3 a b True = (a = b)" "xor3 False a b = (a ≠ b)" "xor3 a False b = (a ≠ b)" "xor3 a b False = (a ≠ b)" by (simp_all add: xor3_def)
text‹Breaking up word equalities into equalities on their
bit lists. Equalities are generated and manipulated in the
reverse order to const‹to_bl›.›
lemma rbl_word_if: "rev (to_bl (if P then x else y)) = map2 (If P) (rev (to_bl x)) (rev (to_bl y))" by (simp add: split_def)
lemma rbl_add_carry_Cons: "(if car then rbl_succ else id) (rbl_add (x # xs) (y # ys)) = xor3 x y car # (if carry x y car then rbl_succ else id) (rbl_add xs ys)" by (simp add: carry_def xor3_def)
lemma rbl_add_suc_carry_fold: "length xs = length ys ==> ∀car. (if car then rbl_succ else id) (rbl_add xs ys) = (foldr (λ(x, y) res car. xor3 x y car # res (carry x y car)) (zip xs ys) (λ_. [])) car" proof (induction rule: list_induct2) case Nil thenshow ?caseby simp next case (Cons x xs y ys) thenshow ?case using rbl_add_carry_Cons by auto qed
lemma to_bl_plus_carry: "to_bl (x + y) = rev (foldr (λ(x, y) res car. xor3 x y car # res (carry x y car)) (rev (zip (to_bl x) (to_bl y))) (λ_. []) False)" using rbl_add_suc_carry_fold[where xs="rev (to_bl x)"and ys="rev (to_bl y)"] by (smt (verit) id_apply length_rev word_add_rbl word_rotate.lbl_lbl zip_rev)
definition"rbl_plus cin xs ys = foldr (λ(x, y) res car. xor3 x y car # res (carry x y car)) (zip xs ys) (λ_. []) cin"
lemma rbl_plus_simps: "rbl_plus cin (x # xs) (y # ys) = xor3 x y cin # rbl_plus (carry x y cin) xs ys" "rbl_plus cin [] ys = []" "rbl_plus cin xs [] = []" by (simp_all add: rbl_plus_def)
definition"rbl_succ2 b xs = (if b then rbl_succ xs else xs)"
lemma rbl_succ2_simps: "rbl_succ2 b [] = []" "rbl_succ2 b (x # xs) = (b ≠ x) # rbl_succ2 (x ∧ b) xs" by (simp_all add: rbl_succ2_def)
lemma twos_complement: "- x = word_succ (not x)" using arg_cong[OF word_add_not[where x=x], where f="λa. a - x + 1"] by (simp add: word_succ_p1 word_sp_01[unfolded word_succ_p1] del: word_add_not)
lemma rbl_word_neg: "rev (to_bl (- x)) = rbl_succ2 True (map Not (rev (to_bl x)))" for x :: ‹'a::len word› by (simp add: twos_complement word_succ_rbl[OF refl] bl_word_not rev_map rbl_succ2_def)
lemma rbl_word_cat: "rev (to_bl (word_cat x y :: 'a::len word)) = takefill False (LENGTH('a)) (rev (to_bl y) @ rev (to_bl x))" by (simp add: word_cat_bl word_rev_tf)
lemma rbl_word_slice: "rev (to_bl (slice n w :: 'a::len word)) = takefill False (LENGTH('a)) (drop n (rev (to_bl w)))" by (simp add: drop_rev slice_take word_rev_tf)
lemma rbl_shiftl: "rev (to_bl (w << n)) = takefill False (size w) (replicate n False @ rev (to_bl w))" by (simp add: bl_shiftl takefill_alt word_size rev_drop)
lemma rbl_shiftr: "rev (to_bl (w >> n)) = takefill False (size w) (drop n (rev (to_bl w)))" by (simp add: shiftr_slice rbl_word_slice word_size)
definition"drop_nonempty v n xs = (if n < length xs then drop n xs else [last (v # xs)])"
lemma drop_nonempty_simps: "drop_nonempty v (Suc n) (x # xs) = drop_nonempty x n xs" "drop_nonempty v 0 (x # xs) = (x # xs)" "drop_nonempty v n [] = [v]" by (simp_all add: drop_nonempty_def)
definition"takefill_last x n xs = takefill (last (x # xs)) n xs"
lemma takefill_last_simps: "takefill_last z (Suc n) (x # xs) = x # takefill_last x n xs" "takefill_last z 0 xs = []" "takefill_last z n [] = replicate n z" by (simp_all add: takefill_last_def) (simp_all add: takefill_alt)
lemma rbl_sshiftr: "rev (to_bl (w >>> n)) = takefill_last False (size w) (drop_nonempty False n (rev (to_bl w)))" proof (cases "n < size w") case True thenshow ?thesis by (simp add: bl_sshiftr takefill_last_def word_size takefill_alt
rev_take last_rev drop_nonempty_def) next case False thenhave🍋: "(w >>> n) = of_bl (replicate (size w) (msb w))" by (intro word_eqI) (simp add: bit_simps word_size msb_nth) with False show ?thesis apply (simp add: word_size takefill_last_def takefill_alt
last_rev word_msb_alt word_rev_tf drop_nonempty_def take_Cons') by (metis Suc_pred len_gt_0 replicate_Suc) qed
lemma nth_word_of_int: "bit (word_of_int x :: 'a::len word) n = (n < LENGTH('a) ∧ bit x n)" by (simp add: bit_word_of_int_iff)
lemma nth_scast: "bit (scast (x :: 'a::len word) :: 'b::len word) n = (n < LENGTH('b) ∧ (if n < LENGTH('a) - 1 then bit x n else bit x (LENGTH('a) - 1)))" by (simp add: bit_signed_iff)
lemma takefill_le2: "length xs ≤ n ==> takefill x m (takefill x n xs) = takefill x m xs" by (simp add: takefill_alt replicate_add[symmetric])
lemma take_rbl_plus: "∀n b. take n (rbl_plus b xs ys) = rbl_plus b (take n xs) (take n ys)" unfolding rbl_plus_def take_zip[symmetric] by (rule list.induct) (auto simp: take_Cons' split_def)
lemma word_rbl_mul_induct: "length xs ≤ size y ==> rbl_mul xs (rev (to_bl y)) = take (length xs) (rev (to_bl (of_bl (rev xs) * y)))" for y :: "'a::len word" proof (induct xs) case Nil show ?caseby (simp add: rbl_mul_simps) next case (Cons z zs)
have rbl_word_plus': "to_bl (x + y) = rev (rbl_plus False (rev (to_bl x)) (rev (to_bl y)))" for x y :: "'a word" by (simp add: rbl_word_plus[symmetric])
have shiftl: "of_bl xs * 2 * y = (of_bl xs * y) << 1"for xs by (simp add: push_bit_eq_mult shiftl_def)
have zip_take_triv: "∧xs ys n. n = length ys ==> zip (take n xs) ys = zip xs ys" by (rule nth_equalityI) simp_all
from Cons have"rbl_plus False (map ((∧) z) (rev (to_bl y))) (False # take (length zs) (rev (to_bl (of_bl (rev zs) * y)))) = rbl_plus False (take (Suc (length zs)) (map ((∧) z) (rev (to_bl y)))) (take (Suc (length zs)) (rev (to_bl (of_bl (rev zs) * y * 2))))" unfolding word_size by (simp add: rbl_plus_def zip_take_triv mult.commute [of _ 2] to_bl_double_eq take_butlast
flip: butlast_rev) with Cons show ?case by (simp add: trans [OF of_bl_append add.commute]
rbl_mul_simps rbl_word_plus' distrib_right mult_bit shiftl rev_map take_rbl_plus) qed
lemma rbl_word_mul: "rev (to_bl (x * y)) = rbl_mul (rev (to_bl x)) (rev (to_bl y))" for x :: "'a::len word" using word_rbl_mul_induct[where xs="rev (to_bl x)"and y=y] by (simp add: word_size)
text‹Breaking up inequalities into bitlist properties.›
definition "rev_bl_order F xs ys = (length xs = length ys ∧ ((xs = ys ∧ F) ∨ (∃n < length xs. drop (Suc n) xs = drop (Suc n) ys ∧¬ xs ! n ∧ ys ! n)))"
lemma rev_bl_order_simps: "rev_bl_order F [] [] = F" "rev_bl_order F (x # xs) (y # ys) = rev_bl_order ((y ∧¬ x) ∨ ((y ∨¬ x) ∧ F)) xs ys" apply (simp_all add: rev_bl_order_def) using less_Suc_eq_0_disj by fastforce
lemma rev_bl_order_rev_simp: "length xs = length ys ==> rev_bl_order F (xs @ [x]) (ys @ [y]) = ((y ∧¬ x) ∨ ((y ∨¬ x) ∧ rev_bl_order F xs ys))" by (induct arbitrary: F rule: list_induct2) (auto simp: rev_bl_order_simps)
lemma rev_bl_order_bl_to_bin: "length xs = length ys ==> rev_bl_order True xs ys = (bl_to_bin (rev xs) ≤ bl_to_bin (rev ys)) ∧ rev_bl_order False xs ys = (bl_to_bin (rev xs) < bl_to_bin (rev ys))" proof (induct xs ys rule: list_induct2) case Nil thenshow ?case by (auto simp: rev_bl_order_simps(1)) next case (Cons x xs y ys) thenshow ?case apply (simp add: rev_bl_order_simps bl_to_bin_app_cat) apply (auto simp add: bl_to_bin_def add1_zle_eq concat_bit_Suc) done qed
lemma word_le_rbl: "x ≤ y ⟷ rev_bl_order True (rev (to_bl x)) (rev (to_bl y))" for x y :: "'a::len word" by (simp add: rev_bl_order_bl_to_bin word_le_def)
lemma word_less_rbl: "x < y ⟷ rev_bl_order False (rev (to_bl x)) (rev (to_bl y))" for x y :: "'a::len word" by (simp add: word_less_alt rev_bl_order_bl_to_bin)
definition"map_last f xs = (if xs = [] then [] else butlast xs @ [f (last xs)])"
lemma map_last_simps: "map_last f [] = []" "map_last f [x] = [f x]" "map_last f (x # y # zs) = x # map_last f (y # zs)" by (simp_all add: map_last_def)
lemma word_sle_rbl: "x <=s y ⟷ rev_bl_order True (map_last Not (rev (to_bl x))) (map_last Not (rev (to_bl y)))" proof - have"length (to_bl x) = length (to_bl y)" by auto with word_msb_alt[where w=x] word_msb_alt[where w=y] show ?thesis unfolding word_sle_msb_le word_le_rbl by (cases "to_bl x"; cases "to_bl y"; auto simp: map_last_def rev_bl_order_rev_simp) qed
lemma word_sless_rbl: "x <s y ⟷ rev_bl_order False (map_last Not (rev (to_bl x))) (map_last Not (rev (to_bl y)))" by (metis (no_types, lifting) rev_bl_order_def signed.less_le signed.not_less word_sle_rbl)
text‹Lemmas for unpacking term‹rev (to_bl n)› for numerals n and also
for irreducible values and expressions.›
fun nat_get_Suc_simproc_fn n_sucs ctxt ct = let
val (f, arg) = dest_comb (Thm.term_of ct);
val n =
(case arg of term‹nat› $ n => n | n => n)
|> HOLogic.dest_number |> snd;
val (i, j) = if n > n_sucs then (n_sucs, n - n_sucs) else (n, 0);
val arg' = funpow i HOLogic.mk_Suc (HOLogic.mk_number 🍋‹nat› j);
val _ = if arg = arg' then raise TERM ("", []) else (); fun propfn g =
HOLogic.mk_eq (g arg, g arg')
|> HOLogic.mk_Trueprop |> Thm.cterm_of ctxt;
val eq1 =
Goal.prove_internal ctxt [] (propfn I)
(K (simp_tac (put_simpset word_ss ctxt) 1)); in
Goal.prove_internal ctxt [] (propfn (curry (op $) f))
(K (simp_tac (put_simpset HOL_ss ctxt addsimps [eq1]) 1))
|> mk_meta_eq |> SOME end handle TERM _ => NONE;
fun nat_get_Suc_simproc n_sucs ts =
Simplifier.make_simproc 🍋
{name = "nat_get_Suc",
kind = Simproc,
lhss = map (fn t => t $ term‹n :: nat›) ts,
proc = K (nat_get_Suc_simproc_fn n_sucs), identifier = []};
fun tac ctxt = let
val (ss, sss) = expand_word_eq_sss; in
foldr1 (op THEN_ALL_NEW)
((CHANGED o safe_full_simp_tac (put_simpset ss ctxt)) ::
map (fn ss => safe_full_simp_tac (put_simpset ss ctxt)) sss) end;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.