Computergestützte Verifikation

Werbung
Computergestützte Verifikation
18.6.2002
1
Zusammenfassung Abstraktion
zentral: Simulation/Bisimulation
Simulation  ACTL*
Bisimulation  CTL*
Jede Menge abstrakter Zustände kann zu Simulation
fortgesetzt werden, aber nicht immer zu einer Bisimulation
Die meisten Reduktionstechniken sind Abstraktionen
2
Allgemeine Abstraktionsverfeinerung
Spaltung eines abstrakten Zustandes kann weitere
Spaltungen notwendig machen  Propagation nach
rückwärts...
... bis sich nix mehr ändert
3
Scheingegenbeispiele
erfüllbare Pfadformel
nicht erfüllbare Pfadformel
dead end state = erreichbar von einem konkreten Zustand im
ersten abstrakten Zustand
bad state = hat Nachfolger
Verfeinerung = trenne dead end und bad states
4
Lasso-Gegenbeispiele
Realisierbar im konkreten System?
Schlaufe im konkreten System kann länger sein als im
abstrakten System
Satz: Wenn abstrakte Schleife überhaupt konkret realisierbar
ist, so auch eine der Länge k x A
A – Länge der abstrakten Schlaufe
k – Anzahl der konkreten Zustände im “kleinsten” abstrakten
5
Zustand
Zusammenfassung Abstraktionsverfeinerung
a) allgemein:
lokale Realisierung der Bisimulationskritierien werden durch
das gesamte Transitionssystem propagiert.
Wichtig: Umkehrbarkeit der Übergangsrelation
b) gegenbeispielgesteuert:
Wichtig:
1. Realisierbarkeit abstrakter Pfade im konkreten System muß
überprüfbar sein
2. geeignete Heuristiken für Trennung von dead ends und bad
states
6
8. Softwareverifikation
8.1 Predicate Abstraction
8.2 Abstract Interpretation
8.3 Slicing
8.4 ...
--- Vorsicht Baustelle --7
Probleme bei der Softwareverifikation
1. komplexe Datentypen und Expressions
2. Pointer und dynamische Datenstrukturen
3. Prozeduren und Rekursion
4. Bibliotheken
8
8.1 Predicate Abstraction
Basis: n boolesche Prädikate auf Programmvariablen
z.B. p = NULL
x > y +1
Jedem Prädikat fi wird eine boolesche Variable bi zugeordnet
konkreter Zustand = Belegung der Programmvariablen
abstrakter Zustand = Formel über den bi
Abstraktionsrelation r:
c r a gdw. [f1(c), ...., fn(c)]  a
Halbordnung “impliziert” auf den abstrakten Zuständen
pc wird fast immer explizit repräsentiert
9
Abstrakte Zustände
c¬d ¬ c d
a b
¬ a b
(¬ b ¬ d)(¬ a ¬ c¬
¬ a¬ b
a¬ b
c d ¬ c¬ d
Praxis: z.B. Repräsentation abstrakter Zustände als BDD
oder: Restriktion auf einfache Konjunktionen
(im Beispiel: ¬ d)
10
Wo kommen Prädikate her?
a) nutzerdefiniert
b) automatisch
- Bedingungen in IF, WHILE, ....
- elementare Aussagen in Formel
11
Abstrakter Nachfolger
geg.: Abstrakter Zustand a, guarded command g: g  x1..n:=T1..n
ges.: a’ so daß
- jeder konkrete Zustand, der von einem von a
repr. Zustand aus per g entsteht, von a’ repr. wird
- a’ mglst. stark
Berechnung von a’ im allg. schwer, für Konjunktionen leichter:
a’:
- false,
n
-

j=1
falls a[bifi]i=1..n ¬ g
bj falls a[bifi]i=1..n  g  fj [ xiTi]i=1..n
¬bj falls a[bifi]i=1..n  g  ¬fj [ xiTi]i=1..n
true,
sonst
 Theorembeweiser
