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};
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        // The list model (`view_helper`) depends only on the element sequence,
140        // not on `list_id`, so this carries no `list_id` clause — letting it
141        // hold even when the insert mints a fresh id for a previously-empty list.
142        &&& 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} // verus!