blob: 5d711d8c2d2b0d89ea4ca911f2c857c8ed395e28 [file]
(*
* Copyright 2016, NICTA
*
* This software may be distributed and modified according to the terms of
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
* See "LICENSE_GPLv2.txt" for details.
*
* @TAG(NICTA_GPL)
*)
theory L4vBucket
imports
"Word_Lib.Word_Lemmas"
"../../../../../cogent/isa/shallow/ShallowUtil"
begin
no_notation fun_app (infixr "$" 10)
(* Copied from HaskellLemmaBucket.thy *)
lemma is_aligned_alignUp[simp]:
"is_aligned (alignUp p n) n"
by (simp add: alignUp_def complement_def
is_aligned_mask mask_def
word_bw_assocs)
lemma alignUp_le[simp]:
"alignUp p n \<le> p + 2 ^ n - 1"
unfolding alignUp_def
by (rule word_and_le2)
lemma complement_mask:
"complement (2 ^ n - 1) = ~~ mask n"
unfolding complement_def mask_def
by simp
lemma alignUp_idem:
fixes a :: "'a::len word"
assumes al: "is_aligned a n"
and sz: "n < len_of TYPE('a)"
shows "alignUp a n = a"
using sz al unfolding alignUp_def
apply (simp add: complement_mask)
apply (subst x_power_minus_1)
apply (subst neg_mask_is_div)
apply (simp only: word_arith_nat_div unat_word_ariths)
apply (simp only: unat_power_lower)
apply (subst power_mod_div)
apply (erule is_alignedE)
apply simp
apply (subst unat_mult_power_lem)
apply simp
apply (subst unat_sub)
apply (subst unat_arith_simps)
apply (simp add: word_size)
apply (simp add: word_size del: unat_1)
apply simp
done
lemma alignUp_not_aligned_eq:
fixes a :: "'a :: len word"
assumes al: "\<not> is_aligned a n"
and sz: "n < len_of TYPE('a)"
shows "alignUp a n = (a div 2 ^ n + 1) * 2 ^ n"
using assms
by (metis alignUp_not_aligned_eq)
lemma alignUp_ge:
fixes a :: "'a :: len word"
assumes sz: "n < len_of TYPE('a)"
and nowrap: "alignUp a n \<noteq> 0"
shows "a \<le> alignUp a n"
proof (cases "is_aligned a n")
case True
thus ?thesis using sz
by (subst alignUp_idem, simp_all)
next
case False
have lt0: "unat a div 2 ^ n < 2 ^ (len_of TYPE('a) - n)" using sz
apply -
apply (subst td_gal_lt [symmetric])
apply simp
apply (simp add: power_add [symmetric])
done
have"2 ^ n * (unat a div 2 ^ n + 1) \<le> 2 ^ len_of TYPE('a)" using sz
apply -
apply (rule nat_le_power_trans)
apply simp
apply (rule Suc_leI [OF lt0])
apply simp
done
moreover have "2 ^ n * (unat a div 2 ^ n + 1) \<noteq> 2 ^ len_of TYPE('a)" using nowrap sz
apply -
apply (erule contrapos_nn)
apply (subst alignUp_not_aligned_eq [OF False sz])
apply (subst unat_arith_simps)
apply (subst unat_word_ariths)
apply (subst unat_word_ariths)
apply simp
apply (subst mult_mod_left)
apply (simp add: unat_div field_simps power_add[symmetric] mod_mod_power
min.absorb2 unat_power_lower)
done
ultimately have lt: "2 ^ n * (unat a div 2 ^ n + 1) < 2 ^ len_of TYPE('a)" by simp
have "a = a div 2 ^ n * 2 ^ n + a mod 2 ^ n" by (rule word_mod_div_equality [symmetric])
also have "\<dots> < (a div 2 ^ n + 1) * 2 ^ n" using sz lt
apply (simp add: field_simps)
apply (rule word_add_less_mono1)
apply (rule word_mod_less_divisor)
apply (simp add: word_less_nat_alt unat_power_lower)
apply (subst unat_word_ariths)
apply (simp add: unat_div unat_power_lower)
done
also have "\<dots> = alignUp a n"
by (rule alignUp_not_aligned_eq [symmetric]) fact+
finally show ?thesis by (rule order_less_imp_le)
qed
lemma alignUp_le_greater_al:
fixes x :: "'a :: len word"
assumes le: "a \<le> x"
and sz: "n < len_of TYPE('a)"
and al: "is_aligned x n"
shows "alignUp a n \<le> x"
proof (cases "is_aligned a n")
case True
thus ?thesis using sz le by (simp add: alignUp_idem)
next
case False
hence anz: "a mod 2 ^ n \<noteq> 0"
by (rule not_aligned_mod_nz)
from al obtain k where xk: "x = 2 ^ n * of_nat k" and kv: "k < 2 ^ (len_of TYPE('a) - n)"
by (auto elim!: is_alignedE)
hence kn: "unat (of_nat k :: 'a word) * unat ((2::'a word) ^ n) < 2 ^ len_of TYPE('a)"
using sz
apply (subst unat_of_nat_eq)
apply (erule order_less_le_trans)
apply simp
apply (subst mult.commute)
apply (simp add: unat_power_lower)
apply (rule nat_less_power_trans)
apply simp
apply simp
done
have au: "alignUp a n = (a div 2 ^ n + 1) * 2 ^ n"
by (rule alignUp_not_aligned_eq) fact+
also have "\<dots> \<le> of_nat k * 2 ^ n"
proof (rule word_mult_le_mono1 [OF inc_le _ kn])
show "a div 2 ^ n < of_nat k" using kv xk le sz anz
by (simp add: alignUp_div_helper)
show "(0:: 'a word) < 2 ^ n" using sz by (simp add: p2_gt_0 sz)
qed
finally show ?thesis using xk by (simp add: field_simps)
qed
lemma alignUp_is_aligned_nz:
fixes a :: "'a :: len word"
assumes al: "is_aligned x n"
and sz: "n < len_of TYPE('a)"
and ax: "a \<le> x"
and az: "a \<noteq> 0"
shows "alignUp (a::'a :: len word) n \<noteq> 0"
proof (cases "is_aligned a n")
case True
hence "alignUp a n = a" using sz by (simp add: alignUp_idem)
thus ?thesis using az by simp
next
case False
hence anz: "a mod 2 ^ n \<noteq> 0"
by (rule not_aligned_mod_nz)
{
assume asm: "alignUp a n = 0"
have lt0: "unat a div 2 ^ n < 2 ^ (len_of TYPE('a) - n)" using sz
apply -
apply (subst td_gal_lt [symmetric])
apply simp
apply (simp add: power_add [symmetric])
done
have leq: "2 ^ n * (unat a div 2 ^ n + 1) \<le> 2 ^ len_of TYPE('a)" using sz
apply -
apply (rule nat_le_power_trans)
apply simp
apply (rule Suc_leI [OF lt0])
apply simp
done
from al obtain k where kv: "k < 2 ^ (len_of TYPE('a) - n)" and xk: "x = 2 ^ n * of_nat k"
by (auto elim!: is_alignedE)
hence "a div 2 ^ n < of_nat k" using ax sz anz
by (rule alignUp_div_helper)
hence r: "unat a div 2 ^ n < k" using sz
apply (simp add: unat_div word_less_nat_alt)
apply (subst (asm) unat_of_nat)
apply (subst (asm) mod_less)
apply (rule order_less_le_trans [OF kv])
apply (simp add: unat_power_lower)+
done
have "alignUp a n = (a div 2 ^ n + 1) * 2 ^ n"
by (rule alignUp_not_aligned_eq) fact+
hence "\<dots> = 0" using asm by simp
hence "unat a div 2 ^ n = 2 ^ (len_of TYPE('a) - n) - 1" using sz leq
apply -
apply (rule nat_diff_add)
apply simp
apply (subst nat_mult_eq_cancel1 [where k = "2 ^ n", symmetric])
apply simp
apply (subst power_add [symmetric])
apply simp
apply (drule unat_cong)
apply simp
apply (subst (asm) unat_word_ariths)
apply (subst (asm) unat_word_ariths)
apply (simp add: unat_div mult_mod_left power_add [symmetric] mod_mod_power
min.absorb2)
apply (clarsimp simp: field_simps)
apply (rule ccontr)
apply (drule (1) order_le_neq_trans)
apply (force simp add: unat_power_lower)
done
hence "2 ^ (len_of TYPE('a) - n) - 1 < k" using r
by simp
hence False using kv by simp
} thus ?thesis by (clarsimp simp del: word_neq_0_conv)
qed
lemma alignUp_ar_helper:
fixes a :: "'a :: len word"
assumes al: "is_aligned x n"
and sz: "n < len_of TYPE('a)"
and sub: "{x..x + 2 ^ n - 1} \<subseteq> {a..b}"
and anz: "a \<noteq> 0"
shows "a \<le> alignUp a n \<and> alignUp a n + 2 ^ n - 1 \<le> b"
proof
from al have xl: "x \<le> x + 2 ^ n - 1" by (simp add: is_aligned_no_overflow)
from xl sub have ax: "a \<le> x"
by (clarsimp elim!: range_subset_lower [where x = x])
show "a \<le> alignUp a n"
proof (rule alignUp_ge)
show "alignUp a n \<noteq> 0" using al sz ax anz
by (rule alignUp_is_aligned_nz)
qed fact+
show "alignUp a n + 2 ^ n - 1 \<le> b"
proof (rule order_trans)
from xl show tp: "x + 2 ^ n - 1 \<le> b" using sub
by (clarsimp elim!: range_subset_upper [where x = x])
from ax have "alignUp a n \<le> x"
by (rule alignUp_le_greater_al) fact+
hence "alignUp a n + (2 ^ n - 1) \<le> x + (2 ^ n - 1)" using xl
apply -
apply (erule word_plus_mono_left)
apply (subst olen_add_eqv)
apply (simp add: field_simps)
done
thus "alignUp a n + 2 ^ n - 1 \<le> x + 2 ^ n - 1"
by (simp add: field_simps)
qed
qed
end