1#[cfg(creusot)]
4use crate::resolve::structural_resolve;
5use crate::{logic::Mapping, prelude::*};
6use core::marker::PhantomData;
7
8#[opaque]
30#[builtin("set.Fset.fset")]
31pub struct FSet<T>(PhantomData<T>);
32
33impl<T> FSet<T> {
34 #[logic]
36 #[builtin("set.Fset.empty", ascription)]
37 pub fn empty() -> Self {
38 dead
39 }
40
41 #[logic(open, inline)]
43 pub fn contains(self, e: T) -> bool {
44 Self::mem(e, self)
45 }
46
47 #[doc(hidden)]
51 #[logic]
52 #[builtin("set.Fset.mem")]
53 pub fn mem(_: T, _: Self) -> bool {
54 dead
55 }
56
57 #[logic(open, inline)]
59 pub fn insert(self, e: T) -> Self {
60 Self::add(e, self)
61 }
62
63 #[doc(hidden)]
67 #[logic]
68 #[builtin("set.Fset.add")]
69 pub fn add(_: T, _: Self) -> Self {
70 dead
71 }
72
73 #[logic]
75 #[builtin("set.Fset.is_empty")]
76 pub fn is_empty(self) -> bool {
77 dead
78 }
79
80 #[logic(open, inline)]
82 pub fn remove(self, e: T) -> Self {
83 Self::rem(e, self)
84 }
85
86 #[doc(hidden)]
90 #[logic]
91 #[builtin("set.Fset.remove")]
92 pub fn rem(_: T, _: Self) -> Self {
93 dead
94 }
95
96 #[logic]
100 #[builtin("set.Fset.union")]
101 pub fn union(self, other: Self) -> Self {
102 let _ = other;
103 dead
104 }
105
106 #[logic]
110 #[builtin("set.Fset.inter")]
111 pub fn intersection(self, other: Self) -> Self {
112 let _ = other;
113 dead
114 }
115
116 #[logic]
120 #[builtin("set.Fset.diff")]
121 pub fn difference(self, other: Self) -> Self {
122 let _ = other;
123 dead
124 }
125
126 #[logic]
128 #[builtin("set.Fset.subset")]
129 pub fn is_subset(self, other: Self) -> bool {
130 let _ = other;
131 dead
132 }
133
134 #[logic(open, inline)]
136 pub fn is_superset(self, other: Self) -> bool {
137 Self::is_subset(other, self)
138 }
139
140 #[logic]
142 #[builtin("set.Fset.disjoint")]
143 pub fn disjoint(self, other: Self) -> bool {
144 let _ = other;
145 dead
146 }
147
148 #[logic]
150 #[builtin("set.Fset.cardinal")]
151 pub fn len(self) -> Int {
152 dead
153 }
154
155 #[logic]
162 #[builtin("set.Fset.pick")]
163 pub fn peek(self) -> T {
164 dead
165 }
166
167 #[logic(open)]
173 #[ensures(#[trigger(self == other)] result == (self == other))]
174 pub fn ext_eq(self, other: Self) -> bool {
175 pearlite! {
176 forall <e: T> self.contains(e) == other.contains(e)
177 }
178 }
179
180 #[logic(open)]
182 #[ensures(forall<y: T> result.contains(y) == (x == y))]
183 pub fn singleton(x: T) -> Self {
184 FSet::empty().insert(x)
185 }
186
187 #[logic(open)]
189 #[ensures(forall<y: U> result.contains(y) == exists<x: T> self.contains(x) && f.get(x).contains(y))]
190 #[variant(self.len())]
191 pub fn unions<U>(self, f: Mapping<T, FSet<U>>) -> FSet<U> {
192 if self.len() == 0 {
193 FSet::empty()
194 } else {
195 let x = self.peek();
196 f.get(x).union(self.remove(x).unions(f))
197 }
198 }
199
200 #[logic]
202 #[builtin("set.Fset.map")]
203 pub fn fmap<U>(_: Mapping<T, U>, _: Self) -> FSet<U> {
204 dead
205 }
206
207 #[logic(open)]
209 pub fn map<U>(self, f: Mapping<T, U>) -> FSet<U> {
210 FSet::fmap(f, self)
211 }
212
213 #[logic]
215 #[builtin("set.Fset.filter")]
216 pub fn filter(self, f: Mapping<T, bool>) -> Self {
217 let _ = f;
218 dead
219 }
220
221 #[logic(open)]
223 #[ensures(forall<xs: Seq<T>> result.contains(xs) == (0 < xs.len() && s.contains(xs[0]) && ss.contains(xs.tail())))]
224 pub fn cons(s: FSet<T>, ss: FSet<Seq<T>>) -> FSet<Seq<T>> {
225 proof_assert!(forall<x:T, xs: Seq<T>> xs.push_front(x).tail() == xs);
226 proof_assert!(forall<xs: Seq<T>> 0 < xs.len() ==> xs.tail().push_front(xs[0]) == xs);
227 s.unions(|x| ss.map(|xs: Seq<_>| xs.push_front(x)))
228 }
229
230 #[logic(open)]
232 #[ensures(forall<xs: Seq<T>> result.contains(xs) == (exists<ys: Seq<T>, zs: Seq<T>> s.contains(ys) && t.contains(zs) && xs == ys.concat(zs)))]
233 pub fn concat(s: FSet<Seq<T>>, t: FSet<Seq<T>>) -> FSet<Seq<T>> {
234 s.unions(|ys: Seq<_>| t.map(|zs| ys.concat(zs)))
235 }
236
237 #[logic(open)]
239 #[requires(n >= 0)]
240 #[ensures(forall<xs: Seq<T>> result.contains(xs) == (xs.len() == n && forall<x: T> xs.contains(x) ==> self.contains(x)))]
241 #[variant(n)]
242 pub fn replicate(self, n: Int) -> FSet<Seq<T>> {
243 pearlite! {
244 if n == 0 {
245 proof_assert! { forall<xs: Seq<T>> xs.len() == 0 ==> xs == Seq::empty() };
246 FSet::singleton(Seq::empty())
247 } else {
248 proof_assert! { forall<xs: Seq<T>, i> 0 < i && i < xs.len() ==> xs[i] == xs.tail()[i-1] };
249 FSet::cons(self, self.replicate(n - 1))
250 }
251 }
252 }
253
254 #[logic(open)]
256 #[requires(n >= 0)]
257 #[ensures(forall<xs: Seq<T>> result.contains(xs) == (xs.len() <= n && forall<x: T> xs.contains(x) ==> self.contains(x)))]
258 #[variant(n)]
259 pub fn replicate_up_to(self, n: Int) -> FSet<Seq<T>> {
260 pearlite! {
261 if n == 0 {
262 proof_assert! { forall<xs: Seq<T>> xs.len() == 0 ==> xs == Seq::empty() };
263 FSet::singleton(Seq::empty())
264 } else {
265 self.replicate_up_to(n - 1).union(self.replicate(n))
266 }
267 }
268 }
269
270 #[logic]
272 #[ensures(self.union(other).unions(f) == self.unions(f).union(other.unions(f)))]
273 #[ensures(self.unions(|x| f.get(x).union(g.get(x))) == self.unions(f).union(self.unions(g)))]
274 pub fn unions_union<U>(self, other: Self, f: Mapping<T, FSet<U>>, g: Mapping<T, FSet<U>>) {}
275
276 #[logic]
278 #[ensures(self.union(other).map(f) == self.map(f).union(other.map(f)))]
279 pub fn map_union<U>(self, other: Self, f: Mapping<T, U>) {}
280
281 #[logic]
283 #[ensures(FSet::concat(s1.union(s2), t) == FSet::concat(s1, t).union(FSet::concat(s2, t)))]
284 #[ensures(FSet::concat(t, s1.union(s2)) == FSet::concat(t, s1).union(FSet::concat(t, s2)))]
285 pub fn concat_union(s1: FSet<Seq<T>>, s2: FSet<Seq<T>>, t: FSet<Seq<T>>) {}
286
287 #[logic]
289 #[ensures(FSet::concat(FSet::cons(self, t), u) == FSet::cons(self, FSet::concat(t, u)))]
290 pub fn cons_concat(self, t: FSet<Seq<T>>, u: FSet<Seq<T>>) {
291 proof_assert!(forall<x: T, xs: Seq<T>, ys: Seq<T>> xs.push_front(x).concat(ys) == xs.concat(ys).push_front(x));
292 proof_assert!(forall<x: T, ys: Seq<T>> ys.push_front(x).tail() == ys);
293 proof_assert!(forall<ys: Seq<T>> 0 < ys.len() ==> ys == ys.tail().push_front(ys[0]));
294 proof_assert!(forall<xs> FSet::concat(FSet::cons(self, t), u).contains(xs) ==
295 FSet::cons(self, FSet::concat(t, u)).contains(xs));
296 }
297
298 #[logic]
300 #[requires(0 <= n && 0 <= m)]
301 #[ensures(self.replicate(n + m) == FSet::concat(self.replicate(n), self.replicate(m)))]
302 #[variant(n)]
303 pub fn concat_replicate(self, n: Int, m: Int) {
304 pearlite! {
305 if n == 0 {
306 Self::concat_empty(self.replicate(m));
307 } else {
308 self.cons_concat(self.replicate(n - 1), self.replicate(m));
309 self.concat_replicate(n - 1, m);
310 }
311 }
312 }
313
314 #[logic]
316 #[ensures(FSet::concat(FSet::singleton(Seq::empty()), s) == s)]
317 #[ensures(FSet::concat(s, FSet::singleton(Seq::empty())) == s)]
318 pub fn concat_empty(s: FSet<Seq<T>>) {
319 proof_assert!(forall<xs: Seq<T>> xs.concat(Seq::empty()) == xs);
320 proof_assert!(forall<xs: Seq<T>> Seq::empty().concat(xs) == xs);
321 }
322
323 #[logic]
325 #[requires(0 <= n && n < m)]
326 #[ensures(self.replicate_up_to(m) == self.replicate_up_to(n).union(
327 FSet::concat(self.replicate(n + 1), self.replicate_up_to(m - n - 1))))]
328 #[variant(m)]
329 pub fn concat_replicate_up_to(self, n: Int, m: Int) {
330 pearlite! {
331 if n + 1 == m {
332 Self::concat_empty(self.replicate(n + 1));
333 } else {
334 Self::concat_union(self.replicate(n), self.replicate(m - 1), self.replicate(m - n - 1));
335 self.concat_replicate(n, m - n - 1);
336 self.concat_replicate_up_to(n, m - 1);
337 }
338 }
339 }
340}
341
342impl FSet<Int> {
343 #[logic(open)]
345 #[builtin("set.FsetInt.interval")]
346 pub fn interval(i: Int, j: Int) -> FSet<Int> {
347 let _ = (i, j);
348 dead
349 }
350}
351
352impl<T> FSet<T> {
354 #[trusted]
356 #[check(ghost)]
357 #[ensures(result.is_empty())]
358 #[allow(unreachable_code)]
359 pub fn new() -> Ghost<Self> {
360 Ghost::conjure()
361 }
362
363 #[trusted]
383 #[check(ghost)]
384 #[ensures(result == self.len())]
385 pub fn len_ghost(&self) -> Int {
386 panic!()
387 }
388
389 #[trusted]
404 #[check(ghost)]
405 #[ensures(result == self.contains(*value))]
406 pub fn contains_ghost(&self, value: &T) -> bool {
407 let _ = value;
408 panic!()
409 }
410
411 #[trusted]
437 #[check(ghost)]
438 #[ensures(^self == (*self).insert(value))]
439 #[ensures(result == !(*self).contains(value))]
440 pub fn insert_ghost(&mut self, value: T) -> bool {
441 let _ = value;
442 panic!()
443 }
444
445 #[trusted]
460 #[check(ghost)]
461 #[ensures(^self == (*self).remove(*value))]
462 #[ensures(result == (*self).contains(*value))]
463 pub fn remove_ghost(&mut self, value: &T) -> bool {
464 let _ = value;
465 panic!()
466 }
467
468 #[trusted]
484 #[check(ghost)]
485 #[ensures(^self == Self::empty())]
486 pub fn clear_ghost(&mut self) {}
487}
488
489impl<T: Clone + Copy> Clone for FSet<T> {
490 #[trusted]
491 #[check(ghost)]
492 #[ensures(result == *self)]
493 fn clone(&self) -> Self {
494 *self
495 }
496}
497
498impl<T: Clone + Copy> Copy for FSet<T> {}
500
501impl<T> Invariant for FSet<T> {
502 #[logic(open, prophetic, inline)]
503 #[creusot::trusted_trivial_if_param_trivial]
504 fn invariant(self) -> bool {
505 pearlite! { forall<x: T> self.contains(x) ==> inv(x) }
506 }
507}
508impl<T> Resolve for FSet<T> {
509 #[logic(open, prophetic)]
510 #[creusot::trusted_trivial_if_param_trivial]
511 fn resolve(self) -> bool {
512 pearlite! { forall<x: T> self.contains(x) ==> resolve(x) }
513 }
514
515 #[trusted]
516 #[logic(open(self), prophetic)]
517 #[requires(structural_resolve(self))]
518 #[ensures(self.resolve())]
519 fn resolve_coherence(self) {}
520}