VCC Case Study: Single-lane Bridge Problem Summer School on Software Engineering and Verification...
-
Upload
roland-mosley -
Category
Documents
-
view
219 -
download
0
Transcript of VCC Case Study: Single-lane Bridge Problem Summer School on Software Engineering and Verification...
VCC Case Study: Single-lane Bridge Problem
Summer School on Software Engineering and Verification (SSSEV)July 17-27, Moscow, Russia
Mentors: Stephan TobiesJohn Wickerson
Formal2Normal team: Andrey Dereza * Anatoliy Gorbenko ** Lyubov Reva ** Leanid Vaitsekhovich*** Oleg Illiashenko ** Oleksii Starov**_________________________________________________________
* - Caddiesoft, Ukraine** - National Aerospace University “KhAI”, Ukraine*** - Brest State Technical University, Belarus
Abstract
The project is devoted to VCC case study development.
A system under study: a real-time system that controls traffic on a single-lane bridge
The purpose of the project: to demonstrate feasibility and usefulness of VCC tool to compare different implementations and annotation
techniques Our approach:
to employ a stepwise (refined-based) development and verification
2
Single-lane bridge
© J.-R. Abrial. Modeling in Event-B: System and Software Engineering 3
Single-lane bridge: System requirements FUN-1 The system is controlling cars on a bridge between
the mainland and an island
FUN-2 The number of cars on the bridge and the island is limited
FUN-3 The bridge is a single-line. Cars can move in a one way or the other, not both at the same time
EQP-1 The system has two traffic lights with two colours: green and red
EQP-2 The traffic lights control the entrance to the bridge at both ends of it
EQP-3 Cars are not supposed to pass on a red traffic light, only on a green one
EQP-4 The system is equipped with four car sensors each with two states: on or off
EQP-5 The sensors are used to detect the presence of cars entering or leaving the bridge
4
Abstract model
Invariants n >= 0 n <= d
Events driveOut driveInto
ISLAND
LAND
driveOut
driveInton
MA
X_C
OU
NT
FUN-1 The system is controlling cars on a bridge between the mainland and an island
FUN-2 The number of cars on the bridge and the island is limited
5
Step-wise developmentRequirement Refinement Implementation’s and VCC’s features
Variables Structure Threads
FUN-1 Abstractmodel
√ √ √
FUN-2 Abstractmodel
√ √ O
FUN-3 REF-1 √ √ O
EQP-1 REF-2 - √ O
EQP-2 REF-2 - √ O
EQP-3 REF-2 - √ O
EQP-4 REF-3 - O O
EQP-5 REF-3 - O O
6
VCC implementation using Variables #include <vcc.h>
#include <stdio.h>#include <stdlib.h>#include <assert.h>
#define MAX_COUNT 100
int driveInto(unsigned *pn) _(requires (*pn) >= 0 && (*pn) <= MAX_COUNT) _(writes pn) _(ensures (*pn) >= 0 && (*pn) <= MAX_COUNT){ if ((*pn) < MAX_COUNT) { (*pn)++; return 1; } return 0;}
int driveOut(unsigned *pn) _(requires (*pn) >= 0 && (*pn) <= MAX_COUNT) _(writes pn) _(ensures (*pn) >= 0 && (*pn) <= MAX_COUNT){ if ((*pn) > 0) { (*pn)--; return 1; } return 0;}
7
VCC implementation using Structure #include <vcc.h>#include <stdio.h>#include <stdlib.h>#include <assert.h>
#define MAX_COUNT 100
typedef struct _parkingIsland { // count of cars on the island unsigned n; _(invariant \this->n >= 0 && \this->n <= MAX_COUNT) // can be extended
} ParkingIsland;
void parkingInit(ParkingIsland *p) _(writes \extent(p)) _(ensures \wrapped(p)) { p->n = 0; _(wrap p)}
int driveInto(ParkingIsland *p) _(updates p){ if (p->n < MAX_COUNT) { _(unwrapping p){ p->n++; } return 1; } return 0;}
int driveOut(ParkingIsland *p) _(updates p){ if (p->n > 0) { _(unwrapping p){ p->n--; } return 1; } return 0;}
8
Simulationunsigned n; // counter of cars on the islandint main() _(writes &n){ n = 0; unsigned waitingCars = 0;
// testing int roadIsBusy; for (unsigned i = 0; i < 1000; ++i) _(invariant waitingCars <= i && i <= 1000) _(invariant n >= 0 && n <= MAX_COUNT) { // one car pass for each iteration roadIsBusy = 0;
// in if (rand() & 1) { // normal distribution may be more natural waitingCars++; if (driveInto(&n)) { waitingCars--; roadIsBusy = 1; } } else if (waitingCars) { // do not think about the cars speed if (driveInto(&n)) { waitingCars--; roadIsBusy = 1; } }
// out if (!roadIsBusy && rand() & 1) { driveOut(&n); }
_(assert n >= 0) _(assert n <= MAX_COUNT)
#ifndef VERIFY // runtime check assert(n >= 0); assert(n <= MAX_COUNT);
// output for state printf("%3d >==< %3d\n", n, waitingCars);#endif
}
return 0;}
9
Refinement 1
Invariants a, n, b >= 0 a + n + b <= MAX_COUNT (a = 0) (b = 0)
ISLAND
LAND
m_out
m_innM
AX
_CO
UN
T
i_out
i_in ab
BRIDGE
Events m_out m_in i_in i_out
10
VCC Implementation Using Structure #include <vcc.h>#include <stdio.h>#include <stdlib.h>#include <assert.h>
#define MAX_COUNT 100
typedef struct _parkingIsland { unsigned n; unsigned a; unsigned b; unsigned w; _(invariant n >= 0 && a >= 0 && b >= 0) _(invariant n + a + b <= MAX_COUNT) _(invariant a == 0 || b == 0) } ParkingIsland;
void parkingInit(ParkingIsland *p) _(writes \extent(p)) _(ensures \wrapped(p)){ p->n = p->a = p->b = p->w = 0; _(wrap p)}
int i_in(ParkingIsland *p) _(updates p){ if (p->a > 0) { _(unwrapping p){ p->a--; p->n++; } return 1; } return 0;}int i_out(ParkingIsland *p) _(updates p){ if (p->a == 0 && p->n > 0) { _(unwrapping p){ p->n--; p->b++; } return 1; } return 0;}
int m_in(ParkingIsland *p) _(updates p){ if (p->b > 0) { _(unwrapping p){ p->b--; } return 1; } return 0;}int m_out(ParkingIsland *p) _(updates p){ if (p->b == 0 && p->n+p->a < MAX_COUNT) { _(unwrapping p){ p->a++; } return 1; } else { _(unwrapping p){ _(unchecked)p->w++; }return 0; } }
11
SimulationParkingIsland pIsland; // parking on the island object
void main() _(writes \extent(&pIsland)){ parkingInit(&pIsland); // testing for (unsigned i = 0; i < 1000; ++i) _(writes &pIsland)// FIXME: why?! _(invariant \wrapped(&pIsland)) { if (rand() & 1) i_out(&pIsland); if (rand() & 1) m_out(&pIsland);
// temporary, to have more representative data if (i % 3 == 0) { i_in(&pIsland); m_in(&pIsland); }
_(assert \wrapped(&pIsland)) #ifndef VERIFY // runtime check assert(pIsland.n >= 0); assert(pIsland.a >= 0); assert(pIsland.b >= 0); assert(pIsland.w >= 0); assert(pIsland.n + pIsland.a <= MAX_COUNT); assert(!(pIsland.a && pIsland.b));
// output for state printf("%3d >= ( %3d-> <-%3d ) =< %3d\n", pIsland.n, pIsland.b, pIsland.a, pIsland.w);#endif }}
97 >= ( 0-> <-3 ) =< 236 97 >= ( 0-> <-3 ) =< 237 97 >= ( 0-> <-3 ) =< 237 98 >= ( 0-> <-2 ) =< 238 98 >= ( 0-> <-2 ) =< 239 98 >= ( 0-> <-2 ) =< 240 99 >= ( 0-> <-1 ) =< 240 99 >= ( 0-> <-1 ) =< 241 99 >= ( 0-> <-1 ) =< 241100 >= ( 0-> <-0 ) =< 241 99 >= ( 1-> <-0 ) =< 242 99 >= ( 1-> <-0 ) =< 243 99 >= ( 0-> <-0 ) =< 244 99 >= ( 0-> <-0 ) =< 244 98 >= ( 1-> <-0 ) =< 245 97 >= ( 1-> <-0 ) =< 246 96 >= ( 2-> <-0 ) =< 247 96 >= ( 2-> <-0 ) =< 248
12
Refinement 2
Invariants a, n, b >= 0 a + n + b <= MAX_COUNT (a = 0) (b = 0) il_tl xor ml_tl …
Events ML_out ML_in IN_in IN_out
13
ISLAND
LAND
ML_out
ML_innM
AX
_CO
UN
T
IL_out
IL_in ab
BRIDGE ml_tl
il_tl
VCC implementation elements#include <vcc.h>#include <stdio.h>#include <stdlib.h>#include <assert.h>
#define MAX_COUNT 1000#define LIGHT_DELAY 10#define SPEED_DELAY 10
typedef struct _trafficLight { unsigned light_i; unsigned light_m; unsigned delay;} TrafficLight;
typedef struct _parkingIsland { TrafficLight tl; unsigned n; unsigned a; unsigned b; unsigned w; // main invariants _(invariant n >= 0 && a >= 0 && b >= 0) _(invariant n + a + b <= MAX_COUNT) _(invariant a == 0 || b == 0) // traffic lights _(invariant tl.light_i == 0 || tl.light_i == 1) _(invariant tl.light_m == 0 || tl.light_m == 1) _(invariant (a + n < MAX_COUNT && b == 0 && a != 0) ==> tl.light_i == 1) _(invariant (a == 0 && b != 0) ==> tl.light_m == 1)} ParkingIsland;
void updateLights(ParkingIsland *pi) _(writes pi) _(writes &pi->tl.delay) _(writes &pi->tl.light_i) _(writes &pi->tl.light_m){ if (pi->a == 0 && pi->b == 0) { _(unchecked)pi->tl.delay--; if (pi->tl.delay == 0) { pi->tl.light_i = !pi->tl.light_i; pi->tl.light_m = !pi->tl.light_m; pi->tl.delay = LIGHT_DELAY; } } else { pi->tl.delay = LIGHT_DELAY; if (pi->a) { pi->tl.light_i = 0; pi->tl.light_m = 1; } else { pi->tl.light_i = 1; pi->tl.light_m = 0; } }}
14
VCC implementation (next - atomic)#include <vcc.h>#include <stdio.h>#include <stdlib.h>#include <assert.h>#include "atomic.h"
#define MAX_COUNT 100
typedef struct _parkingIsland { volatile unsigned n; _(invariant n == \old(n) || n == \old(n) + 1 || n == \old(n) - 1) _(invariant \this->n >= 0 && \this->n <= MAX_COUNT)} ParkingIsland;
// todo
int driveInto(ParkingIsland *p){ _(atomic p) { // todo }
// todo}
15
Lessons learned
If assertion involves a variable used in a cycle above, there should be a cycle’s invariant concerns this variable => Could be implemented in VCC
Usage of structures simplifies assertions. But hierarchy of structures sophisticates proof
16
Conclusion
Sometimes VСС requires assertions which are redundant
The complexity of the annotations depends on implementation features
To use VCC in an effective way it is necessary to work out a special coding style
17
Any questions?
18