mirror of
https://github.com/AdaCore/why3.git
synced 2026-02-12 12:34:55 -08:00
89 lines
1.8 KiB
Plaintext
89 lines
1.8 KiB
Plaintext
|
|
(** Swapping two integers in-place *)
|
|
|
|
module Swap
|
|
|
|
use int.Int
|
|
use ref.Ref
|
|
|
|
let swap (ref a b: int) : unit
|
|
writes { a, b }
|
|
ensures { a = old b /\ b = old a }
|
|
=
|
|
a <- a + b;
|
|
b <- a - b;
|
|
a <- a - b
|
|
|
|
end
|
|
|
|
(** It also works fine with machine integers, even with overflows *)
|
|
|
|
module SwapInt32
|
|
|
|
use int.Int
|
|
use ref.Ref
|
|
|
|
(** a simple model of 32-bit integers with addition, subtraction,
|
|
and possible overflows *)
|
|
|
|
type int32 = < range -0x8000_0000 0x7fff_ffff >
|
|
|
|
meta coercion function int32'int
|
|
|
|
constant width : int = int32'maxInt - int32'minInt + 1
|
|
|
|
val (+) (a: int32) (b: int32) : int32
|
|
ensures { result =
|
|
if a + b < int32'minInt then a + b + width
|
|
else if a + b > int32'maxInt then a + b - width
|
|
else a + b }
|
|
|
|
val (-) (a: int32) (b: int32) : int32
|
|
ensures { result =
|
|
if a - b < int32'minInt then a - b + width
|
|
else if a - b > int32'maxInt then a - b - width
|
|
else a - b }
|
|
|
|
predicate in_bounds (n: int32) = int32'minInt <= n <= int32'maxInt
|
|
|
|
(** purely applicative version first *)
|
|
|
|
let swap (a b: int32) : (x: int32, y: int32)
|
|
requires { in_bounds a /\ in_bounds b }
|
|
ensures { int32'int x = b /\ int32'int y = a }
|
|
=
|
|
let a = a + b in
|
|
let b = a - b in
|
|
let a = a - b in
|
|
a, b
|
|
|
|
(** then rephrased with mutable variables *)
|
|
|
|
let swap_ref (ref a b: int32) : unit
|
|
requires { in_bounds a /\ in_bounds b }
|
|
writes { a, b }
|
|
ensures { int32'int a = old b /\ int32'int b = old a }
|
|
=
|
|
a <- a + b;
|
|
b <- a - b;
|
|
a <- a - b
|
|
|
|
end
|
|
|
|
(** with bitwise XOR this time *)
|
|
|
|
module SwapInt32xor
|
|
|
|
use bv.BV32
|
|
use ref.Ref
|
|
|
|
let swap (ref a b: t) : unit
|
|
writes { a, b }
|
|
ensures { a = old b /\ b = old a }
|
|
= a <- bw_xor a b;
|
|
b <- bw_xor a b;
|
|
a <- bw_xor a b
|
|
|
|
end
|
|
|