ostd/specs/mm/frame/linked_list/
linked_list_specs.rs1use vstd::prelude::*;
2use vstd_extra::{cast_ptr::*, ownership::*, prelude::*};
3
4use super::linked_list_owners::*;
5use crate::mm::{
6 Paddr, PagingLevel, Vaddr,
7 frame::{linked_list::Link, *},
8};
9
10verus! {
11
12impl CursorModel {
13 pub open spec fn move_next_spec(self) -> Self {
14 if self.list_model.list.len() > 0 {
15 if self.rear.len() > 0 {
16 let cur = self.rear[0];
17 Self {
18 fore: self.fore.insert(self.fore.len() as int, cur),
19 rear: self.rear.remove(0),
20 list_model: self.list_model,
21 }
22 } else {
23 Self {
24 fore: Seq::<LinkModel>::empty(),
25 rear: self.fore,
26 list_model: self.list_model,
27 }
28 }
29 } else {
30 self
31 }
32 }
33
34 pub open spec fn move_prev_spec(self) -> Self {
35 if self.list_model.list.len() > 0 {
36 if self.fore.len() > 0 {
37 let cur = self.fore[self.fore.len() - 1];
38 Self {
39 fore: self.fore.remove(self.fore.len() - 1),
40 rear: self.rear.insert(0, cur),
41 list_model: self.list_model,
42 }
43 } else {
44 Self {
45 fore: self.rear,
46 rear: Seq::<LinkModel>::empty(),
47 list_model: self.list_model,
48 }
49 }
50 } else {
51 self
52 }
53 }
54
55 pub open spec fn remove(self) -> Self {
56 let rear = self.rear.remove(0);
57
58 Self {
59 fore: self.fore,
60 rear: rear,
61 list_model: LinkedListModel { list: self.fore.add(rear) },
62 }
63 }
64
65 pub open spec fn insert(self, link: LinkModel) -> Self {
66 let fore = self.fore.insert(self.fore.len() as int, link);
67
68 Self {
69 fore: fore,
70 rear: self.rear,
71 list_model: LinkedListModel { list: fore.add(self.rear) },
72 }
73 }
74}
75
76impl<M: AnyFrameMeta + Repr<MetaSlotSmall>> CursorOwner<M> {
77 pub open spec fn remove_owner_spec(self, post: Self) -> bool {
78 &&& post.list_own.list == self.list_own.list.remove(self.index)
79 &&& post.index == self.index
80 }
81
82 pub proof fn remove_owner_spec_implies_model_spec(self, post: Self)
83 requires
84 self.remove_owner_spec(post),
85 0 <= self.index < self.length(),
86 ensures
87 post@ == self@.remove(),
88 {
89 let idx = self.index;
90 let s = self.list_own.list;
91 let ps = post.list_own.list;
92
93 LinkedListOwner::<M>::lemma_view_preserves_len(s);
94 LinkedListOwner::<M>::lemma_view_preserves_len(ps);
95
96 let vh_s = LinkedListOwner::<M>::view_helper(s);
97 let vh_ps = LinkedListOwner::<M>::view_helper(ps);
98
99 assert(post@.fore == self@.fore) by {
100 assert forall|j: int| 0 <= j < vh_ps[..idx].len() implies #[trigger] vh_ps[..idx][j]
101 == vh_s[..idx][j] by {
102 LinkedListOwner::<M>::lemma_view_helper_index(ps, j);
103 LinkedListOwner::<M>::lemma_view_helper_index(s, j);
104 };
105 };
106
107 assert(post@.rear == self@.remove().rear) by {
108 assert forall|j: int| 0 <= j < vh_ps[idx..].len() implies #[trigger] vh_ps[idx..][j]
109 == vh_s[idx..].remove(0)[j] by {
110 LinkedListOwner::<M>::lemma_view_helper_index(ps, idx + j);
111 LinkedListOwner::<M>::lemma_view_helper_index(s, idx + j + 1);
112 };
113 };
114
115 assert forall|j: int| 0 <= j < vh_ps.len() implies #[trigger] vh_ps[j] == vh_s[..idx].add(
116 vh_s[idx..].remove(0),
117 )[j] by {
118 LinkedListOwner::<M>::lemma_view_helper_index(ps, j);
119 if j < idx {
120 LinkedListOwner::<M>::lemma_view_helper_index(s, j);
121 } else {
122 LinkedListOwner::<M>::lemma_view_helper_index(s, j + 1);
123 }
124 };
125 assert(vh_ps == vh_s[..idx].add(vh_s[idx..].remove(0)));
126 assert(post@.list_model == self@.remove().list_model);
127 }
128
129 pub open spec fn insert_owner_spec(self, link: LinkOwner, post: Self) -> bool {
130 &&& post.list_own.list == self.list_own.list.insert(self.index, link)
134 &&& post.index == self.index + 1
135 }
136
137 pub proof fn insert_owner_spec_implies_model_spec(self, link: LinkOwner, post: Self)
138 requires
139 self.insert_owner_spec(link, post),
140 0 <= self.index <= self.length(),
141 ensures
142 post@ == self@.insert(link@),
143 {
144 let idx = self.index;
145 let s = self.list_own.list;
146 let ps = post.list_own.list;
147
148 LinkedListOwner::<M>::lemma_view_preserves_len(s);
149 LinkedListOwner::<M>::lemma_view_preserves_len(ps);
150 LinkedListOwner::<M>::lemma_view_helper_insert(s, idx, link);
151
152 let vh_s = LinkedListOwner::<M>::view_helper(s);
153 let vh_ps = LinkedListOwner::<M>::view_helper(ps);
154
155 assert(post@.fore == self@.insert(link@).fore) by {
156 assert forall|j: int| 0 <= j < vh_ps[..idx + 1].len() implies #[trigger] vh_ps[..idx
157 + 1][j] == vh_s[..idx].insert(idx as int, link@)[j] by {
158 LinkedListOwner::<M>::lemma_view_helper_index(ps, j);
159 if j < idx {
160 LinkedListOwner::<M>::lemma_view_helper_index(s, j);
161 }
162 };
163 };
164
165 assert(post@.rear == self@.insert(link@).rear) by {
166 assert forall|j: int| 0 <= j < vh_ps[idx + 1..].len() implies #[trigger] vh_ps[idx
167 + 1..][j] == vh_s[idx..][j] by {
168 LinkedListOwner::<M>::lemma_view_helper_index(ps, idx + 1 + j);
169 LinkedListOwner::<M>::lemma_view_helper_index(s, idx + j);
170 };
171 };
172
173 let new_fore = vh_s[..idx].insert(idx as int, link@);
174 assert forall|j: int| 0 <= j < vh_ps.len() implies #[trigger] vh_ps[j] == new_fore.add(
175 vh_s[idx..],
176 )[j] by {
177 LinkedListOwner::<M>::lemma_view_helper_index(ps, j);
178 if j < idx {
179 LinkedListOwner::<M>::lemma_view_helper_index(s, j);
180 } else if j > idx {
181 LinkedListOwner::<M>::lemma_view_helper_index(s, j - 1);
182 }
183 };
184 assert(vh_ps == new_fore.add(vh_s[idx..]));
185 assert(post@.list_model == self@.insert(link@).list_model);
186 }
187
188 pub open spec fn move_next_owner_spec(self) -> Self {
189 if self.length() == 0 {
190 self
191 } else if self.index == self.length() {
192 Self { list_own: self.list_own, index: 0 }
193 } else if self.index == self.length() - 1 {
194 Self { list_own: self.list_own, index: self.index + 1 }
195 } else {
196 Self { list_own: self.list_own, index: self.index + 1 }
197 }
198 }
199
200 pub open spec fn move_prev_owner_spec(self) -> Self {
201 if self.length() == 0 {
202 self
203 } else if self.index == self.length() {
204 Self { list_own: self.list_own, index: self.index - 1 }
205 } else if self.index == 0 {
206 Self { list_own: self.list_own, index: self.length() }
207 } else {
208 Self { list_own: self.list_own, index: self.index - 1 }
209 }
210 }
211}
212
213}