1#[cfg(creusot)]
2use crate::resolve::structural_resolve;
3use crate::{logic::Mapping, prelude::*};
4use std::marker::PhantomData;
5
6#[opaque]
28#[builtin("set.Fset.fset")]
29pub struct FSet<T>(PhantomData<T>);
30
31impl<T> FSet<T> {
32 #[logic]
34 #[builtin("set.Fset.empty", ascription)]
35 pub fn empty() -> Self {
36 dead
37 }
38
39 #[logic(open, inline)]
41 pub fn contains(self, e: T) -> bool {
42 Self::mem(e, self)
43 }
44
45 #[doc(hidden)]
49 #[logic]
50 #[builtin("set.Fset.mem")]
51 pub fn mem(_: T, _: Self) -> bool {
52 dead
53 }
54
55 #[logic(open, inline)]
57 pub fn insert(self, e: T) -> Self {
58 Self::add(e, self)
59 }
60
61 #[doc(hidden)]
65 #[logic]
66 #[builtin("set.Fset.add")]
67 pub fn add(_: T, _: Self) -> Self {
68 dead
69 }
70
71 #[logic]
73 #[builtin("set.Fset.is_empty")]
74 pub fn is_empty(self) -> bool {
75 dead
76 }
77
78 #[logic(open, inline)]
80 pub fn remove(self, e: T) -> Self {
81 Self::rem(e, self)
82 }
83
84 #[doc(hidden)]
88 #[logic]
89 #[builtin("set.Fset.remove")]
90 pub fn rem(_: T, _: Self) -> Self {
91 dead
92 }
93
94 #[logic]
98 #[builtin("set.Fset.union")]
99 pub fn union(self, other: Self) -> Self {
100 let _ = other;
101 dead
102 }
103
104 #[logic]
108 #[builtin("set.Fset.inter")]
109 pub fn intersection(self, other: Self) -> Self {
110 let _ = other;
111 dead
112 }
113
114 #[logic]
118 #[builtin("set.Fset.diff")]
119 pub fn difference(self, other: Self) -> Self {
120 let _ = other;
121 dead
122 }
123
124 #[logic]
126 #[builtin("set.Fset.subset")]
127 pub fn is_subset(self, other: Self) -> bool {
128 let _ = other;
129 dead
130 }
131
132 #[logic(open, inline)]
134 pub fn is_superset(self, other: Self) -> bool {
135 Self::is_subset(other, self)
136 }
137
138 #[logic]
140 #[builtin("set.Fset.disjoint")]
141 pub fn disjoint(self, other: Self) -> bool {
142 let _ = other;
143 dead
144 }
145
146 #[logic]
148 #[builtin("set.Fset.cardinal")]
149 pub fn len(self) -> Int {
150 dead
151 }
152
153 #[logic]
160 #[builtin("set.Fset.pick")]
161 pub fn peek(self) -> T {
162 dead
163 }
164
165 #[logic(open)]
171 #[ensures(result == (self == other))]
172 pub fn ext_eq(self, other: Self) -> bool {
173 pearlite! {
174 forall <e: T> self.contains(e) == other.contains(e)
175 }
176 }
177
178 #[logic(open)]
180 #[ensures(forall<y: T> result.contains(y) == (x == y))]
181 pub fn singleton(x: T) -> Self {
182 FSet::empty().insert(x)
183 }
184
185 #[logic(open)]
187 #[ensures(forall<y: U> result.contains(y) == exists<x: T> self.contains(x) && f.get(x).contains(y))]
188 #[variant(self.len())]
189 pub fn unions<U>(self, f: Mapping<T, FSet<U>>) -> FSet<U> {
190 if self.len() == 0 {
191 FSet::empty()
192 } else {
193 let x = self.peek();
194 f.get(x).union(self.remove(x).unions(f))
195 }
196 }
197
198 #[logic]
200 #[builtin("set.Fset.map")]
201 pub fn fmap<U>(_: Mapping<T, U>, _: Self) -> FSet<U> {
202 dead
203 }
204
205 #[logic(open)]
207 pub fn map<U>(self, f: Mapping<T, U>) -> FSet<U> {
208 FSet::fmap(f, self)
209 }
210
211 #[logic]
213 #[builtin("set.Fset.filter")]
214 pub fn filter(self, f: Mapping<T, bool>) -> Self {
215 let _ = f;
216 dead
217 }
218
219 #[logic(open)]
221 #[ensures(forall<xs: Seq<T>> result.contains(xs) == (0 < xs.len() && s.contains(xs[0]) && ss.contains(xs.tail())))]
222 pub fn cons(s: FSet<T>, ss: FSet<Seq<T>>) -> FSet<Seq<T>> {
223 proof_assert!(forall<x:T, xs: Seq<T>> xs.push_front(x).tail() == xs);
224 proof_assert!(forall<xs: Seq<T>> 0 < xs.len() ==> xs.tail().push_front(xs[0]) == xs);
225 s.unions(|x| ss.map(|xs: Seq<_>| xs.push_front(x)))
226 }
227
228 #[logic(open)]
230 #[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)))]
231 pub fn concat(s: FSet<Seq<T>>, t: FSet<Seq<T>>) -> FSet<Seq<T>> {
232 s.unions(|ys: Seq<_>| t.map(|zs| ys.concat(zs)))
233 }
234
235 #[logic(open)]
237 #[requires(n >= 0)]
238 #[ensures(forall<xs: Seq<T>> result.contains(xs) == (xs.len() == n && forall<x: T> xs.contains(x) ==> self.contains(x)))]
239 #[variant(n)]
240 pub fn replicate(self, n: Int) -> FSet<Seq<T>> {
241 pearlite! {
242 if n == 0 {
243 proof_assert! { forall<xs: Seq<T>> xs.len() == 0 ==> xs == Seq::empty() };
244 FSet::singleton(Seq::empty())
245 } else {
246 proof_assert! { forall<xs: Seq<T>, i> 0 < i && i < xs.len() ==> xs[i] == xs.tail()[i-1] };
247 FSet::cons(self, self.replicate(n - 1))
248 }
249 }
250 }
251
252 #[logic(open)]
254 #[requires(n >= 0)]
255 #[ensures(forall<xs: Seq<T>> result.contains(xs) == (xs.len() <= n && forall<x: T> xs.contains(x) ==> self.contains(x)))]
256 #[variant(n)]
257 pub fn replicate_up_to(self, n: Int) -> FSet<Seq<T>> {
258 pearlite! {
259 if n == 0 {
260 proof_assert! { forall<xs: Seq<T>> xs.len() == 0 ==> xs == Seq::empty() };
261 FSet::singleton(Seq::empty())
262 } else {
263 self.replicate_up_to(n - 1).union(self.replicate(n))
264 }
265 }
266 }
267}
268
269impl FSet<Int> {
270 #[logic(open)]
272 #[builtin("set.FsetInt.interval")]
273 pub fn interval(i: Int, j: Int) -> FSet<Int> {
274 let _ = (i, j);
275 dead
276 }
277}
278
279impl<T> FSet<T> {
281 #[trusted]
283 #[check(ghost)]
284 #[ensures(result.is_empty())]
285 #[allow(unreachable_code)]
286 pub fn new() -> Ghost<Self> {
287 Ghost::conjure()
288 }
289
290 #[trusted]
310 #[check(ghost)]
311 #[ensures(result == self.len())]
312 pub fn len_ghost(&self) -> Int {
313 panic!()
314 }
315
316 #[trusted]
331 #[check(ghost)]
332 #[ensures(result == self.contains(*value))]
333 pub fn contains_ghost(&self, value: &T) -> bool {
334 let _ = value;
335 panic!()
336 }
337
338 #[trusted]
364 #[check(ghost)]
365 #[ensures(^self == (*self).insert(value))]
366 #[ensures(result == !(*self).contains(value))]
367 pub fn insert_ghost(&mut self, value: T) -> bool {
368 let _ = value;
369 panic!()
370 }
371
372 #[trusted]
374 #[check(ghost)]
375 #[ensures(^self == (*self).insert(*value))]
376 #[ensures(result == !(*self).contains(*value))]
377 pub fn insert_ghost_unsized(&mut self, value: Box<T>) -> bool {
378 let _ = value;
379 panic!()
380 }
381
382 #[trusted]
397 #[check(ghost)]
398 #[ensures(^self == (*self).remove(*value))]
399 #[ensures(result == (*self).contains(*value))]
400 pub fn remove_ghost(&mut self, value: &T) -> bool {
401 let _ = value;
402 panic!()
403 }
404
405 #[trusted]
421 #[check(ghost)]
422 #[ensures(^self == Self::empty())]
423 pub fn clear_ghost(&mut self) {}
424}
425
426impl<T: Clone + Copy> Clone for FSet<T> {
427 #[trusted]
428 #[check(ghost)]
429 #[ensures(result == *self)]
430 fn clone(&self) -> Self {
431 *self
432 }
433}
434
435impl<T: Clone + Copy> Copy for FSet<T> {}
437
438impl<T> Invariant for FSet<T> {
439 #[logic(open, prophetic, inline)]
440 #[creusot::trusted_trivial_if_param_trivial]
441 fn invariant(self) -> bool {
442 pearlite! { forall<x: T> self.contains(x) ==> inv(x) }
443 }
444}
445impl<T> Resolve for FSet<T> {
446 #[logic(open, prophetic)]
447 #[creusot::trusted_trivial_if_param_trivial]
448 fn resolve(self) -> bool {
449 pearlite! { forall<x: T> self.contains(x) ==> resolve(x) }
450 }
451
452 #[trusted]
453 #[logic(open(self), prophetic)]
454 #[requires(structural_resolve(self))]
455 #[ensures(self.resolve())]
456 fn resolve_coherence(self) {}
457}
458
459#[logic(open)]
464#[ensures(forall<s1: FSet<T>, s2: FSet<T>, f: Mapping<T, FSet<U>>> s1.union(s2).unions(f) == s1.unions(f).union(s2.unions(f)))]
465#[ensures(forall<s: FSet<T>, f: Mapping<T, FSet<U>>, g: Mapping<T, FSet<U>>>
466 s.unions(|x| f.get(x).union(g.get(x))) == s.unions(f).union(s.unions(g)))]
467pub fn unions_union<T, U>() {}
468
469#[logic(open)]
471#[ensures(forall<s: FSet<T>, t: FSet<T>, f: Mapping<T, U>> s.union(t).map(f) == s.map(f).union(t.map(f)))]
472pub fn map_union<T, U>() {}
473
474#[logic(open)]
476#[ensures(forall<s1: FSet<Seq<T>>, s2: FSet<Seq<T>>, t: FSet<Seq<T>>>
477 FSet::concat(s1.union(s2), t) == FSet::concat(s1, t).union(FSet::concat(s2, t)))]
478#[ensures(forall<s: FSet<Seq<T>>, t1: FSet<Seq<T>>, t2: FSet<Seq<T>>>
479 FSet::concat(s, t1.union(t2)) == FSet::concat(s, t1).union(FSet::concat(s, t2)))]
480pub fn concat_union<T>() {}
481
482#[logic(open)]
484#[ensures(forall<s: FSet<T>, t: FSet<Seq<T>>, u: FSet<Seq<T>>> FSet::concat(FSet::cons(s, t), u) == FSet::cons(s, FSet::concat(t, u)))]
485pub fn cons_concat<T>() {
486 proof_assert! { forall<x: T, xs: Seq<T>, ys: Seq<T>> xs.push_front(x).concat(ys) == xs.concat(ys).push_front(x) };
487 proof_assert! { forall<x: T, ys: Seq<T>> ys.push_front(x).tail() == ys };
488 proof_assert! { forall<ys: Seq<T>> 0 < ys.len() ==> ys == ys.tail().push_front(ys[0]) };
489}
490
491#[logic(open)]
493#[requires(0 <= n && 0 <= m)]
494#[ensures(s.replicate(n + m) == FSet::concat(s.replicate(n), s.replicate(m)))]
495#[variant(n)]
496pub fn concat_replicate<T>(n: Int, m: Int, s: FSet<T>) {
497 pearlite! {
498 if n == 0 {
499 concat_empty(s.replicate(m));
500 } else {
501 cons_concat::<T>();
502 concat_replicate(n - 1, m, s);
503 }
504 }
505}
506
507#[logic(open)]
509#[ensures(FSet::concat(FSet::singleton(Seq::empty()), s) == s)]
510#[ensures(FSet::concat(s, FSet::singleton(Seq::empty())) == s)]
511pub fn concat_empty<T>(s: FSet<Seq<T>>) {
512 proof_assert! { forall<xs: Seq<T>> xs.concat(Seq::empty()) == xs };
513 proof_assert! { forall<xs: Seq<T>> Seq::empty().concat(xs) == xs };
514}
515
516#[logic(open)]
518#[requires(0 <= n && n < m)]
519#[ensures(s.replicate_up_to(m) == s.replicate_up_to(n).union(
520 FSet::concat(s.replicate(n + 1), s.replicate_up_to(m - n - 1))))]
521#[variant(m)]
522pub fn concat_replicate_up_to<T>(n: Int, m: Int, s: FSet<T>) {
523 pearlite! {
524 if n + 1 == m {
525 concat_empty(s.replicate(n + 1));
526 } else {
527 concat_union::<T>();
528 concat_replicate(n, m - n - 1, s);
529 concat_replicate_up_to(n, m - 1, s);
530 }
531 }
532}