1#![feature(rustc_attrs)]
2#![allow(unused_imports)]
3
4use super::laws_eq::*;
5use super::prelude::*;
6use super::std_specs::cmp::{OrdSpec, PartialEqSpec, PartialOrdSpec};
7use core::cmp::Ordering;
8
9verus! {
10
11#[verifier::opaque]
12pub open spec fn obeys_partial_cmp_spec_properties<T: PartialOrd>() -> bool {
13 &&& forall|x: T, y: T| #[trigger]
14 x.partial_cmp_spec(&y) == Some(Ordering::Equal) <==> x.eq_spec(&y)
15 &&& forall|x: T, y: T| #[trigger]
16 x.partial_cmp_spec(&y) == Some(Ordering::Less) <==> y.partial_cmp_spec(&x) == Some(
17 Ordering::Greater,
18 )
19 &&& forall|x: T, y: T, z: T|
20 x.partial_cmp_spec(&y) == Some(Ordering::Less) && #[trigger] y.partial_cmp_spec(&z) == Some(
21 Ordering::Less,
22 ) ==> #[trigger] x.partial_cmp_spec(&z) == Some(Ordering::Less)
23 &&& forall|x: T, y: T, z: T|
24 x.partial_cmp_spec(&y) == Some(Ordering::Greater) && #[trigger] y.partial_cmp_spec(&z)
25 == Some(Ordering::Greater) ==> #[trigger] x.partial_cmp_spec(&z) == Some(
26 Ordering::Greater,
27 )
28 &&& obeys_eq_spec_properties::<T>()
29}
30
31#[verifier::opaque]
32pub open spec fn obeys_cmp_partial_ord<T: PartialOrd>() -> bool {
33 &&& T::obeys_eq_spec()
34 &&& T::obeys_partial_cmp_spec()
35 &&& forall|x: T, y: T| x.eq_spec(&y) <==> x.partial_cmp_spec(&y) == Some(Ordering::Equal)
36}
37
38#[verifier::opaque]
39pub open spec fn obeys_cmp_ord<T: Ord>() -> bool {
40 &&& T::obeys_cmp_spec()
41 &&& forall|x: T, y: T|
42 #![trigger x.partial_cmp_spec(&y)]
43 #![trigger x.cmp_spec(&y)]
44 x.partial_cmp_spec(&y) == Some(x.cmp_spec(&y))
45}
46
47pub open spec fn obeys_cmp<T: Ord>() -> bool {
48 &&& obeys_eq::<T>()
49 &&& obeys_cmp_partial_ord::<T>()
50 &&& obeys_cmp_ord::<T>()
51 &&& obeys_partial_cmp_spec_properties::<T>()
52}
53
54#[deprecated(note = "`laws_cmp::obeys_cmp_spec` has been renamed to `laws_cmp::obeys_cmp`")]
55#[verifier::inline]
56pub open spec fn obeys_cmp_spec<T: Ord>() -> bool {
57 obeys_cmp::<T>()
58}
59
60macro_rules! num_laws_cmp {
61 ($n: ty, $modname:ident) => {
62 verus! {
63 mod $modname {
64 use super::*;
65
66 pub broadcast proof fn lemma_obeys_cmp_spec()
67 ensures
68 #[trigger] obeys_cmp::<$n>(),
69 {
70 broadcast use group_laws_eq;
71 reveal(obeys_eq_spec_properties);
72 reveal(obeys_partial_cmp_spec_properties);
73 reveal(obeys_cmp_partial_ord);
74 reveal(obeys_cmp_ord);
75 assert(obeys_eq::<$n>());
76 }
77 }
78 }
79 }
80}
81
82num_laws_cmp!(u8, u8_laws);
83
84num_laws_cmp!(i8, i8_laws);
85
86num_laws_cmp!(u16, u16_laws);
87
88num_laws_cmp!(i16, i16_laws);
89
90num_laws_cmp!(u32, u32_laws);
91
92num_laws_cmp!(i32, i32_laws);
93
94num_laws_cmp!(u64, u64_laws);
95
96num_laws_cmp!(i64, i64_laws);
97
98num_laws_cmp!(u128, u128_laws);
99
100num_laws_cmp!(i128, i128_laws);
101
102num_laws_cmp!(usize, usize_laws);
103
104num_laws_cmp!(isize, isize_laws);
105
106macro_rules! tuple_cmp_impl {
107 ($modname:ident, $($T:ident )+) => {
108 verus! {
109 mod $modname {
110 use super::*;
111
112 pub broadcast proof fn lemma_obeys_cmp_spec<$($T,)+>()
113 where
114 $($T: Ord + PartialEq,)+
115 requires
116 $(obeys_cmp::<$T>(),)+
117 ensures
118 #[trigger] obeys_cmp::<($($T,)+)>(),
119 {
120 broadcast use group_laws_eq;
121 reveal(obeys_eq_spec_properties);
122 reveal(obeys_partial_cmp_spec_properties);
123 reveal(obeys_cmp_partial_ord);
124 reveal(obeys_cmp_ord);
125 assert(obeys_cmp::<($($T,)+)>());
126 }
127 }
128 }
129 }
130}
131
132tuple_cmp_impl!(tuple_1_laws, T);
133
134tuple_cmp_impl!(tuple_2_laws, U T);
135
136proof fn lemma_isomorphic_obeys_cmp<T: PartialEq + Ord, U: PartialEq + Ord>(f: spec_fn(U) -> T)
137 requires
138 obeys_cmp::<T>(),
139 obeys_eq::<U>(),
140 U::obeys_partial_cmp_spec(),
141 U::obeys_cmp_spec(),
142 forall|x: U, y: U| x.eq_spec(&y) == f(x).eq_spec(&f(y)),
143 forall|x: U, y: U| x.partial_cmp_spec(&y) == f(x).partial_cmp_spec(&f(y)),
144 forall|x: U, y: U| x.cmp_spec(&y) == f(x).cmp_spec(&f(y)),
145 ensures
146 obeys_cmp::<U>(),
147{
148 reveal(obeys_eq_spec_properties);
149 reveal(obeys_partial_cmp_spec_properties);
150 reveal(obeys_cmp_partial_ord);
151 reveal(obeys_cmp_ord);
152}
153
154proof fn lemma_obeys_cmp_obeys_traits<T: Ord>()
155 requires
156 obeys_cmp::<T>(),
157 ensures
158 T::obeys_eq_spec(),
159 T::obeys_partial_cmp_spec(),
160 T::obeys_cmp_spec(),
161{
162 reveal(obeys_cmp_partial_ord);
163 reveal(obeys_cmp_ord);
164}
165
166macro_rules! tuple_cmp_induct_impl {
167 ($modname:ident, $inductmod:ident, 0 $U:ident, $($idx:tt $T:ident, )+) => {
168 verus! {
169 mod $modname {
170 use super::*;
171
172 pub broadcast proof fn lemma_obeys_cmp_spec<$U, $($T,)+>()
173 where
174 $U: Ord + PartialEq,
175 $($T: Ord + PartialEq,)+
176 requires
177 obeys_cmp::<$U>(),
178 $(obeys_cmp::<$T>(),)+
179 ensures
180 #[trigger] obeys_cmp::<($U, $($T,)+)>(),
181 {
182 broadcast use super::tuple_2_laws::lemma_obeys_cmp_spec;
183 broadcast use super::$inductmod::lemma_obeys_cmp_spec;
184 broadcast use group_laws_eq;
185 lemma_obeys_cmp_obeys_traits::<$U>();
186 $(lemma_obeys_cmp_obeys_traits::<$T>();)+
187 lemma_isomorphic_obeys_cmp(|x: ($U, $($T,)+)| (x.0, ($(x.$idx,)+)));
188 assert(obeys_cmp::<($U, $($T,)+)>());
189 }
190 }
191 }
192 };
193}
194
195tuple_cmp_induct_impl!(tuple_3_laws, tuple_2_laws, 0 V, 1 U, 2 T,);
196
197tuple_cmp_induct_impl!(tuple_4_laws, tuple_3_laws, 0 X, 1 W, 2 V, 3 U, );
198
199tuple_cmp_induct_impl!(tuple_5_laws, tuple_4_laws, 0 X, 1 W, 2 V, 3 U, 4 T, );
200
201tuple_cmp_induct_impl!(tuple_6_laws, tuple_5_laws, 0 Y, 1 X, 2 W, 3 V, 4 U, 5 T, );
202
203tuple_cmp_induct_impl!(tuple_7_laws, tuple_6_laws, 0 Z, 1 Y, 2 X, 3 W, 4 V, 5 U, 6 T, );
204
205tuple_cmp_induct_impl!(tuple_8_laws, tuple_7_laws, 0 A, 1 Z, 2 Y, 3 X, 4 W, 5 V, 6 U, 7 T, );
206
207tuple_cmp_induct_impl!(tuple_9_laws, tuple_8_laws, 0 B, 1 A, 2 Z, 3 Y, 4 X, 5 W, 6 V, 7 U, 8 T, );
208
209tuple_cmp_induct_impl!(tuple_10_laws, tuple_9_laws, 0 C, 1 B, 2 A, 3 Z, 4 Y, 5 X, 6 W, 7 V, 8 U, 9 T, );
210
211tuple_cmp_induct_impl!(tuple_11_laws, tuple_10_laws, 0 D, 1 C, 2 B, 3 A, 4 Z, 5 Y, 6 X, 7 W, 8 V, 9 U, 10 T, );
212
213tuple_cmp_induct_impl!(tuple_12_laws, tuple_11_laws, 0 E, 1 D, 2 C, 3 B, 4 A, 5 Z, 6 Y, 7 X, 8 W, 9 V, 10 U, 11 T, );
214
215pub broadcast proof fn lemma_ref_obeys_cmp_spec<T: Ord>()
216 requires
217 obeys_cmp::<T>(),
218 ensures
219 #[trigger] obeys_cmp::<&T>(),
220{
221 broadcast use lemma_ref_obeys_eq_spec;
222
223 assert(obeys_eq::<&T>());
224
225 assert(obeys_cmp_partial_ord::<&T>() && obeys_cmp_ord::<&T>()) by {
226 reveal(obeys_cmp_partial_ord);
227 reveal(obeys_cmp_ord);
228 }
229
230 assert(obeys_partial_cmp_spec_properties::<&T>()) by {
231 reveal(obeys_cmp_partial_ord);
232 reveal(obeys_partial_cmp_spec_properties);
233 }
234}
235
236pub broadcast proof fn lemma_option_obeys_cmp_spec<T: Ord>()
237 requires
238 obeys_cmp::<T>(),
239 ensures
240 #[trigger] obeys_cmp::<Option<T>>(),
241{
242 broadcast use lemma_option_obeys_eq_spec;
243
244 assert(obeys_eq::<Option<T>>());
245
246 assert(obeys_cmp_partial_ord::<Option<T>>() && obeys_cmp_ord::<Option<T>>()) by {
247 reveal(obeys_cmp_partial_ord);
248 reveal(obeys_cmp_ord);
249 }
250
251 assert(obeys_partial_cmp_spec_properties::<Option<T>>()) by {
252 reveal(obeys_cmp_partial_ord);
253 reveal(obeys_partial_cmp_spec_properties);
254 }
255}
256
257pub broadcast group group_laws_cmp {
258 u8_laws::lemma_obeys_cmp_spec,
259 i8_laws::lemma_obeys_cmp_spec,
260 u16_laws::lemma_obeys_cmp_spec,
261 i16_laws::lemma_obeys_cmp_spec,
262 u32_laws::lemma_obeys_cmp_spec,
263 i32_laws::lemma_obeys_cmp_spec,
264 u64_laws::lemma_obeys_cmp_spec,
265 i64_laws::lemma_obeys_cmp_spec,
266 u128_laws::lemma_obeys_cmp_spec,
267 i128_laws::lemma_obeys_cmp_spec,
268 usize_laws::lemma_obeys_cmp_spec,
269 isize_laws::lemma_obeys_cmp_spec,
270 lemma_ref_obeys_cmp_spec,
271 lemma_option_obeys_cmp_spec,
272 tuple_1_laws::lemma_obeys_cmp_spec,
273 tuple_2_laws::lemma_obeys_cmp_spec,
274 tuple_3_laws::lemma_obeys_cmp_spec,
275 tuple_4_laws::lemma_obeys_cmp_spec,
276 tuple_5_laws::lemma_obeys_cmp_spec,
277 tuple_6_laws::lemma_obeys_cmp_spec,
278 tuple_7_laws::lemma_obeys_cmp_spec,
279 tuple_8_laws::lemma_obeys_cmp_spec,
280 tuple_9_laws::lemma_obeys_cmp_spec,
281 tuple_10_laws::lemma_obeys_cmp_spec,
282 tuple_11_laws::lemma_obeys_cmp_spec,
283 tuple_12_laws::lemma_obeys_cmp_spec,
284}
285
286}