21.11.2014 Aufrufe

Scheiding

Scheiding

Scheiding

MEHR ANZEIGEN
WENIGER ANZEIGEN

Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.

YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.

Seminar Logik SS2005<br />

Ilka <strong>Scheiding</strong><br />

Thema: ROBDDs - Reduced Ordered Binary Decision Diagrams<br />

Modelchecking kann man mit verschiedenen Datenstrukturen durchführen. Vorraussetzung<br />

ist, dass mit der verwendeten Datenstruktur Mengen eindeutig dargestellt werden können. Seit<br />

1990 werden Reduced Ordered Binary Decision Diagrams (ROBDDs), eine spezielle Form<br />

von binären Entscheidungsdiagrammen, als Datenstruktur für Modelchecking verwendet.<br />

Nutzt man ROBDDs als Datenstruktur für Modelchecking, so spricht man von Symbolic<br />

Modelchecking.<br />

Welche Vorteile es bringt, beim Modelchecking ROBDDs zu nutzen, möchte ich im<br />

Folgenden erklären.<br />

Boolsche Formeln sind eine uns bekannte Repräsentation von Mengen. Eine entscheidende<br />

Frage beim Umgang mit boolschen Formeln ist die, in welcher Datenstruktur sie abgelegt<br />

werden sollen. Einige Datenstrukturen, wie zum Beispiel Truth Tables, sind exponentiell in<br />

der Anzahl der Variablen. Dies führt schon bei wenigen Variablen dazu, dass der<br />

Speicherplatzbedarf unverhältnismäßig groß wird. Diesen Effekt nennt man „State Explosion<br />

Problem“. Andere Datenstrukturen, zum Beispiel Disjunktive Normalform, lassen sich<br />

kompakt speichern, haben aber bei manchen Operationen und Anwendungen, zum Beispiel<br />

bei Überprüfung von Erfüllbarkeit (SAT), einen sehr hohen Rechenaufwand. Operationen und<br />

Anwendungen, die für Modelchecking von Bedeutung sind, lassen sich sehr zeiteffizient auf<br />

ROBDDs durchführen. Hierauf werde ich später näher eingehen. Auch benötigen ROBDDs<br />

so wenig Speicherplatz, dass das State Explosion Problem erst bei sehr viel mehr Variablen<br />

als bei Truth Tables auftritt.<br />

Binäres Entscheidungsdiagramm (Engl.: Binary Decision Diagramm, kurz: BDD) ist ein sehr<br />

allgemeiner Begriff, unter den viele Datenstrukturen fallen, die sehr unterschiedlich sein<br />

können. Es gibt viele verschiedene Arten von BDDs. Die optimale Datenstruktur kann für<br />

verschiedene Mengen (boolsche Formeln) unterschiedlich sein. Da die Ermittlung der<br />

optimalen Datenstruktur sehr zeitaufwendig ist, suchen wir eine Datenstruktur, die im Mittel<br />

sehr gut geeignet ist. ROBDDs sind für sehr viele Mengen eine gute Repräsentation.<br />

Im Folgenden möchte ich erklären, wie ein ROBDD aufgebaut ist und welche Regeln für<br />

ROBDDs gelten.<br />

Zunächst möchte ich jedoch eine andere Form von BDDs, die Binary Decision Trees (BDTs)<br />

einführen. Anhand von Veränderungen dieses BDTs und weiteren Regeln, die wir nach und<br />

nach hinzunehmen werden, möchte ich mich schrittweise dem Aufbau von ROBDDs nähern.


Aufbau von Binary Decision Trees (BDTs)<br />

Es gibt mehrere Arten, eine Boolsche Formel durch Binarbäume darzustellen. Für unsere<br />

Zwecke ist folgende Art der Repräsentation nötig:<br />

Graphisch ist unser BDT ein Binärbaum mit je einer soliden und einer gestrichelten<br />

ausgehenden Kante von jedem Non Terminal Node. Jeder innere Knoten repräsentiert eine<br />

Variable und trägt sowohl den Namen (=Label) dieser Variable als auch den boolschen Wert<br />

