1#[cfg(feature = "alloc")]
3use super::{BmpString, Ia5StringOwned, PrintableStringOwned, TeletexStringOwned, Utf8StringOwned};
4use super::{
5 BmpStringSpec, Ia5String, Ia5StringSpec, Integer, PrintableString, PrintableStringSpec,
6 TeletexString, TeletexStringSpec,
7};
8use crate::core::exec::fns::Pred;
9use crate::core::spec::SpecPred;
10#[cfg(feature = "alloc")]
11use alloc::vec::Vec;
12use vstd::prelude::*;
13use vstd::string::StringSliceAdditionalSpecFns;
14
15verus! {
16
17#[derive(Clone, Copy)]
23pub struct Size<const HAS_MIN: bool, const MIN: usize, const HAS_MAX: bool, const MAX: usize>;
24
25#[derive(Clone, Copy)]
32pub struct IntegerRange<const HAS_MIN: bool, const MIN: i64, const HAS_MAX: bool, const MAX: i64>;
33
34pub open spec fn integer_in_range<
35 const HAS_MIN: bool,
36 const MIN: i64,
37 const HAS_MAX: bool,
38 const MAX: i64,
39>(value: int) -> bool {
40 &&& (HAS_MIN ==> MIN as int <= value)
41 &&& (HAS_MAX ==> value <= MAX as int)
42}
43
44fn integer_in_range_exec<const HAS_MIN: bool, const MIN: i64, const HAS_MAX: bool, const MAX: i64>(
45 value: i64,
46) -> (ok: bool)
47 ensures
48 ok == integer_in_range::<HAS_MIN, MIN, HAS_MAX, MAX>(value as int),
49{
50 (!HAS_MIN || MIN <= value) && (!HAS_MAX || value <= MAX)
51}
52
53impl<const HAS_MIN: bool, const MIN: i64, const HAS_MAX: bool, const MAX: i64> SpecPred<
54 int,
55> for IntegerRange<HAS_MIN, MIN, HAS_MAX, MAX> {
56 open spec fn apply(&self, value: int) -> bool {
57 integer_in_range::<HAS_MIN, MIN, HAS_MAX, MAX>(value)
58 }
59}
60
61impl<const HAS_MIN: bool, const MIN: i64, const HAS_MAX: bool, const MAX: i64> SpecPred<
62 i8,
63> for IntegerRange<HAS_MIN, MIN, HAS_MAX, MAX> {
64 open spec fn apply(&self, value: i8) -> bool {
65 integer_in_range::<HAS_MIN, MIN, HAS_MAX, MAX>(value as int)
66 }
67}
68
69impl<const HAS_MIN: bool, const MIN: i64, const HAS_MAX: bool, const MAX: i64> Pred<
70 i8,
71> for IntegerRange<HAS_MIN, MIN, HAS_MAX, MAX> {
72 fn test(&self, value: &i8) -> (ok: bool) {
73 integer_in_range_exec::<HAS_MIN, MIN, HAS_MAX, MAX>(*value as i64)
74 }
75}
76
77impl<const HAS_MIN: bool, const MIN: i64, const HAS_MAX: bool, const MAX: i64> SpecPred<
78 i16,
79> for IntegerRange<HAS_MIN, MIN, HAS_MAX, MAX> {
80 open spec fn apply(&self, value: i16) -> bool {
81 integer_in_range::<HAS_MIN, MIN, HAS_MAX, MAX>(value as int)
82 }
83}
84
85impl<const HAS_MIN: bool, const MIN: i64, const HAS_MAX: bool, const MAX: i64> Pred<
86 i16,
87> for IntegerRange<HAS_MIN, MIN, HAS_MAX, MAX> {
88 fn test(&self, value: &i16) -> (ok: bool) {
89 integer_in_range_exec::<HAS_MIN, MIN, HAS_MAX, MAX>(*value as i64)
90 }
91}
92
93impl<'a, const HAS_MIN: bool, const MIN: i64, const HAS_MAX: bool, const MAX: i64> Pred<
94 Integer<'a>,
95> for IntegerRange<HAS_MIN, MIN, HAS_MAX, MAX> {
96 fn test(&self, value: &Integer<'a>) -> (ok: bool) {
97 value.in_i64_range::<HAS_MIN, MIN, HAS_MAX, MAX>()
98 }
99}
100
101pub open spec fn size_in_range<
102 const HAS_MIN: bool,
103 const MIN: usize,
104 const HAS_MAX: bool,
105 const MAX: usize,
106>(len: nat) -> bool {
107 &&& (HAS_MIN ==> MIN as nat <= len)
108 &&& (HAS_MAX ==> len <= MAX as nat)
109}
110
111fn size_in_range_exec<const HAS_MIN: bool, const MIN: usize, const HAS_MAX: bool, const MAX: usize>(
112 len: usize,
113) -> (ok: bool)
114 ensures
115 ok == size_in_range::<HAS_MIN, MIN, HAS_MAX, MAX>(len as nat),
116{
117 (!HAS_MIN || MIN <= len) && (!HAS_MAX || len <= MAX)
118}
119
120impl<T, const HAS_MIN: bool, const MIN: usize, const HAS_MAX: bool, const MAX: usize> SpecPred<
121 Seq<T>,
122> for Size<HAS_MIN, MIN, HAS_MAX, MAX> {
123 open spec fn apply(&self, value: Seq<T>) -> bool {
124 size_in_range::<HAS_MIN, MIN, HAS_MAX, MAX>(value.len())
125 }
126}
127
128impl<
129 'a,
130 T: DeepView,
131 const HAS_MIN: bool,
132 const MIN: usize,
133 const HAS_MAX: bool,
134 const MAX: usize,
135> Pred<&'a [T]> for Size<HAS_MIN, MIN, HAS_MAX, MAX> {
136 fn test(&self, value: &&'a [T]) -> (ok: bool) {
137 size_in_range_exec::<HAS_MIN, MIN, HAS_MAX, MAX>(value.len())
138 }
139}
140
141#[cfg(feature = "alloc")]
142impl<
143 T: DeepView,
144 const HAS_MIN: bool,
145 const MIN: usize,
146 const HAS_MAX: bool,
147 const MAX: usize,
148> Pred<Vec<T>> for Size<HAS_MIN, MIN, HAS_MAX, MAX> {
149 fn test(&self, value: &Vec<T>) -> (ok: bool) {
150 size_in_range_exec::<HAS_MIN, MIN, HAS_MAX, MAX>(value.len())
151 }
152}
153
154impl<'a, const HAS_MIN: bool, const MIN: usize, const HAS_MAX: bool, const MAX: usize> Pred<
155 &'a str,
156> for Size<HAS_MIN, MIN, HAS_MAX, MAX> {
157 fn test(&self, value: &&'a str) -> (ok: bool) {
158 size_in_range_exec::<HAS_MIN, MIN, HAS_MAX, MAX>(value.unicode_len())
159 }
160}
161
162#[cfg(feature = "alloc")]
163impl<const HAS_MIN: bool, const MIN: usize, const HAS_MAX: bool, const MAX: usize> Pred<
164 Utf8StringOwned,
165> for Size<HAS_MIN, MIN, HAS_MAX, MAX> {
166 fn test(&self, value: &Utf8StringOwned) -> (ok: bool) {
167 size_in_range_exec::<HAS_MIN, MIN, HAS_MAX, MAX>(value.as_str().unicode_len())
168 }
169}
170
171impl<const HAS_MIN: bool, const MIN: usize, const HAS_MAX: bool, const MAX: usize> SpecPred<
172 PrintableStringSpec,
173> for Size<HAS_MIN, MIN, HAS_MAX, MAX> {
174 open spec fn apply(&self, value: PrintableStringSpec) -> bool {
175 size_in_range::<HAS_MIN, MIN, HAS_MAX, MAX>(value.inner.len())
176 }
177}
178
179impl<'a, const HAS_MIN: bool, const MIN: usize, const HAS_MAX: bool, const MAX: usize> Pred<
180 PrintableString<'a>,
181> for Size<HAS_MIN, MIN, HAS_MAX, MAX> {
182 fn test(&self, value: &PrintableString<'a>) -> (ok: bool) {
183 size_in_range_exec::<HAS_MIN, MIN, HAS_MAX, MAX>(value.inner().unicode_len())
184 }
185}
186
187#[cfg(feature = "alloc")]
188impl<const HAS_MIN: bool, const MIN: usize, const HAS_MAX: bool, const MAX: usize> Pred<
189 PrintableStringOwned,
190> for Size<HAS_MIN, MIN, HAS_MAX, MAX> {
191 fn test(&self, value: &PrintableStringOwned) -> (ok: bool) {
192 size_in_range_exec::<HAS_MIN, MIN, HAS_MAX, MAX>(value.inner().unicode_len())
193 }
194}
195
196impl<const HAS_MIN: bool, const MIN: usize, const HAS_MAX: bool, const MAX: usize> SpecPred<
197 Ia5StringSpec,
198> for Size<HAS_MIN, MIN, HAS_MAX, MAX> {
199 open spec fn apply(&self, value: Ia5StringSpec) -> bool {
200 size_in_range::<HAS_MIN, MIN, HAS_MAX, MAX>(value.inner.len())
201 }
202}
203
204impl<'a, const HAS_MIN: bool, const MIN: usize, const HAS_MAX: bool, const MAX: usize> Pred<
205 Ia5String<'a>,
206> for Size<HAS_MIN, MIN, HAS_MAX, MAX> {
207 fn test(&self, value: &Ia5String<'a>) -> (ok: bool) {
208 size_in_range_exec::<HAS_MIN, MIN, HAS_MAX, MAX>(value.inner().unicode_len())
209 }
210}
211
212#[cfg(feature = "alloc")]
213impl<const HAS_MIN: bool, const MIN: usize, const HAS_MAX: bool, const MAX: usize> Pred<
214 Ia5StringOwned,
215> for Size<HAS_MIN, MIN, HAS_MAX, MAX> {
216 fn test(&self, value: &Ia5StringOwned) -> (ok: bool) {
217 size_in_range_exec::<HAS_MIN, MIN, HAS_MAX, MAX>(value.inner().unicode_len())
218 }
219}
220
221impl<const HAS_MIN: bool, const MIN: usize, const HAS_MAX: bool, const MAX: usize> SpecPred<
222 TeletexStringSpec,
223> for Size<HAS_MIN, MIN, HAS_MAX, MAX> {
224 open spec fn apply(&self, value: TeletexStringSpec) -> bool {
225 size_in_range::<HAS_MIN, MIN, HAS_MAX, MAX>(value.inner.len())
226 }
227}
228
229impl<'a, const HAS_MIN: bool, const MIN: usize, const HAS_MAX: bool, const MAX: usize> Pred<
230 TeletexString<'a>,
231> for Size<HAS_MIN, MIN, HAS_MAX, MAX> {
232 fn test(&self, value: &TeletexString<'a>) -> (ok: bool) {
233 size_in_range_exec::<HAS_MIN, MIN, HAS_MAX, MAX>(value.inner().unicode_len())
234 }
235}
236
237#[cfg(feature = "alloc")]
238impl<const HAS_MIN: bool, const MIN: usize, const HAS_MAX: bool, const MAX: usize> Pred<
239 TeletexStringOwned,
240> for Size<HAS_MIN, MIN, HAS_MAX, MAX> {
241 fn test(&self, value: &TeletexStringOwned) -> (ok: bool) {
242 size_in_range_exec::<HAS_MIN, MIN, HAS_MAX, MAX>(value.inner().unicode_len())
243 }
244}
245
246impl<const HAS_MIN: bool, const MIN: usize, const HAS_MAX: bool, const MAX: usize> SpecPred<
247 BmpStringSpec,
248> for Size<HAS_MIN, MIN, HAS_MAX, MAX> {
249 open spec fn apply(&self, value: BmpStringSpec) -> bool {
250 size_in_range::<HAS_MIN, MIN, HAS_MAX, MAX>(value.inner.len())
251 }
252}
253
254#[cfg(feature = "alloc")]
255impl<const HAS_MIN: bool, const MIN: usize, const HAS_MAX: bool, const MAX: usize> Pred<
256 BmpString,
257> for Size<HAS_MIN, MIN, HAS_MAX, MAX> {
258 fn test(&self, value: &BmpString) -> (ok: bool) {
259 size_in_range_exec::<HAS_MIN, MIN, HAS_MAX, MAX>(value.inner().unicode_len())
260 }
261}
262
263#[derive(Copy)]
265pub struct ConstraintOr<L, R>(pub L, pub R);
266
267impl<L: Clone, R: Clone> Clone for ConstraintOr<L, R> {
268 fn clone(&self) -> (cloned: Self)
269 ensures
270 call_ensures(L::clone, (&self.0,), cloned.0),
271 call_ensures(R::clone, (&self.1,), cloned.1),
272 {
273 ConstraintOr(self.0.clone(), self.1.clone())
274 }
275}
276
277impl<T, L: SpecPred<T>, R: SpecPred<T>> SpecPred<T> for ConstraintOr<L, R> {
278 open spec fn apply(&self, value: T) -> bool {
279 self.0.apply(value) || self.1.apply(value)
280 }
281}
282
283impl<T: DeepView, L: Pred<T>, R: Pred<T>> Pred<T> for ConstraintOr<L, R> {
284 fn test(&self, value: &T) -> (ok: bool) {
285 self.0.test(value) || self.1.test(value)
286 }
287}
288
289#[derive(Copy)]
291pub struct ConstraintAnd<L, R>(pub L, pub R);
292
293impl<L: Clone, R: Clone> Clone for ConstraintAnd<L, R> {
294 fn clone(&self) -> (cloned: Self)
295 ensures
296 call_ensures(L::clone, (&self.0,), cloned.0),
297 call_ensures(R::clone, (&self.1,), cloned.1),
298 {
299 ConstraintAnd(self.0.clone(), self.1.clone())
300 }
301}
302
303impl<T, L: SpecPred<T>, R: SpecPred<T>> SpecPred<T> for ConstraintAnd<L, R> {
304 open spec fn apply(&self, value: T) -> bool {
305 self.0.apply(value) && self.1.apply(value)
306 }
307}
308
309impl<T: DeepView, L: Pred<T>, R: Pred<T>> Pred<T> for ConstraintAnd<L, R> {
310 fn test(&self, value: &T) -> (ok: bool) {
311 self.0.test(value) && self.1.test(value)
312 }
313}
314
315#[derive(Copy)]
317pub struct ConstraintNot<P>(pub P);
318
319impl<P: Clone> Clone for ConstraintNot<P> {
320 fn clone(&self) -> (cloned: Self)
321 ensures
322 call_ensures(P::clone, (&self.0,), cloned.0),
323 {
324 ConstraintNot(self.0.clone())
325 }
326}
327
328impl<T, P: SpecPred<T>> SpecPred<T> for ConstraintNot<P> {
329 open spec fn apply(&self, value: T) -> bool {
330 !self.0.apply(value)
331 }
332}
333
334impl<T: DeepView, P: Pred<T>> Pred<T> for ConstraintNot<P> {
335 fn test(&self, value: &T) -> (ok: bool) {
336 !self.0.test(value)
337 }
338}
339
340}