creusot_std/logic/
real.rs1use crate::{
3 invariant::{InhabitedInvariant, Subset},
4 logic::ops::{AddLogic, DivLogic, MulLogic, NegLogic, SubLogic},
5 prelude::*,
6};
7#[cfg(all(creusot, feature = "num-rational"))]
8use num_rational::BigRational;
9
10#[builtin("real.Real.real")]
11pub struct Real;
12
13#[cfg(all(creusot, feature = "num-rational"))]
14impl DeepModel for BigRational {
15 type DeepModelTy = Real;
16
17 #[logic(opaque)]
18 fn deep_model(self) -> Self::DeepModelTy {
19 dead
20 }
21}
22
23impl Real {
24 #[logic]
25 #[builtin("real.FromInt.from_int")]
26 pub fn from_int(_: Int) -> Self {
27 dead
28 }
29}
30
31impl PartialOrdLogic for Real {
32 #[logic]
33 #[builtin("real.Real.(<)")]
34 fn lt_log(self, _: Self) -> bool {
35 dead
36 }
37
38 #[logic]
39 #[builtin("real.Real.(<=)")]
40 fn le_log(self, _: Self) -> bool {
41 dead
42 }
43
44 #[logic]
45 #[ensures(!(self < self))]
46 fn irreflexive(self) {}
47
48 #[logic]
49 #[requires(x < y)]
50 #[requires(y < z)]
51 #[ensures(x < z)]
52 fn transitive(x: Self, y: Self, z: Self) {}
53
54 #[logic]
55 #[ensures((self <= other) == (self < other || self == other))]
56 fn le_lt_log(self, other: Self) {}
57}
58
59impl OrdLogic for Real {
60 #[logic]
61 #[ensures(self < other || self == other || other < self)]
62 fn lt_log_total(self, other: Self) {}
63}
64
65impl AddLogic for Real {
66 type Output = Self;
67 #[logic]
68 #[builtin("real.Real.(+)")]
69 #[allow(unused_variables)]
70 fn add_logic(self, other: Self) -> Self {
71 dead
72 }
73}
74
75impl SubLogic for Real {
76 type Output = Self;
77 #[logic]
78 #[builtin("real.Real.(-)")]
79 #[allow(unused_variables)]
80 fn sub_logic(self, other: Self) -> Self {
81 dead
82 }
83}
84
85impl MulLogic for Real {
86 type Output = Self;
87 #[logic]
88 #[builtin("real.Real.(*)")]
89 #[allow(unused_variables)]
90 fn mul_logic(self, other: Self) -> Self {
91 dead
92 }
93}
94
95impl DivLogic for Real {
96 type Output = Self;
97 #[logic]
98 #[builtin("real.Real.(/)")]
99 #[allow(unused_variables)]
100 fn div_logic(self, other: Self) -> Self {
101 dead
102 }
103}
104
105impl NegLogic for Real {
106 type Output = Self;
107 #[logic]
108 #[builtin("real.Real.(-_)")]
109 fn neg_logic(self) -> Self {
110 dead
111 }
112}
113
114struct PositiveRealInner(Real);
115
116impl Invariant for PositiveRealInner {
117 #[logic]
118 fn invariant(self) -> bool {
119 self.0 > Real::from_int(0)
120 }
121}
122
123impl InhabitedInvariant for PositiveRealInner {
124 #[logic]
125 #[ensures(result.invariant())]
126 fn inhabits() -> Self {
127 Self(Real::from_int(1))
128 }
129}
130
131pub struct PositiveReal(Subset<PositiveRealInner>);
133
134impl PositiveReal {
135 #[logic]
136 #[ensures(result > Real::from_int(0))]
137 pub fn to_real(self) -> Real {
138 pearlite! { self.0.inner().0 }
139 }
140
141 #[logic]
142 #[requires(n > Real::from_int(0))]
143 #[ensures(result.to_real() == n)]
144 pub fn new(n: Real) -> PositiveReal {
145 PositiveReal(Subset::new_logic(PositiveRealInner(n)))
146 }
147
148 #[logic(open)]
149 #[ensures(#[trigger(self == other)] result == (self == other))]
150 pub fn ext_eq(self, other: Self) -> bool {
151 let _ = Subset::<PositiveRealInner>::inner_inj;
152 self.to_real() == other.to_real()
153 }
154
155 #[logic(open, inline)]
156 pub fn from_int(i: Int) -> Self {
157 Self::new(Real::from_int(i))
158 }
159}
160
161impl PartialOrdLogic for PositiveReal {
162 #[logic(open)]
163 fn le_log(self, o: Self) -> bool {
164 self.to_real() <= o.to_real()
165 }
166
167 #[logic(open)]
168 fn lt_log(self, o: Self) -> bool {
169 self.to_real() < o.to_real()
170 }
171
172 #[logic]
173 #[ensures(!(self < self))]
174 fn irreflexive(self) {}
175
176 #[logic]
177 #[requires(x < y)]
178 #[requires(y < z)]
179 #[ensures(x < z)]
180 fn transitive(x: Self, y: Self, z: Self) {}
181
182 #[logic(law)]
183 #[ensures((self <= other) == (self < other || self == other))]
184 fn le_lt_log(self, other: Self) {
185 let _ = PositiveReal::ext_eq;
186 }
187}
188
189impl OrdLogic for PositiveReal {
190 #[logic(law)]
191 #[ensures(self < other || self == other || other < self)]
192 fn lt_log_total(self, other: Self) {
193 let _ = PositiveReal::ext_eq;
194 }
195}
196
197impl AddLogic for PositiveReal {
198 type Output = Self;
199 #[logic]
200 #[ensures(result.to_real() == self.to_real() + other.to_real())]
201 fn add_logic(self, other: Self) -> Self {
202 Self::new(self.to_real() + other.to_real())
203 }
204}
205
206impl MulLogic for PositiveReal {
207 type Output = Self;
208 #[logic]
209 #[ensures(result.to_real() == self.to_real() * other.to_real())]
210 fn mul_logic(self, other: Self) -> Self {
211 Self::new(self.to_real() * other.to_real())
212 }
213}
214
215impl DivLogic for PositiveReal {
216 type Output = Self;
217 #[logic]
218 #[ensures(result.to_real() == self.to_real() / other.to_real())]
219 fn div_logic(self, other: Self) -> Self {
220 Self::new(self.to_real() / other.to_real())
221 }
222}