(1 oder 0), welcher dem Wahrheitswert seiner Variable entspricht. Die Blattknoten (Terminal<br />

Nodes) entsprechen nicht Variablen, sondern Wahrheitswerten. Wir benennen sie daher<br />

schlicht „0“ oder „1“, entsprechend ihrer boolschen Belegung. Im Gegensatz zu anderen<br />

gängigen Repräsentationen werden Operatoren (Λ, V, etc.) nicht durch Knoten dargestellt.<br />

Operatoren nehmen Einfluss darauf, wie der Graph aufgebaut wird. Hierzu kommen wir<br />

jedoch später.<br />

BDT für Formel f(x,y,z) = -y Λ (x V -z)<br />

Zu einer boolschen Formel gibt es meist viele Möglichkeiten, ein BDT dieser Art aufzubauen.<br />

Reihenfolge und Anzahl der Vorkommnisse der Variablen sind beliebig.<br />

Um den Wahrheitswert einer Funktion f bei einer bestimmten Belegung der in f verwendeten<br />

Variablen zu ermitteln, beginnen wir mit der Betrachtung an der Wurzel. Dem Wurzelknoten<br />

ist eine Variable zugeordnet, in diesem Fall die Variable x. x hat nun die Belegung 1 oder 0.<br />

Ist die Belegung 0, folgen wir dem gestrichelten Pfad zu einem der Kinderknoten von x.<br />

Diesen nennt man auch lo(x). Ist die Belegung von x = 1, so bewegen wir uns zu dem Kind<br />

von x, zu dem man über die solide Kante gelangt (hi(x)).<br />

Als nächstes betrachten wir das Kind von x, zu dem wir gelangt sind. Wir tun dies auf die<br />

selbe Weise wie bei x: Ist die Variablenbelegung dieses Kindes von x = 0, so folgen wir der<br />

gestrichelten Kante, ist sie 1, der soliden Kante. Auf diese Weise bewegen wir uns stetig<br />

abwärts in unserem BDT, bis wir zu einem Blattknoten gelangen. Am Blattknoten können wir<br />

den Wahrheitswert für f mit der benutzten Variablenbelegung ablesen. Sind wir bei einem<br />

Blattknoten „0“ angelangt, so ist der Wahrheitswert der Boolschen Formel mit dieser<br />

benutzen Variablenbelegung „0“ (false), sind wir bei einem Blattknoten „1“ angelangt, so ist<br />

er ebenfalls „1“ (true). Es ist nicht möglich, dass wir zwei Knoten, die mit der selben Variable<br />

gelabelt sind, einmal über die solide und einmal über die gestrichelte Kante verlassen, da eine<br />

Variable nicht sowohl =1 als auch =0 sein kann.<br />

In obigem Beispiel wäre die Formel für die Belegung f( x = 0, y = 0, z = 0) = 1 (true) ,<br />

ebenso wäre sie = 1 (true) für (x = 1, y = 0), hierbei beeinflusst z den Wert des Ergebnisses<br />

nicht, z kann also sowohl = 1 als auch = 0 sein, um die Belegung wahr zu machen. Für alle<br />

anderen Belegungen wird f = 0 (false).


Aufbau von RBDDs<br />

BDTs haben nicht unbedingt einen geringeren Speicherplatzbedarf als Truth Tables, die<br />

Anzahl der Knoten kann ebenfalls exponentiell werden. Um den Speicherplatz zu optimieren<br />

überführen wir den BDT nun in ein Reduced Binary Decision Diagram (RBDD), indem wir<br />

drei Optimierungen vornehmen.<br />

Diese drei Optimierungen sind:<br />

C1: Redundante Terminale entfernen<br />

Alle Pfade die in Blattknoten mit der Belegung 0 führen, werden in einem einzigen<br />

Blattknoten „0“ zusammengeführt. Mit Pfaden zu Blattknoten 1 wird analog<br />

verfahren. Blattknoten, in die nun kein Pfad mehr führt, werden gelöscht. Hatten schon<br />

im BDT alle Blattknoten den selben boolschen Wert, werden alle Pfade in einem<br />

einzigen Knoten mit diesem Wert zusammengeführt.<br />

Redundante Terminale entfernen<br />

C2: Redundante Entscheidungsknoten löschen<br />

