mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-12-11 14:15:12 -05:00
Exposed node owners in all predicates related to nodes. Adapted proofs to new predicates.
Changed predicates: - `xLIST_ITEM` - `DLS` - `xLIST` - `readyLists_p` - `List_array_p`
This commit is contained in:
parent
70f1041778
commit
e800ebd293
6 changed files with 713 additions and 369 deletions
57
tasks.c
57
tasks.c
|
|
@ -987,47 +987,47 @@ static void prvYieldForTask( TCB_t * pxTCB,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//@ open taskISRLockInv_p();
|
//@ open taskISRLockInv_p();
|
||||||
//@ open readyLists_p(?gCellLists);
|
//@ open readyLists_p(?gCellLists, ?gOwnerLists);
|
||||||
//@ List_array_p_index_within_limits(&pxReadyTasksLists, uxCurrentPriority);
|
//@ List_array_p_index_within_limits(&pxReadyTasksLists, uxCurrentPriority);
|
||||||
//@ List_array_split(pxReadyTasksLists, uxCurrentPriority);
|
//@ List_array_split(pxReadyTasksLists, uxCurrentPriority);
|
||||||
//@ List_t* gReadyList = &pxReadyTasksLists[uxCurrentPriority];
|
//@ List_t* gReadyList = &pxReadyTasksLists[uxCurrentPriority];
|
||||||
|
|
||||||
//@ assert( xLIST(gReadyList, ?gSize, ?gIndex, ?gEnd, ?gCells, ?gVals) );
|
//@ assert( xLIST(gReadyList, ?gSize, ?gIndex, ?gEnd, ?gCells, ?gVals, ?gOwners) );
|
||||||
|
|
||||||
//@ open xLIST(gReadyList, _, _, _, _, _);
|
//@ open xLIST(gReadyList, _, _, _, _, _, _);
|
||||||
if( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxCurrentPriority ] ) ) == pdFALSE )
|
if( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxCurrentPriority ] ) ) == pdFALSE )
|
||||||
{
|
{
|
||||||
List_t * const pxReadyList = &( pxReadyTasksLists[ uxCurrentPriority ] );
|
List_t * const pxReadyList = &( pxReadyTasksLists[ uxCurrentPriority ] );
|
||||||
//@ assert( pxReadyList->pxIndex |-> gIndex );
|
//@ assert( pxReadyList->pxIndex |-> gIndex );
|
||||||
/*@ assert( DLS(gEnd, ?gEndPrev, gEnd, gEndPrev,
|
/*@ assert( DLS(gEnd, ?gEndPrev, gEnd, gEndPrev,
|
||||||
gCells, gVals, gReadyList) );
|
gCells, gVals, gOwners, gReadyList) );
|
||||||
@*/
|
@*/
|
||||||
|
|
||||||
|
|
||||||
//@ DLS_open_2(pxReadyList->pxIndex);
|
//@ DLS_open_2(pxReadyList->pxIndex);
|
||||||
//@ assert( xLIST_ITEM(gIndex, _, ?gIndexNext, ?gIndexPrev, gReadyList) );
|
//@ assert( xLIST_ITEM(gIndex, _, ?gIndexNext, ?gIndexPrev, _, gReadyList) );
|
||||||
ListItem_t * pxLastTaskItem = pxReadyList->pxIndex->pxPrevious;
|
ListItem_t * pxLastTaskItem = pxReadyList->pxIndex->pxPrevious;
|
||||||
ListItem_t * pxTaskItem = pxLastTaskItem;
|
ListItem_t * pxTaskItem = pxLastTaskItem;
|
||||||
//@ close xLIST_ITEM(gIndex, _, gIndexNext, gIndexPrev, gReadyList);
|
//@ close xLIST_ITEM(gIndex, _, gIndexNext, gIndexPrev, _, gReadyList);
|
||||||
//@ DLS_close_2(pxReadyList->pxIndex, gCells, gVals);
|
//@ DLS_close_2(pxReadyList->pxIndex, gCells, gVals, gOwners);
|
||||||
|
|
||||||
//@ assert( mem(pxTaskItem, gCells) == true);
|
//@ assert( mem(pxTaskItem, gCells) == true);
|
||||||
|
|
||||||
//@ open DLS(gEnd, gEndPrev, gEnd, gEndPrev, gCells, gVals, gReadyList);
|
//@ open DLS(gEnd, gEndPrev, gEnd, gEndPrev, gCells, gVals, gOwners, gReadyList);
|
||||||
//@ assert( xLIST_ITEM(&pxReadyList->xListEnd, _, _, _, gReadyList) );
|
//@ assert( xLIST_ITEM(&pxReadyList->xListEnd, _, _, _, _, gReadyList) );
|
||||||
//@ open xLIST_ITEM(&pxReadyList->xListEnd, _, _, _, gReadyList);
|
//@ open xLIST_ITEM(&pxReadyList->xListEnd, _, _, _, _, gReadyList);
|
||||||
// opening required to prove validity of `&( pxReadyList->xListEnd )`
|
// opening required to prove validity of `&( pxReadyList->xListEnd )`
|
||||||
///@ assert( pointer_within_limits( &pxReadyList->xListEnd ) == true );
|
///@ assert( pointer_within_limits( &pxReadyList->xListEnd ) == true );
|
||||||
//@ close xLIST_ITEM(&pxReadyList->xListEnd, _, _, _, gReadyList);
|
//@ close xLIST_ITEM(&pxReadyList->xListEnd, _, _, _, _, gReadyList);
|
||||||
if( ( void * ) pxLastTaskItem == ( void * ) &( pxReadyList->xListEnd ) )
|
if( ( void * ) pxLastTaskItem == ( void * ) &( pxReadyList->xListEnd ) )
|
||||||
{
|
{
|
||||||
//@ assert( gVals == cons(?gV, ?gRest) );
|
//@ assert( gVals == cons(?gV, ?gRest) );
|
||||||
//@ assert( xLIST_ITEM(?gOldLastTaskItem, gV, ?gO, gEndPrev, gReadyList) );
|
//@ assert( xLIST_ITEM(?gOldLastTaskItem, gV, ?gO, gEndPrev, _, gReadyList) );
|
||||||
pxLastTaskItem = pxLastTaskItem->pxPrevious;
|
pxLastTaskItem = pxLastTaskItem->pxPrevious;
|
||||||
//@ close xLIST_ITEM(gOldLastTaskItem, gV, gO, gEndPrev, gReadyList);
|
//@ close xLIST_ITEM(gOldLastTaskItem, gV, gO, gEndPrev, _, gReadyList);
|
||||||
}
|
}
|
||||||
//@ close DLS(gEnd, gEndPrev, gEnd, gEndPrev, gCells, gVals, gReadyList);
|
//@ close DLS(gEnd, gEndPrev, gEnd, gEndPrev, gCells, gVals, gOwners, gReadyList);
|
||||||
//@ close xLIST(gReadyList, _, gIndex, gEnd, gCells, gVals);
|
//@ close xLIST(gReadyList, _, gIndex, gEnd, gCells, gVals, gOwners);
|
||||||
|
|
||||||
/* The ready task list for uxCurrentPriority is not empty, so uxTopReadyPriority
|
/* The ready task list for uxCurrentPriority is not empty, so uxTopReadyPriority
|
||||||
* must not be decremented any further */
|
* must not be decremented any further */
|
||||||
|
|
@ -1035,19 +1035,20 @@ static void prvYieldForTask( TCB_t * pxTCB,
|
||||||
|
|
||||||
//@ mem_nth(uxCurrentPriority, gCellLists);
|
//@ mem_nth(uxCurrentPriority, gCellLists);
|
||||||
//@ assert( mem(gCells, gCellLists) == true);
|
//@ assert( mem(gCells, gCellLists) == true);
|
||||||
//@ open_collection_of_sharedSeg_TCB(gCellLists, gCells);
|
// //@ open_collection_of_sharedSeg_TCB(gCellLists, gCells);
|
||||||
|
|
||||||
do
|
do
|
||||||
/*@ invariant
|
/*@ invariant
|
||||||
mem(pxTaskItem, gCells) == true &*&
|
mem(pxTaskItem, gCells) == true &*&
|
||||||
xLIST(gReadyList, gSize, gIndex, gEnd, gCells, gVals) &*&
|
xLIST(gReadyList, gSize, gIndex, gEnd, gCells, gVals, gOwners) &*&
|
||||||
foreach(gCells, sharedSeg_TCB_of_itemOwner);
|
// foreach(gCells, sharedSeg_TCB_of_itemOwner);
|
||||||
|
true;
|
||||||
@*/
|
@*/
|
||||||
{
|
{
|
||||||
TCB_t * pxTCB;
|
TCB_t * pxTCB;
|
||||||
|
|
||||||
//@ open xLIST(gReadyList, gSize, gIndex, gEnd, gCells, gVals);
|
//@ open xLIST(gReadyList, gSize, gIndex, gEnd, gCells, gVals, gOwners);
|
||||||
//@ assert( DLS(gEnd, ?gEndPrev2, gEnd, gEndPrev2, gCells, gVals, gReadyList) );
|
//@ assert( DLS(gEnd, ?gEndPrev2, gEnd, gEndPrev2, gCells, gVals, gOwners, gReadyList) );
|
||||||
|
|
||||||
// Building an SSA for important variables helps us to
|
// Building an SSA for important variables helps us to
|
||||||
// refer to the right instances.
|
// refer to the right instances.
|
||||||
|
|
@ -1057,8 +1058,8 @@ static void prvYieldForTask( TCB_t * pxTCB,
|
||||||
pxTaskItem = pxTaskItem->pxNext;
|
pxTaskItem = pxTaskItem->pxNext;
|
||||||
//@ struct xLIST_ITEM* gTaskItem_1 = pxTaskItem;
|
//@ struct xLIST_ITEM* gTaskItem_1 = pxTaskItem;
|
||||||
|
|
||||||
//@ close xLIST_ITEM(gTaskItem_0, _, _, _, gReadyList);
|
//@ close xLIST_ITEM(gTaskItem_0, _, _, _, _, gReadyList);
|
||||||
//@ DLS_close_2(gTaskItem_0, gCells, gVals);
|
//@ DLS_close_2(gTaskItem_0, gCells, gVals, gOwners);
|
||||||
|
|
||||||
if( ( void * ) pxTaskItem == ( void * ) &( pxReadyList->xListEnd ) )
|
if( ( void * ) pxTaskItem == ( void * ) &( pxReadyList->xListEnd ) )
|
||||||
{
|
{
|
||||||
|
|
@ -1066,20 +1067,20 @@ static void prvYieldForTask( TCB_t * pxTCB,
|
||||||
pxTaskItem = pxTaskItem->pxNext;
|
pxTaskItem = pxTaskItem->pxNext;
|
||||||
//@ struct xLIST_ITEM* gTaskItem_2 = pxTaskItem;
|
//@ struct xLIST_ITEM* gTaskItem_2 = pxTaskItem;
|
||||||
|
|
||||||
//@ close xLIST_ITEM(gTaskItem_1, _, _, _, gReadyList);
|
//@ close xLIST_ITEM(gTaskItem_1, _, _, _, _, gReadyList);
|
||||||
//@ DLS_close_2(gTaskItem_1, gCells, gVals);
|
//@ DLS_close_2(gTaskItem_1, gCells, gVals, gOwners);
|
||||||
}
|
}
|
||||||
|
|
||||||
//@ struct xLIST_ITEM* gTaskItem_3 = pxTaskItem;
|
//@ struct xLIST_ITEM* gTaskItem_3 = pxTaskItem;
|
||||||
|
|
||||||
//@ DLS_open_2(gTaskItem_3);
|
//@ DLS_open_2(gTaskItem_3);
|
||||||
pxTCB = pxTaskItem->pvOwner;
|
pxTCB = pxTaskItem->pvOwner;
|
||||||
//@ close xLIST_ITEM(gTaskItem_3, _, _, _, gReadyList);
|
//@ close xLIST_ITEM(gTaskItem_3, _, _, _, _, gReadyList);
|
||||||
//@ DLS_close_2(gTaskItem_3, gCells, gVals);
|
//@ DLS_close_2(gTaskItem_3, gCells, gVals, gOwners);
|
||||||
|
|
||||||
// Get access to sharedSeg_TCB_p(pxTCB).
|
// Get access to sharedSeg_TCB_p(pxTCB).
|
||||||
//@ foreach_remove(gTaskItem_3, gCells);
|
// //@ foreach_remove(gTaskItem_3, gCells);
|
||||||
//@ open sharedSeg_TCB_of_itemOwner(gTaskItem_3);
|
// //@ open sharedSeg_TCB_of_itemOwner(gTaskItem_3);
|
||||||
|
|
||||||
|
|
||||||
/*debug_printf("Attempting to schedule %s on core %d\n", pxTCB->pcTaskName, portGET_CORE_ID() ); */
|
/*debug_printf("Attempting to schedule %s on core %d\n", pxTCB->pcTaskName, portGET_CORE_ID() ); */
|
||||||
|
|
|
||||||
|
|
@ -7,69 +7,86 @@
|
||||||
/*@
|
/*@
|
||||||
// TODO: We know that the list of priority 0 is never empty.
|
// TODO: We know that the list of priority 0 is never empty.
|
||||||
// It contains the idle task and nothing else.
|
// It contains the idle task and nothing else.
|
||||||
predicate readyLists_p(list<list<struct xLIST_ITEM*> > gCellLists) =
|
predicate readyLists_p(list<list<struct xLIST_ITEM*> > gCellLists,
|
||||||
|
list<list<void*> > gOwnerLists) =
|
||||||
configMAX_PRIORITIES == length(gCellLists) &*&
|
configMAX_PRIORITIES == length(gCellLists) &*&
|
||||||
List_array_p(&pxReadyTasksLists, configMAX_PRIORITIES, gCellLists);
|
List_array_p(&pxReadyTasksLists, configMAX_PRIORITIES,
|
||||||
|
gCellLists, gOwnerLists);
|
||||||
|
|
||||||
|
|
||||||
predicate List_array_p(List_t* array, int size,
|
predicate List_array_p(List_t* array, int size,
|
||||||
list<list<struct xLIST_ITEM*> > cellLists) =
|
list<list<struct xLIST_ITEM*> > cellLists,
|
||||||
|
list<list<void*> > ownerLists) =
|
||||||
size >= 0 &*&
|
size >= 0 &*&
|
||||||
length(cellLists) == size &*&
|
length(cellLists) == size &*&
|
||||||
|
length(ownerLists) == length(cellLists) &*&
|
||||||
size > 0
|
size > 0
|
||||||
? (
|
? (
|
||||||
cellLists == cons(?gCells, ?gTailcellLists) &*&
|
cellLists == cons(?gCells, ?gTailCellLists) &*&
|
||||||
|
ownerLists == cons(?gOwners, ?gTailOwnerLists) &*&
|
||||||
pointer_within_limits(array) == true &*&
|
pointer_within_limits(array) == true &*&
|
||||||
xLIST(array, ?gNumberOfItems, ?gIndex, ?gListEnd, gCells, ?gVals)
|
xLIST(array, ?gNumberOfItems, ?gIndex, ?gListEnd, gCells, ?gVals,
|
||||||
|
gOwners)
|
||||||
&*&
|
&*&
|
||||||
List_array_p(array + 1, size - 1, gTailcellLists)
|
List_array_p(array + 1, size - 1, gTailCellLists, gTailOwnerLists)
|
||||||
)
|
)
|
||||||
: cellLists == nil;
|
: (
|
||||||
|
cellLists == nil &*&
|
||||||
|
ownerLists == nil
|
||||||
|
);
|
||||||
|
|
||||||
lemma void List_array_size_positive(List_t* pxArray)
|
lemma void List_array_size_positive(List_t* pxArray)
|
||||||
requires List_array_p(pxArray, ?gSize, ?gCellLists);
|
requires List_array_p(pxArray, ?gSize, ?gCellLists, ?gOwnerLists);
|
||||||
ensures List_array_p(pxArray, gSize, gCellLists) &*&
|
ensures
|
||||||
gSize >= 0 &*& gSize == length(gCellLists);
|
List_array_p(pxArray, gSize, gCellLists, gOwnerLists) &*&
|
||||||
|
gSize >= 0 &*&
|
||||||
|
gSize == length(gCellLists) &*&
|
||||||
|
length(gCellLists) == length(gOwnerLists);
|
||||||
{
|
{
|
||||||
open List_array_p(pxArray, gSize, gCellLists);
|
open List_array_p(pxArray, gSize, gCellLists, gOwnerLists);
|
||||||
close List_array_p(pxArray, gSize, gCellLists);
|
close List_array_p(pxArray, gSize, gCellLists, gOwnerLists);
|
||||||
}
|
}
|
||||||
|
|
||||||
lemma void List_array_split(List_t* array, int index)
|
lemma void List_array_split(List_t* array, int index)
|
||||||
requires
|
requires
|
||||||
List_array_p(array, ?gSize, ?gCellLists) &*&
|
List_array_p(array, ?gSize, ?gCellLists, ?gOwnerLists) &*&
|
||||||
0 <= index &*& index < gSize;
|
0 <= index &*& index < gSize;
|
||||||
ensures
|
ensures
|
||||||
List_array_p(array, index, ?gPrefCellLists) &*&
|
List_array_p(array, index, ?gPrefCellLists, ?gPrefOwnerLists) &*&
|
||||||
gPrefCellLists == take(index, gCellLists) &*&
|
gPrefCellLists == take(index, gCellLists) &*&
|
||||||
|
gPrefOwnerLists == take(index, gOwnerLists) &*&
|
||||||
pointer_within_limits(array) == true &*&
|
pointer_within_limits(array) == true &*&
|
||||||
xLIST(array + index, _, _, _, ?gCells, ?vals) &*&
|
xLIST(array + index, _, _, _, ?gCells, ?gVals, ?gOwners) &*&
|
||||||
gCells == nth(index, gCellLists) &*&
|
gCells == nth(index, gCellLists) &*&
|
||||||
List_array_p(array + index + 1, gSize-index-1, ?gSufCellLists) &*&
|
gOwners == nth(index, gOwnerLists) &*&
|
||||||
gSufCellLists == drop(index+1, gCellLists);
|
List_array_p(array + index + 1, gSize-index-1, ?gSufCellLists, ?gSufOwnerLists) &*&
|
||||||
|
gSufCellLists == drop(index+1, gCellLists) &*&
|
||||||
|
gSufOwnerLists == drop(index+1, gOwnerLists);
|
||||||
{
|
{
|
||||||
open List_array_p(array, gSize, gCellLists);
|
open List_array_p(array, gSize, gCellLists, gOwnerLists);
|
||||||
|
|
||||||
if( index > 0 ) {
|
if( index > 0 ) {
|
||||||
List_array_split(array + 1, index - 1);
|
List_array_split(array + 1, index - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
close List_array_p(array, index, take(index, gCellLists));
|
close List_array_p(array, index, take(index, gCellLists), take(index, gOwnerLists));
|
||||||
}
|
}
|
||||||
|
|
||||||
lemma void List_array_join(List_t* array)
|
lemma void List_array_join(List_t* array)
|
||||||
requires
|
requires
|
||||||
List_array_p(array, ?gPrefSize, ?gPrefCellLists) &*&
|
List_array_p(array, ?gPrefSize, ?gPrefCellLists, ?gPrefOwnerLists) &*&
|
||||||
xLIST(array + gPrefSize, _, _, _, ?gCells, _) &*&
|
xLIST(array + gPrefSize, _, _, _, ?gCells, _, ?gOwners) &*&
|
||||||
pointer_within_limits(array + gPrefSize) == true &*&
|
pointer_within_limits(array + gPrefSize) == true &*&
|
||||||
List_array_p(array + gPrefSize + 1, ?gSufSize, ?gSufCellLists);
|
List_array_p(array + gPrefSize + 1, ?gSufSize, ?gSufCellLists, ?gSufOwnerLists);
|
||||||
ensures
|
ensures
|
||||||
List_array_p(array, ?gSize, ?gCellLists) &*&
|
List_array_p(array, ?gSize, ?gCellLists, ?gOwnerLists) &*&
|
||||||
gSize == length(gCellLists) &*&
|
gSize == length(gCellLists) &*&
|
||||||
|
length(gCellLists) == length(gOwnerLists) &*&
|
||||||
gSize == gPrefSize + 1 + gSufSize &*&
|
gSize == gPrefSize + 1 + gSufSize &*&
|
||||||
gCellLists == append(gPrefCellLists, cons(gCells, gSufCellLists));
|
gCellLists == append(gPrefCellLists, cons(gCells, gSufCellLists)) &*&
|
||||||
|
gOwnerLists == append(gPrefOwnerLists, cons(gOwners, gSufOwnerLists));
|
||||||
{
|
{
|
||||||
open List_array_p(array, gPrefSize, gPrefCellLists);
|
open List_array_p(array, gPrefSize, gPrefCellLists, gPrefOwnerLists);
|
||||||
List_array_size_positive(array + gPrefSize + 1);
|
List_array_size_positive(array + gPrefSize + 1);
|
||||||
|
|
||||||
if( gPrefSize > 0 ) {
|
if( gPrefSize > 0 ) {
|
||||||
|
|
@ -77,7 +94,8 @@ ensures
|
||||||
}
|
}
|
||||||
|
|
||||||
close List_array_p(array, gPrefSize + 1 + gSufSize,
|
close List_array_p(array, gPrefSize + 1 + gSufSize,
|
||||||
append(gPrefCellLists, cons(gCells, gSufCellLists)));
|
append(gPrefCellLists, cons(gCells, gSufCellLists)),
|
||||||
|
append(gPrefOwnerLists, cons(gOwners, gSufOwnerLists)));
|
||||||
}
|
}
|
||||||
@*/
|
@*/
|
||||||
|
|
||||||
|
|
@ -87,16 +105,16 @@ ensures
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
lemma void List_array_p_index_within_limits(List_t* array, int index)
|
lemma void List_array_p_index_within_limits(List_t* array, int index)
|
||||||
requires List_array_p(array, ?gSize, ?gCellListss) &*&
|
requires List_array_p(array, ?gSize, ?gCellLists, ?gOwnerLists) &*&
|
||||||
0 <= index &*& index < gSize;
|
0 <= index &*& index < gSize;
|
||||||
ensures List_array_p(array, gSize, gCellListss) &*&
|
ensures List_array_p(array, gSize, gCellLists, gOwnerLists) &*&
|
||||||
pointer_within_limits(&array[index]) == true;
|
pointer_within_limits(&array[index]) == true;
|
||||||
{
|
{
|
||||||
open List_array_p(array, gSize, gCellListss);
|
open List_array_p(array, gSize, gCellLists, gOwnerLists);
|
||||||
if( index > 0) {
|
if( index > 0) {
|
||||||
List_array_p_index_within_limits(&array[1], index-1);
|
List_array_p_index_within_limits(&array[1], index-1);
|
||||||
}
|
}
|
||||||
close List_array_p(array, gSize, gCellListss);
|
close List_array_p(array, gSize, gCellLists, gOwnerLists);
|
||||||
}
|
}
|
||||||
@*/
|
@*/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -129,10 +129,12 @@
|
||||||
#endif /* VERIFAST_SINGLE_CORE */
|
#endif /* VERIFAST_SINGLE_CORE */
|
||||||
|
|
||||||
#ifndef VERIFAST_SINGLE_CORE
|
#ifndef VERIFAST_SINGLE_CORE
|
||||||
/* Reason for deletion:
|
/* Reasons for rewrite:
|
||||||
* Breaking change in VeriFast. VeriFast now ensures that no uninitialised
|
* - Breaking change in VeriFast. VeriFast now ensures that no uninitialised
|
||||||
* values are read. `x |-> _` is interpreted as "uninitialised",
|
* values are read. `x |-> _` is interpreted as "uninitialised",
|
||||||
* `x |-> ?v` is interpreted as "initialised".
|
* `x |-> ?v` is interpreted as "initialised".
|
||||||
|
* - In order to verify the scheduler, we have to reason about each node's
|
||||||
|
* owner. Hence, the predicate has to expose it.
|
||||||
*/
|
*/
|
||||||
/*@
|
/*@
|
||||||
predicate xLIST_ITEM(
|
predicate xLIST_ITEM(
|
||||||
|
|
@ -140,11 +142,12 @@
|
||||||
TickType_t xItemValue,
|
TickType_t xItemValue,
|
||||||
struct xLIST_ITEM *pxNext,
|
struct xLIST_ITEM *pxNext,
|
||||||
struct xLIST_ITEM *pxPrevious,
|
struct xLIST_ITEM *pxPrevious,
|
||||||
|
void* pxOwner,
|
||||||
struct xLIST *pxContainer;) =
|
struct xLIST *pxContainer;) =
|
||||||
n->xItemValue |-> xItemValue &*&
|
n->xItemValue |-> xItemValue &*&
|
||||||
n->pxNext |-> pxNext &*&
|
n->pxNext |-> pxNext &*&
|
||||||
n->pxPrevious |-> pxPrevious &*&
|
n->pxPrevious |-> pxPrevious &*&
|
||||||
n->pvOwner |-> ?gOwner &*&
|
n->pvOwner |-> pxOwner &*&
|
||||||
n->pxContainer |-> pxContainer;
|
n->pxContainer |-> pxContainer;
|
||||||
@*/
|
@*/
|
||||||
#else
|
#else
|
||||||
|
|
@ -163,240 +166,522 @@
|
||||||
@*/
|
@*/
|
||||||
#endif /* VERIFAST_SINGLE_CORE */
|
#endif /* VERIFAST_SINGLE_CORE */
|
||||||
|
|
||||||
/* Ferreira et al. (STTT'14) doubly-linked list segment (DLS). */
|
|
||||||
/*@
|
|
||||||
predicate DLS(
|
|
||||||
struct xLIST_ITEM *n,
|
|
||||||
struct xLIST_ITEM *nprev,
|
|
||||||
struct xLIST_ITEM *mnext,
|
|
||||||
struct xLIST_ITEM *m,
|
|
||||||
list<struct xLIST_ITEM * > cells,
|
|
||||||
list<TickType_t > vals,
|
|
||||||
struct xLIST *pxContainer) =
|
|
||||||
n == m
|
|
||||||
? cells == cons(n, nil) &*&
|
|
||||||
vals == cons(?v, nil) &*&
|
|
||||||
xLIST_ITEM(n, v, mnext, nprev, pxContainer)
|
|
||||||
: cells == cons(n, ?cells0) &*&
|
|
||||||
vals == cons(?v, ?vals0) &*&
|
|
||||||
xLIST_ITEM(n, v, ?o, nprev, pxContainer) &*& DLS(o, n, mnext, m, cells0, vals0, pxContainer);
|
|
||||||
|
|
||||||
|
|
||||||
lemma void dls_star_item(
|
#ifndef VERIFAST_SINGLE_CORE
|
||||||
struct xLIST_ITEM *n,
|
/* Reason for rewrite:
|
||||||
struct xLIST_ITEM *m,
|
* In order to verify the scheduler, we have to reason about each node's
|
||||||
struct xLIST_ITEM *o)
|
* owner. Hence, the predicate has to expose it.
|
||||||
requires DLS(n, ?nprev, ?mnext, m, ?cells, ?vals, ?l) &*& xLIST_ITEM(o, ?v, ?onext, ?oprev, ?l2);
|
*/
|
||||||
ensures DLS(n, nprev, mnext, m, cells, vals, l) &*& xLIST_ITEM(o, v, onext, oprev, l2) &*& mem(o, cells) == false;
|
|
||||||
{
|
/* Ferreira et al. (STTT'14) doubly-linked list segment (DLS). */
|
||||||
open DLS(n, nprev, mnext, m, cells, vals, l);
|
/*@
|
||||||
if (n == m) {
|
predicate DLS(
|
||||||
assert xLIST_ITEM(n, _, _, _, _);
|
struct xLIST_ITEM *n,
|
||||||
open xLIST_ITEM(n, _, _, _, _);
|
struct xLIST_ITEM *nprev,
|
||||||
open xLIST_ITEM(o, _, _, _, _);
|
struct xLIST_ITEM *mnext,
|
||||||
assert n != o;
|
struct xLIST_ITEM *m,
|
||||||
close xLIST_ITEM(o, _, _, _, _);
|
list<struct xLIST_ITEM * > cells,
|
||||||
close xLIST_ITEM(n, _, _, _, _);
|
list<TickType_t > vals,
|
||||||
close DLS(n, nprev, mnext, m, cells, vals, l);
|
list<void*> owners,
|
||||||
|
struct xLIST *pxContainer) =
|
||||||
|
n == m
|
||||||
|
? cells == cons(n, nil) &*&
|
||||||
|
vals == cons(?v, nil) &*&
|
||||||
|
owners == cons(?ow, nil) &*&
|
||||||
|
xLIST_ITEM(n, v, mnext, nprev, ow, pxContainer)
|
||||||
|
: cells == cons(n, ?cells0) &*&
|
||||||
|
vals == cons(?v, ?vals0) &*&
|
||||||
|
owners == cons(?ow, ?owners0) &*&
|
||||||
|
xLIST_ITEM(n, v, ?o, nprev, ow, pxContainer) &*& DLS(o, n, mnext, m, cells0, vals0, owners0, pxContainer);
|
||||||
|
@*/
|
||||||
|
#else
|
||||||
|
/* Ferreira et al. (STTT'14) doubly-linked list segment (DLS). */
|
||||||
|
/*@
|
||||||
|
predicate DLS(
|
||||||
|
struct xLIST_ITEM *n,
|
||||||
|
struct xLIST_ITEM *nprev,
|
||||||
|
struct xLIST_ITEM *mnext,
|
||||||
|
struct xLIST_ITEM *m,
|
||||||
|
list<struct xLIST_ITEM * > cells,
|
||||||
|
list<TickType_t > vals,
|
||||||
|
struct xLIST *pxContainer) =
|
||||||
|
n == m
|
||||||
|
? cells == cons(n, nil) &*&
|
||||||
|
vals == cons(?v, nil) &*&
|
||||||
|
xLIST_ITEM(n, v, mnext, nprev, pxContainer)
|
||||||
|
: cells == cons(n, ?cells0) &*&
|
||||||
|
vals == cons(?v, ?vals0) &*&
|
||||||
|
xLIST_ITEM(n, v, ?o, nprev, pxContainer) &*& DLS(o, n, mnext, m, cells0, vals0, pxContainer);
|
||||||
|
@*/
|
||||||
|
#endif /* VERIFAST_SINGLE_CORE */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef VERIFAST_SINGLE_CORE
|
||||||
|
/* Reason for rewrite:
|
||||||
|
* Predicates `xLIST_ITEM` and `DLS` have been extended to expose node
|
||||||
|
* owners. Proofs using these predicates must be adapted as well.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*@
|
||||||
|
lemma void dls_star_item(
|
||||||
|
struct xLIST_ITEM *n,
|
||||||
|
struct xLIST_ITEM *m,
|
||||||
|
struct xLIST_ITEM *o)
|
||||||
|
requires DLS(n, ?nprev, ?mnext, m, ?cells, ?vals, ?owners, ?l) &*& xLIST_ITEM(o, ?v, ?onext, ?oprev, ?ow, ?l2);
|
||||||
|
ensures DLS(n, nprev, mnext, m, cells, vals, owners, l) &*& xLIST_ITEM(o, v, onext, oprev, ow, l2) &*& mem(o, cells) == false;
|
||||||
|
{
|
||||||
|
open DLS(n, nprev, mnext, m, cells, vals, owners, l);
|
||||||
|
if (n == m) {
|
||||||
|
assert xLIST_ITEM(n, _, _, _, _, _);
|
||||||
|
open xLIST_ITEM(n, _, _, _, _, _);
|
||||||
|
open xLIST_ITEM(o, _, _, _, _, _);
|
||||||
|
assert n != o;
|
||||||
|
close xLIST_ITEM(o, _, _, _, _, _);
|
||||||
|
close xLIST_ITEM(n, _, _, _, _, _);
|
||||||
|
close DLS(n, nprev, mnext, m, cells, vals, owners, l);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert DLS(?nnext, n, mnext, m, tail(cells), tail(vals), tail(owners), l);
|
||||||
|
dls_star_item(nnext, m, o);
|
||||||
|
open xLIST_ITEM(n, _, _, _, _, _);
|
||||||
|
open xLIST_ITEM(o, _, _, _, _, _);
|
||||||
|
assert n != o;
|
||||||
|
close xLIST_ITEM(o, _, _, _, _, _);
|
||||||
|
close xLIST_ITEM(n, _, _, _, _, _);
|
||||||
|
close DLS(n, nprev, mnext, m, cells, vals, owners, l);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
assert DLS(?nnext, n, mnext, m, tail(cells), tail(vals), l);
|
|
||||||
dls_star_item(nnext, m, o);
|
lemma void dls_distinct(
|
||||||
open xLIST_ITEM(n, _, _, _, _);
|
struct xLIST_ITEM *n,
|
||||||
open xLIST_ITEM(o, _, _, _, _);
|
struct xLIST_ITEM *nprev,
|
||||||
assert n != o;
|
struct xLIST_ITEM *mnext,
|
||||||
close xLIST_ITEM(o, _, _, _, _);
|
struct xLIST_ITEM *m,
|
||||||
close xLIST_ITEM(n, _, _, _, _);
|
list<struct xLIST_ITEM * > cells)
|
||||||
close DLS(n, nprev, mnext, m, cells, vals, l);
|
requires DLS(n, nprev, mnext, m, cells, ?vals, ?owners, ?l);
|
||||||
|
ensures DLS(n, nprev, mnext, m, cells, vals, owners, l) &*& distinct(cells) == true;
|
||||||
|
{
|
||||||
|
if (n == m) {
|
||||||
|
open DLS(n, nprev, mnext, m, cells, vals, owners, l);
|
||||||
|
close DLS(n, nprev, mnext, m, cells, vals, owners, l);
|
||||||
|
} else {
|
||||||
|
open DLS(n, nprev, mnext, m, cells, vals, owners, l);
|
||||||
|
assert DLS(?nnext, n, mnext, m, tail(cells), tail(vals), tail(owners), l);
|
||||||
|
dls_distinct(nnext, n, mnext, m, tail(cells));
|
||||||
|
dls_star_item(nnext, m, n);
|
||||||
|
close DLS(n, nprev, mnext, m, cells, vals, owners, l);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
@*/
|
||||||
|
#else
|
||||||
|
/*@
|
||||||
lemma void dls_distinct(
|
lemma void dls_star_item(
|
||||||
struct xLIST_ITEM *n,
|
struct xLIST_ITEM *n,
|
||||||
struct xLIST_ITEM *nprev,
|
struct xLIST_ITEM *m,
|
||||||
struct xLIST_ITEM *mnext,
|
struct xLIST_ITEM *o)
|
||||||
struct xLIST_ITEM *m,
|
requires DLS(n, ?nprev, ?mnext, m, ?cells, ?vals, ?l) &*& xLIST_ITEM(o, ?v, ?onext, ?oprev, ?l2);
|
||||||
list<struct xLIST_ITEM * > cells)
|
ensures DLS(n, nprev, mnext, m, cells, vals, l) &*& xLIST_ITEM(o, v, onext, oprev, l2) &*& mem(o, cells) == false;
|
||||||
requires DLS(n, nprev, mnext, m, cells, ?vals, ?l);
|
{
|
||||||
ensures DLS(n, nprev, mnext, m, cells, vals, l) &*& distinct(cells) == true;
|
|
||||||
{
|
|
||||||
if (n == m) {
|
|
||||||
open DLS(n, nprev, mnext, m, cells, vals, l);
|
open DLS(n, nprev, mnext, m, cells, vals, l);
|
||||||
close DLS(n, nprev, mnext, m, cells, vals, l);
|
if (n == m) {
|
||||||
} else {
|
assert xLIST_ITEM(n, _, _, _, _);
|
||||||
|
open xLIST_ITEM(n, _, _, _, _);
|
||||||
|
open xLIST_ITEM(o, _, _, _, _);
|
||||||
|
assert n != o;
|
||||||
|
close xLIST_ITEM(o, _, _, _, _);
|
||||||
|
close xLIST_ITEM(n, _, _, _, _);
|
||||||
|
close DLS(n, nprev, mnext, m, cells, vals, l);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert DLS(?nnext, n, mnext, m, tail(cells), tail(vals), l);
|
||||||
|
dls_star_item(nnext, m, o);
|
||||||
|
open xLIST_ITEM(n, _, _, _, _);
|
||||||
|
open xLIST_ITEM(o, _, _, _, _);
|
||||||
|
assert n != o;
|
||||||
|
close xLIST_ITEM(o, _, _, _, _);
|
||||||
|
close xLIST_ITEM(n, _, _, _, _);
|
||||||
|
close DLS(n, nprev, mnext, m, cells, vals, l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
lemma void dls_distinct(
|
||||||
|
struct xLIST_ITEM *n,
|
||||||
|
struct xLIST_ITEM *nprev,
|
||||||
|
struct xLIST_ITEM *mnext,
|
||||||
|
struct xLIST_ITEM *m,
|
||||||
|
list<struct xLIST_ITEM * > cells)
|
||||||
|
requires DLS(n, nprev, mnext, m, cells, ?vals, ?l);
|
||||||
|
ensures DLS(n, nprev, mnext, m, cells, vals, l) &*& distinct(cells) == true;
|
||||||
|
{
|
||||||
|
if (n == m) {
|
||||||
|
open DLS(n, nprev, mnext, m, cells, vals, l);
|
||||||
|
close DLS(n, nprev, mnext, m, cells, vals, l);
|
||||||
|
} else {
|
||||||
|
open DLS(n, nprev, mnext, m, cells, vals, l);
|
||||||
|
assert DLS(?nnext, n, mnext, m, tail(cells), tail(vals), l);
|
||||||
|
dls_distinct(nnext, n, mnext, m, tail(cells));
|
||||||
|
dls_star_item(nnext, m, n);
|
||||||
|
close DLS(n, nprev, mnext, m, cells, vals, l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@*/
|
||||||
|
#endif /* VERIFAST_SINGLE_CORE */
|
||||||
|
|
||||||
|
#ifndef VERIFAST_SINGLE_CORE
|
||||||
|
/* Reason for rewrite:
|
||||||
|
* In order to verify the scheduler, we have to reason about each node's
|
||||||
|
* owner. Hence, the predicate has to expose it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*@
|
||||||
|
predicate xLIST(
|
||||||
|
struct xLIST *l,
|
||||||
|
int uxNumberOfItems,
|
||||||
|
struct xLIST_ITEM *pxIndex,
|
||||||
|
struct xLIST_ITEM *xListEnd,
|
||||||
|
list<struct xLIST_ITEM *>cells,
|
||||||
|
list<TickType_t >vals,
|
||||||
|
list<void*> owners) =
|
||||||
|
l->uxNumberOfItems |-> uxNumberOfItems &*&
|
||||||
|
l->pxIndex |-> pxIndex &*&
|
||||||
|
mem(pxIndex, cells) == true &*&
|
||||||
|
xListEnd == &(l->xListEnd) &*&
|
||||||
|
xListEnd == head(cells) &*&
|
||||||
|
portMAX_DELAY == head(vals) &*&
|
||||||
|
struct_xLIST_ITEM_padding(&l->xListEnd) &*&
|
||||||
|
length(cells) == length(vals) &*&
|
||||||
|
length(owners) == length(cells) &*&
|
||||||
|
uxNumberOfItems + 1 == length(cells) &*&
|
||||||
|
DLS(xListEnd, ?endprev, xListEnd, endprev, cells, vals, owners, l);
|
||||||
|
@*/
|
||||||
|
#else
|
||||||
|
/*@
|
||||||
|
predicate xLIST(
|
||||||
|
struct xLIST *l,
|
||||||
|
int uxNumberOfItems,
|
||||||
|
struct xLIST_ITEM *pxIndex,
|
||||||
|
struct xLIST_ITEM *xListEnd,
|
||||||
|
list<struct xLIST_ITEM *>cells,
|
||||||
|
list<TickType_t >vals) =
|
||||||
|
l->uxNumberOfItems |-> uxNumberOfItems &*&
|
||||||
|
l->pxIndex |-> pxIndex &*&
|
||||||
|
mem(pxIndex, cells) == true &*&
|
||||||
|
xListEnd == &(l->xListEnd) &*&
|
||||||
|
xListEnd == head(cells) &*&
|
||||||
|
portMAX_DELAY == head(vals) &*&
|
||||||
|
struct_xLIST_ITEM_padding(&l->xListEnd) &*&
|
||||||
|
length(cells) == length(vals) &*&
|
||||||
|
uxNumberOfItems + 1 == length(cells) &*&
|
||||||
|
DLS(xListEnd, ?endprev, xListEnd, endprev, cells, vals, l);
|
||||||
|
@*/
|
||||||
|
#endif /* VERIFAST_SINGLE_CORE */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef VERIFAST_SINGLE_CORE
|
||||||
|
/* Reason for rewrite:
|
||||||
|
* Predicates `xLIST_ITEM`, `DLS` and `xLIST` have been extended to expose
|
||||||
|
* node owners. Proofs using these predicates must be adapted as well.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*@
|
||||||
|
lemma void xLIST_distinct_cells(struct xLIST *l)
|
||||||
|
requires xLIST(l, ?n, ?idx, ?end, ?cells, ?vals, ?owners);
|
||||||
|
ensures xLIST(l, n, idx, end, cells, vals, owners) &*& distinct(cells) == true;
|
||||||
|
{
|
||||||
|
open xLIST(l, n, idx, end, cells, vals, owners);
|
||||||
|
assert DLS(end, ?endprev, end, _, cells, vals, owners, l);
|
||||||
|
dls_distinct(end, endprev, end, endprev, cells);
|
||||||
|
close xLIST(l, n, idx, end, cells, vals, owners);
|
||||||
|
}
|
||||||
|
|
||||||
|
lemma void xLIST_star_item(struct xLIST *l, struct xLIST_ITEM *x)
|
||||||
|
requires xLIST(l, ?n, ?idx, ?end, ?cells, ?vals, ?owners) &*& xLIST_ITEM(x, ?v, ?xnext, ?xprev, ?ow, ?l2);
|
||||||
|
ensures xLIST(l, n, idx, end, cells, vals, owners) &*& xLIST_ITEM(x, v, xnext, xprev, ow, l2) &*& mem(x, cells) == false;
|
||||||
|
{
|
||||||
|
open xLIST(l, n, idx, end, cells, vals, owners);
|
||||||
|
assert DLS(end, ?endprev, end, _, cells, vals, owners, l);
|
||||||
|
dls_distinct(end, endprev, end, endprev, cells);
|
||||||
|
dls_star_item(end, endprev, x);
|
||||||
|
close xLIST(l, n, idx, end, cells, vals, owners);
|
||||||
|
}
|
||||||
|
|
||||||
|
lemma void dls_first_mem(
|
||||||
|
struct xLIST_ITEM *n,
|
||||||
|
struct xLIST_ITEM *nprev,
|
||||||
|
struct xLIST_ITEM *mnext,
|
||||||
|
struct xLIST_ITEM *m,
|
||||||
|
list<struct xLIST_ITEM * > cells)
|
||||||
|
requires DLS(n, nprev, mnext, m, cells, ?vals, ?owners, ?l);
|
||||||
|
ensures DLS(n, nprev, mnext, m, cells, vals, owners, l) &*& mem(n, cells) == true &*& index_of(n, cells) == 0;
|
||||||
|
{
|
||||||
|
open DLS(n, nprev, mnext, m, cells, vals, owners, l);
|
||||||
|
if (n == m) {
|
||||||
|
assert cells == cons(n, nil);
|
||||||
|
close DLS(n, nprev, mnext, m, cells, vals, owners, l);
|
||||||
|
} else {
|
||||||
|
assert cells == cons(n, ?tail);
|
||||||
|
close DLS(n, nprev, mnext, m, cells, vals, owners, l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lemma void dls_not_empty(
|
||||||
|
struct xLIST_ITEM *n,
|
||||||
|
struct xLIST_ITEM *m,
|
||||||
|
list<struct xLIST_ITEM * > cells,
|
||||||
|
struct xLIST_ITEM *x)
|
||||||
|
requires DLS(n, m, n, m, cells, ?vals, ?owners, ?l) &*& mem(x, cells) == true &*& x != n;
|
||||||
|
ensures DLS(n, m, n, m, cells, vals, owners, l) &*& n != m;
|
||||||
|
{
|
||||||
|
open DLS(n, m, n, m, cells, vals, owners, l);
|
||||||
|
close DLS(n, m, n, m, cells, vals, owners, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
lemma void dls_last_mem(
|
||||||
|
struct xLIST_ITEM *n,
|
||||||
|
struct xLIST_ITEM *nprev,
|
||||||
|
struct xLIST_ITEM *mnext,
|
||||||
|
struct xLIST_ITEM *m,
|
||||||
|
list<struct xLIST_ITEM * > cells)
|
||||||
|
requires DLS(n, nprev, mnext, m, cells, ?vals, ?owners, ?l);
|
||||||
|
ensures DLS(n, nprev, mnext, m, cells, vals, owners, l) &*& mem(m, cells) == true &*& index_of(m, cells) == length(cells) - 1;
|
||||||
|
{
|
||||||
|
open DLS(n, nprev, mnext, m, cells, vals, owners, l);
|
||||||
|
if (n == m) {
|
||||||
|
// trivial
|
||||||
|
} else {
|
||||||
|
open xLIST_ITEM(n, _, ?nnext, _, _, l);
|
||||||
|
assert DLS(?o, n, mnext, m, tail(cells), tail(vals), tail(owners), l);
|
||||||
|
dls_last_mem(o, n, mnext, m, tail(cells));
|
||||||
|
close xLIST_ITEM(n, _, nnext, _, _, l);
|
||||||
|
}
|
||||||
|
close DLS(n, nprev, mnext, m, cells, vals, owners, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
lemma void split(
|
||||||
|
struct xLIST_ITEM *n,
|
||||||
|
struct xLIST_ITEM *nprev,
|
||||||
|
struct xLIST_ITEM *mnext,
|
||||||
|
struct xLIST_ITEM *m,
|
||||||
|
list<struct xLIST_ITEM * > cells,
|
||||||
|
list<TickType_t > vals,
|
||||||
|
struct xLIST_ITEM *x,
|
||||||
|
int i)
|
||||||
|
requires DLS(n, nprev, mnext, m, cells, vals, ?owners, ?l) &*& x != n &*& mem(x, cells) == true &*& index_of(x,cells) == i;
|
||||||
|
ensures DLS(n, nprev, x, ?xprev, take(i, cells), take(i, vals), take(i, owners), l) &*& DLS(x, xprev, mnext, m, drop(i, cells), drop(i, vals), drop(i, owners), l) &*& xprev == nth(i-1, cells);
|
||||||
|
{
|
||||||
|
open DLS(n, nprev, mnext, m, cells, vals, owners, l);
|
||||||
|
assert n != m;
|
||||||
|
assert xLIST_ITEM(n, ?v, ?nnext, _, ?ow, _);
|
||||||
|
assert DLS(nnext, n, mnext, m, tail(cells), tail(vals), tail(owners), l);
|
||||||
|
if (nnext == x) {
|
||||||
|
close DLS(n, nprev, x, n, singleton(n), singleton(v), singleton(ow), l);
|
||||||
|
open DLS(x, n, mnext, m, tail(cells), tail(vals), tail(owners), l);
|
||||||
|
open xLIST_ITEM(x, _, ?xnext, ?xprev, ?xow, l);
|
||||||
|
close xLIST_ITEM(x, _, xnext, xprev, xow, l);
|
||||||
|
close DLS(x, n, mnext, m, tail(cells), tail(vals), tail(owners), l);
|
||||||
|
} else {
|
||||||
|
assert nnext != x;
|
||||||
|
split(nnext, n, mnext, m, tail(cells), tail(vals), x, i - 1);
|
||||||
|
assert DLS(nnext, n, x, ?xprev, take(i-1, tail(cells)), take(i-1, tail(vals)), take(i-1, tail(owners)), l);
|
||||||
|
dls_distinct(nnext, n, x, xprev, take(i-1, tail(cells)));
|
||||||
|
dls_star_item(nnext, xprev, n);
|
||||||
|
dls_last_mem(nnext, n, x, xprev, take(i-1, tail(cells)));
|
||||||
|
assert n != xprev;
|
||||||
|
close DLS(n, nprev, x, xprev, take(i, cells), take(i, vals), take(i, owners), l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lemma void join(
|
||||||
|
struct xLIST_ITEM *n1,
|
||||||
|
struct xLIST_ITEM *nprev1,
|
||||||
|
struct xLIST_ITEM *mnext1,
|
||||||
|
struct xLIST_ITEM *m1,
|
||||||
|
list<struct xLIST_ITEM * > cells1,
|
||||||
|
list<TickType_t > vals1,
|
||||||
|
struct xLIST_ITEM *n2,
|
||||||
|
struct xLIST_ITEM *nprev2,
|
||||||
|
struct xLIST_ITEM *mnext2,
|
||||||
|
struct xLIST_ITEM *m2,
|
||||||
|
list<struct xLIST_ITEM * > cells2,
|
||||||
|
list<TickType_t > vals2)
|
||||||
|
requires
|
||||||
|
DLS(n1, nprev1, mnext1, m1, cells1, vals1, ?owners1, ?l) &*&
|
||||||
|
DLS(n2, nprev2, mnext2, m2, cells2, vals2, ?owners2, l) &*&
|
||||||
|
mnext1 == n2 &*& m1 == nprev2;
|
||||||
|
ensures DLS(n1, nprev1, mnext2, m2, append(cells1, cells2), append(vals1, vals2), append(owners1, owners2), l);
|
||||||
|
{
|
||||||
|
if (n1 == m1) {
|
||||||
|
dls_first_mem(n1, nprev1, mnext1, m1, cells1);
|
||||||
|
dls_last_mem(n2, nprev2, mnext2, m2, cells2);
|
||||||
|
open DLS(n1, nprev1, mnext1, m1, cells1, vals1, owners1, l);
|
||||||
|
dls_star_item(n2, m2, n1);
|
||||||
|
close DLS(n1, nprev1, mnext2, m2, append(singleton(n1), cells2), append(vals1, vals2), append(owners1, owners2) ,l);
|
||||||
|
} else {
|
||||||
|
open DLS(n1, nprev1, mnext1, m1, cells1, vals1, owners1, l);
|
||||||
|
assert DLS(?o, n1, mnext1, m1, ?cells1_tail, ?vals1_tail, ?owners1_tail, l);
|
||||||
|
join(o, n1, mnext1, m1, cells1_tail, vals1_tail,
|
||||||
|
n2, nprev2, mnext2, m2, cells2, vals2);
|
||||||
|
assert DLS(o, n1, mnext2, m2, append(cells1_tail, cells2), append(vals1_tail, vals2), append(owners1_tail, owners2), l);
|
||||||
|
dls_last_mem(o, n1, mnext2, m2, append(cells1_tail, cells2));
|
||||||
|
dls_star_item(o, m2, n1);
|
||||||
|
close DLS(n1, nprev1, mnext2, m2, append(cells1, cells2), append(vals1, vals2), append(owners1, owners2), l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@*/
|
||||||
|
#else
|
||||||
|
/*@
|
||||||
|
lemma void xLIST_distinct_cells(struct xLIST *l)
|
||||||
|
requires xLIST(l, ?n, ?idx, ?end, ?cells, ?vals);
|
||||||
|
ensures xLIST(l, n, idx, end, cells, vals) &*& distinct(cells) == true;
|
||||||
|
{
|
||||||
|
open xLIST(l, n, idx, end, cells, vals);
|
||||||
|
assert DLS(end, ?endprev, end, _, cells, vals, l);
|
||||||
|
dls_distinct(end, endprev, end, endprev, cells);
|
||||||
|
close xLIST(l, n, idx, end, cells, vals);
|
||||||
|
}
|
||||||
|
|
||||||
|
lemma void xLIST_star_item(struct xLIST *l, struct xLIST_ITEM *x)
|
||||||
|
requires xLIST(l, ?n, ?idx, ?end, ?cells, ?vals) &*& xLIST_ITEM(x, ?v, ?xnext, ?xprev, ?l2);
|
||||||
|
ensures xLIST(l, n, idx, end, cells, vals) &*& xLIST_ITEM(x, v, xnext, xprev, l2) &*& mem(x, cells) == false;
|
||||||
|
{
|
||||||
|
open xLIST(l, n, idx, end, cells, vals);
|
||||||
|
assert DLS(end, ?endprev, end, _, cells, vals, l);
|
||||||
|
dls_distinct(end, endprev, end, endprev, cells);
|
||||||
|
dls_star_item(end, endprev, x);
|
||||||
|
close xLIST(l, n, idx, end, cells, vals);
|
||||||
|
}
|
||||||
|
|
||||||
|
lemma void dls_first_mem(
|
||||||
|
struct xLIST_ITEM *n,
|
||||||
|
struct xLIST_ITEM *nprev,
|
||||||
|
struct xLIST_ITEM *mnext,
|
||||||
|
struct xLIST_ITEM *m,
|
||||||
|
list<struct xLIST_ITEM * > cells)
|
||||||
|
requires DLS(n, nprev, mnext, m, cells, ?vals, ?l);
|
||||||
|
ensures DLS(n, nprev, mnext, m, cells, vals, l) &*& mem(n, cells) == true &*& index_of(n, cells) == 0;
|
||||||
|
{
|
||||||
open DLS(n, nprev, mnext, m, cells, vals, l);
|
open DLS(n, nprev, mnext, m, cells, vals, l);
|
||||||
assert DLS(?nnext, n, mnext, m, tail(cells), tail(vals), l);
|
if (n == m) {
|
||||||
dls_distinct(nnext, n, mnext, m, tail(cells));
|
assert cells == cons(n, nil);
|
||||||
dls_star_item(nnext, m, n);
|
close DLS(n, nprev, mnext, m, cells, vals, l);
|
||||||
|
} else {
|
||||||
|
assert cells == cons(n, ?tail);
|
||||||
|
close DLS(n, nprev, mnext, m, cells, vals, l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lemma void dls_not_empty(
|
||||||
|
struct xLIST_ITEM *n,
|
||||||
|
struct xLIST_ITEM *m,
|
||||||
|
list<struct xLIST_ITEM * > cells,
|
||||||
|
struct xLIST_ITEM *x)
|
||||||
|
requires DLS(n, m, n, m, cells, ?vals, ?l) &*& mem(x, cells) == true &*& x != n;
|
||||||
|
ensures DLS(n, m, n, m, cells, vals, l) &*& n != m;
|
||||||
|
{
|
||||||
|
open DLS(n, m, n, m, cells, vals, l);
|
||||||
|
close DLS(n, m, n, m, cells, vals, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
lemma void dls_last_mem(
|
||||||
|
struct xLIST_ITEM *n,
|
||||||
|
struct xLIST_ITEM *nprev,
|
||||||
|
struct xLIST_ITEM *mnext,
|
||||||
|
struct xLIST_ITEM *m,
|
||||||
|
list<struct xLIST_ITEM * > cells)
|
||||||
|
requires DLS(n, nprev, mnext, m, cells, ?vals, ?l);
|
||||||
|
ensures DLS(n, nprev, mnext, m, cells, vals, l) &*& mem(m, cells) == true &*& index_of(m, cells) == length(cells) - 1;
|
||||||
|
{
|
||||||
|
open DLS(n, nprev, mnext, m, cells, vals, l);
|
||||||
|
if (n == m) {
|
||||||
|
// trivial
|
||||||
|
} else {
|
||||||
|
open xLIST_ITEM(n, _, ?nnext, _, l);
|
||||||
|
assert DLS(?o, n, mnext, m, tail(cells), tail(vals), l);
|
||||||
|
dls_last_mem(o, n, mnext, m, tail(cells));
|
||||||
|
close xLIST_ITEM(n, _, nnext, _, l);
|
||||||
|
}
|
||||||
close DLS(n, nprev, mnext, m, cells, vals, l);
|
close DLS(n, nprev, mnext, m, cells, vals, l);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
predicate xLIST(
|
lemma void split(
|
||||||
struct xLIST *l,
|
struct xLIST_ITEM *n,
|
||||||
int uxNumberOfItems,
|
struct xLIST_ITEM *nprev,
|
||||||
struct xLIST_ITEM *pxIndex,
|
struct xLIST_ITEM *mnext,
|
||||||
struct xLIST_ITEM *xListEnd,
|
struct xLIST_ITEM *m,
|
||||||
list<struct xLIST_ITEM *>cells,
|
list<struct xLIST_ITEM * > cells,
|
||||||
list<TickType_t >vals) =
|
list<TickType_t > vals,
|
||||||
l->uxNumberOfItems |-> uxNumberOfItems &*&
|
struct xLIST_ITEM *x,
|
||||||
l->pxIndex |-> pxIndex &*&
|
int i)
|
||||||
mem(pxIndex, cells) == true &*&
|
requires DLS(n, nprev, mnext, m, cells, vals, ?l) &*& x != n &*& mem(x, cells) == true &*& index_of(x,cells) == i;
|
||||||
xListEnd == &(l->xListEnd) &*&
|
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);
|
||||||
xListEnd == head(cells) &*&
|
{
|
||||||
portMAX_DELAY == head(vals) &*&
|
open DLS(n, nprev, mnext, m, cells, vals, l);
|
||||||
struct_xLIST_ITEM_padding(&l->xListEnd) &*&
|
assert n != m;
|
||||||
length(cells) == length(vals) &*&
|
assert xLIST_ITEM(n, ?v, ?nnext, _, _);
|
||||||
uxNumberOfItems + 1 == length(cells) &*&
|
assert DLS(nnext, n, mnext, m, tail(cells), tail(vals), l);
|
||||||
DLS(xListEnd, ?endprev, xListEnd, endprev, cells, vals, l);
|
if (nnext == x) {
|
||||||
|
close DLS(n, nprev, x, n, singleton(n), singleton(v), l);
|
||||||
lemma void xLIST_distinct_cells(struct xLIST *l)
|
open DLS(x, n, mnext, m, tail(cells), tail(vals), l);
|
||||||
requires xLIST(l, ?n, ?idx, ?end, ?cells, ?vals);
|
open xLIST_ITEM(x, _, ?xnext, ?xprev, l);
|
||||||
ensures xLIST(l, n, idx, end, cells, vals) &*& distinct(cells) == true;
|
close xLIST_ITEM(x, _, xnext, xprev, l);
|
||||||
{
|
close DLS(x, n, mnext, m, tail(cells), tail(vals), l);
|
||||||
open xLIST(l, n, idx, end, cells, vals);
|
} else {
|
||||||
assert DLS(end, ?endprev, end, _, cells, vals, l);
|
assert nnext != x;
|
||||||
dls_distinct(end, endprev, end, endprev, cells);
|
split(nnext, n, mnext, m, tail(cells), tail(vals), x, i - 1);
|
||||||
close xLIST(l, n, idx, end, cells, vals);
|
assert DLS(nnext, n, x, ?xprev, take(i-1, tail(cells)), take(i-1, tail(vals)), l);
|
||||||
}
|
dls_distinct(nnext, n, x, xprev, take(i-1, tail(cells)));
|
||||||
|
dls_star_item(nnext, xprev, n);
|
||||||
lemma void xLIST_star_item(struct xLIST *l, struct xLIST_ITEM *x)
|
dls_last_mem(nnext, n, x, xprev, take(i-1, tail(cells)));
|
||||||
requires xLIST(l, ?n, ?idx, ?end, ?cells, ?vals) &*& xLIST_ITEM(x, ?v, ?xnext, ?xprev, ?l2);
|
assert n != xprev;
|
||||||
ensures xLIST(l, n, idx, end, cells, vals) &*& xLIST_ITEM(x, v, xnext, xprev, l2) &*& mem(x, cells) == false;
|
close DLS(n, nprev, x, xprev, take(i, cells), take(i, vals), l);
|
||||||
{
|
}
|
||||||
open xLIST(l, n, idx, end, cells, vals);
|
|
||||||
assert DLS(end, ?endprev, end, _, cells, vals, l);
|
|
||||||
dls_distinct(end, endprev, end, endprev, cells);
|
|
||||||
dls_star_item(end, endprev, x);
|
|
||||||
close xLIST(l, n, idx, end, cells, vals);
|
|
||||||
}
|
|
||||||
|
|
||||||
lemma void dls_first_mem(
|
|
||||||
struct xLIST_ITEM *n,
|
|
||||||
struct xLIST_ITEM *nprev,
|
|
||||||
struct xLIST_ITEM *mnext,
|
|
||||||
struct xLIST_ITEM *m,
|
|
||||||
list<struct xLIST_ITEM * > cells)
|
|
||||||
requires DLS(n, nprev, mnext, m, cells, ?vals, ?l);
|
|
||||||
ensures DLS(n, nprev, mnext, m, cells, vals, l) &*& mem(n, cells) == true &*& index_of(n, cells) == 0;
|
|
||||||
{
|
|
||||||
open DLS(n, nprev, mnext, m, cells, vals, l);
|
|
||||||
if (n == m) {
|
|
||||||
assert cells == cons(n, nil);
|
|
||||||
close DLS(n, nprev, mnext, m, cells, vals, l);
|
|
||||||
} else {
|
|
||||||
assert cells == cons(n, ?tail);
|
|
||||||
close DLS(n, nprev, mnext, m, cells, vals, l);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
lemma void dls_not_empty(
|
lemma void join(
|
||||||
struct xLIST_ITEM *n,
|
struct xLIST_ITEM *n1,
|
||||||
struct xLIST_ITEM *m,
|
struct xLIST_ITEM *nprev1,
|
||||||
list<struct xLIST_ITEM * > cells,
|
struct xLIST_ITEM *mnext1,
|
||||||
struct xLIST_ITEM *x)
|
struct xLIST_ITEM *m1,
|
||||||
requires DLS(n, m, n, m, cells, ?vals, ?l) &*& mem(x, cells) == true &*& x != n;
|
list<struct xLIST_ITEM * > cells1,
|
||||||
ensures DLS(n, m, n, m, cells, vals, l) &*& n != m;
|
list<TickType_t > vals1,
|
||||||
{
|
struct xLIST_ITEM *n2,
|
||||||
open DLS(n, m, n, m, cells, vals, l);
|
struct xLIST_ITEM *nprev2,
|
||||||
close DLS(n, m, n, m, cells, vals, l);
|
struct xLIST_ITEM *mnext2,
|
||||||
}
|
struct xLIST_ITEM *m2,
|
||||||
|
list<struct xLIST_ITEM * > cells2,
|
||||||
lemma void dls_last_mem(
|
list<TickType_t > vals2)
|
||||||
struct xLIST_ITEM *n,
|
requires
|
||||||
struct xLIST_ITEM *nprev,
|
DLS(n1, nprev1, mnext1, m1, cells1, vals1, ?l) &*&
|
||||||
struct xLIST_ITEM *mnext,
|
DLS(n2, nprev2, mnext2, m2, cells2, vals2, l) &*&
|
||||||
struct xLIST_ITEM *m,
|
mnext1 == n2 &*& m1 == nprev2;
|
||||||
list<struct xLIST_ITEM * > cells)
|
ensures DLS(n1, nprev1, mnext2, m2, append(cells1, cells2), append(vals1, vals2), l);
|
||||||
requires DLS(n, nprev, mnext, m, cells, ?vals, ?l);
|
{
|
||||||
ensures DLS(n, nprev, mnext, m, cells, vals, l) &*& mem(m, cells) == true &*& index_of(m, cells) == length(cells) - 1;
|
if (n1 == m1) {
|
||||||
{
|
dls_first_mem(n1, nprev1, mnext1, m1, cells1);
|
||||||
open DLS(n, nprev, mnext, m, cells, vals, l);
|
dls_last_mem(n2, nprev2, mnext2, m2, cells2);
|
||||||
if (n == m) {
|
open DLS(n1, nprev1, mnext1, m1, cells1, vals1, l);
|
||||||
// trivial
|
dls_star_item(n2, m2, n1);
|
||||||
} else {
|
close DLS(n1, nprev1, mnext2, m2, append(singleton(n1), cells2), append(vals1, vals2), l);
|
||||||
open xLIST_ITEM(n, _, ?nnext, _, l);
|
} else {
|
||||||
assert DLS(?o, n, mnext, m, tail(cells), tail(vals), l);
|
open DLS(n1, nprev1, mnext1, m1, cells1, vals1, l);
|
||||||
dls_last_mem(o, n, mnext, m, tail(cells));
|
assert DLS(?o, n1, mnext1, m1, ?cells1_tail, ?vals1_tail, l);
|
||||||
close xLIST_ITEM(n, _, nnext, _, l);
|
join(o, n1, mnext1, m1, cells1_tail, vals1_tail,
|
||||||
|
n2, nprev2, mnext2, m2, cells2, vals2);
|
||||||
|
assert DLS(o, n1, mnext2, m2, append(cells1_tail, cells2), append(vals1_tail, vals2), l);
|
||||||
|
dls_last_mem(o, n1, mnext2, m2, append(cells1_tail, cells2));
|
||||||
|
dls_star_item(o, m2, n1);
|
||||||
|
close DLS(n1, nprev1, mnext2, m2, append(cells1, cells2), append(vals1, vals2), l);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
close DLS(n, nprev, mnext, m, cells, vals, l);
|
@*/
|
||||||
}
|
#endif /* VERIFAST_SINGLE_CORE */
|
||||||
|
|
||||||
|
|
||||||
lemma void split(
|
|
||||||
struct xLIST_ITEM *n,
|
|
||||||
struct xLIST_ITEM *nprev,
|
|
||||||
struct xLIST_ITEM *mnext,
|
|
||||||
struct xLIST_ITEM *m,
|
|
||||||
list<struct xLIST_ITEM * > cells,
|
|
||||||
list<TickType_t > vals,
|
|
||||||
struct xLIST_ITEM *x,
|
|
||||||
int i)
|
|
||||||
requires DLS(n, nprev, mnext, m, cells, vals, ?l) &*& x != n &*& mem(x, cells) == true &*& index_of(x,cells) == i;
|
|
||||||
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);
|
|
||||||
{
|
|
||||||
open DLS(n, nprev, mnext, m, cells, vals, l);
|
|
||||||
assert n != m;
|
|
||||||
assert xLIST_ITEM(n, ?v, ?nnext, _, _);
|
|
||||||
assert DLS(nnext, n, mnext, m, tail(cells), tail(vals), l);
|
|
||||||
if (nnext == x) {
|
|
||||||
close DLS(n, nprev, x, n, singleton(n), singleton(v), l);
|
|
||||||
open DLS(x, n, mnext, m, tail(cells), tail(vals), l);
|
|
||||||
open xLIST_ITEM(x, _, ?xnext, ?xprev, l);
|
|
||||||
close xLIST_ITEM(x, _, xnext, xprev, l);
|
|
||||||
close DLS(x, n, mnext, m, tail(cells), tail(vals), l);
|
|
||||||
} else {
|
|
||||||
assert nnext != x;
|
|
||||||
split(nnext, n, mnext, m, tail(cells), tail(vals), x, i - 1);
|
|
||||||
assert DLS(nnext, n, x, ?xprev, take(i-1, tail(cells)), take(i-1, tail(vals)), l);
|
|
||||||
dls_distinct(nnext, n, x, xprev, take(i-1, tail(cells)));
|
|
||||||
dls_star_item(nnext, xprev, n);
|
|
||||||
dls_last_mem(nnext, n, x, xprev, take(i-1, tail(cells)));
|
|
||||||
assert n != xprev;
|
|
||||||
close DLS(n, nprev, x, xprev, take(i, cells), take(i, vals), l);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lemma void join(
|
|
||||||
struct xLIST_ITEM *n1,
|
|
||||||
struct xLIST_ITEM *nprev1,
|
|
||||||
struct xLIST_ITEM *mnext1,
|
|
||||||
struct xLIST_ITEM *m1,
|
|
||||||
list<struct xLIST_ITEM * > cells1,
|
|
||||||
list<TickType_t > vals1,
|
|
||||||
struct xLIST_ITEM *n2,
|
|
||||||
struct xLIST_ITEM *nprev2,
|
|
||||||
struct xLIST_ITEM *mnext2,
|
|
||||||
struct xLIST_ITEM *m2,
|
|
||||||
list<struct xLIST_ITEM * > cells2,
|
|
||||||
list<TickType_t > vals2)
|
|
||||||
requires
|
|
||||||
DLS(n1, nprev1, mnext1, m1, cells1, vals1, ?l) &*&
|
|
||||||
DLS(n2, nprev2, mnext2, m2, cells2, vals2, l) &*&
|
|
||||||
mnext1 == n2 &*& m1 == nprev2;
|
|
||||||
ensures DLS(n1, nprev1, mnext2, m2, append(cells1, cells2), append(vals1, vals2), l);
|
|
||||||
{
|
|
||||||
if (n1 == m1) {
|
|
||||||
dls_first_mem(n1, nprev1, mnext1, m1, cells1);
|
|
||||||
dls_last_mem(n2, nprev2, mnext2, m2, cells2);
|
|
||||||
open DLS(n1, nprev1, mnext1, m1, cells1, vals1, l);
|
|
||||||
dls_star_item(n2, m2, n1);
|
|
||||||
close DLS(n1, nprev1, mnext2, m2, append(singleton(n1), cells2), append(vals1, vals2), l);
|
|
||||||
} else {
|
|
||||||
open DLS(n1, nprev1, mnext1, m1, cells1, vals1, l);
|
|
||||||
assert DLS(?o, n1, mnext1, m1, ?cells1_tail, ?vals1_tail, l);
|
|
||||||
join(o, n1, mnext1, m1, cells1_tail, vals1_tail,
|
|
||||||
n2, nprev2, mnext2, m2, cells2, vals2);
|
|
||||||
assert DLS(o, n1, mnext2, m2, append(cells1_tail, cells2), append(vals1_tail, vals2), l);
|
|
||||||
dls_last_mem(o, n1, mnext2, m2, append(cells1_tail, cells2));
|
|
||||||
dls_star_item(o, m2, n1);
|
|
||||||
close DLS(n1, nprev1, mnext2, m2, append(cells1, cells2), append(vals1, vals2), l);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@*/
|
|
||||||
|
|
||||||
#ifdef VERIFAST_TODO
|
#ifdef VERIFAST_TODO
|
||||||
lemma void idx_remains_in_list<t>(
|
lemma void idx_remains_in_list<t>(
|
||||||
|
|
|
||||||
|
|
@ -359,6 +359,7 @@ ensures
|
||||||
}
|
}
|
||||||
@*/
|
@*/
|
||||||
|
|
||||||
|
#ifdef IGNORE_DEPRECATED
|
||||||
/* By verifying the following function, we can validate that the above lemmas
|
/* By verifying the following function, we can validate that the above lemmas
|
||||||
* apply to the use cases they are meant for.
|
* apply to the use cases they are meant for.
|
||||||
*/
|
*/
|
||||||
|
|
@ -410,6 +411,7 @@ void lemma_validation__DLS_item_next(struct xLIST_ITEM* pxTaskItem)
|
||||||
|
|
||||||
//@ assert( mem(pxItem_1, gCells) == true );
|
//@ assert( mem(pxItem_1, gCells) == true );
|
||||||
}
|
}
|
||||||
|
#endif I/* GNORE_DEPRECATED */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -429,6 +431,7 @@ predicate DLS_prefix(
|
||||||
// prefix args
|
// prefix args
|
||||||
list<struct xLIST_ITEM*> prefCells,
|
list<struct xLIST_ITEM*> prefCells,
|
||||||
list<TickType_t> prefVals,
|
list<TickType_t> prefVals,
|
||||||
|
list<void*> prefOwners,
|
||||||
struct xLIST_ITEM* item,
|
struct xLIST_ITEM* item,
|
||||||
struct xLIST_ITEM* itemPrev,
|
struct xLIST_ITEM* itemPrev,
|
||||||
// unsplit DLS args
|
// unsplit DLS args
|
||||||
|
|
@ -436,22 +439,26 @@ predicate DLS_prefix(
|
||||||
struct xLIST_ITEM *endPrev,
|
struct xLIST_ITEM *endPrev,
|
||||||
struct xLIST *pxContainer) =
|
struct xLIST *pxContainer) =
|
||||||
length(prefCells) == length(prefVals) &*&
|
length(prefCells) == length(prefVals) &*&
|
||||||
|
length(prefOwners) == length(prefCells) &*&
|
||||||
switch(prefCells) {
|
switch(prefCells) {
|
||||||
case nil: return
|
case nil: return
|
||||||
prefVals == nil &*&
|
prefVals == nil &*&
|
||||||
|
prefOwners == nil &*&
|
||||||
item == end &*&
|
item == end &*&
|
||||||
itemPrev == endPrev;
|
itemPrev == endPrev;
|
||||||
case cons(headItem, tailCells): return
|
case cons(headItem, tailCells): return
|
||||||
item != end &*&
|
item != end &*&
|
||||||
// itemPrev != endPrev &*& // do we need to know this?
|
// itemPrev != endPrev &*& // do we need to know this?
|
||||||
headItem == end &*&
|
headItem == end &*&
|
||||||
DLS(end, endPrev, item, itemPrev, prefCells, prefVals, pxContainer);
|
DLS(end, endPrev, item, itemPrev, prefCells, prefVals, prefOwners,
|
||||||
|
pxContainer);
|
||||||
};
|
};
|
||||||
|
|
||||||
predicate DLS_suffix(
|
predicate DLS_suffix(
|
||||||
// suffix args
|
// suffix args
|
||||||
list<struct xLIST_ITEM*> sufCells,
|
list<struct xLIST_ITEM*> sufCells,
|
||||||
list<TickType_t> sufVals,
|
list<TickType_t> sufVals,
|
||||||
|
list<void*> sufOwners,
|
||||||
struct xLIST_ITEM* item,
|
struct xLIST_ITEM* item,
|
||||||
struct xLIST_ITEM* itemNext,
|
struct xLIST_ITEM* itemNext,
|
||||||
// unsplit DLS args
|
// unsplit DLS args
|
||||||
|
|
@ -459,38 +466,43 @@ predicate DLS_suffix(
|
||||||
struct xLIST_ITEM *endPrev,
|
struct xLIST_ITEM *endPrev,
|
||||||
struct xLIST *pxContainer) =
|
struct xLIST *pxContainer) =
|
||||||
length(sufCells) == length(sufVals) &*&
|
length(sufCells) == length(sufVals) &*&
|
||||||
|
length(sufOwners) == length(sufCells) &*&
|
||||||
switch(sufCells) {
|
switch(sufCells) {
|
||||||
case nil: return
|
case nil: return
|
||||||
sufVals == nil &*&
|
sufVals == nil &*&
|
||||||
|
sufOwners == nil &*&
|
||||||
item == endPrev &*&
|
item == endPrev &*&
|
||||||
itemNext == end;
|
itemNext == end;
|
||||||
case cons(headItem, tailCells): return
|
case cons(headItem, tailCells): return
|
||||||
item != endPrev &*&
|
item != endPrev &*&
|
||||||
mem(endPrev, sufCells) == true &*&
|
mem(endPrev, sufCells) == true &*&
|
||||||
index_of(endPrev, sufCells) == length(sufCells)-1 &*&
|
index_of(endPrev, sufCells) == length(sufCells)-1 &*&
|
||||||
DLS(itemNext, item, end, endPrev, sufCells, sufVals, pxContainer);
|
DLS(itemNext, item, end, endPrev, sufCells, sufVals, sufOwners,
|
||||||
|
pxContainer);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
lemma void DLS_open_2(struct xLIST_ITEM* pxItem)
|
lemma void DLS_open_2(struct xLIST_ITEM* pxItem)
|
||||||
requires
|
requires
|
||||||
DLS(?gEnd, ?gEndPrev, gEnd, gEndPrev, ?gCells, ?gVals, ?gList) &*&
|
DLS(?gEnd, ?gEndPrev, gEnd, gEndPrev, ?gCells, ?gVals, ?gOwners, ?gList) &*&
|
||||||
mem(pxItem, gCells) == true &*&
|
mem(pxItem, gCells) == true &*&
|
||||||
gEnd == head(gCells) &*&
|
gEnd == head(gCells) &*&
|
||||||
length(gCells) == length(gVals) &*&
|
length(gCells) == length(gVals) &*&
|
||||||
|
length(gOwners) == length(gCells) &*&
|
||||||
length(gCells) > 1;
|
length(gCells) > 1;
|
||||||
ensures
|
ensures
|
||||||
DLS_prefix(?gPrefCells, ?gPrefVals, pxItem, ?gItemPrev,
|
DLS_prefix(?gPrefCells, ?gPrefVals, ?gPrefOwners, pxItem, ?gItemPrev,
|
||||||
gEnd, gEndPrev, gList)
|
gEnd, gEndPrev, gList)
|
||||||
&*&
|
&*&
|
||||||
xLIST_ITEM(pxItem, ?gItemVal, ?gItemNext, gItemPrev, gList)
|
xLIST_ITEM(pxItem, ?gItemVal, ?gItemNext, gItemPrev, ?gOw, gList)
|
||||||
&*&
|
&*&
|
||||||
DLS_suffix(?gSufCells, ?gSufVals, pxItem, gItemNext, gEnd, gEndPrev, gList)
|
DLS_suffix(?gSufCells, ?gSufVals, ?gSufOwners, pxItem, gItemNext,
|
||||||
|
gEnd, gEndPrev, gList)
|
||||||
&*&
|
&*&
|
||||||
// gCells == gPrefCells + item + gSufCells
|
// lists have form "prefix + element + suffix"
|
||||||
gCells == append(gPrefCells, append(singleton(pxItem), gSufCells)) &*&
|
gCells == append(gPrefCells, append(singleton(pxItem), gSufCells)) &*&
|
||||||
// gVals == gPrefVals + item + gSufVals
|
gVals == append(gPrefVals, append(singleton(gItemVal), gSufVals)) &*&
|
||||||
gVals == append(gPrefVals, append(singleton(gItemVal), gSufVals))
|
gOwners == append(gPrefOwners, append(singleton(gOw), gSufOwners))
|
||||||
&*&
|
&*&
|
||||||
// next in cells
|
// next in cells
|
||||||
mem(gItemNext, gCells) == true &*&
|
mem(gItemNext, gCells) == true &*&
|
||||||
|
|
@ -502,25 +514,27 @@ ensures
|
||||||
// pxItem is first/ left-most item in the list
|
// pxItem is first/ left-most item in the list
|
||||||
// -> empty prefix
|
// -> empty prefix
|
||||||
|
|
||||||
open DLS(gEnd, gEndPrev, gEnd, gEndPrev, gCells, gVals, gList);
|
open DLS(gEnd, gEndPrev, gEnd, gEndPrev, gCells, gVals, gOwners, gList);
|
||||||
assert( xLIST_ITEM(pxItem, ?gItemVal, ?gItemNext, ?gItemPrev, gList) );
|
assert( xLIST_ITEM(pxItem, ?gItemVal, ?gItemNext, ?gItemPrev, ?gOw, gList) );
|
||||||
assert( DLS(gItemNext, pxItem, gEnd, gEndPrev, ?gSufCells, ?gSufVals,
|
assert( DLS(gItemNext, pxItem, gEnd, gEndPrev,
|
||||||
gList) );
|
?gSufCells, ?gSufVals, ?gSufOwners, gList) );
|
||||||
close DLS_prefix(nil, nil, pxItem, gItemPrev,
|
close DLS_prefix(nil, nil, nil, pxItem, gItemPrev,
|
||||||
gEnd, gEndPrev, gList);
|
gEnd, gEndPrev, gList);
|
||||||
|
|
||||||
// Prove: `mem(gItemNext, gCells) == true`
|
// Prove: `mem(gItemNext, gCells) == true`
|
||||||
open DLS(gItemNext, pxItem, gEnd, gEndPrev, gSufCells, gSufVals, gList);
|
open DLS(gItemNext, pxItem, gEnd, gEndPrev,
|
||||||
|
gSufCells, gSufVals, gSufOwners, gList);
|
||||||
assert( mem(gItemNext, gCells) == true );
|
assert( mem(gItemNext, gCells) == true );
|
||||||
close DLS(gItemNext, pxItem, gEnd, gEndPrev, gSufCells, gSufVals, gList);
|
close DLS(gItemNext, pxItem, gEnd, gEndPrev,
|
||||||
|
gSufCells, gSufVals, gSufOwners, gList);
|
||||||
|
|
||||||
// Prove: `mem(gItemPrev, gCells) == true `
|
// Prove: `mem(gItemPrev, gCells) == true `
|
||||||
assert( gItemPrev == gEndPrev );
|
assert( gItemPrev == gEndPrev );
|
||||||
dls_last_mem(gItemNext, pxItem, gEnd, gEndPrev, gSufCells);
|
dls_last_mem(gItemNext, pxItem, gEnd, gEndPrev, gSufCells);
|
||||||
assert( mem(gItemPrev, gCells) == true );
|
assert( mem(gItemPrev, gCells) == true );
|
||||||
|
|
||||||
close DLS_suffix(gSufCells, gSufVals, pxItem, gItemNext, gEnd, gEndPrev,
|
close DLS_suffix(gSufCells, gSufVals, gSufOwners, pxItem, gItemNext,
|
||||||
gList);
|
gEnd, gEndPrev, gList);
|
||||||
} else {
|
} else {
|
||||||
// pxItem is not the first/ left-most item in the list
|
// pxItem is not the first/ left-most item in the list
|
||||||
// -> non-empty prefix
|
// -> non-empty prefix
|
||||||
|
|
@ -529,13 +543,13 @@ ensures
|
||||||
int gItemIndex = index_of(pxItem, gCells);
|
int gItemIndex = index_of(pxItem, gCells);
|
||||||
split(gEnd, gEndPrev, gEnd, gEndPrev, gCells, gVals, pxItem, gItemIndex);
|
split(gEnd, gEndPrev, gEnd, gEndPrev, gCells, gVals, pxItem, gItemIndex);
|
||||||
|
|
||||||
assert( DLS(gEnd, gEndPrev, pxItem, ?gItemPrev, ?gPrefCells, ?gPrefVals,
|
assert( DLS(gEnd, gEndPrev, pxItem, ?gItemPrev,
|
||||||
gList) );
|
?gPrefCells, ?gPrefVals, ?gPrefOwners, gList) );
|
||||||
// -> Will be wrapped inside the prefix constructed at the end of this
|
// -> Will be wrapped inside the prefix constructed at the end of this
|
||||||
// lemma.
|
// lemma.
|
||||||
|
|
||||||
assert( DLS(pxItem, gItemPrev, gEnd, gEndPrev, ?gPartCells, ?gPartVals,
|
assert( DLS(pxItem, gItemPrev, gEnd, gEndPrev,
|
||||||
gList) );
|
?gPartCells, ?gPartVals, ?gPartOwners, gList) );
|
||||||
// -> The tail of this DLS will make up the suffix constructed at the
|
// -> The tail of this DLS will make up the suffix constructed at the
|
||||||
// end of this lemma.
|
// end of this lemma.
|
||||||
|
|
||||||
|
|
@ -547,16 +561,16 @@ ensures
|
||||||
// Prove: `head(gPrefCells) == gEnd`
|
// Prove: `head(gPrefCells) == gEnd`
|
||||||
// Necessary to construct prefix later.
|
// Necessary to construct prefix later.
|
||||||
// Implies `mem(gItemPrev, gCells) == true`.
|
// Implies `mem(gItemPrev, gCells) == true`.
|
||||||
open DLS(gEnd, gEndPrev, pxItem, gItemPrev, gPrefCells, gPrefVals,
|
open DLS(gEnd, gEndPrev, pxItem, gItemPrev,
|
||||||
gList);
|
gPrefCells, gPrefVals, gPrefOwners, gList);
|
||||||
assert( head(gPrefCells) == gEnd );
|
assert( head(gPrefCells) == gEnd );
|
||||||
close DLS(gEnd, gEndPrev, pxItem, gItemPrev, gPrefCells, gPrefVals,
|
close DLS(gEnd, gEndPrev, pxItem, gItemPrev,
|
||||||
gList);
|
gPrefCells, gPrefVals, gPrefOwners, gList);
|
||||||
assert( mem(gItemPrev, gCells) == true );
|
assert( mem(gItemPrev, gCells) == true );
|
||||||
|
|
||||||
open DLS(pxItem, gItemPrev, gEnd, gEndPrev, gPartCells, gPartVals,
|
open DLS(pxItem, gItemPrev, gEnd, gEndPrev,
|
||||||
gList);
|
gPartCells, gPartVals, gPartOwners, gList);
|
||||||
assert( xLIST_ITEM(pxItem, ?gItemVal, ?gItemNext, gItemPrev, gList) );
|
assert( xLIST_ITEM(pxItem, ?gItemVal, ?gItemNext, gItemPrev, ?gOw, gList) );
|
||||||
|
|
||||||
if( pxItem == gEndPrev ) {
|
if( pxItem == gEndPrev ) {
|
||||||
// pxItem is the last/ right-most item in the list.
|
// pxItem is the last/ right-most item in the list.
|
||||||
|
|
@ -572,69 +586,78 @@ ensures
|
||||||
|
|
||||||
|
|
||||||
// prove: mem(gItemNext, gCells) == true
|
// prove: mem(gItemNext, gCells) == true
|
||||||
open xLIST_ITEM(pxItem, gItemVal, gItemNext, gItemPrev, gList);
|
open xLIST_ITEM(pxItem, gItemVal, gItemNext, gItemPrev, gOw,
|
||||||
|
gList);
|
||||||
assert( gItemNext == gEnd );
|
assert( gItemNext == gEnd );
|
||||||
assert( mem(gItemNext, gCells) == true );
|
assert( mem(gItemNext, gCells) == true );
|
||||||
close xLIST_ITEM(pxItem, gItemVal, gItemNext, gItemPrev, gList);
|
close xLIST_ITEM(pxItem, gItemVal, gItemNext, gItemPrev, gOw,
|
||||||
|
gList);
|
||||||
|
|
||||||
close DLS_prefix(gPrefCells, gPrefVals, pxItem, gItemPrev,
|
close DLS_prefix(gPrefCells, gPrefVals, gPrefOwners, pxItem,
|
||||||
|
gItemPrev, gEnd, gEndPrev, gList);
|
||||||
|
close DLS_suffix(nil, nil, nil, pxItem, gItemNext,
|
||||||
gEnd, gEndPrev, gList);
|
gEnd, gEndPrev, gList);
|
||||||
close DLS_suffix(nil, nil, pxItem, gItemNext, gEnd, gEndPrev, gList);
|
|
||||||
} else {
|
} else {
|
||||||
// pxItem is not the last/ right-most item in the list.
|
// pxItem is not the last/ right-most item in the list.
|
||||||
// -> non-empty suffix
|
// -> non-empty suffix
|
||||||
|
|
||||||
assert( DLS(gItemNext, pxItem, gEnd, gEndPrev, ?gSufCells, ?gSufVals,
|
assert( DLS(gItemNext, pxItem, gEnd, gEndPrev,
|
||||||
gList) );
|
?gSufCells, ?gSufVals, ?gSufOwners, gList) );
|
||||||
assert( gSufCells == drop(1, gPartCells) );
|
assert( gSufCells == drop(1, gPartCells) );
|
||||||
|
|
||||||
// Prove: - `drop(gItemIndex+1, gCells) == gSufCells`
|
// Prove: - `drop(gItemIndex+1, gCells) == gSufCells`
|
||||||
// - `drop(gItemIndex+1, gVals) == gSufVals`
|
// - `drop(gItemIndex+1, gVals) == gSufVals`
|
||||||
|
// - `drop(gItemIndex+1, gOwners) == gSufOwners`
|
||||||
// -> Required to prove `mem(gItemNext, gCells) == true` and also to
|
// -> Required to prove `mem(gItemNext, gCells) == true` and also to
|
||||||
// prove relationship between gCells/gVals and their segmentation.
|
// prove relationship between gCells/gVals and their segmentation.
|
||||||
assert( drop(1, drop(gItemIndex, gCells)) == gSufCells );
|
assert( drop(1, drop(gItemIndex, gCells)) == gSufCells );
|
||||||
assert( drop(1, drop(gItemIndex, gVals)) == gSufVals );
|
assert( drop(1, drop(gItemIndex, gVals)) == gSufVals );
|
||||||
|
assert( drop(1, drop(gItemIndex, gOwners)) == gSufOwners );
|
||||||
drop_n_plus_m(gCells, 1, gItemIndex);
|
drop_n_plus_m(gCells, 1, gItemIndex);
|
||||||
drop_n_plus_m(gVals, 1, gItemIndex);
|
drop_n_plus_m(gVals, 1, gItemIndex);
|
||||||
|
drop_n_plus_m(gOwners, 1, gItemIndex);
|
||||||
assert( drop(gItemIndex+1, gCells) == gSufCells );
|
assert( drop(gItemIndex+1, gCells) == gSufCells );
|
||||||
assert( drop(gItemIndex+1, gVals) == gSufVals );
|
assert( drop(gItemIndex+1, gVals) == gSufVals );
|
||||||
|
assert( drop(gItemIndex+1, gOwners) == gSufOwners );
|
||||||
|
|
||||||
// Prove: `mem(gItemNext, gCells) == true`
|
// Prove: `mem(gItemNext, gCells) == true`
|
||||||
open DLS(gItemNext, pxItem, gEnd, gEndPrev, gSufCells, gSufVals,
|
open DLS(gItemNext, pxItem, gEnd, gEndPrev,
|
||||||
gList);
|
gSufCells, gSufVals, gSufOwners, gList);
|
||||||
assert( mem(gItemNext, gSufCells) == true );
|
assert( mem(gItemNext, gSufCells) == true );
|
||||||
mem_suffix_implies_mem(gItemNext, gCells, gItemIndex+1);
|
mem_suffix_implies_mem(gItemNext, gCells, gItemIndex+1);
|
||||||
assert( mem(gItemNext, gCells) == true );
|
assert( mem(gItemNext, gCells) == true );
|
||||||
close DLS(gItemNext, pxItem, gEnd, gEndPrev, gSufCells, gSufVals,
|
close DLS(gItemNext, pxItem, gEnd, gEndPrev,
|
||||||
gList);
|
gSufCells, gSufVals, gSufOwners, gList);
|
||||||
|
|
||||||
close DLS_prefix(gPrefCells, gPrefVals, pxItem, gItemPrev,
|
close DLS_prefix(gPrefCells, gPrefVals, gPrefOwners,
|
||||||
gEnd, gEndPrev, gList);
|
pxItem, gItemPrev, gEnd, gEndPrev, gList);
|
||||||
dls_last_mem(gItemNext, pxItem, gEnd, gEndPrev, gSufCells);
|
dls_last_mem(gItemNext, pxItem, gEnd, gEndPrev, gSufCells);
|
||||||
close DLS_suffix(gSufCells, gSufVals, pxItem, gItemNext, gEnd,
|
close DLS_suffix(gSufCells, gSufVals, gSufOwners, pxItem, gItemNext,
|
||||||
gEndPrev, gList);
|
gEnd, gEndPrev, gList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lemma void DLS_close_2(struct xLIST_ITEM* pxItem,
|
lemma void DLS_close_2(struct xLIST_ITEM* pxItem,
|
||||||
list<struct xLIST_ITEM*> gCells,
|
list<struct xLIST_ITEM*> gCells,
|
||||||
list<TickType_t> gVals)
|
list<TickType_t> gVals,
|
||||||
|
list<void*> gOwners)
|
||||||
requires
|
requires
|
||||||
length(gCells) == length(gVals) &*&
|
length(gCells) == length(gVals) &*&
|
||||||
DLS_prefix(?gPrefCells, ?gPrefVals, pxItem, ?gItemPrev,
|
DLS_prefix(?gPrefCells, ?gPrefVals, ?gPrefOwners, pxItem, ?gItemPrev,
|
||||||
?gEnd, ?gEndPrev, ?gList)
|
?gEnd, ?gEndPrev, ?gList)
|
||||||
&*&
|
&*&
|
||||||
gEnd == head(gCells)
|
gEnd == head(gCells)
|
||||||
&*&
|
&*&
|
||||||
xLIST_ITEM(pxItem, ?gItemVal, ?gItemNext, gItemPrev, gList)
|
xLIST_ITEM(pxItem, ?gItemVal, ?gItemNext, gItemPrev, ?gOw, gList)
|
||||||
&*&
|
&*&
|
||||||
DLS_suffix(?gSufCells, ?gSufVals, pxItem, gItemNext, gEnd, gEndPrev, gList)
|
DLS_suffix(?gSufCells, ?gSufVals, ?gSufOwners, pxItem, gItemNext,
|
||||||
|
gEnd, gEndPrev, gList)
|
||||||
&*&
|
&*&
|
||||||
// gCells == gPrefCells + item + gSufCells
|
// lists have form "prefix + element + suffix"
|
||||||
gCells == append(gPrefCells, append(singleton(pxItem), gSufCells)) &*&
|
gCells == append(gPrefCells, append(singleton(pxItem), gSufCells)) &*&
|
||||||
// gVals == gPrefVals + item + gSufVals
|
gVals == append(gPrefVals, append(singleton(gItemVal), gSufVals)) &*&
|
||||||
gVals == append(gPrefVals, append(singleton(gItemVal), gSufVals))
|
gOwners == append(gPrefOwners, append(singleton(gOw), gSufOwners))
|
||||||
&*&
|
&*&
|
||||||
// next in cells
|
// next in cells
|
||||||
mem(gItemNext, gCells) == true &*&
|
mem(gItemNext, gCells) == true &*&
|
||||||
|
|
@ -642,7 +665,7 @@ requires
|
||||||
mem(gItemPrev, gCells) == true
|
mem(gItemPrev, gCells) == true
|
||||||
;
|
;
|
||||||
ensures
|
ensures
|
||||||
DLS(gEnd, gEndPrev, gEnd, gEndPrev, gCells, gVals, gList) &*&
|
DLS(gEnd, gEndPrev, gEnd, gEndPrev, gCells, gVals, gOwners, gList) &*&
|
||||||
mem(pxItem, gCells) == true &*&
|
mem(pxItem, gCells) == true &*&
|
||||||
mem(gItemNext, gCells) == true &*&
|
mem(gItemNext, gCells) == true &*&
|
||||||
mem(gItemPrev, gCells) == true &*&
|
mem(gItemPrev, gCells) == true &*&
|
||||||
|
|
@ -654,7 +677,7 @@ ensures
|
||||||
// pxItem is first/ left-most item in the list
|
// pxItem is first/ left-most item in the list
|
||||||
// -> empty prefix
|
// -> empty prefix
|
||||||
|
|
||||||
open DLS_prefix(gPrefCells, gPrefVals, pxItem, gItemPrev,
|
open DLS_prefix(gPrefCells, gPrefVals, gPrefOwners, pxItem, gItemPrev,
|
||||||
gEnd, gEndPrev, gList);
|
gEnd, gEndPrev, gList);
|
||||||
assert( pxItem == gEnd );
|
assert( pxItem == gEnd );
|
||||||
assert( gPrefVals == nil );
|
assert( gPrefVals == nil );
|
||||||
|
|
@ -662,36 +685,39 @@ ensures
|
||||||
if( gSufCells == nil ) {
|
if( gSufCells == nil ) {
|
||||||
// pxItem is last/ right-most item in the list
|
// pxItem is last/ right-most item in the list
|
||||||
|
|
||||||
open DLS_suffix(gSufCells, gSufVals, pxItem, gItemNext, gEnd,
|
open DLS_suffix(gSufCells, gSufVals, gSufOwners, pxItem, gItemNext,
|
||||||
gEndPrev, gList);
|
gEnd, gEndPrev, gList);
|
||||||
assert( pxItem == gEndPrev );
|
assert( pxItem == gEndPrev );
|
||||||
assert( gSufVals == nil );
|
assert( gSufVals == nil );
|
||||||
|
|
||||||
close DLS(gEnd, gEndPrev, gEnd, gEndPrev, gCells, gVals, gList);
|
close DLS(gEnd, gEndPrev, gEnd, gEndPrev, gCells, gVals, gOwners,
|
||||||
|
gList);
|
||||||
} else {
|
} else {
|
||||||
// pxItem is not last/ right-most item in the list
|
// pxItem is not last/ right-most item in the list
|
||||||
|
|
||||||
open DLS_suffix(gSufCells, gSufVals, pxItem, gItemNext, gEnd,
|
open DLS_suffix(gSufCells, gSufVals, gSufOwners, pxItem, gItemNext,
|
||||||
gEndPrev, gList);
|
gEnd, gEndPrev, gList);
|
||||||
close DLS(gEnd, gEndPrev, gEnd, gEndPrev, gCells, gVals, gList);
|
close DLS(gEnd, gEndPrev, gEnd, gEndPrev, gCells, gVals, gOwners,
|
||||||
|
gList);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// pxItem is not the first/ left-most item in the list
|
// pxItem is not the first/ left-most item in the list
|
||||||
// -> non-empty prefix
|
// -> non-empty prefix
|
||||||
// (potentially empty suffix)
|
// (potentially empty suffix)
|
||||||
|
|
||||||
open DLS_prefix(gPrefCells, gPrefVals, pxItem, gItemPrev,
|
open DLS_prefix(gPrefCells, gPrefVals, gPrefOwners, pxItem, gItemPrev,
|
||||||
gEnd, gEndPrev, gList);
|
gEnd, gEndPrev, gList);
|
||||||
|
|
||||||
if( gSufCells == nil ) {
|
if( gSufCells == nil ) {
|
||||||
// pxItem is the last/ right-most item in the list
|
// pxItem is the last/ right-most item in the list
|
||||||
// -> empty suffix
|
// -> empty suffix
|
||||||
|
|
||||||
open DLS_suffix(gSufCells, gSufVals, pxItem, gItemNext, gEnd,
|
open DLS_suffix(gSufCells, gSufVals, gSufOwners, pxItem, gItemNext,
|
||||||
gEndPrev, gList);
|
gEnd, gEndPrev, gList);
|
||||||
assert( pxItem == gEndPrev );
|
assert( pxItem == gEndPrev );
|
||||||
close DLS(pxItem, gItemPrev, gEnd, gEndPrev,
|
close DLS(pxItem, gItemPrev, gEnd, gEndPrev,
|
||||||
singleton(pxItem), singleton(gItemVal), gList);
|
singleton(pxItem), singleton(gItemVal), singleton(gOw),
|
||||||
|
gList);
|
||||||
join(gEnd, gEndPrev, pxItem, gItemPrev, gPrefCells, gPrefVals,
|
join(gEnd, gEndPrev, pxItem, gItemPrev, gPrefCells, gPrefVals,
|
||||||
pxItem, gItemPrev, gEnd, gEndPrev,
|
pxItem, gItemPrev, gEnd, gEndPrev,
|
||||||
singleton(pxItem), singleton(gItemVal));
|
singleton(pxItem), singleton(gItemVal));
|
||||||
|
|
@ -699,10 +725,11 @@ ensures
|
||||||
// pxItem is not the last/ right-most item in the list
|
// pxItem is not the last/ right-most item in the list
|
||||||
// -> non-empty suffix
|
// -> non-empty suffix
|
||||||
|
|
||||||
open DLS_suffix(gSufCells, gSufVals, pxItem, gItemNext, gEnd,
|
open DLS_suffix(gSufCells, gSufVals, gSufOwners, pxItem, gItemNext,
|
||||||
gEndPrev, gList);
|
gEnd, gEndPrev, gList);
|
||||||
close DLS(pxItem, gItemPrev, gEnd, gEndPrev,
|
close DLS(pxItem, gItemPrev, gEnd, gEndPrev,
|
||||||
cons(pxItem, gSufCells), cons(gItemVal, gSufVals),
|
cons(pxItem, gSufCells), cons(gItemVal, gSufVals),
|
||||||
|
cons(gOw, gSufOwners),
|
||||||
gList);
|
gList);
|
||||||
join(gEnd, gEndPrev, pxItem, gItemPrev, gPrefCells, gPrefVals,
|
join(gEnd, gEndPrev, pxItem, gItemPrev, gPrefCells, gPrefVals,
|
||||||
pxItem, gItemPrev, gEnd, gEndPrev,
|
pxItem, gItemPrev, gEnd, gEndPrev,
|
||||||
|
|
@ -714,14 +741,15 @@ ensures
|
||||||
|
|
||||||
struct xLIST_ITEM* lemma_validation__DLS_item_next_2(struct xLIST_ITEM* pxTaskItem)
|
struct xLIST_ITEM* lemma_validation__DLS_item_next_2(struct xLIST_ITEM* pxTaskItem)
|
||||||
/*@ requires
|
/*@ requires
|
||||||
DLS(?gEnd, ?gEndPrev, gEnd, gEndPrev, ?gCells, ?gVals, ?gList) &*&
|
DLS(?gEnd, ?gEndPrev, gEnd, gEndPrev, ?gCells, ?gVals, ?gOwners, ?gList) &*&
|
||||||
mem(pxTaskItem, gCells) == true &*&
|
mem(pxTaskItem, gCells) == true &*&
|
||||||
gEnd == head(gCells) &*&
|
gEnd == head(gCells) &*&
|
||||||
length(gCells) == length(gVals) &*&
|
length(gCells) == length(gVals) &*&
|
||||||
|
length(gOwners) == length(gCells) &*&
|
||||||
length(gCells) > 1;
|
length(gCells) > 1;
|
||||||
@*/
|
@*/
|
||||||
/*@ ensures
|
/*@ ensures
|
||||||
DLS(gEnd, gEndPrev, gEnd, gEndPrev, gCells, gVals, gList) &*&
|
DLS(gEnd, gEndPrev, gEnd, gEndPrev, gCells, gVals, gOwners, gList) &*&
|
||||||
mem(pxTaskItem, gCells) == true &*&
|
mem(pxTaskItem, gCells) == true &*&
|
||||||
mem(result, gCells) == true;
|
mem(result, gCells) == true;
|
||||||
@*/
|
@*/
|
||||||
|
|
@ -732,30 +760,34 @@ struct xLIST_ITEM* lemma_validation__DLS_item_next_2(struct xLIST_ITEM* pxTaskIt
|
||||||
|
|
||||||
//@ DLS_open_2(gTaskItem_0);
|
//@ DLS_open_2(gTaskItem_0);
|
||||||
/*@ assert( xLIST_ITEM(gTaskItem_0, ?gTaskItem_0_val,
|
/*@ assert( xLIST_ITEM(gTaskItem_0, ?gTaskItem_0_val,
|
||||||
?gTaskItem_0_next, ?gTaskItem_0_prev, gList) );
|
?gTaskItem_0_next, ?gTaskItem_0_prev, ?gTaskItem_0_owner,
|
||||||
|
gList) );
|
||||||
@*/
|
@*/
|
||||||
pxTaskItem = pxTaskItem->pxNext;
|
pxTaskItem = pxTaskItem->pxNext;
|
||||||
//@ struct xLIST_ITEM* gTaskItem_1 = pxTaskItem;
|
//@ struct xLIST_ITEM* gTaskItem_1 = pxTaskItem;
|
||||||
|
|
||||||
/*@ close xLIST_ITEM(gTaskItem_0, gTaskItem_0_val,
|
/*@ close xLIST_ITEM(gTaskItem_0, gTaskItem_0_val,
|
||||||
gTaskItem_0_next, gTaskItem_0_prev, gList);
|
gTaskItem_0_next, gTaskItem_0_prev, gTaskItem_0_owner,
|
||||||
|
gList);
|
||||||
@*/
|
@*/
|
||||||
//@ DLS_close_2(gTaskItem_0, gCells, gVals);
|
//@ DLS_close_2(gTaskItem_0, gCells, gVals, gOwners);
|
||||||
|
|
||||||
|
|
||||||
// second iteration step
|
// second iteration step
|
||||||
|
|
||||||
//@ DLS_open_2(gTaskItem_1);
|
//@ DLS_open_2(gTaskItem_1);
|
||||||
/*@ assert( xLIST_ITEM(gTaskItem_1, ?gTaskItem_1_val,
|
/*@ assert( xLIST_ITEM(gTaskItem_1, ?gTaskItem_1_val,
|
||||||
?gTaskItem_1_next, ?gTaskItem_1_prev, gList) );
|
?gTaskItem_1_next, ?gTaskItem_1_prev, ?gTaskItem_1_owner,
|
||||||
|
gList) );
|
||||||
@*/
|
@*/
|
||||||
pxTaskItem = pxTaskItem->pxNext;
|
pxTaskItem = pxTaskItem->pxNext;
|
||||||
//@ struct xLIST_ITEM* gTaskItem_2 = pxTaskItem;
|
//@ struct xLIST_ITEM* gTaskItem_2 = pxTaskItem;
|
||||||
|
|
||||||
/*@ close xLIST_ITEM(gTaskItem_1, gTaskItem_1_val,
|
/*@ close xLIST_ITEM(gTaskItem_1, gTaskItem_1_val,
|
||||||
gTaskItem_1_next, gTaskItem_1_prev, gList);
|
gTaskItem_1_next, gTaskItem_1_prev, gTaskItem_1_owner,
|
||||||
|
gList);
|
||||||
@*/
|
@*/
|
||||||
//@ DLS_close_2(gTaskItem_1, gCells, gVals);
|
//@ DLS_close_2(gTaskItem_1, gCells, gVals, gOwners);
|
||||||
|
|
||||||
|
|
||||||
//@ assert( mem(gTaskItem_2, gCells) == true );
|
//@ assert( mem(gTaskItem_2, gCells) == true );
|
||||||
|
|
@ -765,14 +797,15 @@ struct xLIST_ITEM* lemma_validation__DLS_item_next_2(struct xLIST_ITEM* pxTaskIt
|
||||||
|
|
||||||
struct xLIST_ITEM* lemma_validation__DLS_item_prev_2(struct xLIST_ITEM* pxTaskItem)
|
struct xLIST_ITEM* lemma_validation__DLS_item_prev_2(struct xLIST_ITEM* pxTaskItem)
|
||||||
/*@ requires
|
/*@ requires
|
||||||
DLS(?gEnd, ?gEndPrev, gEnd, gEndPrev, ?gCells, ?gVals, ?gList) &*&
|
DLS(?gEnd, ?gEndPrev, gEnd, gEndPrev, ?gCells, ?gVals, ?gOwners, ?gList) &*&
|
||||||
mem(pxTaskItem, gCells) == true &*&
|
mem(pxTaskItem, gCells) == true &*&
|
||||||
gEnd == head(gCells) &*&
|
gEnd == head(gCells) &*&
|
||||||
length(gCells) == length(gVals) &*&
|
length(gCells) == length(gVals) &*&
|
||||||
|
length(gOwners) == length(gCells) &*&
|
||||||
length(gCells) > 1;
|
length(gCells) > 1;
|
||||||
@*/
|
@*/
|
||||||
/*@ ensures
|
/*@ ensures
|
||||||
DLS(gEnd, gEndPrev, gEnd, gEndPrev, gCells, gVals, gList) &*&
|
DLS(gEnd, gEndPrev, gEnd, gEndPrev, gCells, gVals, gOwners, gList) &*&
|
||||||
mem(pxTaskItem, gCells) == true &*&
|
mem(pxTaskItem, gCells) == true &*&
|
||||||
mem(result, gCells) == true;
|
mem(result, gCells) == true;
|
||||||
@*/
|
@*/
|
||||||
|
|
@ -783,30 +816,34 @@ struct xLIST_ITEM* lemma_validation__DLS_item_prev_2(struct xLIST_ITEM* pxTaskIt
|
||||||
|
|
||||||
//@ DLS_open_2(gTaskItem_0);
|
//@ DLS_open_2(gTaskItem_0);
|
||||||
/*@ assert( xLIST_ITEM(gTaskItem_0, ?gTaskItem_0_val,
|
/*@ assert( xLIST_ITEM(gTaskItem_0, ?gTaskItem_0_val,
|
||||||
?gTaskItem_0_next, ?gTaskItem_0_prev, gList) );
|
?gTaskItem_0_next, ?gTaskItem_0_prev, ?gTaskItem_0_owner,
|
||||||
|
gList) );
|
||||||
@*/
|
@*/
|
||||||
pxTaskItem = pxTaskItem->pxPrevious;
|
pxTaskItem = pxTaskItem->pxPrevious;
|
||||||
//@ struct xLIST_ITEM* gTaskItem_1 = pxTaskItem;
|
//@ struct xLIST_ITEM* gTaskItem_1 = pxTaskItem;
|
||||||
|
|
||||||
/*@ close xLIST_ITEM(gTaskItem_0, gTaskItem_0_val,
|
/*@ close xLIST_ITEM(gTaskItem_0, gTaskItem_0_val,
|
||||||
gTaskItem_0_next, gTaskItem_0_prev, gList);
|
gTaskItem_0_next, gTaskItem_0_prev, gTaskItem_0_owner,
|
||||||
|
gList);
|
||||||
@*/
|
@*/
|
||||||
//@ DLS_close_2(gTaskItem_0, gCells, gVals);
|
//@ DLS_close_2(gTaskItem_0, gCells, gVals, gOwners);
|
||||||
|
|
||||||
|
|
||||||
// second iteration step
|
// second iteration step
|
||||||
|
|
||||||
//@ DLS_open_2(gTaskItem_1);
|
//@ DLS_open_2(gTaskItem_1);
|
||||||
/*@ assert( xLIST_ITEM(gTaskItem_1, ?gTaskItem_1_val,
|
/*@ assert( xLIST_ITEM(gTaskItem_1, ?gTaskItem_1_val,
|
||||||
?gTaskItem_1_next, ?gTaskItem_1_prev, gList) );
|
?gTaskItem_1_next, ?gTaskItem_1_prev, ?gTaskItem_1_owner,
|
||||||
|
gList) );
|
||||||
@*/
|
@*/
|
||||||
pxTaskItem = pxTaskItem->pxPrevious;
|
pxTaskItem = pxTaskItem->pxPrevious;
|
||||||
//@ struct xLIST_ITEM* gTaskItem_2 = pxTaskItem;
|
//@ struct xLIST_ITEM* gTaskItem_2 = pxTaskItem;
|
||||||
|
|
||||||
/*@ close xLIST_ITEM(gTaskItem_1, gTaskItem_1_val,
|
/*@ close xLIST_ITEM(gTaskItem_1, gTaskItem_1_val,
|
||||||
gTaskItem_1_next, gTaskItem_1_prev, gList);
|
gTaskItem_1_next, gTaskItem_1_prev,gTaskItem_1_owner,
|
||||||
|
gList);
|
||||||
@*/
|
@*/
|
||||||
//@ DLS_close_2(gTaskItem_1, gCells, gVals);
|
//@ DLS_close_2(gTaskItem_1, gCells, gVals, gOwners);
|
||||||
|
|
||||||
|
|
||||||
//@ assert( mem(gTaskItem_2, gCells) == true );
|
//@ assert( mem(gTaskItem_2, gCells) == true );
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,9 @@ predicate uninit_TCB_p(TCB_t * tcb, int stackSize) =
|
||||||
malloc_block_tskTaskControlBlock(tcb) &*&
|
malloc_block_tskTaskControlBlock(tcb) &*&
|
||||||
tcb->pxTopOfStack |-> _ &*&
|
tcb->pxTopOfStack |-> _ &*&
|
||||||
|
|
||||||
xLIST_ITEM(&tcb->xStateListItem, _, _, _, _) &*&
|
xLIST_ITEM(&tcb->xStateListItem, _, _, _, _, _) &*&
|
||||||
struct_xLIST_ITEM_padding(&tcb->xStateListItem) &*&
|
struct_xLIST_ITEM_padding(&tcb->xStateListItem) &*&
|
||||||
xLIST_ITEM(&tcb->xEventListItem, _, _, _, _) &*&
|
xLIST_ITEM(&tcb->xEventListItem, _, _, _, _, _) &*&
|
||||||
struct_xLIST_ITEM_padding(&tcb->xEventListItem) &*&
|
struct_xLIST_ITEM_padding(&tcb->xEventListItem) &*&
|
||||||
|
|
||||||
tcb->uxPriority |-> _ &*&
|
tcb->uxPriority |-> _ &*&
|
||||||
|
|
@ -59,9 +59,9 @@ predicate TCB_p(TCB_t * tcb, uint32_t ulFreeBytesOnStack) =
|
||||||
stack_p_2(stackPtr, ?ulStackDepth, topPtr,
|
stack_p_2(stackPtr, ?ulStackDepth, topPtr,
|
||||||
ulFreeBytesOnStack, ?ulUsedCells, ?ulUnalignedBytes) &*&
|
ulFreeBytesOnStack, ?ulUsedCells, ?ulUnalignedBytes) &*&
|
||||||
|
|
||||||
xLIST_ITEM(&tcb->xStateListItem, _, _, _, _) &*&
|
xLIST_ITEM(&tcb->xStateListItem, _, _, _, _, _) &*&
|
||||||
struct_xLIST_ITEM_padding(&tcb->xStateListItem) &*&
|
struct_xLIST_ITEM_padding(&tcb->xStateListItem) &*&
|
||||||
xLIST_ITEM(&tcb->xEventListItem, _, _, _, _) &*&
|
xLIST_ITEM(&tcb->xEventListItem, _, _, _, _, _) &*&
|
||||||
struct_xLIST_ITEM_padding(&tcb->xEventListItem) &*&
|
struct_xLIST_ITEM_padding(&tcb->xEventListItem) &*&
|
||||||
|
|
||||||
tcb->uxPriority |-> _ &*&
|
tcb->uxPriority |-> _ &*&
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ predicate taskISRLockInv_p() =
|
||||||
integer_((void*) &uxTopReadyPriority, sizeof(UBaseType_t), false, ?gTopReadyPriority) &*&
|
integer_((void*) &uxTopReadyPriority, sizeof(UBaseType_t), false, ?gTopReadyPriority) &*&
|
||||||
0 <= gTopReadyPriority &*& gTopReadyPriority < configMAX_PRIORITIES
|
0 <= gTopReadyPriority &*& gTopReadyPriority < configMAX_PRIORITIES
|
||||||
&*&
|
&*&
|
||||||
readyLists_p(?gCellLists)
|
readyLists_p(?gCellLists, ?gOwnerLists)
|
||||||
&*&
|
&*&
|
||||||
// ∀gCells ∈ gCellLists. ∀item ∈ gCells. sharedSeg_TCB_p(item->pvOwner)
|
// ∀gCells ∈ gCellLists. ∀item ∈ gCells. sharedSeg_TCB_p(item->pvOwner)
|
||||||
//foreach(gCellLists, foreach_sharedSeg_TCB_of_itemOwner);
|
//foreach(gCellLists, foreach_sharedSeg_TCB_of_itemOwner);
|
||||||
|
|
@ -117,6 +117,9 @@ ensures locked_p(otherLocks);
|
||||||
|
|
||||||
// ∀items ∈ itemLists. ∀it ∈ items. sharedSeg_TCB_p(it->pvOwner)
|
// ∀items ∈ itemLists. ∀it ∈ items. sharedSeg_TCB_p(it->pvOwner)
|
||||||
predicate collection_of_sharedSeg_TCB_p(list<list<struct xLIST_ITEM*> > itemLists) =
|
predicate collection_of_sharedSeg_TCB_p(list<list<struct xLIST_ITEM*> > itemLists) =
|
||||||
|
true;
|
||||||
|
@*/
|
||||||
|
/*
|
||||||
foreach(itemLists, foreach_sharedSeg_TCB_of_itemOwner);
|
foreach(itemLists, foreach_sharedSeg_TCB_of_itemOwner);
|
||||||
|
|
||||||
// Auxiliary prediactes to express nested quantification
|
// Auxiliary prediactes to express nested quantification
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue