2 (** Swapping two integers in-place *)
9 let swap (ref a b: int) : unit
11 ensures { a = old b /\ b = old a }
19 (** It also works fine with machine integers, even with overflows *)
26 (** a simple model of 32-bit integers with addition, subtraction,
27 and possible overflows *)
29 type int32 = < range -0x8000_0000 0x7fff_ffff >
31 meta coercion function int32'int
33 constant width : int = int32'maxInt - int32'minInt + 1
35 val (+) (a: int32) (b: int32) : int32
37 if a + b < int32'minInt then a + b + width
38 else if a + b > int32'maxInt then a + b - width
41 val (-) (a: int32) (b: int32) : int32
43 if a - b < int32'minInt then a - b + width
44 else if a - b > int32'maxInt then a - b - width
47 predicate in_bounds (n: int32) = int32'minInt <= n <= int32'maxInt
49 (** purely applicative version first *)
51 let swap (a b: int32) : (x: int32, y: int32)
52 requires { in_bounds a /\ in_bounds b }
53 ensures { int32'int x = b /\ int32'int y = a }
60 (** then rephrased with mutable variables *)
62 let swap_ref (ref a b: int32) : unit
63 requires { in_bounds a /\ in_bounds b }
65 ensures { int32'int a = old b /\ int32'int b = old a }
73 (** with bitwise XOR this time *)
80 let swap (ref a b: t) : unit
82 ensures { a = old b /\ b = old a }