Enden beide von einem beliebigen Knoten x ausgehenden Pfade (der solide und der<br />

gestrichelte) im selben Knoten (hi(x) = lo(x)), so wird x gelöscht, da die Belegung von<br />

x keinen Einfluss auf den weiteren Verlauf des Pfades und somit der Überprüfung, hat.<br />

Alle Pfade, die vorher in x reinführten, führen nun in das Kind von x. Hierbei ist es<br />

unerheblich, ob das Kind von x ein innerer Knoten oder ein Blattknoten ist.<br />

Redundante Entscheidungsknoten löschen


C3: Gleiche Teilgraphen löschen<br />

Gibt es in einem BDD zwei exakt identische Teilgraphen deren Wurzelknoten wir x<br />

und y nennen, so werden alle eingehenden Pfade in den Knoten x auf den Knoten y<br />

umgeleitet, x und der gesamte Untergraph von x werden gelöscht.<br />

Gleiche Teilgraphen löschen<br />

Die Reihenfolge in der wir die Optimierungen durchführen spielt keine Rolle. Sie können<br />

auch beliebig oft hintereinander durchgeführt werden, denn es kann passieren, dass z.B. durch<br />

Anwendung von C3 und der daraus folgenden Umleitung eines Pfades ein redundanter<br />

Blattknoten entsteht, der erst danach (durch C2) gelöscht werden kann.<br />

Ein BDD ist reduziert (= RBDD), wenn C1, C2 oder C3 nicht mehr angewendet werden<br />

können.<br />

Ein reduzierter BDD ist auch wieder ein BDD, d.h. alle Eigenschaften eines BDD bleiben bei<br />

der Reduzierung erhalten. Da es nun vorkommen kann, dass ein Knoten mehr als einen<br />

Eingangspfad hat, sprechen wir von nun an nicht mehr über einen Binärbaum, sondern über<br />

ein Diagramm oder Graph.<br />

Die Reduzierungen dienen hier nur der Veranschaulichung. In guten Implementierungen wird<br />

durch dynamisches Programmieren ein nicht reduziertes BDD gar nicht erzeugt. Alle Knoten<br />

werden bei ihrer Erzeugung in einer Hash Table abgespeichert. Dabei wird auch überprüft, ob<br />

der gerade zu erzeugende Knoten sich bereits in der Hash Table befindet (unerheblich wo im<br />

Diagramm er sich befindet). Ist ein identischer Knoten bereits vorhanden, so wird der aktuelle<br />

Knoten nicht erzeugt, sondern seine eingehenden Pfade werden auf den bereits vorhandenen<br />

umgelenkt. Auf diese Weise entstehen nur reduzierte BDDs, also RBDDs.<br />

Durch die Reduzierungen kann es passieren, dass ein ganzes Diagramm auf einen einzigen<br />

Blattknoten reduziert wird. Ist dies der Fall und der Blattknoten ist ein Knoten mit dem Wert<br />

„0“, so nennen wir das Diagramm „B 0 “. Analog nennen wir es „B 1 “, wenn es nur aus dem<br />

Knoten mit dem Wert „1“ besteht.<br />

Ordnung und Größe von RBBDs<br />

Wie anfangs erwähnt gibt es viele Möglichkeiten ein BDD, so auch ein RBDD, aufzubauen.<br />

Ein wichtiger Aspekt hierbei ist die Anordnung von Variablen.<br />

Eine „Variablenordnung“ ist die Reihenfolge von Variablen, wie sie von der Wurzel zu den<br />

Blättern hin in ein (R)BDD eingefügt werden.


ROBDDs<br />

ROBDDs sind RBDDs für die eine Variablenordnung gilt. Hierbei gelten folgende Regeln:<br />

- Jede Variable darf in der Variablenordnung genau einmal vorkommen.<br />

- Jede Variable, die in einem ROBDD vorkommt, muss (!) in die Variablenordnung<br />

aufgenommen werden.<br />

- Nicht jede Variable der Variablenordnung muss in jedem ROBDD einen Knoten<br />

bekommen.<br />

Alle ROBDDs, die in einem Kontext miteinander stehen, müssen sich einer gemeinsamen<br />

