uint32: word_type_copy_ring Abs_uint32 Rep_uint32
by standard (fact zero_uint32.rep_eq one_uint32.rep_eq
plus_uint32.rep_eq uminus_uint32.rep_eq minus_uint32.rep_eq
times_uint32.rep_eq divide_uint32.rep_eq modulo_uint32.rep_eq
equal_uint32.rep_eq less_eq_uint32.rep_eq less_uint32.rep_eq
bot_uint32.rep_eq top_uint32.rep_eq)+
proof -
show ‹OFCLASS(uint32, comm_ring_1_class)›
by (rule uint32.of_class_comm_ring_1)
show ‹OFCLASS(uint32, semiring_modulo_class)›
by (fact uint32.of_class_semiring_modulo)
show ‹OFCLASS(uint32, equal_class)›
by (fact uint32.of_class_equal)
show ‹OFCLASS(uint32, linorder_class)›
by (fact uint32.of_class_linorder)
show ‹OFCLASS(uint32, order_bot_class)›
by (fact uint32.of_class_order_bot)
show ‹OFCLASS(uint32, order_top_class)›
by (fact uint32.of_class_order_top)
uint32 :: ‹{interval_bot, interval_top}›
by (fact uint32.of_class_interval_bot uint32.of_class_interval_top)+
uint32 :: ring_bit_operations
bit_uint32 :: ‹uint32 ==> nat ==> bool› is bit .
not_uint32 :: ‹uint32 ==> uint32› is ‹Bit_Operations.not› .
and_uint32 :: ‹uint32 ==> uint32 ==> uint32› is ‹Bit_Operations.and› .
or_uint32 :: ‹uint32 ==> uint32 ==> uint32› is ‹Bit_Operations.or› .
xor_uint32 :: ‹uint32 ==> uint32 ==> uint32› is ‹Bit_Operations.xor› .
mask_uint32 :: ‹nat ==> uint32› is mask .
push_bit_uint32 :: ‹nat ==> uint32 ==> uint32› is push_bit .
drop_bit_uint32 :: ‹nat ==> uint32 ==> uint32› is drop_bit .
signed_drop_bit_uint32 :: ‹nat ==> uint32 ==> uint32› is signed_drop_bit .
take_bit_uint32 :: ‹nat ==> uint32 ==> uint32› is take_bit .
set_bit_uint32 :: ‹nat ==> uint32 ==> uint32› is Bit_Operations.set_bit .
unset_bit_uint32 :: ‹nat ==> uint32 ==> uint32› is unset_bit .
flip_bit_uint32 :: ‹nat ==> uint32 ==> uint32› is flip_bit .
using uint32.of_class_bit_comprehension
by simp_all standard
‹Code setup›
code_module Uint32 ⇀ (SML)
\<open>(* Test that words can handle numbers between 0 and 31 *)
val _ = if5 <= Word.wordSize then () else raise (Fail ("wordSize less than 5"));
structure Uint32 : sig
val shiftl : Word32.word -> IntInf.int -> Word32.word
val shiftr : Word32.word -> IntInf.int -> Word32.word
val shiftr_signed : Word32.word -> IntInf.int -> Word32.word
val test_bit : Word32.word -> IntInf.int -> bool end = struct
fun shiftl x n =
Word32.<< (x, Word.fromLargeInt (IntInf.toLarge n))
fun shiftr x n =
Word32.>> (x, Word.fromLargeInt (IntInf.toLarge n))
fun shiftr_signed x n =
Word32.~>> (x, Word.fromLargeInt (IntInf.toLarge n))
fun test_bit x n =
Word32.andb (x, Word32.<< (0wx1, Word.fromLargeInt (IntInf.toLarge n))) <> Word32.fromInt 0
text‹
OCaml and Scala provide only signed 32bit numbers, so we use these and
implement sign-sensitive operations like comparisons manually. ›
code_printing code_module"Uint32"⇀ (OCaml) ‹module Uint32 : sig
val less : int32 -> int32 -> bool
val less_eq : int32 -> int32 -> bool
val shiftl : int32 -> Z.t -> int32
val shiftr : int32 -> Z.t -> int32
val shiftr_signed : int32 -> Z.t -> int32
val test_bit : int32 -> Z.t -> bool
= struct
so they are greater than positive ones *) let less x y = if Int32.compare x Int32.zero < 0then
Int32.compare y Int32.zero < 0 && Int32.compare x y < 0
else Int32.compare y Int32.zero < 0 || Int32.compare x y < 0;;
let less_eq x y = if Int32.compare x Int32.zero < 0then
Int32.compare y Int32.zero < 0 && Int32.compare x y <= 0
else Int32.compare y Int32.zero < 0 || Int32.compare x y <= 0;;
let shiftl x n = Int32.shift_left x (Z.to_int n);;
let shiftr x n = Int32.shift_right_logical x (Z.to_int n);;
let shiftr_signed x n = Int32.shift_right x (Z.to_int n);;
let test_bit x n =
Int32.compare
(Int32.logand x (Int32.shift_left Int32.one (Z.to_int n)))
Int32.zero
<> 0;;
text‹
OCaml's conversion from Big\_int to int32 demands that the value fits int a signed 32-bit integer.
The following justifies the implementation. ›
context includes bit_operations_syntax begin
definition Uint32_signed :: "integer ==> uint32" where"Uint32_signed i = (if i < -(0x80000000) ∨ i ≥ 0x80000000 then undefined Uint32 i else Uint32 i)"
lemma Uint32_code [code]: "Uint32 i = (let i' = i AND 0xFFFFFFFF in if bit i' 31 then Uint32_signed (i' - 0x100000000) else Uint32_signed i')"
including undefined_transfer and integer.lifting unfolding Uint32_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 cong del: if_cong) done
lemma Uint32_signed_code [code]: "Rep_uint32 (Uint32_signed i) = (if i < -(0x80000000) ∨ i ≥ 0x80000000 then Rep_uint32 (undefined Uint32 i) else word_of_int (int_of_integer i))" unfolding Uint32_signed_def Uint32_def by (simp add: Abs_uint32_inverse)
end
text‹
Avoid @{term Abs_uint32} in generated code, use @{term Rep_uint32'} instead.
The symbolic implementations for code\_simp use @{term Rep_uint32}.
The new destructor @{term Rep_uint32'} is executable.
As the simplifier is given the [code abstract] equations literally,
we cannot implement @{term Rep_uint32} directly, because that makes code\_simp loop.
If code generation raises Match, some equation probably contains @{term Rep_uint32}
([code abstract] equations for @{typ uint32} may use @{term Rep_uint32} because
these instances will be folded away.)
To convert @{typ "32 word"} values into @{typ uint32}, use @{term "Abs_uint32'"}. ›
definition Rep_uint32' where [simp]: "Rep_uint32' = Rep_uint32"
definition uint32_divmod :: "uint32 ==> uint32 ==> uint32 × uint32"where "uint32_divmod x y = (if y = 0 then (undefined ((div) :: uint32 ==> _) x (0 :: uint32), undefined ((mod) :: uint32 ==> _) x (0 :: uint32)) else (x div y, x mod y))"
definition uint32_div :: "uint32 ==> uint32 ==> uint32" where"uint32_div x y = fst (uint32_divmod x y)"
definition uint32_mod :: "uint32 ==> uint32 ==> uint32" where"uint32_mod x y = snd (uint32_divmod x y)"
lemma div_uint32_code [code]: "x div y = (if y = 0 then 0 else uint32_div x y)"
including undefined_transfer unfolding uint32_divmod_def uint32_div_def by transfer (simp add: word_div_def)
lemma mod_uint32_code [code]: "x mod y = (if y = 0 then x else uint32_mod x y)"
including undefined_transfer unfolding uint32_mod_def uint32_divmod_def by transfer (simp add: word_mod_def)
definition uint32_sdiv :: "uint32 ==> uint32 ==> uint32" where [code del]: "uint32_sdiv x y = (if y = 0 then undefined ((div) :: uint32 ==> _) x (0 :: uint32) else Abs_uint32 (Rep_uint32 x sdiv Rep_uint32 y))"
definition div0_uint32 :: "uint32 ==> uint32" where [code del]: "div0_uint32 x = undefined ((div) :: uint32 ==> _) x (0 :: uint32)" declare [[code abort: div0_uint32]]
definition mod0_uint32 :: "uint32 ==> uint32" where [code del]: "mod0_uint32 x = undefined ((mod) :: uint32 ==> _) x (0 :: uint32)" declare [[code abort: mod0_uint32]]
lemma uint32_divmod_code [code]: "uint32_divmod x y = (if 0x80000000 ≤ y then if x < y then (0, x) else (1, x - y) else if y = 0 then (div0_uint32 x, mod0_uint32 x) else let q = push_bit 1 (uint32_sdiv (drop_bit 1 x) y); r = x - q * y in if r ≥ y then (q + 1, r - y) else (q, r))"
including undefined_transfer unfolding uint32_divmod_def uint32_sdiv_def div0_uint32_def mod0_uint32_def
less_eq_uint32.rep_eq apply transfer apply (simp add: divmod_via_sdivmod push_bit_eq_mult) done
lemma uint32_sdiv_code [code]: "Rep_uint32 (uint32_sdiv x y) = (if y = 0 then Rep_uint32 (undefined ((div) :: uint32 ==> _) x (0 :: uint32)) else Rep_uint32 x sdiv Rep_uint32 y)" unfolding uint32_sdiv_def by(simp add: Abs_uint32_inverse)
text‹
Note that we only need a translation for signed division, but not for the remainder
because @{thm uint32_divmod_code} computes both with division only. ›
global_interpretation uint32: word_type_copy_target_language Abs_uint32 Rep_uint32 signed_drop_bit_uint32
uint32_of_nat nat_of_uint32 uint32_of_int int_of_uint32 Uint32 integer_of_uint32 32 set_bits_aux_uint32 3231 defines uint32_test_bit = uint32.test_bit and uint32_shiftl = uint32.shiftl and uint32_shiftr = uint32.shiftr and uint32_sshiftr = uint32.sshiftr by standard simp_all
code_printing constant uint32_test_bit ⇀
(SML) "Uint32.test'_bit"and
(Haskell) "Data'_Bits.testBitBounded"and
(OCaml) "Uint32.test'_bit"and
(Scala) "Uint32.test'_bit"and
(Eval) "(fn w => fn n => if n < 0 orelse 32 <= n then raise (Fail \"argument to uint32'_test'_bit out of bounds\") else Uint32.test'_bit w n)"
code_printing constant uint32_shiftl ⇀
(SML) "Uint32.shiftl"and
(Haskell) "Data'_Bits.shiftlBounded"and
(OCaml) "Uint32.shiftl"and
(Scala) "Uint32.shiftl"and
(Eval) "(fn w => fn i => if i < 0 orelse i >= 32 then raise Fail \"argument to uint32'_shiftl out of bounds\" else Uint32.shiftl w i)"
code_printing constant uint32_shiftr ⇀
(SML) "Uint32.shiftr"and
(Haskell) "Data'_Bits.shiftrBounded"and
(OCaml) "Uint32.shiftr"and
(Scala) "Uint32.shiftr"and
(Eval) "(fn w => fn i => if i < 0 orelse i >= 32 then raise Fail \"argument to uint32'_shiftr out of bounds\" else Uint32.shiftr w i)"
code_printing constant uint32_sshiftr ⇀
(SML) "Uint32.shiftr'_signed"and
(Haskell) "(Prelude.fromInteger (Prelude.toInteger (Data'_Bits.shiftrBounded (Prelude.fromInteger (Prelude.toInteger _) :: Uint32.Int32) _)) :: Uint32.Word32)"and
(OCaml) "Uint32.shiftr'_signed"and
(Scala) "Uint32.shiftr'_signed"and
(Eval) "(fn w => fn i => if i < 0 orelse i >= 32 then raise Fail \"argument to uint32'_shiftr'_signed out of bounds\" else Uint32.shiftr'_signed w i)"
context includes bit_operations_syntax begin
lemma uint32_msb_test_bit: "msb x ⟷ bit (x :: uint32) 31" by transfer (simp add: msb_word_iff_bit)
lemma msb_uint32_code [code]: "msb x ⟷ uint32_test_bit x 31" by (simp add: uint32.test_bit_def uint32_msb_test_bit)
lemma uint32_of_int_code [code]: "uint32_of_int i = Uint32 (integer_of_int i)"
including integer.lifting by transfer simp
lemma int_of_uint32_code [code]: "int_of_uint32 x = int_of_integer (integer_of_uint32 x)"
including integer.lifting by transfer simp
lemma uint32_of_nat_code [code]: "uint32_of_nat = uint32_of_int ∘ int" by transfer (simp add: fun_eq_iff)
lemma nat_of_uint32_code [code]: "nat_of_uint32 x = nat_of_integer (integer_of_uint32 x)" unfolding integer_of_uint32_def including integer.lifting by transfer simp
definition integer_of_uint32_signed :: "uint32 ==> integer" where "integer_of_uint32_signed n = (if bit n 31 then undefined integer_of_uint32 n else integer_of_uint32 n)"
lemma integer_of_uint32_signed_code [code]: "integer_of_uint32_signed n = (if bit n 31 then undefined integer_of_uint32 n else integer_of_int (uint (Rep_uint32' n)))" by (simp add: integer_of_uint32_signed_def integer_of_uint32_def)
lemma integer_of_uint32_code [code]: "integer_of_uint32 n = (if bit n 31 then integer_of_uint32_signed (n AND 0x7FFFFFFF) OR 0x80000000 else integer_of_uint32_signed n)" proof - have‹integer_of_uint32_signed (n AND 0x7FFFFFFF) OR 0x80000000 = Bit_Operations.set_bit 31 (integer_of_uint32_signed (take_bit 31 n))› by (simp add: take_bit_eq_mask set_bit_eq_or push_bit_eq_mult mask_eq_exp_minus_1) moreoverhave‹integer_of_uint32 n = Bit_Operations.set_bit 31 (integer_of_uint32 (take_bit 31 n))›if‹bit n 31› proof (rule bit_eqI) fix m from that show‹bit (integer_of_uint32 n) m = bit (Bit_Operations.set_bit 31 (integer_of_uint32 (take_bit 31 n))) m›for m
including integer.lifting by transfer (auto simp add: bit_simps dest: bit_imp_le_length) qed ultimatelyshow ?thesis by simp (simp add: integer_of_uint32_signed_def bit_simps) qed
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.