Skip to main content

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

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