Variablenordnung bedienen. Dies gilt insbesondere für ROBDDs, die miteinander verglichen<br />

oder durch Operatoren (V, Λ, XOR) miteinander verknüpft werden sollen.<br />

Bauen wir einen RBDD auf, so ist die Variablenordnung entscheidend für die Größe des<br />

RBDDs. Die optimale Variablenordnung zu finden ist ein komplexes Problem und hat einen<br />

hohen Rechenaufwand, es gibt jedoch Heuristiken, die zeiteffizient recht gute<br />

Variablenordnungen berechnen. Einen wichtigen Ansatz für die heuristische Betrachtung<br />

dieses Problems möchte ich im Folgenden nennen und an einem Beispiel verdeutlichen.<br />

Ansatz: Was in logischem Zusammenhang steht, sollte auch zusammen betrachtet werden<br />

Beispiel:<br />

f = ((a1=b1) Λ (a2=b2) Λ (a3=b3))<br />

Der Wahrheitswert des gesamten Ausdrucks f, hängt davon ab, ob die geklammerten<br />

Teilausdrücke wahr sind. Diese Teilausdrücke können aber erst einen Wahrheitswert<br />

zugeordnet bekommen, wenn alle darin vorkommenden Variablen betrachtet wurden. Daher<br />

ist es sinnvoll, jeweils die Variablen eines Teilausdrucks im ROBDD in räumlicher Nähe<br />

anzuordnen, z.B. auf einem Pfad direkt untereinander, wie im Beispiel links, um sie somit<br />

beim Durchlaufen des Graphen auch kurz nacheinander zu betrachten. Dadurch kann<br />

gegebenenfalls recht schnell entschieden werden, ob ein Ausdruck noch wahr (oder falsch)<br />

werden kann.


Variablenordnung:<br />

a1, b1, a2, b2 , a3 , b3<br />

Variablenordnung: a1, a2 , a3, b1 , b2 , b3<br />

Eine Variablenordnung in der jede Variable nur einmal vorkommen darf, wie es bei ROBDDs<br />

der Fall ist, hat den positiven Effekt, dass auf einem Pfad von der Wurzel zu einem<br />

Blattknoten keine Variable mehrmals betrachtet wird.<br />

Folgendes Beispiel soll verdeutlichen, warum dies so ist:<br />

Haben wir einen Ausschnitt aus einem Graphen wie links zu sehen, so<br />

ist die zugehörige Variablenordnung „..a…b...a…“ , da es einen Pfad<br />

gibt, auf dem a sowohl vor b als auch nach b betrachtet wird. Dies ist<br />

jedoch nach der Definition von ROBDDs nicht zulässig. Hierbei ist<br />

unerheblich, ob zwischen a und b bzw. b und a noch andere Variablen<br />

liegen.<br />

Eine Struktur dieser Art ist in einem ROBDD ebenfalls nicht möglich,<br />

da einer der beiden Knoten als redundanter Entscheidungsknoten<br />

gelöscht bzw. nicht erstellt werden würde.<br />

Dies führt zu folgender Beobachtung: Betrachten wir zwei beliebige aber feste Variablen x<br />

und y. Steht x in der Variablenordnung vor y, so kommen x und y im RBDD entweder nicht<br />

auf dem selben Pfad vor oder x steht vor (= näher an der Wurzel als) y.


Gibt es keine Variablenordnung, so kann man für die selbe boolsche Formel viele BDDs mit<br />

verschiedenen Strukturen erzeugen. Durch die Variablenordnung aber haben ROBDDs eine<br />

eindeutige (kanonische) Repräsentation. Das heißt wenn zwei ROBDDs R 1 und R 2 die selbe<br />

boolsche Funktion repräsentieren, dann ist ihre Struktur identisch. Zu einer Boolschen Formel<br />

kann man also unter Berücksichtigung einer bestimmten Variablenordnung genau ein<br />

ROBDD aufbauen.<br />

Die kanonische Repräsentation ist einer der größten Vorteile von ROBDDs. Hierdurch<br />

können für boolsche Formeln folgende Tests sehr schnell durchgeführt werden:<br />

