3 (** {2 Powers of two} *)
9 function pow2 (i:int) : int
11 axiom Power_0 : pow2 0 = 1
12 meta "remove_unused:dependency" axiom Power_0, function pow2
14 axiom Power_s : forall n: int. n >= 0 -> pow2 (n+1) = 2 * pow2 n
15 meta "remove_unused:dependency" axiom Power_s, function pow2
17 lemma Power_1 : pow2 1 = 2
18 meta "remove_unused:dependency" lemma Power_1, function pow2
21 forall n m: int. n >= 0 /\ m >= 0 -> pow2 (n+m) = pow2 n * pow2 m
22 meta "remove_unused:dependency" lemma Power_sum, function pow2
24 lemma pow2pos: forall i:int. i >= 0 -> pow2 i > 0
25 meta "remove_unused:dependency" lemma pow2pos, function pow2
27 lemma pow2_0: pow2 0 = 0x1
28 lemma pow2_1: pow2 1 = 0x2
29 lemma pow2_2: pow2 2 = 0x4
30 lemma pow2_3: pow2 3 = 0x8
31 lemma pow2_4: pow2 4 = 0x10
32 lemma pow2_5: pow2 5 = 0x20
33 lemma pow2_6: pow2 6 = 0x40
34 lemma pow2_7: pow2 7 = 0x80
35 lemma pow2_8: pow2 8 = 0x100
36 lemma pow2_9: pow2 9 = 0x200
37 lemma pow2_10: pow2 10 = 0x400
38 lemma pow2_11: pow2 11 = 0x800
39 lemma pow2_12: pow2 12 = 0x1000
40 lemma pow2_13: pow2 13 = 0x2000
41 lemma pow2_14: pow2 14 = 0x4000
42 lemma pow2_15: pow2 15 = 0x8000
43 lemma pow2_16: pow2 16 = 0x10000
44 lemma pow2_17: pow2 17 = 0x20000
45 lemma pow2_18: pow2 18 = 0x40000
46 lemma pow2_19: pow2 19 = 0x80000
47 lemma pow2_20: pow2 20 = 0x100000
48 lemma pow2_21: pow2 21 = 0x200000
49 lemma pow2_22: pow2 22 = 0x400000
50 lemma pow2_23: pow2 23 = 0x800000
51 lemma pow2_24: pow2 24 = 0x1000000
52 lemma pow2_25: pow2 25 = 0x2000000
53 lemma pow2_26: pow2 26 = 0x4000000
54 lemma pow2_27: pow2 27 = 0x8000000
55 lemma pow2_28: pow2 28 = 0x10000000
56 lemma pow2_29: pow2 29 = 0x20000000
57 lemma pow2_30: pow2 30 = 0x40000000
58 lemma pow2_31: pow2 31 = 0x80000000
59 lemma pow2_32: pow2 32 = 0x100000000
60 lemma pow2_33: pow2 33 = 0x200000000
61 lemma pow2_34: pow2 34 = 0x400000000
62 lemma pow2_35: pow2 35 = 0x800000000
63 lemma pow2_36: pow2 36 = 0x1000000000
64 lemma pow2_37: pow2 37 = 0x2000000000
65 lemma pow2_38: pow2 38 = 0x4000000000
66 lemma pow2_39: pow2 39 = 0x8000000000
67 lemma pow2_40: pow2 40 = 0x10000000000
68 lemma pow2_41: pow2 41 = 0x20000000000
69 lemma pow2_42: pow2 42 = 0x40000000000
70 lemma pow2_43: pow2 43 = 0x80000000000
71 lemma pow2_44: pow2 44 = 0x100000000000
72 lemma pow2_45: pow2 45 = 0x200000000000
73 lemma pow2_46: pow2 46 = 0x400000000000
74 lemma pow2_47: pow2 47 = 0x800000000000
75 lemma pow2_48: pow2 48 = 0x1000000000000
76 lemma pow2_49: pow2 49 = 0x2000000000000
77 lemma pow2_50: pow2 50 = 0x4000000000000
78 lemma pow2_51: pow2 51 = 0x8000000000000
79 lemma pow2_52: pow2 52 = 0x10000000000000
80 lemma pow2_53: pow2 53 = 0x20000000000000
81 lemma pow2_54: pow2 54 = 0x40000000000000
82 lemma pow2_55: pow2 55 = 0x80000000000000
83 lemma pow2_56: pow2 56 = 0x100000000000000
84 lemma pow2_57: pow2 57 = 0x200000000000000
85 lemma pow2_58: pow2 58 = 0x400000000000000
86 lemma pow2_59: pow2 59 = 0x800000000000000
87 lemma pow2_60: pow2 60 = 0x1000000000000000
88 lemma pow2_61: pow2 61 = 0x2000000000000000
89 lemma pow2_62: pow2 62 = 0x4000000000000000
90 lemma pow2_63: pow2 63 = 0x8000000000000000
91 lemma pow2_64: pow2 64 = 0x10000000000000000
93 meta "remove_unused:dependency" lemma pow2_0, function pow2
94 meta "remove_unused:dependency" lemma pow2_1, function pow2
95 meta "remove_unused:dependency" lemma pow2_2, function pow2
96 meta "remove_unused:dependency" lemma pow2_3, function pow2
97 meta "remove_unused:dependency" lemma pow2_4, function pow2
98 meta "remove_unused:dependency" lemma pow2_5, function pow2
99 meta "remove_unused:dependency" lemma pow2_6, function pow2
100 meta "remove_unused:dependency" lemma pow2_7, function pow2
101 meta "remove_unused:dependency" lemma pow2_8, function pow2
102 meta "remove_unused:dependency" lemma pow2_9, function pow2
103 meta "remove_unused:dependency" lemma pow2_10, function pow2
104 meta "remove_unused:dependency" lemma pow2_11, function pow2
105 meta "remove_unused:dependency" lemma pow2_12, function pow2
106 meta "remove_unused:dependency" lemma pow2_13, function pow2
107 meta "remove_unused:dependency" lemma pow2_14, function pow2
108 meta "remove_unused:dependency" lemma pow2_15, function pow2
109 meta "remove_unused:dependency" lemma pow2_16, function pow2
110 meta "remove_unused:dependency" lemma pow2_17, function pow2
111 meta "remove_unused:dependency" lemma pow2_18, function pow2
112 meta "remove_unused:dependency" lemma pow2_19, function pow2
113 meta "remove_unused:dependency" lemma pow2_20, function pow2
114 meta "remove_unused:dependency" lemma pow2_21, function pow2
115 meta "remove_unused:dependency" lemma pow2_22, function pow2
116 meta "remove_unused:dependency" lemma pow2_23, function pow2
117 meta "remove_unused:dependency" lemma pow2_24, function pow2
118 meta "remove_unused:dependency" lemma pow2_25, function pow2
119 meta "remove_unused:dependency" lemma pow2_26, function pow2
120 meta "remove_unused:dependency" lemma pow2_27, function pow2
121 meta "remove_unused:dependency" lemma pow2_28, function pow2
122 meta "remove_unused:dependency" lemma pow2_29, function pow2
123 meta "remove_unused:dependency" lemma pow2_30, function pow2
124 meta "remove_unused:dependency" lemma pow2_31, function pow2
125 meta "remove_unused:dependency" lemma pow2_32, function pow2
126 meta "remove_unused:dependency" lemma pow2_33, function pow2
127 meta "remove_unused:dependency" lemma pow2_34, function pow2
128 meta "remove_unused:dependency" lemma pow2_35, function pow2
129 meta "remove_unused:dependency" lemma pow2_36, function pow2
130 meta "remove_unused:dependency" lemma pow2_37, function pow2
131 meta "remove_unused:dependency" lemma pow2_38, function pow2
132 meta "remove_unused:dependency" lemma pow2_39, function pow2
133 meta "remove_unused:dependency" lemma pow2_40, function pow2
134 meta "remove_unused:dependency" lemma pow2_41, function pow2
135 meta "remove_unused:dependency" lemma pow2_42, function pow2
136 meta "remove_unused:dependency" lemma pow2_43, function pow2
137 meta "remove_unused:dependency" lemma pow2_44, function pow2
138 meta "remove_unused:dependency" lemma pow2_45, function pow2
139 meta "remove_unused:dependency" lemma pow2_46, function pow2
140 meta "remove_unused:dependency" lemma pow2_47, function pow2
141 meta "remove_unused:dependency" lemma pow2_48, function pow2
142 meta "remove_unused:dependency" lemma pow2_49, function pow2
143 meta "remove_unused:dependency" lemma pow2_50, function pow2
144 meta "remove_unused:dependency" lemma pow2_51, function pow2
145 meta "remove_unused:dependency" lemma pow2_52, function pow2
146 meta "remove_unused:dependency" lemma pow2_53, function pow2
147 meta "remove_unused:dependency" lemma pow2_54, function pow2
148 meta "remove_unused:dependency" lemma pow2_55, function pow2
149 meta "remove_unused:dependency" lemma pow2_56, function pow2
150 meta "remove_unused:dependency" lemma pow2_57, function pow2
151 meta "remove_unused:dependency" lemma pow2_58, function pow2
152 meta "remove_unused:dependency" lemma pow2_59, function pow2
153 meta "remove_unused:dependency" lemma pow2_60, function pow2
154 meta "remove_unused:dependency" lemma pow2_61, function pow2
155 meta "remove_unused:dependency" lemma pow2_62, function pow2
156 meta "remove_unused:dependency" lemma pow2_63, function pow2
157 meta "remove_unused:dependency" lemma pow2_64, function pow2
160 (*** use int.EuclideanDivision
162 lemma Div_pow: forall x i:int.
163 i > 0 -> pow2 (i-1) <= x < pow2 i -> div x (pow2 (i-1)) = 1
165 lemma Div_div_pow: forall x i j:int.
166 i > 0 /\ j > 0 -> div (div x (pow2 i)) (pow2 j) = div x (pow2 (i+j))
168 lemma Mod_pow2_gen: forall x i k :int.
169 0 <= k < i -> mod (div (x + pow2 i) (pow2 k)) 2 = mod (div x (pow2 k)) 2
174 (** {2 Generic theory of Bit Vectors (arbitrary length)} *)
182 axiom size_pos : size > 0
186 (** `nth b n` is the `n`-th bit of `b`. Bit 0 is
187 the least significant bit *)
188 val function nth t int : bool
190 axiom nth_out_of_bound: forall x n. n < 0 \/ n >= size -> nth x n = False
194 forall n:int. nth zeros n = False
195 meta "remove_unused:dependency" axiom Nth_zeros, function zeros
201 forall n. 0 <= n < size -> nth ones n = True
202 meta "remove_unused:dependency" axiom Nth_ones, function ones
204 (** Bitwise operators *)
206 (* /!\ NOTE : both bw_and and bw_or don't need guard on n because of
207 nth out of bound axiom *)
208 val function bw_and (v1 v2 : t) : t
210 forall v1 v2:t, n:int. 0 <= n < size ->
211 nth (bw_and v1 v2) n = andb (nth v1 n) (nth v2 n)
212 meta "remove_unused:dependency" axiom Nth_bw_and, function bw_and
214 val function bw_or (v1 v2 : t) : t
216 forall v1 v2:t, n:int. 0 <= n < size ->
217 nth (bw_or v1 v2) n = orb (nth v1 n) (nth v2 n)
218 meta "remove_unused:dependency" axiom Nth_bw_or, function bw_or
220 val function bw_xor (v1 v2 : t) : t
222 forall v1 v2:t, n:int. 0 <= n < size ->
223 nth (bw_xor v1 v2) n = xorb (nth v1 n) (nth v2 n)
224 meta "remove_unused:dependency" axiom Nth_bw_xor, function bw_xor
226 val function bw_not (v : t) : t
228 forall v:t, n:int. 0 <= n < size ->
229 nth (bw_not v) n = notb (nth v n)
230 meta "remove_unused:dependency" axiom Nth_bw_not, function bw_not
232 (** Shift operators *)
234 (** Warning: shift operators of an amount greater than or equal to
235 the size are specified here, in concordance with SMTLIB. This is
236 not necessarily the case in hardware, where the amount of the
237 shift might be taken modulo the size, eg. `lsr x 64` might be
238 equal to `x`, whereas in this theory it is 0.
241 val function lsr t int : t
244 forall b:t,n s:int. 0 <= s -> 0 <= n -> n+s < size ->
245 nth (lsr b s) n = nth b (n+s)
246 meta "remove_unused:dependency" axiom Lsr_nth_low, function lsr
249 forall b:t,n s:int. 0 <= s -> 0 <= n -> n+s >= size ->
250 nth (lsr b s) n = False
251 meta "remove_unused:dependency" axiom Lsr_nth_high, function lsr
253 lemma lsr_zeros: forall x. lsr x 0 = x
254 meta "remove_unused:dependency" lemma lsr_zeros, function lsr
256 val function asr t int : t
259 forall b:t,n s:int. 0 <= s -> 0 <= n < size -> n+s < size ->
260 nth (asr b s) n = nth b (n+s)
261 meta "remove_unused:dependency" axiom Asr_nth_low, function asr
264 forall b:t,n s:int. 0 <= s -> 0 <= n < size -> n+s >= size ->
265 nth (asr b s) n = nth b (size-1)
266 meta "remove_unused:dependency" axiom Asr_nth_high, function asr
268 lemma asr_zeros: forall x. asr x 0 = x
269 meta "remove_unused:dependency" lemma asr_zeros, function asr
271 val function lsl t int : t
274 forall b:t,n s:int. 0 <= s <= n < size ->
275 nth (lsl b s) n = nth b (n-s)
276 meta "remove_unused:dependency" axiom Lsl_nth_high, function lsl
279 forall b:t,n s:int. 0 <= n < s ->
280 nth (lsl b s) n = False
281 meta "remove_unused:dependency" axiom Lsl_nth_low, function lsl
283 lemma lsl_zeros: forall x. lsl x 0 = x
284 meta "remove_unused:dependency" lemma lsl_zeros, function lsl
286 use int.EuclideanDivision
287 (* use int.ComputerDivision as CD*)
289 function rotate_right t int : t
291 axiom Nth_rotate_right :
292 forall v n i. 0 <= i < size -> 0 <= n ->
293 nth (rotate_right v n) i = nth v (mod (i + n) size)
294 meta "remove_unused:dependency" axiom Nth_rotate_right, function rotate_right
296 function rotate_left t int : t
298 axiom Nth_rotate_left :
299 forall v n i. 0 <= i < size -> 0 <= n ->
300 nth (rotate_left v n) i = nth v (mod (i - n) size)
301 meta "remove_unused:dependency" axiom Nth_rotate_left, function rotate_left
304 (** Conversions from/to integers *)
308 constant two_power_size : int
309 (* not needed yet, since sdiv and srem are not yet realized
310 constant two_power_size_minus_one : int
312 constant max_int : int
314 axiom two_power_size_val : two_power_size = pow2 size
315 (* not needed yet, since sdiv and srem are not yet realized
316 axiom two_power_size_minus_one_val : two_power_size_minus_one = pow2 (size-1)
318 axiom max_int_val : max_int = two_power_size - 1
320 predicate is_signed_positive t
322 function to_uint t : int
323 val to_uint (x:t) : int ensures { result = to_uint x }
324 val function of_int int : t
326 function to_int (x:t) : int =
327 if (is_signed_positive x) then (to_uint x) else (- (two_power_size - (to_uint x)))
328 val to_int (x:t) : int ensures { result = to_int x }
330 axiom to_uint_extensionality :
331 forall v,v':t. to_uint v = to_uint v' -> v = v'
332 meta "remove_unused:dependency" axiom to_uint_extensionality, function to_uint
334 axiom to_int_extensionality:
335 forall v,v':t. to_int v = to_int v' -> v = v'
336 meta "remove_unused:dependency" axiom to_int_extensionality, function to_int
339 predicate uint_in_range (i : int) = (Int.(<=) 0 i) /\ (Int.(<=) i max_int)
342 axiom to_uint_bounds :
344 forall v:t. uint_in_range (to_uint v)
346 forall v:t. 0 <= to_uint v < two_power_size
347 meta "remove_unused:dependency" axiom to_uint_bounds, function to_uint
349 axiom to_uint_of_int :
350 forall i. 0 <= i < two_power_size -> to_uint (of_int i) = i
351 meta "remove_unused:dependency" axiom to_uint_of_int, function to_uint
352 meta "remove_unused:dependency" axiom to_uint_of_int, function of_int
355 axiom to_int_bounds :
356 forall v:t. - two_power_size_minus_one <= to_int v < two_power_size_minus_one
358 axiom to_int_of_int :
359 forall i. - two_power_size_minus_one <= i < two_power_size_minus_one -> to_int (of_int i) = i
364 axiom to_uint_size_bv : to_uint size_bv = size
365 axiom to_uint_zeros : to_uint zeros = 0
366 axiom to_uint_one : to_uint one = 1
367 axiom to_uint_ones : to_uint ones = max_int
369 (** comparison operators *)
371 use export why3.WellFounded.WellFounded
373 let predicate ult (x y : t) =
374 Int.(<) (to_uint x) (to_uint y)
376 (* note : the following must be a lemma so that it is cloned in the instances *)
377 lemma ult_wf : well_founded ult
378 meta "vc:proved_wf" predicate ult, lemma ult_wf
379 meta "remove_unused:dependency" lemma ult_wf, predicate ult
381 let predicate ule (x y : t) =
382 Int.(<=) (to_uint x) (to_uint y)
384 let predicate ugt (x y : t) =
385 Int.(>) (to_uint x) (to_uint y)
387 lemma ugt_wf : well_founded ugt
388 meta "vc:proved_wf" predicate ugt, lemma ugt_wf
389 meta "remove_unused:dependency" lemma ugt_wf, predicate ugt
391 let predicate uge (x y : t) =
392 Int.(>=) (to_uint x) (to_uint y)
394 let predicate slt (v1 v2 : t) =
395 Int.(<) (to_int v1) (to_int v2)
397 lemma slt_wf : well_founded slt
398 meta "vc:proved_wf" predicate slt, lemma slt_wf
399 meta "remove_unused:dependency" lemma slt_wf, predicate slt
401 let predicate sle (v1 v2 : t) =
402 Int.(<=) (to_int v1) (to_int v2)
404 let predicate sgt (v1 v2 : t) =
405 Int.(>) (to_int v1) (to_int v2)
407 lemma sgt_wf : well_founded sgt
408 meta "vc:proved_wf" predicate sgt, lemma sgt_wf
409 meta "remove_unused:dependency" lemma sgt_wf, predicate sgt
411 let predicate sge (v1 v2 : t) =
412 Int.(>=) (to_int v1) (to_int v2)
414 axiom positive_is_ge_zeros:
415 forall x. is_signed_positive x <-> sge x zeros
416 meta "remove_unused:dependency" axiom positive_is_ge_zeros, predicate sge
417 meta "remove_unused:dependency" axiom positive_is_ge_zeros, predicate is_signed_positive
419 (** Arithmetic operators *)
421 val function add (v1 v2 : t) : t
423 forall v1 v2. to_uint (add v1 v2) = mod (Int.(+) (to_uint v1) (to_uint v2)) two_power_size
424 meta "remove_unused:dependency" axiom to_uint_add, function add
425 lemma to_uint_add_bounded:
427 to_uint v1 + to_uint v2 < two_power_size ->
428 to_uint (add v1 v2) = to_uint v1 + to_uint v2
429 meta "remove_unused:dependency" lemma to_uint_add_bounded, function add
430 lemma to_uint_add_overflow:
432 to_uint v1 + to_uint v2 >= two_power_size ->
433 to_uint (add v1 v2) = to_uint v1 + to_uint v2 - two_power_size
434 meta "remove_unused:dependency" lemma to_uint_add_overflow, function add
436 val function sub (v1 v2 : t) : t
438 forall v1 v2. to_uint (sub v1 v2) = mod (Int.(-) (to_uint v1) (to_uint v2)) two_power_size
439 meta "remove_unused:dependency" axiom to_uint_sub , function sub
440 lemma to_uint_sub_bounded:
442 0 <= to_uint v1 - to_uint v2 ->
443 to_uint (sub v1 v2) = to_uint v1 - to_uint v2
444 meta "remove_unused:dependency" lemma to_uint_sub_bounded, function sub
445 lemma to_uint_sub_overflow:
447 0 > to_uint v1 - to_uint v2 ->
448 to_uint (sub v1 v2) = to_uint v1 - to_uint v2 + two_power_size
449 meta "remove_unused:dependency" lemma to_uint_sub_overflow, function sub
451 val function neg (v1 : t) : t
453 forall v. to_uint (neg v) = mod (Int.(-_) (to_uint v)) two_power_size
454 meta "remove_unused:dependency" axiom to_uint_neg, function neg
455 lemma to_uint_neg_no_mod:
456 forall v. to_uint (neg v) =
457 if v = zeros then 0 else two_power_size - to_uint v
458 meta "remove_unused:dependency" lemma to_uint_neg_no_mod, function neg
460 val function mul (v1 v2 : t) : t
462 forall v1 v2. to_uint (mul v1 v2) = mod (Int.( * ) (to_uint v1) (to_uint v2)) two_power_size
463 meta "remove_unused:dependency" axiom to_uint_mul, function mul
464 lemma to_uint_mul_bounded:
466 to_uint v1 * to_uint v2 < two_power_size ->
467 to_uint (mul v1 v2) = to_uint v1 * to_uint v2
468 meta "remove_unused:dependency" lemma to_uint_mul_bounded, function mul
470 val function udiv (v1 v2 : t) : t
472 forall v1 v2. to_uint (udiv v1 v2) = div (to_uint v1) (to_uint v2)
473 meta "remove_unused:dependency" axiom to_uint_udiv, function udiv
475 val function urem (v1 v2 : t) : t
477 forall v1 v2. to_uint (urem v1 v2) = mod (to_uint v1) (to_uint v2)
478 meta "remove_unused:dependency" axiom to_uint_urem, function urem
480 val function sdiv (v1 v2 : t) : t
483 forall v1 v2. to_int (sdiv v1 v2) = CD.mod (CD.div (to_int v1) (to_int v2)) two_power_size
484 axiom to_int_sdiv_bounded:
486 v1 <> (lsl one (size-1)) \/ v2 <> ones ->
487 to_int (sdiv v1 v2) = CD.div (to_int v1) (to_int v2)
490 val function srem (v1 v2 : t) : t
493 forall v1 v2. to_int (srem v1 v2) = CD.mod (to_int v1) (to_int v2)
496 (** Bitvector alternatives for shifts, rotations and nth *)
498 (** logical shift right *)
499 val function lsr_bv t t : t
503 lsr_bv x n = lsr x (to_uint n)
504 meta "remove_unused:dependency" axiom lsr_bv_is_lsr, function lsr_bv
508 to_uint (lsr_bv v n) = div (to_uint v) (pow2 ( to_uint n ))
509 meta "remove_unused:dependency" axiom to_uint_lsr, function lsr_bv
511 (** arithmetic shift right *)
512 val function asr_bv t t : t
516 asr_bv x n = asr x (to_uint n)
517 meta "remove_unused:dependency" axiom asr_bv_is_asr, function asr_bv
519 (** logical shift left *)
520 val function lsl_bv t t : t
524 lsl_bv x n = lsl x (to_uint n)
525 meta "remove_unused:dependency" axiom lsl_bv_is_lsl, function lsl_bv
529 to_uint (lsl_bv v n) = mod (Int.( * ) (to_uint v) (pow2 (to_uint n))) two_power_size
530 meta "remove_unused:dependency" axiom to_uint_lsl, function lsl_bv
534 val function rotate_right_bv (v n : t) : t
536 val function rotate_left_bv (v n : t) : t
538 axiom rotate_left_bv_is_rotate_left :
539 forall v n. rotate_left_bv v n = rotate_left v (to_uint n)
540 meta "remove_unused:dependency" axiom rotate_left_bv_is_rotate_left, function rotate_left_bv
541 meta "remove_unused:dependency" axiom rotate_left_bv_is_rotate_left, function rotate_left
543 axiom rotate_right_bv_is_rotate_right :
544 forall v n. rotate_right_bv v n = rotate_right v (to_uint n)
545 meta "remove_unused:dependency" axiom rotate_right_bv_is_rotate_right, function rotate_right_bv
546 meta "remove_unused:dependency" axiom rotate_right_bv_is_rotate_right, function rotate_right
548 val function nth_bv t t: bool
552 nth_bv x i = not (bw_and (lsr_bv x i) one = zeros)
553 meta "remove_unused:dependency" axiom nth_bv_def, function nth_bv
557 nth x (to_uint i) = nth_bv x i
558 meta "remove_unused:dependency" axiom Nth_bv_is_nth, function nth_bv
559 meta "remove_unused:dependency" axiom Nth_bv_is_nth, function nth
561 axiom Nth_bv_is_nth2:
562 forall x i. 0 <= i < two_power_size ->
563 nth_bv x (of_int i) = nth x i
564 meta "remove_unused:dependency" axiom Nth_bv_is_nth2, function nth_bv
565 meta "remove_unused:dependency" axiom Nth_bv_is_nth2, function nth
567 (** equality axioms *)
569 predicate eq_sub_bv t t t t
571 axiom eq_sub_bv_def: forall a b i n.
572 let mask = lsl_bv (sub (lsl_bv one n) one) i in
573 eq_sub_bv a b i n = (bw_and b mask = bw_and a mask)
574 meta "remove_unused:dependency" axiom eq_sub_bv_def, predicate eq_sub_bv
576 predicate eq_sub (a b:t) (i n:int) =
577 forall j. i <= j < i + n -> nth a j = nth b j
579 axiom eq_sub_equiv: forall a b i n:t.
580 eq_sub a b (to_uint i) (to_uint n)
581 <-> eq_sub_bv a b i n
582 meta "remove_unused:dependency" axiom eq_sub_equiv, predicate eq_sub_bv
583 meta "remove_unused:dependency" axiom eq_sub_equiv, predicate eq_sub
585 predicate (==) (v1 v2 : t) =
588 axiom Extensionality [@W:non_conservative_extension:N] :
589 forall x y : t [x == y]. x == y -> x = y
590 meta "remove_unused:dependency" axiom Extensionality, predicate (==)
592 val eq (v1 v2 : t) : bool
593 ensures { result <-> v1 = v2 }
597 (** {2 Bit Vectors of common sizes, 8/16/32/64/128/256} *)
600 constant size : int = 256
601 constant two_power_size : int = 0x1_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000
603 use int.Int as Int (* needed to use range types *)
605 type t = < range 0 0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF >
607 constant zeros : t = 0x0
608 constant one : t = 0x1
609 constant ones : t = 0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF
611 clone export BV_Gen with
613 function to_uint = t'int,
614 constant size = size,
615 constant two_power_size = two_power_size,
616 constant max_int = t'maxInt,
617 constant zeros = zeros,
621 goal two_power_size_val,
623 axiom . (* should this be "lemma"? "goal"? *)
628 constant size : int = 128
629 constant two_power_size : int = 0x1_0000_0000_0000_0000_0000_0000_0000_0000
631 use int.Int as Int (* needed to use range types *)
633 type t = < range 0 0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF >
635 constant zeros : t = 0x0
636 constant one : t = 0x1
637 constant ones : t = 0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF
639 clone export BV_Gen with
641 function to_uint = t'int,
642 constant size = size,
643 constant two_power_size = two_power_size,
644 constant max_int = t'maxInt,
649 goal two_power_size_val,
651 axiom . (* should this be "lemma"? "goal"? *)
656 constant size : int = 64
657 constant two_power_size : int = 0x1_0000_0000_0000_0000
659 use int.Int as Int (* needed to use range types *)
661 type t = < range 0 0xFFFF_FFFF_FFFF_FFFF >
663 constant zeros : t = 0x0
664 constant one : t = 0x1
665 constant ones : t = 0xFFFF_FFFF_FFFF_FFFF
667 clone export BV_Gen with
669 function to_uint = t'int,
670 constant size = size,
671 constant two_power_size = two_power_size,
672 constant max_int = t'maxInt,
677 goal two_power_size_val,
679 axiom . (* should this be "lemma"? "goal"? *)
684 constant size : int = 32
685 constant two_power_size : int = 0x1_0000_0000
687 use int.Int as Int (* needed to use range types *)
689 type t = < range 0 0xFFFF_FFFF >
691 constant zeros : t = 0x0
692 constant one : t = 0x1
693 constant ones : t = 0xFFFF_FFFF
695 clone export BV_Gen with
697 function to_uint = t'int,
698 constant size = size,
699 constant two_power_size = two_power_size,
700 constant max_int = t'maxInt,
705 goal two_power_size_val,
707 axiom . (* should this be "lemma"? "goal"? *)
712 constant size : int = 16
713 constant two_power_size : int = 0x1_0000
715 use int.Int as Int (* needed to use range types *)
717 type t = < range 0 0xFFFF >
719 constant zeros : t = 0x0
720 constant one : t = 0x1
721 constant ones : t = 0xFFFF
723 clone export BV_Gen with
725 function to_uint = t'int,
726 constant size = size,
727 constant two_power_size = two_power_size,
728 constant max_int = t'maxInt,
733 goal two_power_size_val,
735 axiom . (* should this be "lemma"? "goal"? *)
740 constant size : int = 8
741 constant two_power_size : int = 0x1_00
743 use int.Int as Int (* needed to use range types *)
745 type t = < range 0 0xFF >
747 constant zeros : t = 0x0
748 constant one : t = 0x1
749 constant ones : t = 0xFF
751 clone export BV_Gen with
753 function to_uint = t'int,
754 constant size = size,
755 constant two_power_size = two_power_size,
756 constant max_int = t'maxInt,
761 goal two_power_size_val,
763 axiom . (* should this be "lemma"? "goal"? *)
767 (** {2 Generic Converter} *)
769 module BVConverter_Gen
774 predicate in_small_range bigBV
776 function to_uint_small smallBV : int
777 function to_uint_big bigBV : int
779 val function toBig smallBV : bigBV (* unsigned, that is "zero extend" *)
780 val function stoBig smallBV : bigBV (* signed, that is "sign extend" *)
781 val function toSmall bigBV : smallBV
783 axiom toSmall_to_uint :
784 forall x:bigBV. in_small_range x ->
785 to_uint_big x = to_uint_small (toSmall x)
787 axiom toBig_to_uint :
789 to_uint_small x = to_uint_big (toBig x)
791 (* TODO: specify stoBig by axioms too *)
795 (** {2 Converters of common size_bvs} *)
797 module BVConverter_128_256
801 predicate in_range (b : BV256.t) = BV256.ule b (0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF:BV256.t)
803 clone export BVConverter_Gen with
804 type bigBV = BV256.t,
805 type smallBV = BV128.t,
806 predicate in_small_range = in_range,
807 function to_uint_small = BV128.t'int,
808 function to_uint_big = BV256.t'int,
809 axiom toSmall_to_uint, (* TODO: "lemma"? "goal"? *)
810 axiom toBig_to_uint (* TODO: "lemma"? "goal"? *)
813 module BVConverter_64_256
817 predicate in_range (b : BV256.t) = BV256.ule b (0xFFFF_FFFF_FFFF_FFFF:BV256.t)
819 clone export BVConverter_Gen with
820 type bigBV = BV256.t,
821 type smallBV = BV64.t,
822 predicate in_small_range = in_range,
823 function to_uint_small = BV64.t'int,
824 function to_uint_big = BV256.t'int,
825 axiom toSmall_to_uint, (* TODO: "lemma"? "goal"? *)
826 axiom toBig_to_uint (* TODO: "lemma"? "goal"? *)
829 module BVConverter_32_256
833 predicate in_range (b : BV256.t) = BV256.ule b (0xFFFF_FFFF:BV256.t)
835 clone export BVConverter_Gen with
836 type bigBV = BV256.t,
837 type smallBV = BV32.t,
838 predicate in_small_range = in_range,
839 function to_uint_small = BV32.t'int,
840 function to_uint_big = BV256.t'int,
841 axiom toSmall_to_uint, (* TODO: "lemma"? "goal"? *)
842 axiom toBig_to_uint (* TODO: "lemma"? "goal"? *)
845 module BVConverter_16_256
849 predicate in_range (b : BV256.t) = BV256.ule b (0xFFFF:BV256.t)
851 clone export BVConverter_Gen with
852 type bigBV = BV256.t,
853 type smallBV = BV16.t,
854 predicate in_small_range = in_range,
855 function to_uint_small = BV16.t'int,
856 function to_uint_big = BV256.t'int,
857 axiom toSmall_to_uint, (* TODO: "lemma"? "goal"? *)
858 axiom toBig_to_uint (* TODO: "lemma"? "goal"? *)
861 module BVConverter_8_256
865 predicate in_range (b : BV256.t) = BV256.ule b (0xFF:BV256.t)
867 clone export BVConverter_Gen with
868 type bigBV = BV256.t,
869 type smallBV = BV8.t,
870 predicate in_small_range = in_range,
871 function to_uint_small = BV8.t'int,
872 function to_uint_big = BV256.t'int,
873 axiom toSmall_to_uint, (* TODO: "lemma"? "goal"? *)
874 axiom toBig_to_uint (* TODO: "lemma"? "goal"? *)
877 module BVConverter_64_128
881 predicate in_range (b : BV128.t) = BV128.ule b (0xFFFF_FFFF_FFFF_FFFF:BV128.t)
883 clone export BVConverter_Gen with
884 type bigBV = BV128.t,
885 type smallBV = BV64.t,
886 predicate in_small_range = in_range,
887 function to_uint_small = BV64.t'int,
888 function to_uint_big = BV128.t'int,
889 axiom toSmall_to_uint, (* TODO: "lemma"? "goal"? *)
890 axiom toBig_to_uint (* TODO: "lemma"? "goal"? *)
893 module BVConverter_32_128
897 predicate in_range (b : BV128.t) = BV128.ule b (0xFFFF_FFFF:BV128.t)
899 clone export BVConverter_Gen with
900 type bigBV = BV128.t,
901 type smallBV = BV32.t,
902 predicate in_small_range = in_range,
903 function to_uint_small = BV32.t'int,
904 function to_uint_big = BV128.t'int,
905 axiom toSmall_to_uint, (* TODO: "lemma"? "goal"? *)
906 axiom toBig_to_uint (* TODO: "lemma"? "goal"? *)
909 module BVConverter_16_128
913 predicate in_range (b : BV128.t) = BV128.ule b (0xFFFF:BV128.t)
915 clone export BVConverter_Gen with
916 type bigBV = BV128.t,
917 type smallBV = BV16.t,
918 predicate in_small_range = in_range,
919 function to_uint_small = BV16.t'int,
920 function to_uint_big = BV128.t'int,
921 axiom toSmall_to_uint, (* TODO: "lemma"? "goal"? *)
922 axiom toBig_to_uint (* TODO: "lemma"? "goal"? *)
925 module BVConverter_8_128
929 predicate in_range (b : BV128.t) = BV128.ule b (0xFF:BV128.t)
931 clone export BVConverter_Gen with
932 type bigBV = BV128.t,
933 type smallBV = BV8.t,
934 predicate in_small_range = in_range,
935 function to_uint_small = BV8.t'int,
936 function to_uint_big = BV128.t'int,
937 axiom toSmall_to_uint, (* TODO: "lemma"? "goal"? *)
938 axiom toBig_to_uint (* TODO: "lemma"? "goal"? *)
941 module BVConverter_32_64
945 predicate in_range (b : BV64.t) = BV64.ule b (0xFFFF_FFFF:BV64.t)
947 clone export BVConverter_Gen with
949 type smallBV = BV32.t,
950 predicate in_small_range = in_range,
951 function to_uint_small = BV32.t'int,
952 function to_uint_big = BV64.t'int,
953 axiom toSmall_to_uint, (* TODO: "lemma"? "goal"? *)
954 axiom toBig_to_uint (* TODO: "lemma"? "goal"? *)
957 module BVConverter_16_64
961 predicate in_range (b : BV64.t) = BV64.ule b (0xFFFF:BV64.t)
963 clone export BVConverter_Gen with
965 type smallBV = BV16.t,
966 predicate in_small_range = in_range,
967 function to_uint_small = BV16.t'int,
968 function to_uint_big = BV64.t'int,
969 axiom toSmall_to_uint, (* TODO: "lemma"? "goal"? *)
970 axiom toBig_to_uint (* TODO: "lemma"? "goal"? *)
973 module BVConverter_8_64
977 predicate in_range (b : BV64.t) = BV64.ule b (0xFF:BV64.t)
979 clone export BVConverter_Gen with
981 type smallBV = BV8.t,
982 predicate in_small_range = in_range,
983 function to_uint_small = BV8.t'int,
984 function to_uint_big = BV64.t'int,
985 axiom toSmall_to_uint, (* TODO: "lemma"? "goal"? *)
986 axiom toBig_to_uint (* TODO: "lemma"? "goal"? *)
989 module BVConverter_16_32
993 predicate in_range (b : BV32.t) = BV32.ule b (0xFFFF:BV32.t)
995 clone export BVConverter_Gen with
997 type smallBV = BV16.t,
998 predicate in_small_range = in_range,
999 function to_uint_small = BV16.t'int,
1000 function to_uint_big = BV32.t'int,
1001 axiom toSmall_to_uint, (* TODO: "lemma"? "goal"? *)
1002 axiom toBig_to_uint (* TODO: "lemma"? "goal"? *)
1005 module BVConverter_8_32
1009 predicate in_range (b : BV32.t) = BV32.ule b (0xFF:BV32.t)
1011 clone export BVConverter_Gen with
1012 type bigBV = BV32.t,
1013 type smallBV = BV8.t,
1014 predicate in_small_range = in_range,
1015 function to_uint_small = BV8.t'int,
1016 function to_uint_big = BV32.t'int,
1017 axiom toSmall_to_uint, (* TODO: "lemma"? "goal"? *)
1018 axiom toBig_to_uint (* TODO: "lemma"? "goal"? *)
1021 module BVConverter_8_16
1025 predicate in_range (b : BV16.t) = BV16.ule b (0xFF:BV16.t)
1027 clone export BVConverter_Gen with
1028 type bigBV = BV16.t,
1029 type smallBV = BV8.t,
1030 predicate in_small_range = in_range,
1031 function to_uint_small = BV8.t'int,
1032 function to_uint_big = BV16.t'int,
1033 axiom toSmall_to_uint, (* TODO: "lemma"? "goal"? *)
1034 axiom toBig_to_uint (* TODO: "lemma"? "goal"? *)