forked from sarsko/CreuSAT
-
Notifications
You must be signed in to change notification settings - Fork 0
/
prelude.mlw
255 lines (205 loc) · 5.88 KB
/
prelude.mlw
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
(* Why3 Logical Types *)
module Mapping
let function from_fn (f : 'a -> 'b) : ('a -> 'b) = f
end
module Seq
use export seq.Seq
function to_owned (a : 'a) : 'a = a
end
module Int
use export mach.int.Int
end
(* Rust primitive types *)
module Opaque
type opaque_ptr
type dyn
type foreign
end
module Bool
let eqb (a : bool) (b : bool) : bool =
ensures { result <-> a = b }
match a, b with
| True, True -> True
| False, False -> True
| _ -> False
end
let neqb (a : bool) (b : bool) : bool =
ensures { result <-> a <> b }
not (eqb a b)
let to_int (b : bool) : int =
if b then 1 else 0
use int.Int
let of_int (i : int) : bool =
i = 1
end
module Borrow
type borrowed 'a = { current : 'a; final : 'a; id : int }
let function ( *_ ) x = x.current
let function ( ^_ ) x = x.final
let function get_id (x : borrowed 'a) = x.id
let function borrow_logic (cur fin : 'a) (id : int) = { current = cur; final = fin; id = id; }
val borrow_mut (a : 'a) : borrowed 'a
ensures { *result = a }
val function inherit_id (old_id inherit_path: int) : int
val borrow_final (a: 'a) (id: int) : borrowed 'a
ensures { *result = a }
ensures { result.id = id }
end
module Real
end
(* Signed Integer *)
module IntSize
use export mach.int.Int64
type isize = int64
end
module Int8
use int.Int
type int8 = < range -0x80 0x7f >
let constant min_int8 : int = - 0x80
let constant max_int8 : int = 0x7f
function to_int (x : int8) : int = int8'int x
clone export mach.int.Bounded_int with
type t = int8,
constant min = int8'minInt,
constant max = int8'maxInt,
function to_int = int8'int,
lemma to_int_in_bounds,
lemma extensionality
end
module Int16
use int.Int
type int16 = < range -0x8000 0x7fff >
let constant min_int16 : int = - 0x8000
let constant max_int16 : int = 0x7fff
function to_int (x : int16) : int = int16'int x
clone export mach.int.Bounded_int with
type t = int16,
constant min = int16'minInt,
constant max = int16'maxInt,
function to_int = int16'int,
lemma to_int_in_bounds,
lemma extensionality
end
module Int32
use export mach.int.Int32
end
module Int64
use export mach.int.Int64
end
module Int128
use int.Int
type int128 = < range -0x80000000000000000000000000000000 0x7fffffffffffffffffffffffffffffff >
let constant min_int128 : int = - 0x80000000000000000000000000000000
let constant max_int128 : int = 0x7fffffffffffffffffffffffffffffff
function to_int (x : int128) : int = int128'int x
clone export mach.int.Bounded_int with
type t = int128,
constant min = int128'minInt,
constant max = int128'maxInt,
function to_int = int128'int,
lemma to_int_in_bounds,
lemma extensionality
end
(* Unsigned Integers *)
module UIntSize
use export mach.int.UInt64
type usize = uint64
end
module UInt8
use int.Int
type uint8 = < range 0x0 0xff >
let constant min_uint8 : int = 0x00
let constant max_uint8 : int = 0xff
function to_int (x : uint8) : int = uint8'int x
clone export mach.int.Bounded_int with
type t = uint8,
constant min = uint8'minInt,
constant max = uint8'maxInt,
function to_int = uint8'int,
lemma to_int_in_bounds,
lemma extensionality
end
module UInt16
use int.Int
type uint16 = < range 0x0 0xffff >
let constant min_uint16 : int = 0x00
let constant max_uint16 : int = 0xffff
function to_int (x : uint16) : int = uint16'int x
clone export mach.int.Bounded_int with
type t = uint16,
constant min = uint16'minInt,
constant max = uint16'maxInt,
function to_int = uint16'int,
lemma to_int_in_bounds,
lemma extensionality
end
module UInt32
use export mach.int.UInt32
end
module UInt64
use export mach.int.UInt64
end
module UInt128
use int.Int
type uint128 = < range 0x0 0xffffffffffffffffffffffffffffffff >
let constant min_uint128 : int = 0x00000000000000000000000000000000
let constant max_uint128 : int = 0xffffffffffffffffffffffffffffffff
function to_int (x : uint128) : int = uint128'int x
clone export mach.int.Bounded_int with
type t = uint128,
constant min = uint128'minInt,
constant max = uint128'maxInt,
function to_int = uint128'int,
lemma to_int_in_bounds,
lemma extensionality
end
(* Floats *)
module Float32
use export ieee_float.Float32
end
module Float64
use export ieee_float.Float64
end
module Char
(* utf8 characters (not glyphs)
highly restricted until Why3 supports Unicode strings
*)
use int.Int
type char
function code char : int
axiom code: forall c. 0 <= code c < 0x10FFFF
val function chr (n: int) : char
axiom code_chr: forall n. 0 <= n < 0x10FFFF -> code (chr n) = n
axiom chr_code: forall c. chr (code c) = c
end
module Snapshot
type snap_ty 't
val function new (Snapshot x : 't) : snap_ty 't
val function inner (x : snap_ty 't) : 't
axiom new_spec: forall x: 't [new x]. inner (new x) = x
axiom inner_spec: forall x: snap_ty 't [inner x]. new (inner x) = x
end
module Slice
use seq.Seq
use UIntSize
use int.Int
type slice 'a =
{ elts : seq 'a }
invariant { Seq.length elts <= max_uint64 }
axiom slice_ext :
forall x y: slice 'a. x.elts = y.elts -> x = y
type array 'a = slice 'a
let create (len : uint64) (f : int -> 'a) : slice 'a =
{ elts = Seq.create (to_int len) f}
let function length (s : slice 'a) : uint64 = of_int (Seq.length s.elts)
let function get (s : slice 'a) (ix : uint64) : 'a =
requires { ix < Seq.length s.elts }
Seq.get s.elts (to_int ix)
let set (s : slice 'a) (ix : uint64) (v : 'a) : slice 'a =
requires { 0 <= ix < Seq.length s.elts }
ensures { Seq.length result.elts = Seq.length s.elts }
ensures { result.elts[ix] = v }
ensures { forall j. 0 <= j < Seq.length s.elts /\ j <> ix -> result.elts[j] = s.elts[j] }
{ elts = Seq.set s.elts (to_int ix) v }
function id (s : slice 'a) : seq 'a = s.elts
end