vstd_extra/resource/
range.rs1use vstd::{
3 prelude::*,
4 resource::{Loc, set::GhostSubset},
5 set_lib::FiniteRange,
6};
7
8use crate::range::RangeExtraFns;
9use core::ops::Range;
10
11verus! {
12
13#[verifier::reject_recursive_types(T)]
15pub tracked struct GhostSubRange<T: FiniteRange> {
16 subset: GhostSubset<T>,
17 ghost range: Range<T>,
18}
19
20impl<T: FiniteRange> GhostSubRange<T> {
21 #[verifier::type_invariant]
22 closed spec fn inv(self) -> bool {
23 self.subset@ == self.range.view_set()
24 }
25
26 pub proof fn tracked_new(tracked subset: GhostSubset<T>, range: Range<T>) -> (tracked result:
28 Self)
29 requires
30 subset@ =~= range.view_set(),
31 ensures
32 result.id() == subset.id(),
33 result.range() == range,
34 result@ == range.view_set(),
35 {
36 Self { subset, range }
37 }
38
39 pub closed spec fn id(self) -> Loc {
41 self.subset.id()
42 }
43
44 pub closed spec fn range(self) -> Range<T> {
46 self.range
47 }
48
49 pub open spec fn view(self) -> Set<T> {
51 self.range().view_set()
52 }
53
54 pub proof fn tracked_borrow(tracked &self) -> (tracked result: &GhostSubset<T>)
56 ensures
57 result.id() == self.id(),
58 result@ == self@,
59 {
60 use_type_invariant(self);
61 &self.subset
62 }
63
64 pub proof fn tracked_into_subset(tracked self) -> (tracked result: GhostSubset<T>)
66 ensures
67 result.id() == self.id(),
68 result@ == self@,
69 {
70 use_type_invariant(&self);
71 self.subset
72 }
73}
74
75}