12
Beziehung zu Dijkstras Weakest
Preconditions
geg: Statement s, Zustandseigenschaft f
spost(s,f) = die stärkste Eigenschaft f’, so daß jeder Zustand,
der vor Ausführung von s f erfüllt, nach s f’ erfüllt.
wpre(s,f) = die schwächste Eigenschaft f’, so daß jeder Zustand,
der nach Ausführung von s f erfüllt, vor s f’ erfüllt hat.
Für Zuweisungen:
wpre(x := E, f) = f[x  E]
Satz: (spost(s,f)  f’ )  (f  wpre(s,f’) )
exakter abstrakter Nachfolger von a mit command g: spost(g,a)
13
Theorembeweiser
Eingabe: prädikatenlog. Formel, nicht immer Stufe 1
1. Formel aus entscheidbarer Theorie  Entscheidungsalg.
- SAT-Checker
- Pressburger Arithmetik
- Bitvektor-Arithmetik
- Model Checker
....
2. Rewriting
- Regeln (z.B. Schlussregeln) Termersetzung, Unifikation
- Ziel: Rückführung auf Axiome
- erweiterbare Regelbasis
- Taktiken
14
Abstraktionsverfeinerung
= Hinzunahme weiterer Prädikate
15
typedef struct cell{
int val;
struct cell* next;
} * list;
void partition() {
bool b1,b2,b3,b4;
Beispiel
b1 = unknown();
b3 = unknown();
b2 = true;
b4 = unknown();
list partition(list *l, int v) {
skip;
list curr, prev, newl, nextCurr;
while(*) {
assume(!b1);
curr = * l;
skip;
prev = NULL;
if(*) {
newl = NULL;
assume(b3)
while( curr != NULL) {
if(*) {
nextCurr = curr -> next;
assume(!b2);
if(curr -> val > v) {
skip;
if(prev != NULL) {
}
prev -> next = nextCurr;
if(*) {
}
skip;
if(curr == *l) {
}
*l = nextCurr;
skip;
}
L:
skip;
curr -> next = newl;
} else {
L:
newl = curr;
b1: curr==NULL
assume(!b3);
} else {
b2: prev==NULL
b2 = b1;
prev = curr;
b3: curr->val>v
b4 = b3;
}
b4: prev->val>v
}
curr = nextCurr;
b1 = unknown();
}
b3 = unknown();
return newl; AG(@L curr!=NULL AND curr->val>v
}
AND (prev->val<=v OR prev=NULL))
16
}
assume(b1);
AG(@L !b1 AND b2 AND (!b3 OR b4))
}
Pointer
bisher: wpre(x := E,f) = f[ x  E]
stimmt nicht, wenn Pointer beteiligt sind:
Beispiel: Sei p = & x;
wpre(x = 3, *p > 5) != *p > 5
 (für einen potentiellen Alias y)
wpre(x := E, f) = ( ( &x = &y  f[y  E]) 
( &x != &y  f) )
Nichtdeterminismus, es sei denn, Alias-Analyse kann eine
Alternative ausschließen: “may point to”, “may not point17to”
Bedingungen
IF B THEN T ELSE E END
 IF * THEN assume(X); T ELSE assume(Y); END
X: das stärkste Prädikat (über den gegebenen Prädikaten)
das von B impliziert wird
Y: das stärkste Prädikat (über den gegebenen Prädikaten)
das von ¬B impliziert wird
zwischen X und Y kann Lücke klaffen  Nichtdet.
18
Prozeduren
einfach: Inlining (mit Tiefenrestriktion bei Rekursion)
schwierig: Fixpunktberechnung
19
Übung
main()
{
int x,y,z;
x = 3;
y = x + 1;
while(y > 3)
{
z = 0;
if(x == z)
{
x = x + 1;
z = 3;
}
else
{
y = x - 1;
y++;
}
y = 2 * y;
}
x = foo(y,z);
Transformiere folgendes
C-Programm in ein boolesches
Programm, basierend auf den
Prädikaten x > 0, y = x und
y != 0
}
20
Herunterladen