• Test auf redundante Variablen : Hängt das Ergebnis nicht von Variable x i ab, enthält<br />

das ROBDDs x i nicht.<br />

• Test auf Tautologie: Eine Formel ist immer = 1(true), wenn das zugehörige ROBDDs<br />

= B 1 ist. Besteht das zugehörige ROBDD nicht nur aus dem Blattknoten „1“, so ist es<br />

falsifizierbar.<br />

• Test auf Erfüllbarkeit (SAT) : Ist ein ROBDD = B 0, so ist es nicht erfüllbar, es wird<br />

immer 0 (false). Ist es nicht = B 0, dann gibt es mindestens eine Variablenbelegung, die<br />

diese Formel wahr macht, sie ist also erfüllbar.<br />

Anmerkung zur Laufzeit:<br />

Der Test auf Erfüllbarkeit kann in konstanter Zeit durchgeführt werden. Trotzdem ist SAT<br />

auch mit ROBDDs ein NP-vollständiges Problem, da der Aufbau eines ROBDDs im<br />

Worst Case NP-vollständig ist.<br />

Im Average Case erfolgt die Umwandlung jedoch recht effizient, wodurch ROBDDs in<br />

der Praxis oft vorteilhaft sind.<br />

• Test auf semantische Äquivalenz zweier ROBDDs: Haben zwei oder mehrere<br />

ROBDDs die selbe Struktur, so sind sie semantisch äquivalent. Haben sie<br />

verschiedene Strukturen, sind sie nicht semantisch äquivalent.<br />

Wie viele Belegungen gibt es, die ein ROBDD wahr machen?<br />

Die Anzahl der Belegungen, die ein ROBDD wahr machen, muss für jedes ROBDD einzeln<br />

berechnet werden. Man beginnt die Rechnung von den Blattknoten aus und arbeitet sich zur<br />

Wurzel hin vor. Dabei wird sich für jeden besuchten Knoten gemerkt, wie viele Belegungen<br />

von ihm ausgehend einen Weg zum Blattknoten „1“ ermöglichen. Diese Anzahl kann größer<br />

sein, als die Anzahl der Pfade, die von dem jeweiligen Knoten zum Blattknoten „1“ führen, da<br />

nicht auf jedem Pfad jede Variable der boolschen Formel vorkommt, jedoch auch diese<br />

Variablen berücksichtigt werden.<br />

Beispiel:<br />

Der Knoten „0“ bekommt den Wert 0 zugeordnet, der<br />

Knoten „1“ den Wert 1.<br />

e : 0 + 1 =1<br />

1, da der Knoten „1“ Kinderknoten von e ist<br />

0, da der Knoten „0“ Kinderknoten von e ist<br />

e ist die letzte Variable in dieser Variablenordnung, die in<br />

der Formel vorkommt, daher gibt es keine<br />

Multiplikationen.


d : 0 + 1*2 1 = 2<br />

0, da der Knoten „0“ Kinderknoten von d ist<br />

1, da der Knoten „1“ Kinderknoten von d ist<br />

2 1 , denn genau eine Variable, die in der Formel vorkommt liegt in der Ordnung hinter d,<br />

wurde aber auf diesem Pfad nicht betrachtet.<br />

*2 1 , denn dieser Pfad führt bei e=1 und auch bei e=0 zu einer erfüllenden Belegung.<br />

c : 2*2 0 + 1*2 1 = 4<br />

2*2 0 : die erste 2 wird von d übernommen, *2 0 denn es liegen keine, also 0, Variablen<br />

zwischen c und d.<br />

1*2 1 : 1 wird von e übernommen, *2 1 denn zwischen c und e liegt d, d wurde aber nicht<br />

betrachtet. Dieser Pfad führt also für d = 1 und d = 0 zur 1.<br />

b : 0 + 1*2 3 = 8<br />

0, da der Knoten „0“ Kinderknoten von b ist<br />

1, da der Knoten „1“ ein Kinderknoten von b ist,<br />

*2 3 , denn in diesem Pfad haben wir 3 Variablen der Formel (c,d,e,) nicht betrachtet. Für jede<br />

Kombination aus c=0/1, d=0/1 und e=0/1 führt dieser Pfad also zur 1.<br />

