Skip to main content

ostd/specs/mm/frame/linked_list/
linked_list_specs.rs

1use 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;
99
100        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 {
107            assert forall |j: int| 0 <= j < vh_ps.take(idx).len() implies
108                vh_ps.take(idx)[j] == vh_s.take(idx)[j]
109            by {
110                LinkedListOwner::<M>::view_helper_index(ps, j);
111                LinkedListOwner::<M>::view_helper_index(s, j);
112            };
113        };
114
115        assert(post@.rear =~= self@.remove().rear) by {
116            assert forall |j: int| 0 <= j < vh_ps.skip(idx).len() implies
117                #[trigger] vh_ps.skip(idx)[j] == vh_s.skip(idx).remove(0)[j]
118            by {
119                LinkedListOwner::<M>::view_helper_index(ps, idx + j);
120                LinkedListOwner::<M>::view_helper_index(s, idx + j + 1);
121            };
122        };
123
124        assert forall |j: int| 0 <= j < vh_ps.len() implies
125            #[trigger] vh_ps[j] == vh_s.take(idx).add(vh_s.skip(idx).remove(0))[j]
126        by {
127            LinkedListOwner::<M>::view_helper_index(ps, j);
128            if j < idx {
129                LinkedListOwner::<M>::view_helper_index(s, j);
130            } else {
131                LinkedListOwner::<M>::view_helper_index(s, j + 1);
132            }
133        };
134        assert(vh_ps =~= vh_s.take(idx).add(vh_s.skip(idx).remove(0)));
135        assert(post@.list_model == self@.remove().list_model);
136    }
137
138    pub open spec fn insert_owner_spec(self, link: LinkOwner, post: Self) -> bool
139        recommends
140            self.index < self.length(),
141    {
142        &&& post.list_own.list == self.list_own.list.insert(self.index, link)
143        &&& post.list_own.list_id == self.list_own.list_id
144        &&& post.index == self.index + 1
145    }
146
147    pub proof fn insert_owner_spec_implies_model_spec(self, link: LinkOwner, post: Self)
148        requires
149            self.insert_owner_spec(link, post),
150            0 <= self.index <= self.length(),
151        ensures
152            post@ == self@.insert(link@),
153    {
154        let idx = self.index;
155        let s = self.list_own.list;
156        let ps = post.list_own.list;
157
158        LinkedListOwner::<M>::view_preserves_len(s);
159        LinkedListOwner::<M>::view_preserves_len(ps);
160        LinkedListOwner::<M>::view_helper_insert(s, idx, link);
161
162        let vh_s = LinkedListOwner::<M>::view_helper(s);
163        let vh_ps = LinkedListOwner::<M>::view_helper(ps);
164
165        assert(post@.fore =~= self@.insert(link@).fore) by {
166            assert forall |j: int| 0 <= j < vh_ps.take(idx + 1).len() implies
167                vh_ps.take(idx + 1)[j] == vh_s.take(idx).insert(idx as int, link@)[j]
168            by {
169                LinkedListOwner::<M>::view_helper_index(ps, j);
170                if j < idx {
171                    LinkedListOwner::<M>::view_helper_index(s, j);
172                }
173            };
174        };
175
176        assert(post@.rear =~= self@.insert(link@).rear) by {
177            assert forall |j: int| 0 <= j < vh_ps.skip(idx + 1).len() implies
178                vh_ps.skip(idx + 1)[j] == vh_s.skip(idx)[j]
179            by {
180                LinkedListOwner::<M>::view_helper_index(ps, idx + 1 + j);
181                LinkedListOwner::<M>::view_helper_index(s, idx + j);
182            };
183        };
184
185        let new_fore = vh_s.take(idx).insert(idx as int, link@);
186        assert forall |j: int| 0 <= j < vh_ps.len() implies
187            #[trigger] vh_ps[j] == new_fore.add(vh_s.skip(idx))[j]
188        by {
189            LinkedListOwner::<M>::view_helper_index(ps, j);
190            if j < idx {
191                LinkedListOwner::<M>::view_helper_index(s, j);
192            } else if j > idx {
193                LinkedListOwner::<M>::view_helper_index(s, j - 1);
194            }
195        };
196        assert(vh_ps =~= new_fore.add(vh_s.skip(idx)));
197        assert(post@.list_model == self@.insert(link@).list_model);
198    }
199
200    pub open spec fn move_next_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: 0 }
205        } else if self.index == self.length() - 1 {
206            Self { list_own: self.list_own, index: self.index + 1 }
207        } else {
208            Self { list_own: self.list_own, index: self.index + 1 }
209        }
210    }
211
212    pub open spec fn move_prev_owner_spec(self) -> Self {
213        if self.length() == 0 {
214            self
215        } else if self.index == self.length() {
216            Self { list_own: self.list_own, index: self.index - 1 }
217        } else if self.index == 0 {
218            Self { list_own: self.list_own, index: self.length() }
219        } else {
220            Self { list_own: self.list_own, index: self.index - 1 }
221        }
222    }
223}
224
225} // verus!