3 * Copyright (C) Amazon.com, Inc. or its affiliates. All Rights Reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
6 * this software and associated documentation files (the "Software"), to deal in
7 * the Software without restriction, including without limitation the rights to
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 * the Software, and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in all
13 * copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 * https://www.FreeRTOS.org
23 * https://github.com/FreeRTOS
33 /*@#include "common.gh" */
35 typedef size_t TickType_t;
36 typedef size_t UBaseType_t;
37 typedef ssize_t BaseType_t;
42 /* Empty/no-op macros */
43 #define mtCOVERAGE_TEST_MARKER()
44 #define mtCOVERAGE_TEST_DELAY()
45 #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList )
46 #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList )
47 #define listTEST_LIST_INTEGRITY( pxList )
48 #define listTEST_LIST_ITEM_INTEGRITY( pxListItem )
49 #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxListItem )
50 #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxListItem )
52 /* Max value stored in sentinel xListEnd element */
53 #define portMAX_DELAY UINT_MAX
59 TickType_t xItemValue;
60 struct xLIST_ITEM * pxNext;
61 struct xLIST_ITEM * pxPrevious;
63 struct xLIST * pxContainer;
65 typedef struct xLIST_ITEM ListItem_t;
69 UBaseType_t uxNumberOfItems;
70 struct xLIST_ITEM * pxIndex;
71 #ifdef VERIFAST /*< ***change MiniList_t to ListItem_t*** */
72 struct xLIST_ITEM xListEnd;
74 MiniListItem_t xListEnd;
79 * predicate xLIST_ITEM(
80 * struct xLIST_ITEM *n,
81 * TickType_t xItemValue,
82 * struct xLIST_ITEM *pxNext,
83 * struct xLIST_ITEM *pxPrevious,
84 * struct xLIST *pxContainer;) =
85 * n->xItemValue |-> xItemValue &*&
86 * n->pxNext |-> pxNext &*&
87 * n->pxPrevious |-> pxPrevious &*&
88 * n->pvOwner |-> _ &*&
89 * n->pxContainer |-> pxContainer;
92 /* Ferreira et al. (STTT'14) doubly-linked list segment (DLS). */
96 * struct xLIST_ITEM *n,
97 * struct xLIST_ITEM *nprev,
98 * struct xLIST_ITEM *mnext,
99 * struct xLIST_ITEM *m,
100 * list<struct xLIST_ITEM * > cells,
101 * list<TickType_t > vals,
102 * struct xLIST *pxContainer) =
104 * ? cells == cons(n, nil) &*&
105 * vals == cons(?v, nil) &*&
106 * xLIST_ITEM(n, v, mnext, nprev, pxContainer)
107 * : cells == cons(n, ?cells0) &*&
108 * vals == cons(?v, ?vals0) &*&
109 * xLIST_ITEM(n, v, ?o, nprev, pxContainer) &*& DLS(o, n, mnext, m, cells0, vals0, pxContainer);
111 * lemma void dls_star_item(
112 * struct xLIST_ITEM *n,
113 * struct xLIST_ITEM *m,
114 * struct xLIST_ITEM *o)
115 * requires DLS(n, ?nprev, ?mnext, m, ?cells, ?vals, ?l) &*& xLIST_ITEM(o, ?v, ?onext, ?oprev, ?l2);
116 * ensures DLS(n, nprev, mnext, m, cells, vals, l) &*& xLIST_ITEM(o, v, onext, oprev, l2) &*& mem(o, cells) == false;
118 * open DLS(n, nprev, mnext, m, cells, vals, l);
120 * assert xLIST_ITEM(n, _, _, _, _);
121 * open xLIST_ITEM(n, _, _, _, _);
122 * open xLIST_ITEM(o, _, _, _, _);
124 * close xLIST_ITEM(o, _, _, _, _);
125 * close xLIST_ITEM(n, _, _, _, _);
126 * close DLS(n, nprev, mnext, m, cells, vals, l);
129 * assert DLS(?nnext, n, mnext, m, tail(cells), tail(vals), l);
130 * dls_star_item(nnext, m, o);
131 * open xLIST_ITEM(n, _, _, _, _);
132 * open xLIST_ITEM(o, _, _, _, _);
134 * close xLIST_ITEM(o, _, _, _, _);
135 * close xLIST_ITEM(n, _, _, _, _);
136 * close DLS(n, nprev, mnext, m, cells, vals, l);
140 * lemma void dls_distinct(
141 * struct xLIST_ITEM *n,
142 * struct xLIST_ITEM *nprev,
143 * struct xLIST_ITEM *mnext,
144 * struct xLIST_ITEM *m,
145 * list<struct xLIST_ITEM * > cells)
146 * requires DLS(n, nprev, mnext, m, cells, ?vals, ?l);
147 * ensures DLS(n, nprev, mnext, m, cells, vals, l) &*& distinct(cells) == true;
150 * open DLS(n, nprev, mnext, m, cells, vals, l);
151 * close DLS(n, nprev, mnext, m, cells, vals, l);
153 * open DLS(n, nprev, mnext, m, cells, vals, l);
154 * assert DLS(?nnext, n, mnext, m, tail(cells), tail(vals), l);
155 * dls_distinct(nnext, n, mnext, m, tail(cells));
156 * dls_star_item(nnext, m, n);
157 * close DLS(n, nprev, mnext, m, cells, vals, l);
163 * int uxNumberOfItems,
164 * struct xLIST_ITEM *pxIndex,
165 * struct xLIST_ITEM *xListEnd,
166 * list<struct xLIST_ITEM *>cells,
167 * list<TickType_t >vals) =
168 * l->uxNumberOfItems |-> uxNumberOfItems &*&
169 * l->pxIndex |-> pxIndex &*&
170 * mem(pxIndex, cells) == true &*&
171 * xListEnd == &(l->xListEnd) &*&
172 * xListEnd == head(cells) &*&
173 * portMAX_DELAY == head(vals) &*&
174 * struct_xLIST_ITEM_padding(&l->xListEnd) &*&
175 * length(cells) == length(vals) &*&
176 * uxNumberOfItems + 1 == length(cells) &*&
177 * DLS(xListEnd, ?endprev, xListEnd, endprev, cells, vals, l);
179 * lemma void xLIST_distinct_cells(struct xLIST *l)
180 * requires xLIST(l, ?n, ?idx, ?end, ?cells, ?vals);
181 * ensures xLIST(l, n, idx, end, cells, vals) &*& distinct(cells) == true;
183 * open xLIST(l, n, idx, end, cells, vals);
184 * assert DLS(end, ?endprev, end, _, cells, vals, l);
185 * dls_distinct(end, endprev, end, endprev, cells);
186 * close xLIST(l, n, idx, end, cells, vals);
189 * lemma void xLIST_star_item(struct xLIST *l, struct xLIST_ITEM *x)
190 * requires xLIST(l, ?n, ?idx, ?end, ?cells, ?vals) &*& xLIST_ITEM(x, ?v, ?xnext, ?xprev, ?l2);
191 * ensures xLIST(l, n, idx, end, cells, vals) &*& xLIST_ITEM(x, v, xnext, xprev, l2) &*& mem(x, cells) == false;
193 * open xLIST(l, n, idx, end, cells, vals);
194 * assert DLS(end, ?endprev, end, _, cells, vals, l);
195 * dls_distinct(end, endprev, end, endprev, cells);
196 * dls_star_item(end, endprev, x);
197 * close xLIST(l, n, idx, end, cells, vals);
200 * lemma void dls_first_mem(
201 * struct xLIST_ITEM *n,
202 * struct xLIST_ITEM *nprev,
203 * struct xLIST_ITEM *mnext,
204 * struct xLIST_ITEM *m,
205 * list<struct xLIST_ITEM * > cells)
206 * requires DLS(n, nprev, mnext, m, cells, ?vals, ?l);
207 * ensures DLS(n, nprev, mnext, m, cells, vals, l) &*& mem(n, cells) == true &*& index_of(n, cells) == 0;
209 * open DLS(n, nprev, mnext, m, cells, vals, l);
211 * assert cells == cons(n, nil);
212 * close DLS(n, nprev, mnext, m, cells, vals, l);
214 * assert cells == cons(n, ?tail);
215 * close DLS(n, nprev, mnext, m, cells, vals, l);
219 * lemma void dls_not_empty(
220 * struct xLIST_ITEM *n,
221 * struct xLIST_ITEM *m,
222 * list<struct xLIST_ITEM * > cells,
223 * struct xLIST_ITEM *x)
224 * requires DLS(n, m, n, m, cells, ?vals, ?l) &*& mem(x, cells) == true &*& x != n;
225 * ensures DLS(n, m, n, m, cells, vals, l) &*& n != m;
227 * open DLS(n, m, n, m, cells, vals, l);
228 * close DLS(n, m, n, m, cells, vals, l);
231 * lemma void dls_last_mem(
232 * struct xLIST_ITEM *n,
233 * struct xLIST_ITEM *nprev,
234 * struct xLIST_ITEM *mnext,
235 * struct xLIST_ITEM *m,
236 * list<struct xLIST_ITEM * > cells)
237 * requires DLS(n, nprev, mnext, m, cells, ?vals, ?l);
238 * ensures DLS(n, nprev, mnext, m, cells, vals, l) &*& mem(m, cells) == true &*& index_of(m, cells) == length(cells) - 1;
240 * open DLS(n, nprev, mnext, m, cells, vals, l);
244 * open xLIST_ITEM(n, _, ?nnext, _, l);
245 * assert DLS(?o, n, mnext, m, tail(cells), tail(vals), l);
246 * dls_last_mem(o, n, mnext, m, tail(cells));
247 * close xLIST_ITEM(n, _, nnext, _, l);
249 * close DLS(n, nprev, mnext, m, cells, vals, l);
253 * struct xLIST_ITEM *n,
254 * struct xLIST_ITEM *nprev,
255 * struct xLIST_ITEM *mnext,
256 * struct xLIST_ITEM *m,
257 * list<struct xLIST_ITEM * > cells,
258 * list<TickType_t > vals,
259 * struct xLIST_ITEM *x,
261 * requires DLS(n, nprev, mnext, m, cells, vals, ?l) &*& x != n &*& mem(x, cells) == true &*& index_of(x,cells) == i;
262 * ensures DLS(n, nprev, x, ?xprev, take(i, cells), take(i, vals), l) &*& DLS(x, xprev, mnext, m, drop(i, cells), drop(i, vals), l) &*& xprev == nth(i-1, cells);
264 * open DLS(n, nprev, mnext, m, cells, vals, l);
266 * assert xLIST_ITEM(n, ?v, ?nnext, _, _);
267 * assert DLS(nnext, n, mnext, m, tail(cells), tail(vals), l);
269 * close DLS(n, nprev, x, n, singleton(n), singleton(v), l);
270 * open DLS(x, n, mnext, m, tail(cells), tail(vals), l);
271 * open xLIST_ITEM(x, _, ?xnext, ?xprev, l);
272 * close xLIST_ITEM(x, _, xnext, xprev, l);
273 * close DLS(x, n, mnext, m, tail(cells), tail(vals), l);
276 * split(nnext, n, mnext, m, tail(cells), tail(vals), x, i - 1);
277 * assert DLS(nnext, n, x, ?xprev, take(i-1, tail(cells)), take(i-1, tail(vals)), l);
278 * dls_distinct(nnext, n, x, xprev, take(i-1, tail(cells)));
279 * dls_star_item(nnext, xprev, n);
280 * dls_last_mem(nnext, n, x, xprev, take(i-1, tail(cells)));
282 * close DLS(n, nprev, x, xprev, take(i, cells), take(i, vals), l);
287 * struct xLIST_ITEM *n1,
288 * struct xLIST_ITEM *nprev1,
289 * struct xLIST_ITEM *mnext1,
290 * struct xLIST_ITEM *m1,
291 * list<struct xLIST_ITEM * > cells1,
292 * list<TickType_t > vals1,
293 * struct xLIST_ITEM *n2,
294 * struct xLIST_ITEM *nprev2,
295 * struct xLIST_ITEM *mnext2,
296 * struct xLIST_ITEM *m2,
297 * list<struct xLIST_ITEM * > cells2,
298 * list<TickType_t > vals2)
300 * DLS(n1, nprev1, mnext1, m1, cells1, vals1, ?l) &*&
301 * DLS(n2, nprev2, mnext2, m2, cells2, vals2, l) &*&
302 * mnext1 == n2 &*& m1 == nprev2;
303 * ensures DLS(n1, nprev1, mnext2, m2, append(cells1, cells2), append(vals1, vals2), l);
306 * dls_first_mem(n1, nprev1, mnext1, m1, cells1);
307 * dls_last_mem(n2, nprev2, mnext2, m2, cells2);
308 * open DLS(n1, nprev1, mnext1, m1, cells1, vals1, l);
309 * dls_star_item(n2, m2, n1);
310 * close DLS(n1, nprev1, mnext2, m2, append(singleton(n1), cells2), append(vals1, vals2), l);
312 * open DLS(n1, nprev1, mnext1, m1, cells1, vals1, l);
313 * assert DLS(?o, n1, mnext1, m1, ?cells1_tail, ?vals1_tail, l);
314 * join(o, n1, mnext1, m1, cells1_tail, vals1_tail,
315 * n2, nprev2, mnext2, m2, cells2, vals2);
316 * assert DLS(o, n1, mnext2, m2, append(cells1_tail, cells2), append(vals1_tail, vals2), l);
317 * dls_last_mem(o, n1, mnext2, m2, append(cells1_tail, cells2));
318 * dls_star_item(o, m2, n1);
319 * close DLS(n1, nprev1, mnext2, m2, append(cells1, cells2), append(vals1, vals2), l);
323 * lemma void idx_remains_in_list<t>(
330 * mem(idx, cells) == true &*&
331 * mem(x, cells) == true &*&
332 * index_of(x, cells) == ix;
333 * ensures mem(idx, remove_nth(ix, cells)) == true;
335 * neq_mem_remove(idx, x, cells);
336 * remove_remove_nth(cells, x);
340 /* Following lemma from `verifast/examples/shared_boxes/concurrentqueue.c`.
341 * Used in the uxListRemove proof to show that the item to remove `x` must
342 * have value `nth(i, vals)` where `i == index_of(x, cells)`. */
345 * lemma void drop_nth_index_of<t>(list<t> vs, int i)
347 * 0 <= i && i < length(vs);
349 * head(drop(i , vs)) == nth(i, vs);
357 * drop_nth_index_of(t, i - 1);
364 * lemma void remove_append<t>(t x, list<t> l1, list<t> l2)
365 * requires mem(x, l1) == false;
366 * ensures remove(x, append(l1, l2)) == append(l1, remove(x, l2));
371 * remove_append(x, t1, l2);