File: bitvector_examples.mlw

package info (click to toggle)
why3 1.8.2-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 45,028 kB
  • sloc: xml: 185,443; ml: 111,224; ansic: 3,998; sh: 2,578; makefile: 2,568; java: 865; python: 720; javascript: 290; lisp: 205; pascal: 173
file content (429 lines) | stat: -rw-r--r-- 10,139 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
module Test_proofinuse

  use int.Int
  use int.Power
  use int.EuclideanDivision
  use bv.BV32

  (* Shift is div example -------------------  *)

  let shift_is_div ( x : t ) ( y : t ) : t
    requires { 0 <= t'int y < 32 }
  =
    let res = lsr_bv x 0x1 in
    assert { res = udiv x (2:t) };
    assert { t'int res = div (t'int x) 2 };
    let res : t = lsr_bv res (2:t) in
(*
    assert { res = udiv x (8:t) };
    assert { t'int res = div (t'int x) 8 };
*)
    res

 (* Mask example --------------------- *)

  use bv.BV8 as BV8
  use bv.BV64 as BV64

  use bv.BVConverter_32_64 as C32_46
  use bv.BVConverter_8_32 as C8_32

  type bitvec8 = BV8.t
  type bitvec64 = BV64.t

  let mask ( x : t ) =
    ensures { result = BV8.one }
    (* ensures{ not ( BV8.eq result (BV8.of_int 1) ) } *)
    let res = C8_32.toSmall(
                bw_and
                  (bw_or
                    (bw_and x (0xFFFF_FF00:t))
                    0x1)
                  (0x0000_00FF:t))
    in res

  (* test invariant from frama-c ---------------- *)

  use ref.Ref

  let testVariant( n : t ) =
    let i = ref n in
    let two = 2:t in

    while uge !i two do
    variant{ t'int !i }
      i := lsr_bv !i two
    done

  (* testssss *)

  predicate in_range (n : t) = (ule (0:t) n) /\ (ule n (0x0000_00FF:t))

  predicate add_over (x y : t) = (uge (add x y) x) /\ (uge (add x y) y)

  lemma ttt: forall x y.  (add_over x y) -> (forall i. ult i x -> add_over i y)
end

(** {1 Examples from Hackers Delight} *)

theory Hackers_delight
  use int.Int
  use bv.BV32

  (** de morgan's laws *)

  goal DM1: forall x y.
    bw_not( bw_and x y ) = bw_or (bw_not x) (bw_not y)

  goal DM2: forall x y.
    bw_not( bw_or x y ) = bw_and (bw_not x) (bw_not y)

  goal DM3: forall x.
    bw_not (add x one) = sub (bw_not x) one

  goal DM4: forall x.
    bw_not (sub x one) = add (bw_not x) one

  goal DM5: forall x.
    bw_not (neg x) = sub x one

  goal DM6: forall x y.
    bw_not( bw_xor x y ) = bw_xor (bw_not x) y (* = eq x y *)

  goal DM7: forall x y.
    bw_not( add x y ) = sub (bw_not x) y

  goal DM8: forall x y.
    bw_not( sub x y ) = add (bw_not x) y

  goal DMtest: forall x.
    zeros = bw_not( bw_or x (neg( add x one)))

  (* inequality  *)

  goal IE1: forall x y.
    ule (bw_xor x y) (bw_or x y)

  goal IE2: forall x y.
    ule (bw_and x y) (bw_not( bw_xor x y ))

  goal IE3: forall x y.
    ( ule x (add x y) /\ ule y (add x y) ) -> ule (bw_or x y) (add x y)

  goal IE4: forall x y.
    not ( ule x (add x y) /\ ule y (add x y) ) -> ugt (bw_or x y) (add x y)

  (* shift right and arithmetic shift right *)

  goal SR1: forall x n. ( ule zeros n /\ ule n (31:t)) ->
    bw_or (lsr_bv x n) (lsl_bv (neg( lsr_bv x (31:t) )) (sub (31:t) n))
  = asr_bv x n

  (* rotate en shift *)

  goal RS_left: forall x.
    bw_or (lsl_bv x one) (lsr_bv x (31:t)) = rotate_left_bv x one

  goal RS_right: forall x.
    bw_or (lsr_bv x one) (lsl_bv x (31:t)) = rotate_right_bv x one

  (* bound propagation *)

  goal BP1: forall a b c d x y.
    ( ule a x /\ ule x b /\ ule c y /\ ule y d ) ->
    ( ule b (add b d) /\ ule d (add b d) ) -> (* no overflow in addition *)
      ule (bw_or x y) (add b d) /\ ule zeros (bw_and x y)

  goal BP2: forall a b c d x y.
    ( ule a x /\ ule x b /\ ule c y /\ ule y d ) ->
    ( ule b (add b d) /\ ule d (add b d) ) -> (* no overflow in addition *)
      ule zeros (bw_xor x y) /\ ule (bw_xor x y) (add b d)

  goal BP3: forall a b c d x y.
    ( ule a x /\ ule x b /\ ule c y /\ ule y d ) ->
      ule (bw_not b) (bw_not x) /\ ule (bw_not x) (bw_not a)

end

module Hackers_delight_mod
  use int.Int
  use bv.BV32

  (* de morgan's laws *)

  let dm1 (x : t) (y : t) =
    ensures{ result = bw_or (bw_not x) (bw_not y) }
    bw_not( bw_and x y )

  let dm2 (x : t) (y : t) =
    ensures{ result = bw_and (bw_not x) (bw_not y) }
    bw_not( bw_or x y )

  let dm3 (x : t) =
    ensures{ result = sub (bw_not x) one }
    bw_not( add x 0x1 )

  let dm4 (x : t) =
    ensures{ result = add (bw_not x) one }
    bw_not( sub x 0x1 )

  let dm5 (x : t) =
    ensures{ result = sub x one }
    bw_not( neg x )

  let dm6 (x : t) (y : t) =
    ensures{ result = bw_xor (bw_not x) y }
    bw_not( bw_xor x y )

  let dm7 (x : t) (y : t) =
    ensures{ result = sub (bw_not x) y }
    bw_not( add x y )

  let dm8 (x : t) (y : t) =
    ensures{ result = add (bw_not x) y }
    bw_not( sub x y )

  let dmtest (x : t) =
    ensures{ result = zeros }
    bw_not( bw_or x (neg( add x 0x1)))

  (* inequality  *)

  let ie1 (x : t) (y : t) =
    ensures{ ule result (bw_or x y) }
    bw_xor x y

  let ie2 (x : t) (y : t) =
    ensures{ ule result (bw_not( bw_xor x y ))}
    bw_and x y

  let ie3 (x : t) (y : t) =
    requires{ ule x (add x y) /\ ule y (add x y) }
    ensures{ ule result (add x y) }
    bw_or x y

  let ie4 (x : t) (y : t) =
    requires{ not ( ule x (add x y) /\ ule y (add x y) ) }
    ensures{ ugt result (add x y) }
    bw_or x y

  (* shift right and arithmetic shift right *)

  let sr1 (x : t) (n : t) =
    requires{ ule zeros n /\ ule n (31:t) }
    ensures{ result = asr_bv x n }
    bw_or (lsr_bv x n) (lsl_bv (neg( lsr_bv x (31:t) )) (sub (31:t) n))

  (* rotate en shift *)

  let rs_left (x : t) =
  ensures{ result = rotate_left_bv x one }
    bw_or (lsl_bv x 0x1) (lsr_bv x (31:t))

  let rs_right (x : t) =
  ensures{ result = rotate_right_bv x one }
    bw_or (lsr_bv x 0x1) (lsl_bv x (31:t))

  (* bound propagation *)

  let bp1 (a b c d x y : t) =
  requires{ ule a x /\ ule x b }
  requires{ ule c y /\ ule y d }
  requires{ ule b (add b d) /\ ule d (add b d) } (* no overflow in addition *)
  ensures{ ule result (add b d) }
    bw_or x y

  let bp1' (a b c d x y : t) =
  requires{ ule a x /\ ule x b }
  requires{ ule c y /\ ule y d }
  requires{ ule b (add b d) /\ ule d (add b d) } (* no overflow in addition *)
  ensures{ ule zeros result }
    bw_and x y

  let bp2 (a b c d x y : t) =
  requires{ ule a x /\ ule x b }
  requires{ ule c y /\ ule y d }
  requires{ ule b (add b d) /\ ule d (add b d) } (* no overflow in addition *)
  ensures{ ule zeros result }
  ensures{ ule result (add b d) }
    bw_xor x y

  let bp3 (a b c d x y : t) =
  requires{ ule a x /\ ule x b }
  requires{ ule c y /\ ule y d }
  ensures{ ule (bw_not b) result }
  ensures{ ule result (bw_not a) }
    bw_not x

end

module Test_imperial_violet

  use int.Int
  use int.EuclideanDivision
  use bv.BV32
  use array.Array

  (* to_int and bounds *)

  lemma bv32_bounds_bv:
    forall b. ule zeros b /\ ule b ones

  lemma to_int_ule:
    forall b c. ule b c -> t'int b <= t'int c

  lemma to_int_ult:
    forall b c. ult b c -> t'int b < t'int c

  lemma bv32_bounds_0:
    forall b. 0 <= t'int b

  lemma bv32_bounds:
    forall b. 0 <= t'int b < 0x1_0000_0000

  (* bounded add of array of t *)

  let add (a : array t ) (b : array t) =
    requires{ length a = length b }
    requires{ forall i. 0 <= i < length a ->
                ult a[i] (0x8000_0000:t) }
    requires{ forall i. 0 <= i < length b ->
                ult b[i] (0x8000_0000:t) }
    ensures{ forall i. 0 <= i < length result ->
               t'int result[i] = t'int a[i] + t'int b[i] }
    let sum = make (length a) 0x0 in
    for i = 0 to length a - 1 do
      invariant{ forall j. 0 <= j < i -> sum[j] = add a[j] b[j] }
      invariant{ forall j. 0 <= j < i -> t'int sum[j] = t'int a[j] + t'int b[j] }
      sum[i] <- add a[i] b[i]
    done;
    sum

end

module Test_from_bitvector_example

  use int.Int
  use bv.BV32

  goal Test1:
    let b = bw_and zeros ones in nth_bv b one = False

  goal Test2:
    let b = lsr_bv ones (16:t) in nth_bv b (15:t) = True

  goal Test3:
    let b = lsr_bv ones (16:t) in nth_bv b (16:t) = False

  goal Test4:
    let b = asr_bv ones (16:t) in nth_bv b (15:t) = True

  goal Test5:
    let b = asr_bv ones (16:t) in nth_bv b (16:t) = True

  goal Test6:
    let b = asr_bv (lsr_bv ones one) (16:t) in nth_bv b (16:t) = False

  let lsr31 () =
    ensures{ result = one }
    lsr_bv 0xFFFF_FFFF (31:t)

  let lsr30 () =
    ensures{ result = (3:t) }
    lsr_bv 0xFFFF_FFFF (30:t)

  let lsr29 () =
    ensures{ t'int result = 7 }
    lsr_bv 0xFFFF_FFFF (29:t)

  let lsr28 () =
    ensures{ t'int result = 15 }
    lsr_bv 0xFFFF_FFFF (28:t)

  let lsr27 () =
    ensures{ t'int result = 31 }
    lsr_bv 0xFFFF_FFFF (27:t)

  let lsr26 () =
    ensures{ t'int result = 63 }
    lsr_bv 0xFFFF_FFFF (26:t)

  let lsr20 () =
    ensures{ t'int result = 4095 }
    lsr_bv 0xFFFF_FFFF (20:t)

  let lsr13 () =
    ensures{ t'int result = 524287 }
    lsr_bv 0xFFFF_FFFF (13:t)

  let lsr8 () =
    ensures{ t'int result = 16777215 }
    lsr_bv 0xFFFF_FFFF (8:t)

  goal to_int_0x00000001:
    t'int (lsr_bv ones (31:t)) = 1

  goal to_int_0x00000003:
    t'int (lsr_bv ones (30:t)) = 3

  goal to_int_0x00000007:
    t'int (lsr_bv ones (29:t)) = 7

  goal to_int_0x0000000F:
    t'int (lsr_bv ones (28:t)) = 15

  goal to_int_0x0000001F:
    t'int (lsr_bv ones (27:t)) = 31

  goal to_int_0x0000003F:
    t'int (lsr_bv ones (26:t)) = 63

  goal to_int_0x0000007F:
    t'int (lsr_bv ones (25:t)) = 127

  goal to_int_0x000000FF:
    t'int (lsr_bv ones (24:t)) = 255

  goal to_int_0x000001FF:
    t'int (lsr_bv ones (23:t)) = 511

  goal to_int_0x000003FF:
    t'int (lsr_bv ones (22:t)) = 1023

  goal to_int_0x000007FF:
    t'int (lsr_bv ones (21:t)) = 2047

  goal to_int_0x00000FFF:
    t'int (lsr_bv ones (20:t)) = 4095

  goal to_int_0x00001FFF:
    t'int (lsr_bv ones (19:t)) = 8191

  goal to_int_0x00003FFF:
    t'int (lsr_bv ones (18:t)) = 16383

  goal to_int_0x00007FFF:
    t'int (lsr_bv ones (17:t)) = 32767

  goal to_int_0x0000FFFF:
    t'int (lsr_bv ones (16:t)) = 65535

  goal to_int_0x0001FFFF:
    t'int (lsr_bv ones (15:t)) = 131071

  goal to_int_0x0003FFFF:
    t'int (lsr_bv ones (14:t)) = 262143

  goal to_int_0x0007FFFF:
    t'int (lsr_bv ones (13:t)) = 524287

  goal to_int_0x000FFFFF:
    t'int (lsr_bv ones (12:t)) = 1048575

  goal to_int_0x00FFFFFF:
    t'int (lsr_bv ones (8:t)) = 16777215

  goal to_int_0xFFFFFFFF:
    t'int ones = 4294967295

end