a : 8 + 4 *2 1 = 16<br />

8 wird von b übernommen, es gibt keine Variablen zwischen a und b, daher wird nicht<br />

multipliziert,<br />

4 wird von c übernommen und *2 1 , da wir auf diesem Pfad b, also genau eine Variable, nicht<br />

betrachtet haben.<br />

Da a der Wurzelknoten ist und es von a aus 16 Belegungen gibt, die die Formel wahr machen,<br />

wissen wir, dass es insgesamt 16 Belegungen gibt, die die Formel wahr machen.<br />

Zur Erinnerung:<br />

lo(x) ist der Kinderknoten von x, zu dem wir gelangen, wenn x = 0 ist.<br />

hi(x) ist der Kinderknoten von x, zu dem wir gelangen, wenn x = 1 ist.<br />

Allgemein:<br />

Sei x der Knoten, den wir aktuell betrachten.<br />

Sei A(x) die Anzahl der Belegungen, die die Formel für Variablen ab x wahr macht.<br />

Sei j = A(lo(x)).<br />

Sei h = A(hi(x)).<br />

Sei dl die Anzahl der Variablen, die in der boolschen Formel vorkommen und in der<br />

Variablenordnung zwischen x und lo(x) liegen.<br />

Sei dh die Anzahl der Variablen, die in der boolschen Formel vorkommen und in der<br />

Variablenordnung zwischen x und hi(x) liegen.<br />

Für die Blattknoten gilt A(„0“)=0 , A(„1“)=1<br />

Dann ist A(x) = j * 2 dl + h * 2 dh


Algorithmus apply zur Verknüpfung durch Operatoren<br />

Wollen wir zwei ROBDDs durch einen Operator verknüpfen, wenden wir den Algorithmus<br />

apply an. Dieser Algorithmus bekommt als Input die beiden ROBDDs R1 und R2 und den<br />

Operator und liefert ein ROBDD zurück, welches der Variablenordnung entspricht und genau<br />

für (R1 Op R2) den Wahrheitswert 1 zurückliefert und sonst den Wahrheitswert 0.<br />

Die beiden bisherigen Diagramme werden nicht verändert, sondern ein drittes Diagramm<br />

B f_Op_g wird erstellt.<br />

Der Algorithmus ist rekursiv und beginnt bei dem Wurzelknoten. Er arbeitet wie an<br />

folgendem Beispiel demonstriert:<br />

Zunächst Labeln wir jeden Knoten. Die Blattknoten bekommen nach ihrer Belegung dabei die<br />

selben Werte, da wir einen Blattknoten „0“ („1“) als den selben Knoten betrachten, ganz<br />

gleich in welchem Diagramm er vorkommt. Alle anderen Knotenbezeichnungen vergeben<br />

wir nur ein Mal. Hierdurch entsteht nun dieses Diagramm:<br />

Wie oben schon erwähnt wird auch das neue Diagramm B f_Op_g in der Regel durch Hashing<br />

als ROBDD erzeugt. Im Folgenden wird jedoch nur der Basisalgorithmus erklärt, so dass das<br />

Ergebnis zunächst ein nicht reduziertes Diagramm sein wird.<br />

Wir beginnen bei beiden Diagrammen B f und B g mit der Betrachtung bei den Wurzelknoten<br />

(S2 und S5). Wir bilden einen neuen Wurzelknoten (S2,S5) und labeln ihn mit a. Könnten wir<br />

einem Knoten theoretisch zwei Variablen zuordnen (wie hier a und b), so wählen wir immer<br />

die Variable, die in der Variablenordnung weiter vorne steht. Nun fügen wir zwei Kanten<br />

hinzu, grafisch eine solide und eine gestrichelte. Von (S2,S5) gehen nun zwei Kanten aus, die<br />

zu je einem weiteren Knoten führen sollen. Verfolgen wir zunächst die solide Kante: Von S2<br />

im Diagramm f ausgehend führt die solide Kante zu S1. In g bleiben wir zunächst in S5, da<br />

(S2,S5) mit a gelabelt wurde und a in g nicht vorkommt. In g befinden wir uns daher noch im<br />

