1use crate::{
2 ghost::Plain,
3 invariant::{InhabitedInvariant, Subset},
4 logic::ops::{AddLogic, DivLogic, MulLogic, NegLogic, RemLogic, SubLogic},
5 prelude::*,
6};
7use core::ops::{Add, Div, Mul, Neg, Rem, Sub};
8
9#[intrinsic("int")]
27#[builtin("int")]
28pub struct Int;
29
30impl Clone for Int {
31 #[check(ghost)]
32 #[ensures(result == *self)]
33 fn clone(&self) -> Self {
34 *self
35 }
36}
37impl Copy for Int {}
38impl Plain for Int {
39 #[trusted]
40 #[ensures(*result == *snap)]
41 #[check(ghost)]
42 #[allow(unused_variables)]
43 fn into_ghost(snap: Snapshot<Self>) -> Ghost<Self> {
44 Ghost::conjure()
45 }
46}
47
48impl Int {
50 #[logic]
59 #[builtin("int.Power.power")]
60 #[allow(unused_variables)]
61 pub fn pow(self, p: Int) -> Int {
62 dead
63 }
64
65 #[logic]
74 #[builtin("bv.Pow2int.pow2")]
75 #[allow(unused_variables)]
76 pub fn pow2(self) -> Int {
77 dead
78 }
79
80 #[logic]
89 #[builtin("int.MinMax.max")]
90 #[allow(unused_variables)]
91 pub fn max(self, x: Int) -> Int {
92 dead
93 }
94
95 #[logic]
104 #[builtin("int.MinMax.min")]
105 #[allow(unused_variables)]
106 pub fn min(self, x: Int) -> Int {
107 dead
108 }
109
110 #[logic]
119 #[builtin("int.EuclideanDivision.div")]
120 #[allow(unused_variables)]
121 pub fn div_euclid(self, d: Int) -> Int {
122 dead
123 }
124
125 #[logic]
134 #[builtin("int.EuclideanDivision.mod")]
135 #[allow(unused_variables)]
136 pub fn rem_euclid(self, d: Int) -> Int {
137 dead
138 }
139
140 #[logic(open)]
151 pub fn abs_diff(self, other: Int) -> Int {
152 if self < other { other - self } else { self - other }
153 }
154}
155
156impl AddLogic for Int {
157 type Output = Self;
158 #[logic]
159 #[builtin("int.Int.(+)")]
160 #[allow(unused_variables)]
161 fn add(self, other: Self) -> Self {
162 dead
163 }
164}
165
166impl SubLogic for Int {
167 type Output = Self;
168 #[logic]
169 #[builtin("int.Int.(-)")]
170 #[allow(unused_variables)]
171 fn sub(self, other: Self) -> Self {
172 dead
173 }
174}
175
176impl MulLogic for Int {
177 type Output = Self;
178 #[logic]
179 #[builtin("int.Int.(*)")]
180 #[allow(unused_variables)]
181 fn mul(self, other: Self) -> Self {
182 dead
183 }
184}
185
186impl DivLogic for Int {
187 type Output = Self;
188 #[logic]
189 #[builtin("int.ComputerDivision.div")]
190 #[allow(unused_variables)]
191 fn div(self, other: Self) -> Self {
192 dead
193 }
194}
195
196impl RemLogic for Int {
197 type Output = Self;
198 #[logic]
199 #[builtin("int.ComputerDivision.mod")]
200 #[allow(unused_variables)]
201 fn rem(self, other: Self) -> Self {
202 dead
203 }
204}
205
206impl NegLogic for Int {
207 type Output = Self;
208 #[logic]
209 #[builtin("int.Int.(-_)")]
210 fn neg(self) -> Self {
211 dead
212 }
213}
214
215impl Int {
219 #[trusted]
234 #[check(ghost)]
235 #[ensures(*result == value@)]
236 #[allow(unreachable_code)]
237 #[allow(unused_variables)]
238 pub fn new(value: i128) -> Ghost<Self> {
239 Ghost::conjure()
240 }
241
242 #[trusted]
243 #[check(ghost)]
244 #[ensures(^self == *self + 1)]
245 pub fn incr_ghost(&mut self) {}
246
247 #[trusted]
248 #[check(ghost)]
249 #[ensures(^self == *self - 1)]
250 pub fn decr_ghost(&mut self) {}
251}
252
253impl PartialEq for Int {
254 #[trusted]
255 #[check(ghost)]
256 #[ensures(result == (*self == *other))]
257 #[allow(unused_variables)]
258 fn eq(&self, other: &Self) -> bool {
259 panic!()
260 }
261}
262
263impl PartialOrd for Int {
264 #[trusted]
265 #[check(ghost)]
266 #[ensures(result == Some((*self).cmp_log(*other)))]
267 #[allow(unused_variables)]
268 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
269 panic!()
270 }
271
272 #[trusted]
273 #[check(ghost)]
274 #[ensures(result == (*self).lt_log(*other))]
275 #[allow(unused_variables)]
276 fn lt(&self, other: &Self) -> bool {
277 panic!()
278 }
279
280 #[trusted]
281 #[check(ghost)]
282 #[ensures(result == (*self).le_log(*other))]
283 #[allow(unused_variables)]
284 fn le(&self, other: &Self) -> bool {
285 panic!()
286 }
287
288 #[trusted]
289 #[check(ghost)]
290 #[ensures(result == (*self).gt_log(*other))]
291 #[allow(unused_variables)]
292 fn gt(&self, other: &Self) -> bool {
293 panic!()
294 }
295
296 #[trusted]
297 #[check(ghost)]
298 #[ensures(result == (*self).ge_log(*other))]
299 #[allow(unused_variables)]
300 fn ge(&self, other: &Self) -> bool {
301 panic!()
302 }
303}
304
305impl Add for Int {
306 type Output = Int;
307 #[trusted]
308 #[check(ghost)]
309 #[ensures(result == self + other)]
310 #[allow(unused_variables)]
311 fn add(self, other: Int) -> Self {
312 panic!()
313 }
314}
315
316impl Sub for Int {
317 type Output = Int;
318 #[trusted]
319 #[check(ghost)]
320 #[ensures(result == self - other)]
321 #[allow(unused_variables)]
322 fn sub(self, other: Int) -> Self {
323 panic!()
324 }
325}
326
327impl Mul for Int {
328 type Output = Int;
329 #[trusted]
330 #[check(ghost)]
331 #[ensures(result == self * other)]
332 #[allow(unused_variables)]
333 fn mul(self, other: Int) -> Self {
334 panic!()
335 }
336}
337
338impl Div for Int {
339 type Output = Int;
340 #[trusted]
341 #[check(ghost)]
342 #[ensures(result == self / other)]
343 #[allow(unused_variables)]
344 fn div(self, other: Int) -> Self {
345 panic!()
346 }
347}
348
349impl Rem for Int {
350 type Output = Int;
351 #[trusted]
352 #[check(ghost)]
353 #[ensures(result == self % other)]
354 #[allow(unused_variables)]
355 fn rem(self, other: Int) -> Self {
356 panic!()
357 }
358}
359
360impl Neg for Int {
361 type Output = Int;
362 #[trusted]
363 #[check(ghost)]
364 #[ensures(result == -self)]
365 fn neg(self) -> Self {
366 panic!()
367 }
368}
369
370struct NatInner(Int);
371
372impl Invariant for NatInner {
373 #[logic]
374 fn invariant(self) -> bool {
375 self.0 >= 0
376 }
377}
378
379impl InhabitedInvariant for NatInner {
380 #[logic]
381 #[ensures(result.invariant())]
382 fn inhabits() -> Self {
383 Self(0)
384 }
385}
386
387pub struct Nat(Subset<NatInner>);
389
390impl Nat {
391 #[logic]
392 #[ensures(result >= 0)]
393 pub fn to_int(self) -> Int {
394 pearlite! { self.0.inner().0 }
395 }
396
397 #[logic]
398 #[requires(n >= 0)]
399 #[ensures(result.to_int() == n)]
400 pub fn new(n: Int) -> Nat {
401 Nat(Subset::new_logic(NatInner(n)))
402 }
403
404 #[logic(open)]
405 #[ensures(result == (self == other))]
406 pub fn ext_eq(self, other: Self) -> bool {
407 let _ = Subset::<NatInner>::inner_inj;
408 self.to_int() == other.to_int()
409 }
410}
411
412impl AddLogic for Nat {
413 type Output = Self;
414 #[logic]
415 #[ensures(result.to_int() == self.to_int() + other.to_int())]
416 fn add(self, other: Self) -> Self {
417 Self::new(self.to_int() + other.to_int())
418 }
419}
420
421impl MulLogic for Nat {
422 type Output = Self;
423 #[logic]
424 #[ensures(result.to_int() == self.to_int() * other.to_int())]
425 fn mul(self, other: Self) -> Self {
426 Self::new(self.to_int() * other.to_int())
427 }
428}