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