1use crate::prelude::*;
2use core::marker::PhantomData;
3
4#[cfg(creusot)]
5use core::cmp::Ordering;
6
7#[cfg(creusot)]
12#[trusted]
13pub auto trait Objective {}
14
15pub(crate) struct NotObjective {}
23
24#[cfg(creusot)]
25#[trusted]
26impl !Objective for NotObjective {}
27
28pub type Timestamp = Int;
29
30pub trait HasTimestamp {
31 #[logic]
32 fn get_timestamp(self, view: SyncView) -> Timestamp;
33
34 #[logic(law)]
35 #[requires(x.le_log(y))]
36 #[ensures(self.get_timestamp(x).le_log(self.get_timestamp(y)))]
37 fn get_timestamp_monotonic(self, x: SyncView, y: SyncView);
38}
39
40#[opaque]
42#[derive(Copy)]
43pub struct SyncView(());
44
45impl Clone for SyncView {
46 #[ensures(result == *self)]
47 fn clone(&self) -> Self {
48 *self
49 }
50}
51
52impl SyncView {
53 #[check(ghost)]
54 #[trusted]
55 pub fn new() -> Ghost<Self> {
56 panic!("Should not be called outside ghost code")
57 }
58}
59
60impl OrdLogic for SyncView {
61 #[logic(opaque)]
62 fn cmp_log(self, _: Self) -> Ordering {
63 dead
64 }
65
66 #[logic(law)]
67 #[ensures(x.le_log(y) == (x.cmp_log(y) != Ordering::Greater))]
68 #[trusted]
69 fn cmp_le_log(x: Self, y: Self) {}
70
71 #[logic(law)]
72 #[ensures(x.lt_log(y) == (x.cmp_log(y) == Ordering::Less))]
73 #[trusted]
74 fn cmp_lt_log(x: Self, y: Self) {}
75
76 #[logic(law)]
77 #[ensures(x.ge_log(y) == (x.cmp_log(y) != Ordering::Less))]
78 #[trusted]
79 fn cmp_ge_log(x: Self, y: Self) {}
80
81 #[logic(law)]
82 #[ensures(x.gt_log(y) == (x.cmp_log(y) == Ordering::Greater))]
83 #[trusted]
84 fn cmp_gt_log(x: Self, y: Self) {}
85
86 #[logic(law)]
87 #[ensures(x.cmp_log(x) == Ordering::Equal)]
88 #[trusted]
89 fn refl(x: Self) {}
90
91 #[logic(law)]
92 #[requires(x.cmp_log(y) == o)]
93 #[requires(y.cmp_log(z) == o)]
94 #[ensures(x.cmp_log(z) == o)]
95 #[trusted]
96 fn trans(x: Self, y: Self, z: Self, o: Ordering) {}
97
98 #[logic(law)]
99 #[requires(x.cmp_log(y) == Ordering::Less)]
100 #[ensures(y.cmp_log(x) == Ordering::Greater)]
101 #[trusted]
102 fn antisym1(x: Self, y: Self) {}
103
104 #[logic(law)]
105 #[requires(x.cmp_log(y) == Ordering::Greater)]
106 #[ensures(y.cmp_log(x) == Ordering::Less)]
107 #[trusted]
108 fn antisym2(x: Self, y: Self) {}
109
110 #[logic(law)]
111 #[ensures((x == y) == (x.cmp_log(y) == Ordering::Equal))]
112 #[trusted]
113 fn eq_cmp(x: Self, y: Self) {}
114}
115
116pub struct AtView<T>(PhantomData<T>);
118
119#[cfg(creusot)]
120#[trusted]
121impl<T> Objective for AtView<T> {}
122
123impl<T> AtView<T> {
124 #[logic(opaque)]
125 pub fn view_logic(&self) -> SyncView {
126 dead
127 }
128
129 #[logic(opaque)]
130 pub fn val(&self) -> T {
131 dead
132 }
133
134 #[check(ghost)]
135 #[trusted]
136 #[ensures(result.0 == result.1.view_logic() && result.1.val() == *val)]
137 #[allow(unused_variables)]
138 pub fn new(val: Ghost<T>) -> Ghost<(SyncView, Self)> {
139 Ghost::conjure()
140 }
141
142 #[check(ghost)]
143 #[trusted]
144 #[requires(self.view_logic().le_log(v))]
145 #[ensures(result == self.val())]
146 #[allow(unused_variables)]
147 pub fn into_inner(self, v: SyncView) -> T {
148 panic!("Should not be called outside ghost code")
149 }
150
151 #[check(ghost)]
152 #[trusted]
153 #[ensures(result == self.view_logic())]
154 pub fn view(&self) -> SyncView {
155 panic!("Should not be called outside ghost code")
156 }
157}