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_logic(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 add(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_logic(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().add(x)
185 }
186
187 #[logic(opaque)]
189 #[ensures(forall<y: U> #[trigger(result.contains(&y))]
190 result.contains(&y) == exists<x: T> self.contains(&x) && f.get(x).contains(&y))]
191 #[variant(self.len())]
192 pub fn unions<U>(self, f: Mapping<T, FSet<U>>) -> FSet<U> {
193 if self.len() == 0 {
194 FSet::empty()
195 } else {
196 let x = self.peek();
197 f.get(x).union(self.remove(x).unions(f))
198 }
199 }
200
201 #[logic]
203 #[builtin("set.Fset.map")]
204 pub fn fmap<U>(_: Mapping<T, U>, _: Self) -> FSet<U> {
205 dead
206 }
207
208 #[logic(open)]
210 pub fn map<U>(self, f: Mapping<T, U>) -> FSet<U> {
211 FSet::fmap(f, self)
212 }
213
214 #[logic]
216 #[builtin("set.Fset.filter")]
217 pub fn filter(self, f: Mapping<T, bool>) -> Self {
218 let _ = f;
219 dead
220 }
221
222 #[logic(open)]
224 #[ensures(forall<xs: Seq<T>> result.contains(&xs) == (0 < xs.len() && s.contains(&xs[0]) && ss.contains(&xs.tail())))]
225 pub fn cons(s: FSet<T>, ss: FSet<Seq<T>>) -> FSet<Seq<T>> {
226 proof_assert!(forall<x:T, xs: Seq<T>> xs.cons(x).tail() == xs);
227 proof_assert!(forall<xs: Seq<T>> 0 < xs.len() ==> xs.tail().cons(xs[0]) == xs);
228 s.unions(|x| ss.map(|xs: Seq<_>| xs.cons(x)))
229 }
230
231 #[logic(open)]
233 #[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)))]
234 pub fn concat(s: FSet<Seq<T>>, t: FSet<Seq<T>>) -> FSet<Seq<T>> {
235 s.unions(|ys: Seq<_>| t.map(|zs| ys.concat(zs)))
236 }
237
238 #[logic(open)]
240 #[requires(n >= 0)]
241 #[ensures(forall<xs: Seq<T>> result.contains(&xs) == (xs.len() == n && forall<x: T> xs.contains(x) ==> self.contains(&x)))]
242 #[variant(n)]
243 pub fn replicate(self, n: Int) -> FSet<Seq<T>> {
244 pearlite! {
245 if n == 0 {
246 proof_assert! { forall<xs: Seq<T>> xs.len() == 0 ==> xs == Seq::empty() };
247 FSet::singleton(Seq::empty())
248 } else {
249 proof_assert! { forall<xs: Seq<T>, i> 0 < i && i < xs.len() ==> xs[i] == xs.tail()[i-1] };
250 FSet::cons(self, self.replicate(n - 1))
251 }
252 }
253 }
254
255 #[logic(open)]
257 #[requires(n >= 0)]
258 #[ensures(forall<xs: Seq<T>> result.contains(&xs) == (xs.len() <= n && forall<x: T> xs.contains(x) ==> self.contains(&x)))]
259 #[variant(n)]
260 pub fn replicate_up_to(self, n: Int) -> FSet<Seq<T>> {
261 pearlite! {
262 if n == 0 {
263 proof_assert! { forall<xs: Seq<T>> xs.len() == 0 ==> xs == Seq::empty() };
264 FSet::singleton(Seq::empty())
265 } else {
266 self.replicate_up_to(n - 1).union(self.replicate(n))
267 }
268 }
269 }
270
271 #[logic]
273 #[ensures(self.union(other).unions(f) == self.unions(f).union(other.unions(f)))]
274 #[ensures(self.unions(|x| f.get(x).union(g.get(x))) == self.unions(f).union(self.unions(g)))]
275 pub fn unions_union<U>(self, other: Self, f: Mapping<T, FSet<U>>, g: Mapping<T, FSet<U>>) {}
276
277 #[logic]
279 #[ensures(self.union(other).map(f) == self.map(f).union(other.map(f)))]
280 pub fn map_union<U>(self, other: Self, f: Mapping<T, U>) {}
281
282 #[logic]
284 #[ensures(FSet::concat(s1.union(s2), t) == FSet::concat(s1, t).union(FSet::concat(s2, t)))]
285 #[ensures(FSet::concat(t, s1.union(s2)) == FSet::concat(t, s1).union(FSet::concat(t, s2)))]
286 pub fn concat_union(s1: FSet<Seq<T>>, s2: FSet<Seq<T>>, t: FSet<Seq<T>>) {}
287
288 #[logic]
290 #[ensures(FSet::concat(FSet::cons(self, t), u) == FSet::cons(self, FSet::concat(t, u)))]
291 pub fn cons_concat(self, t: FSet<Seq<T>>, u: FSet<Seq<T>>) {
292 proof_assert!(forall<x: T, xs: Seq<T>, ys: Seq<T>> xs.cons(x).concat(ys) == xs.concat(ys).cons(x));
293 proof_assert!(forall<x: T, ys: Seq<T>> ys.cons(x).tail() == ys);
294 proof_assert!(forall<ys: Seq<T>> 0 < ys.len() ==> ys == ys.tail().cons(ys[0]));
295 proof_assert!(forall<xs> FSet::concat(FSet::cons(self, t), u).contains(xs) ==
296 FSet::cons(self, FSet::concat(t, u)).contains(xs));
297 }
298
299 #[logic]
301 #[requires(0 <= n && 0 <= m)]
302 #[ensures(self.replicate(n + m) == FSet::concat(self.replicate(n), self.replicate(m)))]
303 #[variant(n)]
304 pub fn concat_replicate(self, n: Int, m: Int) {
305 pearlite! {
306 if n == 0 {
307 Self::concat_empty(self.replicate(m));
308 } else {
309 self.cons_concat(self.replicate(n - 1), self.replicate(m));
310 self.concat_replicate(n - 1, m);
311 }
312 }
313 }
314
315 #[logic]
317 #[ensures(FSet::concat(FSet::singleton(Seq::empty()), s) == s)]
318 #[ensures(FSet::concat(s, FSet::singleton(Seq::empty())) == s)]
319 pub fn concat_empty(s: FSet<Seq<T>>) {
320 proof_assert!(forall<xs: Seq<T>> xs.concat(Seq::empty()) == xs);
321 proof_assert!(forall<xs: Seq<T>> Seq::empty().concat(xs) == xs);
322 }
323
324 #[logic]
326 #[requires(0 <= n && n < m)]
327 #[ensures(self.replicate_up_to(m) == self.replicate_up_to(n).union(
328 FSet::concat(self.replicate(n + 1), self.replicate_up_to(m - n - 1))))]
329 #[variant(m)]
330 pub fn concat_replicate_up_to(self, n: Int, m: Int) {
331 pearlite! {
332 if n + 1 == m {
333 Self::concat_empty(self.replicate(n + 1));
334 } else {
335 Self::concat_union(self.replicate(n), self.replicate(m - 1), self.replicate(m - n - 1));
336 self.concat_replicate(n, m - n - 1);
337 self.concat_replicate_up_to(n, m - 1);
338 }
339 }
340 }
341}
342
343impl FSet<Int> {
344 #[logic(open)]
346 #[builtin("set.FsetInt.interval")]
347 pub fn interval(i: Int, j: Int) -> FSet<Int> {
348 let _ = (i, j);
349 dead
350 }
351}
352
353impl<T> FSet<T> {
355 #[trusted]
357 #[check(ghost)]
358 #[ensures(result.is_empty())]
359 #[allow(unreachable_code)]
360 pub fn new() -> Ghost<Self> {
361 Ghost::conjure()
362 }
363
364 #[trusted]
384 #[check(ghost)]
385 #[logic_alias(self.len_logic())]
386 pub fn len(&self) -> Int {
387 panic!()
388 }
389
390 #[trusted]
405 #[check(ghost)]
406 #[logic_alias(self.contains_logic(*value))]
408 pub fn contains(&self, value: &T) -> bool {
409 let _ = value;
410 panic!()
411 }
412
413 #[trusted]
439 #[check(ghost)]
440 #[ensures(^self == (*self).add(value))]
441 #[ensures(result == !(*self).contains(&value))]
442 pub fn insert(&mut self, value: T) -> bool {
443 let _ = value;
444 panic!()
445 }
446
447 #[trusted]
462 #[check(ghost)]
463 #[ensures(^self == (*self).remove(*value))]
464 #[ensures(result == (*self).contains(value))]
465 pub fn delete(&mut self, value: &T) -> bool {
466 let _ = value;
467 panic!()
468 }
469
470 #[trusted]
486 #[check(ghost)]
487 #[ensures(^self == Self::empty())]
488 pub fn clear(&mut self) {}
489}
490
491impl<T: Clone + Copy> Clone for FSet<T> {
492 #[trusted]
493 #[check(ghost)]
494 #[ensures(result == *self)]
495 fn clone(&self) -> Self {
496 *self
497 }
498}
499
500impl<T: Clone + Copy> Copy for FSet<T> {}
502
503impl<T> Invariant for FSet<T> {
504 #[logic(open, prophetic, inline)]
505 #[creusot::trusted_trivial_if_param_trivial]
506 fn invariant(self) -> bool {
507 pearlite! { forall<x: T> self.contains(&x) ==> inv(x) }
508 }
509}
510impl<T> Resolve for FSet<T> {
511 #[logic(open, prophetic)]
512 #[creusot::trusted_trivial_if_param_trivial]
513 fn resolve(self) -> bool {
514 pearlite! { forall<x: T> self.contains(&x) ==> resolve(x) }
515 }
516
517 #[trusted]
518 #[logic(open(self), prophetic)]
519 #[requires(structural_resolve(self))]
520 #[ensures(self.resolve())]
521 fn resolve_coherence(self) {}
522}