theory Uint imports
Uint_Common
Code_Target_Word begin
text‹
This theory provides access to words in the target languages of the code generator
whose bit width is the default of the target language. To that end, the type ‹uint›
models words of width ‹dflt_size›, but ‹dflt_size› is known only to be positive.
Usage restrictions:
Default-size words (type ‹uint›) cannot be used for evaluation, because
the results depend on the particular choice of word size in the target language
and implementation. Symbolic evaluation has not yet been set up for ‹uint›. ›
text‹The default size type› typedecl dflt_size
instantiation dflt_size :: typerep begin definition"typerep_class.typerep ≡ λ_ :: dflt_size itself. Typerep.Typerep (STR ''Uint.dflt_size'') []" instance .. end
consts dflt_size_aux :: "nat" specification (dflt_size_aux) dflt_size_aux_g0: "dflt_size_aux > 0" by auto
hide_fact dflt_size_aux_def
instantiation dflt_size :: len begin definition"len_of_dflt_size (_ :: dflt_size itself) ≡ dflt_size_aux" instanceby(intro_classes)(simp add: len_of_dflt_size_def dflt_size_aux_g0) end
contextincludes integer.lifting begin
lift_definition dflt_size_integer :: integer is"int dflt_size" . declare dflt_size_integer_def[code del] ―‹The code generator will substitute a machine-dependent value for this constant›
lemma dflt_size_by_int[code]: "dflt_size = nat_of_integer dflt_size_integer" by transfer simp
lemma dflt_size[simp]: "dflt_size > 0" "dflt_size ≥ Suc 0" "¬ dflt_size < Suc 0" using len_gt_0[where 'a=dflt_size] by (simp_all del: len_gt_0) end
section‹Type definition and primitive operations›
typedef uint = ‹UNIV :: dflt_size word set› ..
global_interpretation uint: word_type_copy Abs_uint Rep_uint using type_definition_uint by (rule word_type_copy.intro)
setup_lifting type_definition_uint
declare uint.of_word_of [code abstype]
declare Quotient_uint [transfer_rule]
instantiation uint :: ‹{comm_ring_1, semiring_modulo, equal, linorder, order_bot, order_top}› begin
uint: word_type_copy_ring Abs_uint Rep_uint
by standard (fact zero_uint.rep_eq one_uint.rep_eq
plus_uint.rep_eq uminus_uint.rep_eq minus_uint.rep_eq
times_uint.rep_eq divide_uint.rep_eq modulo_uint.rep_eq
equal_uint.rep_eq less_eq_uint.rep_eq less_uint.rep_eq
bot_uint.rep_eq top_uint.rep_eq)+
proof -
show ‹OFCLASS(uint, comm_ring_1_class)›
by (rule uint.of_class_comm_ring_1)
show ‹OFCLASS(uint, semiring_modulo_class)›
by (fact uint.of_class_semiring_modulo)
show ‹OFCLASS(uint, equal_class)›
by (fact uint.of_class_equal)
show ‹OFCLASS(uint, linorder_class)›
by (fact uint.of_class_linorder)
show ‹OFCLASS(uint, order_bot_class)›
by (fact uint.of_class_order_bot)
show ‹OFCLASS(uint, order_top_class)›
by (fact uint.of_class_order_top)
uint :: ‹{interval_bot, interval_top}›
by (fact uint.of_class_interval_bot uint.of_class_interval_top)+
uint :: ring_bit_operations
bit_uint :: ‹uint ==> nat ==> bool› is bit .
not_uint :: ‹uint ==> uint› is ‹Bit_Operations.not› .
and_uint :: ‹uint ==> uint ==> uint› is ‹Bit_Operations.and› .
or_uint :: ‹uint ==> uint ==> uint› is ‹Bit_Operations.or› .
xor_uint :: ‹uint ==> uint ==> uint› is ‹Bit_Operations.xor› .
mask_uint :: ‹nat ==> uint› is mask .
push_bit_uint :: ‹nat ==> uint ==> uint› is push_bit .
drop_bit_uint :: ‹nat ==> uint ==> uint› is drop_bit .
signed_drop_bit_uint :: ‹nat ==> uint ==> uint› is signed_drop_bit .
take_bit_uint :: ‹nat ==> uint ==> uint› is take_bit .
set_bit_uint :: ‹nat ==> uint ==> uint› is Bit_Operations.set_bit .
unset_bit_uint :: ‹nat ==> uint ==> uint› is unset_bit .
flip_bit_uint :: ‹nat ==> uint ==> uint› is flip_bit .
definition wivs_overflow :: int where"wivs_overflow == 2^ (dflt_size - 1)"
lift_definition wivs_overflow_integer :: integer is wivs_overflow . lemma [code]: "wivs_overflow_integer = 2 ^ (dflt_size - 1)" by transfer (simp add: wivs_overflow_def)
definition wivs_least :: int where"wivs_least == - wivs_overflow"
lift_definition wivs_least_integer :: integer is wivs_least . lemma [code]: "wivs_least_integer = - (2 ^ (dflt_size - 1))" by transfer (simp add: wivs_overflow_def wivs_least_def)
definition Uint_signed :: "integer ==> uint"where "Uint_signed i = (if i < wivs_least_integer ∨ wivs_overflow_integer ≤ i then undefined Uint i else Uint i)"
lemma Uint_code [code]: "Uint i = (let i' = i AND wivs_mask_integer in if bit i' wivs_index then Uint_signed (i' - wivs_shift_integer) else Uint_signed i')"
including undefined_transfer unfolding Uint_signed_def apply transfer apply (subst word_of_int_via_signed) apply (auto simp add: mask_eq_exp_minus_1 word_of_int_via_signed
wivs_mask_def wivs_index_def wivs_overflow_def wivs_least_def wivs_shift_def Let_def) done
lemma Uint_signed_code [code]: "Rep_uint (Uint_signed i) = (if i < wivs_least_integer ∨ i ≥ wivs_overflow_integer then Rep_uint (undefined Uint i) else word_of_int (int_of_integer i))" unfolding Uint_signed_def Uint_def by (simp add: Abs_uint_inverse) end
text‹
Avoid @{term Abs_uint} in generated code, use @{term Rep_uint'} instead.
The symbolic implementations for code\_simp use @{term Rep_uint}.
The new destructor @{term Rep_uint'} is executable.
As the simplifier is given the [code abstract] equations literally,
we cannot implement @{term Rep_uint} directly, because that makes code\_simp loop.
If code generation raises Match, some equation probably contains @{term Rep_uint}
([code abstract] equations for @{typ uint} may use @{term Rep_uint} because
these instances will be folded away.) ›
definition Rep_uint' where [simp]: "Rep_uint' = Rep_uint"
lemma Rep_uint'_code [code]: "Rep_uint' x = (BITS n. bit x n)" unfolding Rep_uint'_defby transfer (simp add: set_bits_bit_eq)
lift_definition Abs_uint' :: "dflt_size word ==> uint"is"λx :: dflt_size word. x" .
lemma Abs_uint'_code [code]: "Abs_uint' x = Uint (integer_of_int (uint x))"
including integer.lifting by transfer simp
definition uint_divmod :: "uint ==> uint ==> uint × uint"where "uint_divmod x y = (if y = 0 then (undefined ((div) :: uint ==> _) x (0 :: uint), undefined ((mod) :: uint ==> _) x (0 :: uint)) else (x div y, x mod y))"
definition uint_div :: "uint ==> uint ==> uint" where"uint_div x y = fst (uint_divmod x y)"
definition uint_mod :: "uint ==> uint ==> uint" where"uint_mod x y = snd (uint_divmod x y)"
lemma div_uint_code [code]: "x div y = (if y = 0 then 0 else uint_div x y)"
including undefined_transfer unfolding uint_divmod_def uint_div_def by transfer(simp add: word_div_def)
lemma mod_uint_code [code]: "x mod y = (if y = 0 then x else uint_mod x y)"
including undefined_transfer unfolding uint_mod_def uint_divmod_def by transfer(simp add: word_mod_def)
definition uint_sdiv :: "uint ==> uint ==> uint" where [code del]: "uint_sdiv x y = (if y = 0 then undefined ((div) :: uint ==> _) x (0 :: uint) else Abs_uint (Rep_uint x sdiv Rep_uint y))"
definition div0_uint :: "uint ==> uint" where [code del]: "div0_uint x = undefined ((div) :: uint ==> _) x (0 :: uint)" declare [[code abort: div0_uint]]
definition mod0_uint :: "uint ==> uint" where [code del]: "mod0_uint x = undefined ((mod) :: uint ==> _) x (0 :: uint)" declare [[code abort: mod0_uint]]
lemma uint_divmod_code [code]: "uint_divmod x y = (if wivs_overflow_uint ≤ y then if x < y then (0, x) else (1, x - y) else if y = 0 then (div0_uint x, mod0_uint x) else let q = push_bit 1 (uint_sdiv (drop_bit 1 x) y); r = x - q * y in if r ≥ y then (q + 1, r - y) else (q, r))" proof (cases ‹y = 0›) case True moreoverhave‹x ≥ 0› by transfer simp moreovernote wivs_overflow_uint_greater_eq_0 ultimatelyshow ?thesis by (auto simp add: uint_divmod_def div0_uint_def mod0_uint_def not_less) next case False thenshow ?thesis
including undefined_transfer unfolding uint_divmod_def uint_sdiv_def div0_uint_def mod0_uint_def
wivs_overflow_uint_def apply transfer apply (simp add: divmod_via_sdivmod push_bit_of_1) done qed
lemma uint_sdiv_code [code]: "Rep_uint (uint_sdiv x y) = (if y = 0 then Rep_uint (undefined ((div) :: uint ==> _) x (0 :: uint)) else Rep_uint x sdiv Rep_uint y)" unfolding uint_sdiv_def by(simp add: Abs_uint_inverse)
text‹
Note that we only need a translation for signed division, but not for the remainder
because @{thm uint_divmod_code} computes both with division only. ›
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.