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(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 }
295
296 #[logic]
298 #[requires(0 <= n && 0 <= m)]
299 #[ensures(self.replicate(n + m) == FSet::concat(self.replicate(n), self.replicate(m)))]
300 #[variant(n)]
301 pub fn concat_replicate(self, n: Int, m: Int) {
302 pearlite! {
303 if n == 0 {
304 Self::concat_empty(self.replicate(m));
305 } else {
306 self.cons_concat(self.replicate(n - 1), self.replicate(m));
307 self.concat_replicate(n - 1, m);
308 }
309 }
310 }
311
312 #[logic]
314 #[ensures(FSet::concat(FSet::singleton(Seq::empty()), s) == s)]
315 #[ensures(FSet::concat(s, FSet::singleton(Seq::empty())) == s)]
316 pub fn concat_empty(s: FSet<Seq<T>>) {
317 proof_assert!(forall<xs: Seq<T>> xs.concat(Seq::empty()) == xs);
318 proof_assert!(forall<xs: Seq<T>> Seq::empty().concat(xs) == xs);
319 }
320
321 #[logic]
323 #[requires(0 <= n && n < m)]
324 #[ensures(self.replicate_up_to(m) == self.replicate_up_to(n).union(
325 FSet::concat(self.replicate(n + 1), self.replicate_up_to(m - n - 1))))]
326 #[variant(m)]
327 pub fn concat_replicate_up_to(self, n: Int, m: Int) {
328 pearlite! {
329 if n + 1 == m {
330 Self::concat_empty(self.replicate(n + 1));
331 } else {
332 Self::concat_union(self.replicate(n), self.replicate(m - 1), self.replicate(m - n - 1));
333 self.concat_replicate(n, m - n - 1);
334 self.concat_replicate_up_to(n, m - 1);
335 }
336 }
337 }
338}
339
340impl FSet<Int> {
341 #[logic(open)]
343 #[builtin("set.FsetInt.interval")]
344 pub fn interval(i: Int, j: Int) -> FSet<Int> {
345 let _ = (i, j);
346 dead
347 }
348}
349
350impl<T> FSet<T> {
352 #[trusted]
354 #[check(ghost)]
355 #[ensures(result.is_empty())]
356 #[allow(unreachable_code)]
357 pub fn new() -> Ghost<Self> {
358 Ghost::conjure()
359 }
360
361 #[trusted]
381 #[check(ghost)]
382 #[ensures(result == self.len())]
383 pub fn len_ghost(&self) -> Int {
384 panic!()
385 }
386
387 #[trusted]
402 #[check(ghost)]
403 #[ensures(result == self.contains(*value))]
404 pub fn contains_ghost(&self, value: &T) -> bool {
405 let _ = value;
406 panic!()
407 }
408
409 #[trusted]
435 #[check(ghost)]
436 #[ensures(^self == (*self).insert(value))]
437 #[ensures(result == !(*self).contains(value))]
438 pub fn insert_ghost(&mut self, value: T) -> bool {
439 let _ = value;
440 panic!()
441 }
442
443 #[trusted]
458 #[check(ghost)]
459 #[ensures(^self == (*self).remove(*value))]
460 #[ensures(result == (*self).contains(*value))]
461 pub fn remove_ghost(&mut self, value: &T) -> bool {
462 let _ = value;
463 panic!()
464 }
465
466 #[trusted]
482 #[check(ghost)]
483 #[ensures(^self == Self::empty())]
484 pub fn clear_ghost(&mut self) {}
485}
486
487impl<T: Clone + Copy> Clone for FSet<T> {
488 #[trusted]
489 #[check(ghost)]
490 #[ensures(result == *self)]
491 fn clone(&self) -> Self {
492 *self
493 }
494}
495
496impl<T: Clone + Copy> Copy for FSet<T> {}
498
499impl<T> Invariant for FSet<T> {
500 #[logic(open, prophetic, inline)]
501 #[creusot::trusted_trivial_if_param_trivial]
502 fn invariant(self) -> bool {
503 pearlite! { forall<x: T> self.contains(x) ==> inv(x) }
504 }
505}
506impl<T> Resolve for FSet<T> {
507 #[logic(open, prophetic)]
508 #[creusot::trusted_trivial_if_param_trivial]
509 fn resolve(self) -> bool {
510 pearlite! { forall<x: T> self.contains(x) ==> resolve(x) }
511 }
512
513 #[trusted]
514 #[logic(open(self), prophetic)]
515 #[requires(structural_resolve(self))]
516 #[ensures(self.resolve())]
517 fn resolve_coherence(self) {}
518}