Wurzelknoten S5. Daher erzeugen wir als Kind von (S2,S5) einen Knoten (S1,S5), diesen


labeln wir mit b. Solange es möglich ist, einen Knoten mit einer Variable zu labeln, tun wir<br />

dies (auch wenn ein Teil des Tupels S1 oder S0 ist). Auch in B f_Op_g gilt, dass nur Blattknoten<br />

keiner Variable zugeordnet sind.<br />

Von hier aus wird der Graph nach selbem Prinzip rekursiv weiter aufgebaut, ebenso die<br />

andere Hälfte des Graphen ausgehend von der gestrichelten Kante der Wurzelknoten.<br />

Erreicht ein Pfad in f oder g S1 oder S0, so bleiben wir in diesem Blattknoten stehen.<br />

Aus (S1,S5) ausgehend führt die solide Kante zu (S1,S1). Da wir bei beiden Graphen f und g<br />

in Blattknoten angekommen sind, wird auch der Knoten (S1,S1) zu einem Blattknoten.<br />

Daher erstellen wir nun den Kinderknoten an der gestrichelten Kante von (S1,S5).<br />

Folgen wir von S5 aus der gestrichelten Kante, so gelangen wir zu S6. In f bleiben wir in S1.<br />

Daher wird als zweites Kind von (S1,S5) der Knoten (S1,S6) erstellt.<br />

Bisher haben wir folgenden Graphen für B f_ Op_g erstellt:<br />

Verfahren wir wie oben weiter bis wir auf jedem Pfad in f und g einen Blattknoten erreicht<br />

haben, also bis der Algorithmus terminiert, erhalten wir folgenden Graphen:<br />

Von nun an sind die Bezeichnungen der inneren Knoten irrelevant. Sie dienten nur dem<br />

Aufbau des Graphen.<br />

Bis zu diesem Punkt hatte der Operator, mit dem die beiden Graphen f und g verknüpft<br />

werden, keinen Einfluss auf den Aufbau des neuen Graphen. Mit dem Operator wird jetzt<br />

lediglich festgelegt, welche Werte die Blattknoten bekommen.


Hierzu ersetzen wir alle S0 wieder mit 0 und alle S1 mit 1. Auf diese 0en und 1en wenden wir<br />

nun den Operator an. Da wir in diesem Beispiel Und-verknüpfen, werden alle Paare (1,1)<br />

durch einen Knoten „1“ ersetzt, alle anderen Paare durch einen Knoten „0“.<br />

Würden wir Oder-verknüpfen, würden wir alle Paare (1,1), (1,0) und (0,1) durch einen<br />

Knoten „1“ ersetzen und nur (0,0) durch einen Knoten „0“. Mit Xor würde entsprechend<br />

verfahren.<br />

Um den Graphen B f_ Op_g als ROBDD zu erhalten, müssen wir ihn noch reduzieren:<br />

Shannon Expansion – Hintergrund zum Algorithmus apply<br />

Einschub: Restriktion einer Formel:<br />

Die Schreibweise f[1/x] bedeutet, dass alle in einer Formel f auftretenden Variablen x<br />

durch 1 (true) ersetzt werden. Analog bedeutet f[0/x], dass alle in f auftretenden<br />

Variablen x durch 0 (false) ersetzt werden. Dies nennt man Restriktion von f.<br />

Die Shannon Expansion besagt: Für alle boolschen Formeln und boolschen Variablen, selbst<br />

die, welche nicht in f vorkommen, gilt f ≡ -x Λ f[0/x] V x Λ f[1/x].<br />

Die Shannon Expansion für (f op g) lautet:<br />

f op g ≡ -x i Λ ( f[0/x i ] Λ g[0/x i ] ) V x Λ ( f[1/x i ] Λ g[1/x i ] )


Für den Algorithmus apply wird die Shannon Expansion für f op g als Kontrollfunktion<br />

genutzt. Sei x i jeweils die aktuell betrachtete Variable. Dann werden aus x i heraus zwei<br />

Unterbäume erzeugt, je einer für ([0/x i ] Λ g[0/x i ]) und einer für ( f[1/x i ] Λ g[1/x i ] ).

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!