2.9 Datenstrukturen für boolesche Funktionen

Werbung
2.9 Datenstrukturen für boolesche Funktionen
Darstellung von f : {0, 1}n → {0, 1}m , anders ausgedrückt:
Darstellung von f1 , . . . , fm : {0, 1}n → {0, 1}.
f : {0, 1}n → {0, 1}
←→
f −1 (1)
Also doch nur Mengen?
Ja, aber: Die Mengen sind typischerweise riesig groß.
Kombinatorische Überlegung: Es gibt 2n Elemente in {0, 1}n ,
n
2
also 2 verschiedene Mengen f −1 (1).
→
Jede Datenstruktur braucht für die meisten
Funktionen Ω(2n ) Bits.
. – Seite 196/726
Schaltkreise:
• Elementare boolesche Operationen z. B.
NOT =
AND = ∧
OR = +
EXOR = ⊕
Außerdem Eingänge x1 , . . . , xn , Konstanten 0, 1.
• Schaltkreis beschrieben durch Bausteinliste
B1 , . . . , Bm (Gatterliste, gate list).
Baustein Bi berechnet elementare Operation auf
Vorgängern aus B1 , . . . , Bi−1 , x1 , . . . , xn , 0, 1.
Beispiel:
Volladdierer in unserer Notation
(Addition von zwei Bits mit Übertrag):
x0
B3 ∧
y0
c0
⊕ B1
∧
+ B5 = c1
B4
⊕ B2 = s0
Ziel: Darstellung vieler und vor allem vieler wichtiger
Funktionen in polynomieller Größe und Unterstützung vieler
nützlicher Operationen.
Welche Operationen?
Bezeichne Datenstruktur für f mit Gf , da wir Graphen
betrachten werden:
1.)
Auswertung (evaluation):
Gegeben: Gf und a. Gesucht: f (a).
Motivation: offensichtlich.
2.)
Gleichheitstest (equality test):
Gegeben: Gf und Gg .
Frage: Gilt für alle a: f (a) = g(a)?
Motivation: Hardwareverifikation.
. – Seite 197/726
Neue Realisierung R,
die f darstellen soll,
sei g die dargestellte
Funktion
Spezifikation oder
bekanntermaßen korrekte
Darstellung S von f
?
∀a : S(a) = R(a)
auf Schaltkreisebene
zu schwierig.
Datenstruktur Gf
Umformung muss
(oft) effizient sein,
darf nie die Funktion
verändern.
Datenstruktur Gg
Gleichheitstest
. – Seite 198/726
Also brauchen wir Operationen, die eine durch einen
Schaltkreis dargestellte Funktion in eine Darstellung
innerhalb der Datenstruktur überführen.
Verfahren: Gate-by-Gate-Transformation
• Datenstruktur für Literale (xi oder xi )
sollte klein und direkt herstellbar sein.
• Durchlaufe Bausteinliste z.B.
N
N
h=f
g mit
∈ {AND, OR, EXOR, . . . }
f
g
⊗h
Erzeuge Datenstruktur für h aus
Datenstrukturen für f und g .
. – Seite 199/726
3.)
Synthese (binary synthesis):
N
N
Gegeben: Gf , Gg und . Gesucht: Gh für h = f
g.
Achtung: Selbst kleine Größenzuwächse können sich
aufschaukeln!
4.)
Erfüllbarkeitstest (satisfiability test):
Gegeben: Gf . Frage: ∃ a : f (a) = 1?
Dies ist oft ein Basisproblem (→ Vorlesung GTI).
Gleichheitstest „=“ Synthese + Erfüllbarkeit:
f = g ⇔ f ⊕ g nicht erfüllbar
EXOR
. – Seite 200/726
5.)
Ersetzung durch Funktionen
(replacement by functions):
Gegeben: Gf , Gg , xi .
Gesucht: Gh für h := f|xi =g , genauer:
h(x1 , . . . , xn ) := f x1 , . . . , xi−1 , g(x1 , . . . , xn ), xi+1 , . . . , xn .
Motivation: Modularer Hardwareaufbau.
x1 · · · xn
x1 · · · xn
g
x1 · · · xi−1 xi xi+1 · · · xn
f
x1 · · · xi−1
xi+1 · · · xn
h
. – Seite 201/726
Ersetzung durch Konstanten ist der Spezialfall g ≡ c.
Oft einfacher durchführbar.
Shannon-Zerlegung:
f = (xi ∧ f|xi =1 ) + (xi ∧ f|xi =0 ).
Damit folgt:
f|xi =g = (g ∧ f|xi =1 ) + (g ∧ f|xi =0 )
= if g then f|xi =1 else f|xi =0 = ITE(g, f|xi =1 , f|xi =0 ).
Also: Ersetzung durch Funktionen
= Ersetzung durch Konstanten + 3 binäre Synthesen
= Ersetzung durch Konstanten + ternäre ITE-Synthese.
(Viele OBDD-Pakete unterstützen ITE-Synthese direkt.)
. – Seite 202/726
6.)
Abstraktion oder Quantifizierung
(abstraction / quantification):
Gegeben: Gf , xi , ∀ oder ∃.
Gesucht:
Gg für g := (∃xi )f oder Gh für h := (∀xi )f , wobei
(∃xi )f := f|xi =0 + f|xi =1 und (∀xi )f := f|xi =0 ∧ f|xi =1 .
Motivation: Erfüllbarkeit ⇔ (∃x1 ) . . . (∃xn )f = 1.
Lebendigkeits- und Fairnessbedingungen sind
Existenzaussagen.
Verbotene Konstellationen lassen sich durch
Allaussagen beschreiben.
. – Seite 203/726
7.) Minimierung (minimization):
Gegeben: Gf .
Gesucht: Darstellung von f von minimaler Größe innerhalb
der betrachteten Datenstruktur.
(Wenn Ergebnis eindeutig, auch Reduktion (reduction)
genannt.)
Motivation: Synthese wird einfacher, wenn irgendeine
Darstellung von h das Ziel ist, aber dann entstehen oft sehr
große Darstellungen.
Gate-by-Gate-Transformation nur bei integrierter
Minimierung sinnvoll.
. – Seite 204/726
Warum nicht gleich Schaltkreise als Datenstrukturen?
Gegeben Schaltkreise Sf und Sg mit
|Sf | und |Sg | Bausteinen.
Auswertung:
O(|Sf |).
Synthese:
O(|Sf | + |Sg |), aber Ergebnis
mit |Sf | + |Sg | + 1 Bausteinen.
Ersetzen durch Fktn.: O(|Sf | + |Sg |).
Quantifizierung:
O(|Sf |).
Aber: Gleichheitstest, Erfüllbarkeitstest und Minimierung sind
algorithmisch schwierige Probleme (→ Vorlesung GTI).
In Theorie und Anwendungen Tagungen über SAT.
. – Seite 205/726
OBDDs (ordered binary decision diagrams):
OBDD: Gerichteter, azyklischer Graph, der
nach folgenden Regeln aufgebaut ist:
• Senken: Erlaubte Knoten mit Ausgrad 0 sehen so aus:
0 und 1
• Innere Knoten: Haben genau zwei Nachfolger, Knoten
mit Variable markiert, Kanten mit Konstanten 0 bzw. 1.
xi w
xi w
0
1
w0
w1
w0
w1
Alternativ: 0-Kante gestrichelt, 1-Kante durchgezogen.
• Variablenordnung: Liste aller Variablen in irgendeiner
Reihenfolge: π = (xi1 , . . . , xin ) (Permutation). Variablen
auf jedem Weg im Graph von Quellen zu Senken gemäß
dieser Reihenfolge.
Name für OBDDs mit Variablenordnung π :
π - OBDDs.
Variablenordnung ist frei wählbar, hier stets π = (x1 , . . . , xn ),
wenn nichts anderes gesagt wird.
Der Synthesealgorithmus arbeitet nur, wenn beide OBDDs
dieselbe Variablenordnung benutzen.
Beispiel Multiplexer (Vorlesung Rechnerstrukturen):
gute Variablenordnung:
Größe Θ(n),
schlechte Variablenordnung: Größe Θ(2n ).
. – Seite 206/726
Syntax von π - OBDDs
0 - Kante
x1 - Ebene
x1
x2 - Ebene
x1
x2
xi - Ebene
x2
xi
xi+1 - Ebene
xi+1
xi+1
xi+1
..
.
..
.
xj - Ebene
Alle Kanten
sind
abwärts
gerichtet
..
.
..
.
1 - Kante
xj
xj
..
.
xn - Ebene
Senken
xn
xn
0
1
. – Seite 207/726
Semantik von π - OBDDs
Jeder Knoten repräsentiert eine Funktion fv .
Option 1: Auswertungsalgorithmus für fv (a).
Starte an v , an xi -Knoten wähle ai -Kante,
gib Wert der erreichten Senke aus. O(n) unabhängig von
der OBDD - Größe.
Bezeichnung für so durchlaufenen Weg:
Berechnungsweg für Eingabe a.
Option 2: Globale Sicht auf alle Berechnungswege.
Eingabe a aktiviert alle ai -Kanten aus xi -Knoten.
Dann ist fv (a) der Wert der Senke, die auf dem
eindeutigen an v startenden aktivierten Weg erreicht wird.
. – Seite 208/726
Option 3: Bottom-up-Definition.
• Senken:
0 und 1
stellen konstante Funktionen 0 bzw. 1 dar.
• Innere Knoten:
xi w
w0
w1
Seien alle Funktionen fv für v unterhalb der xi -Ebene
definiert. Dann ist
fw (x) := ITE(xi , fw1 (x), fw0 (x)),
wobei w0 der 0-Nachfolger und w1 der 1-Nachfolger
von w ist.
. – Seite 209/726
Beispiele:
x1 ∧ x2 ∧ x3
x1
x1 + x2 + x3
x1
x2
0
x2
x3
0
0
x3
1
0
1
1
x1 ⊕ x2 ⊕ x3
x1
x2
x2
x3
x3
0
1
1
Ein komplexeres Beispiel – Addition von zwei 4-Bit-Zahlen:
(x3 , x2 , x1 , x0 )2 + (y3 , y2 , y1 , y0 )2 = (s4 , s3 , s2 , s1 , s0 )2 .
s4
s3
x3
x3
s2
y3
y3
y3
x2
y2
y3
x2
y2
y2
x1
x2
y2
y2
y2
s1
x1
x1
s0
y1
y1
x0
y1
y1
x0
x0
y0
0
y1
y1
y0
1
. – Seite 210/726
Erfüllbarkeitstest für fv
Starte eine Tiefensuche von v aus, überprüfe, ob die
O(|Gf |)
1-Senke erreichbar ist.
Beobachtung: Jeder Weg von v zu einer Senke ist für
passende Belegung a Berechnungsweg.
• Wähle ai je nach „Abzweig“ aus xi -Knoten.
• Keine widersprüchlichen Wahlen, da xi höchstens
einmal auf dem Weg – wegen Variablenreihenfolge!
• Fülle noch fehlende ai -Bits irgendwie beliebig auf.
fv (a) = 1: Berechnungsweg zu 1-Senke existiert, damit
insbesondere Weg, den Tiefensuche findet.
fv (a) = 0 für alle a: Alle Berechnungswege von v aus
führen zu 0-Senken. Kein Weg v
1-Senke möglich, da
(Beobachtung) dieser Berechnungsweg wäre.
. – Seite 211/726
Synthese von Gf und Gg zu Gh
durch „Synthese“ der Berechnungswege in Gf und Gg , hier
a = (1, 0, 1, 1, 0).
Gf
Gg
v 1 x1
w 1 x1
Gh für h := f ⊗ g
(v1 , w1 )
x1
x1 in Gf und Gg bearbeitet
v 2 x2
w 2 x2
(v2 , w2 )
x2
x2 bearbeitet, aber in Gf
Knoten mit „späterer Variablen“
w 3 x3
(v3 , w3 )
x3
x3 in Gg bearbeitet,
in Gf „gewartet“
v 3 x4
w 4 x5
(v3 , w4 )
x4
(v4 , w4 )
x5
x4 in Gf bearbeitet,
in Gg „gewartet“
x5 in Gg bearbeitet,
in Gf „gewartet“
v4 1
w5 0
(v4 , w5 ) 1 ⊗ 0
Senken in Gf und Gg erreicht,
Ergebnis durch ⊗ verknüpft
. – Seite 212/726
Synthese durch Kreuzprodukt
Gf = (Vf , Ef ), Gg = (Vg , Eg ), ⊗.
Gh = (Vh , Eh ) mit Vh = Vf × Vg . (Größen multiplizieren sich!)
Am Knoten (v, w) ∈ Vh soll fv ⊗ gw dargestellt werden.
1. Fall: v und w sind xi -Knoten
v xi
v0
(v, w) xi
w xi
v1
w0
w1
(v0 , w0 ) (v1 , w1 )
Korrektheit: Falls (v0 , w0 ) fv0 ⊗ gw0 und (v1 , w1 ) fv1 ⊗ gw1
darstellt, dann auch f(v,w) = fv ⊗ gw .
. – Seite 213/726
Falls (v0 , w0 ) fv0 ⊗ gw0 und (v1 , w1 ) fv1 ⊗ gw1 darstellt,
dann gilt:
f(v,w) = [xi ∧ (fv1 ⊗ gw1 )] + [xi ∧ (fv0 ⊗ gw0 )]
= [(xi ∧ fv1 ) ⊗ (xi ∧ gw1 )] + [(xi ∧ fv0 ) ⊗ (xi ∧ gw0 )]
= (xi ∧ fv1 + xi ∧ fv0 ) ⊗ (xi ∧ gw1 + xi ∧ gw0 )
= f v ⊗ gw .
Gleichungen 1 und 4 sind Definitionen.
Gleichungen 2 und 3 lassen sich durch Fallunterscheidung
(xi = 1 und xi = 0) überprüfen.
. – Seite 214/726
2. Fall: v ist xi -Knoten und w ist xj -Knoten mit j > i
oder Senke
Gf :
Gg :
v xi
(v, w) xi
w xj
Warten in Gg
oder
v0
v1
w0
w1
w c
(v0 , w) (v1 , w)
Falls (v0 , w) fv0 ⊗ gw und (v1 , w) fv1 ⊗ gw darstellt, dann gilt
f(v,w) = [xi ∧ (fv1 ⊗ gw )] + [xi ∧ (fv0 ⊗ gw )]
= [(xi ∧ fv1 ) ⊗ (xi ∧ gw )] + [(xi ∧ fv0 ) ⊗ (xi ∧ gw )]
= (xi ∧ fv1 + xi ∧ fv0 ) ⊗ (xi ∧ gw + xi ∧ gw )
= f v ⊗ gw .
. – Seite 215/726
3. Fall: v ist xj -Knoten mit j > i oder Senke und
w ist xi -Knoten
Spiegelbildlich analog zum Fall 2.
4. Fall: v ist c-Senke und w ist c′ -Senke
v c
(v, w) c ⊗ c′
w c′
Offensichtlich ist f(v,w)
= f v ⊗ gw .
Also gilt Korrektheit auf Senkenebene und damit nach
Induktion über die Ebenen von unten nach oben überall.
O(|Gf | · |Gg |)
Problem: Größenzuwachs!
Größe ist Knotenzahl,
da |Ef | < 2 · |Vf |.
. – Seite 216/726
Synthese unter Vermeidung unerreichbarer Knoten:
Es soll ja „nur“ h am Knoten (v, w) dargestellt werden.
Wenn kein Berechnungsweg, der in (v, w) startet, (v ′ , w′ )
erreicht, kann (v ′ , w′ ) gestrichen werden.
Besser: (v ′ , w′ ) gar nicht erzeugen.
Idee: Konstruiere Gh startend mit (v, w)
(v stellt f und w stellt g dar) mit DFS-Ansatz
. – Seite 217/726
Beispiel 1:
⊕
1
1
x1
x1
2
3
2
3
x2
x2
x2
x2
4
0
1
4
5
x3
0
1
5
6
Beispiel 2:
∧
1
1
x1
x2
2
x2
2
0
1
3
4
x3
0
1
3
4
Synthese unter Vermeidung unerreichbarer Knoten (Forts.):
Problem: Was passiert eigentlich, wenn Knoten bei DFS
mehrfach erreicht werden?
(v, w)
(v ′ , w ′ )
Sollten (wie immer) erkennen, wenn (v ′ , w′ ) wiederholt besucht
wird. Dann nicht noch einmal Graph für fv′ ⊗w′ konstruieren!
Wollen: DFS-Aufruf (v ′ , w′ ) soll Zeiger auf bereits berechnetes
Teil-OBDD für (v ′ , w′ ) liefern, falls vorhanden.
Wir brauchen eine dynamische Datenstruktur, die Suchen
und Einfügen von Paaren ((v ′ , w′ ), Zeiger auf OBDD-Knoten)
unterstützt. Name: Computed-Table.
Wie so etwas allgemein geht → Kap.3, erhalten:
– Bei Anzahl Einträgen s gibt es Datenstruktur mit
Worstcase-Zeit O(log s) für jede Operation.
– Es gibt Techniken, die bei typischen Daten Zeit O(1) pro
Operation brauchen.
Hier s ≤ |Gf ||Gg |. Wir rechnen mit O(1) – sonst Extrafaktor
O(log |Gf | + log |Gg |).
Soll (v ′ , w′ ) als neuer Knoten generiert werden, dann
– Suche in Datenstruktur.
– Falls gefunden, Zeiger auf vorhandenen Knoten.
– Falls nicht gefunden, neuer Knoten, Zeiger auf neuen
Knoten, neuen Knoten in Datenstruktur einfügen.
. – Seite 218/726
Lässt sich das Ergebnis-π -OBDD verkleinern?
Uns fallen zwei Verkleinerungsregeln ein:
xi
0
v
v
1
w
xi
xi
1
0
0
w
Eliminationsregel
(elimination rule)
u
xi
w
1
u′
w
0
u
1
u′
Verschmelzungsregel
(merging rule)
. – Seite 219/726
Eliminationsregel:
Der xi -Test kann offensichtlich übersprungen werden.
Formal fv = xi ∧ fw + xi ∧ fw = fw .
Verschmelzungsregel:
Wenn fv = fw , können die Zeiger auf v „umgebogen“
werden, um auf w zu zeigen.
Es ist fv = xi ∧ fu′ + xi ∧ fu = fw .
. – Seite 220/726
Synthese unter Vermeidung nicht erreichbarer Knoten und
Integration von Eliminationsregel und
Verschmelzungsregel.
DFS-basierte Konstruktion vom Startknoten aus.
Verwendung von Computed-Table, um Knoten nicht
mehrfach zu erzeugen.
Wie sehen Zwischenergebnisse aus? Es gibt
DFS hat den Backtrack auf die
– bestätigte Knoten:
v
erste Kante zu v vollzogen.
– noch nicht angelegte Knoten und
– Knoten in Bearbeitung.
. – Seite 221/726
– Fertige Knoten bleiben erhalten.
– Wegen DFS-Konstruktion gibt es pro Ebene
maximal einen Knoten in Bearbeitung.
(→ nie mehr als n Kanten mehr erzeugt als im Ergebnis.)
– Backtrack erreicht v über die zweite ausgehende Kante.
– Integration der Eliminationsregel:
Zeigen beide ausgehenden Kanten auf denselben Knoten?
Falls ja, Eliminationsregel anwenden.
. – Seite 222/726
Integration der Verschmelzungsregel:
Weitere Datenstruktur, die Suchen und Einfügen
unterstützt. Dort werden Knoten durch (Variable,
0-Nachfolger, 1-Nachfolger) oder (Senke, Wert)
abgespeichert. Name: Unique-Table.
Vorgehensweise beim Synthese-DFS-Aufruf für (v, w):
Rekursiv sei neuer Knoten r erzeugt worden.
• Vor dem Backtrack über die Kante zu (v, w) wird
überprüft, ob ein zu r äquivalenter Knoten (gleiches
Tupel) in der Unique-Table ist.
• Gleiches Tupel vorhanden, zugehöriger Knoten r′ :
Wirf Knoten r weg. Trage r′ in Computed-Table für (v, w)
ein. Gib r′ als Ergebnis des DFS-Aufrufes zurück.
• Kein gleiches Tupel vorhanden: Dann bleibt r erhalten.
Trage r in Computed-Table für (v, w) ein und gib r als
Ergebnis des DFS-Aufrufes zurück.
. – Seite 223/726
synthesisDFS(v,w)
{
if (v.val != UNDEF && w.val != UNDEF) // v,w sind Senken
return(Senke mit Wert v.val * w.val);
r = ComputedTable.search(v,w);
if (r != 0) return(r); // schon mal fuer (v,w) berechnet
else
{
index = min(v.index, w.index); // Fuer Variablenordn. x_1,...,x_n!
r0 = synthesisDFS(v0,w0); // Dabei (v0,w0), (v1,w1) wie in
r1 = synthesisDFS(v1,w1); // Fallunterscheidung gewählt.
if (r0 == r1) // Eliminationsregel schlägt zu
r = r0;
else
{
r’ = UniqueTable.search(index,r0,r1);
if (r’ != 0) { entsorge r0,r1; r = r’; }
else
{
r = new OBDDNode(index,r0,r1);
UniqueTable.insert(index,r0,r1, r);
}
}
ComputedTable.insert(v,w, r);
return(r);
}
}
Wie groß werden die Tabellen?
Unique-Table: ein Eintrag pro Knoten im Ergebnis.
Computed-Table: ein Eintrag pro erreichbarem Knoten im
Kreuzprodukt.
Das kann viel zu viel sein!
Pragmatische Lösung: Verkürze ggf. computed-table
(→ Kap. 3).
Was passiert mit dem Ergebnis?
Schon vorhandene Knoten, die nicht gespeichert sind,
werden wiederholt erzeugt, aber am Ende verschmolzen.
Time-Space-Trade-Off.
. – Seite 225/726
Wie gut ist unser Ergebnis?
Satz: Ein π -OBDD ohne nicht erreichbare Knoten, auf das
weder Eliminationsregel noch Verschmelzungregel
anwendbar sind, hat minimale Größe. Alle minimalen
π -OBDDs für f sind bis auf Benennung der Knoten
identisch.
(In DAP2 ohne Beweis.)
. – Seite 226/726
Ersetzung durch Konstanten
u xi
xi = 0
v
w
v
Dadurch können Knoten unerreichbar und
Verkleinerungsregeln anwendbar werden → in DFS-Ansatz
zum Finden der xi -Knoten integrierbar.
Gleichheitstest, Ersetzung durch Funktionen und
Quantifizierung auf die hier behandelten Operationen
zurückführbar.
. – Seite 227/726
Schaltkreise
O(|Sf |)
expo.
O(1)
expo.
Auswertung
Gleichheitstest
Synthese
Erfüllbarkeitstest
Ersetzung durch
Konstanten
O(|Sf |)
Ersetzung durch
Funktionen
O(|Sf | + |Sg |)
Quantifizierung
O(|Sf | + |Sg |)
Minimierung
expo.
π -OBDDs
O(n)
O(|Gf | · |Gg |)
O(|Gf | · |Gg |)
O(|Gf |)
O(|Gf |)
O(|Gf |2 · |Gg |)
O(|Gf | · |Gg |)
O(Gf )
in Synthese integrierbar
. – Seite 228/726
Herunterladen