creusot_contracts/
peano.rs1use crate::{
29 logic::ord::ord_laws_impl,
30 prelude::{Clone, Default, *},
31};
32use std::cmp::Ordering;
33
34#[derive(Clone, Copy, Default, Eq)]
38#[non_exhaustive]
39#[repr(transparent)]
40pub struct PeanoInt(pub u64);
41
42impl DeepModel for PeanoInt {
43 type DeepModelTy = u64;
44 #[logic(open, inline)]
45 fn deep_model(self) -> u64 {
46 self.0
47 }
48}
49
50impl OrdLogic for PeanoInt {
51 #[logic(open, inline)]
52 fn cmp_log(self, o: Self) -> Ordering {
53 self.0.cmp_log(o.0)
54 }
55 #[logic(open, inline)]
56 fn le_log(self, o: Self) -> bool {
57 self.0.le_log(o.0)
58 }
59 #[logic(open, inline)]
60 fn lt_log(self, o: Self) -> bool {
61 self.0.lt_log(o.0)
62 }
63 #[logic(open, inline)]
64 fn ge_log(self, o: Self) -> bool {
65 self.0.ge_log(o.0)
66 }
67 #[logic(open, inline)]
68 fn gt_log(self, o: Self) -> bool {
69 self.0.gt_log(o.0)
70 }
71 ord_laws_impl! {}
72}
73
74impl View for PeanoInt {
75 type ViewTy = u64;
76 #[logic(open, inline)]
77 fn view(self) -> u64 {
78 self.0
79 }
80}
81
82impl PartialOrd for PeanoInt {
83 #[check(ghost)]
84 #[ensures(result == Some((*self).cmp_log(*other)))]
85 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
86 Some(self.cmp(other))
87 }
88
89 #[check(ghost)]
93 #[ensures(result == (self@ < other@))]
94 fn lt(&self, other: &Self) -> bool {
95 matches!(self.partial_cmp(other), Some(Ordering::Less))
96 }
97 #[check(ghost)]
98 #[ensures(result == (self@ <= other@))]
99 fn le(&self, other: &Self) -> bool {
100 matches!(self.partial_cmp(other), Some(Ordering::Less | Ordering::Equal))
101 }
102 #[check(ghost)]
103 #[ensures(result == (self@ > other@))]
104 fn gt(&self, other: &Self) -> bool {
105 matches!(self.partial_cmp(other), Some(Ordering::Greater))
106 }
107 #[check(ghost)]
108 #[ensures(result == (self@ >= other@))]
109 fn ge(&self, other: &Self) -> bool {
110 matches!(self.partial_cmp(other), Some(Ordering::Greater | Ordering::Equal))
111 }
112}
113impl Ord for PeanoInt {
114 #[check(ghost)]
115 #[ensures(result == (*self).cmp_log(*other))]
116 fn cmp(&self, other: &Self) -> Ordering {
117 self.0.cmp(&other.0)
118 }
119}
120impl PartialEq for PeanoInt {
121 #[check(ghost)]
122 #[ensures(result == (*self == *other))]
123 fn eq(&self, other: &Self) -> bool {
124 self.0 == other.0
125 }
126}
127
128impl PeanoInt {
129 #[check(ghost)]
131 #[ensures(result.0 == 0u64)]
132 pub fn new() -> Self {
133 Self(0)
134 }
135
136 #[trusted]
151 #[check(terminates)]
152 #[ensures(result.0@ == self.0@ + 1)]
153 pub fn incr(self) -> Self {
154 let x = unsafe { std::ptr::read_volatile(&self.0) };
157 Self(x + 1)
158 }
159
160 #[check(ghost)]
162 #[ensures(result == self.0)]
163 pub fn to_u64(self) -> u64 {
164 self.0
165 }
166
167 #[check(ghost)]
169 #[trusted]
170 #[ensures(result@ == self.0@)]
171 pub fn to_i64(self) -> i64 {
172 self.0 as i64
173 }
174
175 #[check(ghost)]
177 #[ensures(result@ == self.0@)]
178 pub fn to_u128(self) -> u128 {
179 self.0 as u128
180 }
181
182 #[check(ghost)]
184 #[ensures(result@ == self.0@)]
185 pub fn to_i128(self) -> i128 {
186 self.0 as i128
187 }
188}
189
190impl From<PeanoInt> for u64 {
191 #[check(ghost)]
192 #[ensures(result == val.0)]
193 fn from(val: PeanoInt) -> Self {
194 val.to_u64()
195 }
196}
197
198impl From<PeanoInt> for i64 {
199 #[check(ghost)]
200 #[ensures(result@ == val.0@)]
201 fn from(val: PeanoInt) -> Self {
202 val.to_i64()
203 }
204}
205
206impl From<PeanoInt> for u128 {
207 #[check(ghost)]
208 #[ensures(result@ == val.0@)]
209 fn from(val: PeanoInt) -> Self {
210 val.to_u128()
211 }
212}
213
214impl From<PeanoInt> for i128 {
215 #[check(ghost)]
216 #[ensures(result@ == val.0@)]
217 fn from(val: PeanoInt) -> Self {
218 val.to_i128()
219 }
220}