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