Wahrheitstabellen
“Wahr oder Falsch” – diese Frage beschäftigt Programmiererinnen und Programmierer tagtäglich. Wann immer sie eine Bedingung formulieren, kommt die Bool’sche Algebra mit ihren Wahrheitstabellen zum Zuge.
Im folgenden beleuchten wir die theoretischen Hintergründe. Und geben einfache, praktische Tipps für alle, die gerne programmieren.
Bool’sche Logik
Die Bezeichnung verdanken wir dem Mathematiker George Boole.
Ob er sich im 18. Jahrhundert hätte vorstellen können, dass seine Studien solch zentralen Stellenwert für einen ganzen Berufszweig haben würden?
Es gelang ihm, die Aussagenlogik als Algebra aufzufassen. Um das zu verstehen, brauchen wir gar nicht so genau zu wissen, was eine “Algebra” ist. Den meisten von uns ist der Begriff bekannt, ohne dessen Definition genau zu kennen.
In der Algebra, präzise in einer Algebra, untersucht man Zahlensysteme hinsichtlich ihrer Regeln. Wir kennen das:
Die ganzen Zahlen mit den beiden Operationen Addition und Subtraktion.
Oder die reellen Zahlen mit den Operationen Addition, Subtraktion, Multiplikation und Division.
George Bool untersuchte ein anderes Zahlensystem. Es besteht aus genau zwei Werten:
True und False – also Wahr und Falsch – oder auch 1 und 0.
Und es kennt eine Reihe von Operationen: Multiplikation, Addition – als die einfachsten Beispiele.
Wie soll das gehen? Wie kann man mit Wahr und Falsch multiplizieren und addieren?
Ganz einfach: wenn wir es nicht wissen, dann können wir es definieren. George Bool hat das getan und untersucht, was dabei passiert.
Aussagenlogik
Boole ist nicht blind vorgegangen, sondern hat auf Bekanntes zurückgegriffen. Auf die Definition einer “Algebra” beispielsweise. Genauer auf die Axiome einer Algebra. Wenn er beweisen kann, dass seine Definition eines neuen Zahlensystems den bekannten und anerkannten Axiomen einer Algebra entspricht, dann hat seine “Erfindung” wirklich Hand und Fuss.
Um es vorwegzunehmen – es ist ihm gelungen.
Addition und Multiplikation hat George Bool nicht einfach so erfunden. Er orientierte sich an der Aussagenlogik, deren Wurzeln ja bis zu den alten Griechen, zu Aristoteles, reicht.
Bool’sche Operationen als Wahrheitstabellen
Und so entstanden die Wahrheitstabellen.
AND wirkt wie die Multiplikation – ersetzte True durch 1 und False durch 0, dann kannst du in der AND-Tabelle die gewohnte Multiplikation ablesen.
Ähnlich bei OR – diese entspricht der Addition – nur dass beim Einsetzen von 0 und 1 bei TRUE or TRUE also 1 or 1 oder auch 1 + 1 nicht zwei resultiert, sondern wieder 1. Wir haben ja gar keine 2.
Und ähnlich geht es bei NOT – hier wird der Wert ‘umgedreht’ also invertiert – im Ansatz so ähnlich wie die Division.
Dieses ‘Zahlensystem’ genügt den Axiomen einer Algebra. Bool hat es bewiesen und deshalb sprechen wir von einer Bool’schen Algebra.
Und die Logik-Ausdrücke mit Wahr und Falsch mit AND, OR, NOT widerspiegeln die Bool’sche Logik.
Und es gibt die bekannten Regeln, die wir aus anderen Algebren kennen.
Sagen wir nämlich, dass AND der Multiplikation entspricht und OR der Addition, dann gilt auch hier:
Punkt vor Strich. Und damit gelten auch die gewohnten Klammerregeln.
Wahrheitstabellen in der Programmierung
Wahrheitstabellen sind aus der Programmierung nicht wegzudenken – in jeder Bedingung, die wir formulieren, beispielsweise in einer IF-Bedingung oder einer WHILE-Bedingung, kommen diese Tabellen zum Zuge:
Wenn wir formulieren:
if (wert1 < wert2): print(“das ist wahr”)
Dann wird der Python-Interpreter den Ausdruck wert1 < wert2 mit den aktuellen Werten der beiden Variablen auswerten und herausfinden, ob die Bedingung zutrifft oder nicht.
Trifft sie zu, dann wird der Rumpf der Bedingung ausgeführt – im Beispiel der Text “das ist wahr” ausgegeben.
Trifft die Bedingung zu, dann wird wert1 < wert2 ersetzt durch den Bool’schen Wert True.
Trifft sie nicht zu, dann wird die Bedingung ersetzt durch den Bool’schen Wert False.
Das passiert auch, wenn die Bedingung etwas komplexer ist – ein Beispiel:
if wert1 < wert2 and wert2 < wert3: print("das ist wahr")
Der Python-Interpreter macht folgendes:
- Ersetzt die Variablen wert1, wert2, wert3 durch die aktuellen Werte
- Vergleicht, ob wert1 < wert2 – trifft das zu, wird dieser Ausdruck ersetzt durch True (sonst False)
- Vergleicht, ob wert2 < wert3 – trifft das zu, wird dieser Ausdruck ersetzt durch True (sonst False)
- Wertet das Gesamtergebnis aus, also Beispielsweise True AND False – und da kommen die Wahrheitstabellen zum Zuge – das Ergebnis wäre hier False und der Text wird nicht ausgegeben.
Wir können beliebig komplexe Bedingungen formulieren und AND – OR – NOT beliebig verwenden.
Natürlich muss die Bedingung für die Programmlogik sinnvoll sein. Und da gilt der
Tipp: Möglichst einfache und leicht verständliche Bedingungen zu formulieren.
Hier ein Beispiel:
if (not ((wert1 < wert2 and wert2 < wert3) or (wert4 > wert5 and wert2 < wert5))): print(“das trifft zu”)
Der menschliche Leser wird die Bedingung nicht ohne weiteres nachvollziehen können.
Der Python-Interpreter ist in der Lage, diesen Ausdruck auszuwerten.
Zuerst werden basierend auf den aktuellen Werten der Variablen alle Vergleichsoperationen durchgeführt und es wird jeweils True oder False eingesetzt.
Wir können wie folgt vereinfachen:
not ((a and b) or (b and c))
Statt der Vergleiche schreiben wir eine Variable – a, b, c und d sind Bool’schen Variablen und sie nehmen jeweils True oder False an, je nachdem, welches Ergebnis der Vergleich liefert.
Das sind die boolean Variables, die in allen Programmiersprachen vorkommen. Und entsprechend sind True und False boolean values, also Bool’sche Werte.
Danach wird die Wahrheitstabelle stufenweise angewendet: zuerst werden die Klammern ersetzt:
not (d or e)
d und e sind wieder Bool’sche Wert und sie stellen das Ergebnis der Auswertung der Klammern an.
Das passiert nochmals:
not(f)
und nochmals. Und so entsteht das Endergebnis.
Algebraisch vereinfachen
Ohne Kommentar ist die Bedingung in diesem if-Statement für die menschliche Leserschaft nicht mehr nachvollziehbar.
Die Regeln der Bool’schen Algebra helfen, solche Bedingungen umzuformen.
NOT dreht alles um: aus 0 wird 1 und aus AND wird OR. Wir lösen die Klammern auf und beginnen von innen:
Hier ein Beispiel:
not ((a and b) or (b and c)) = not(a and b) and not(b and c) = (a or b) and (b or c)
Da könnten wir jetzt die ursprünglichen Vergleiche wieder einsetzen und erhalten eine gleichwertige Bedingung.
Manchmal wird die Bedingung so besser verständlich.
Manchmal auch nicht. Dann lohnt es sich, die Bedingungen aufzuspalten und einzeln zu Formulieren:
AND Bedingung vereinfachen:
Oft wird eine AND-Bedingung so besser nachvollziehbar:
if (wert1 < wert2 and wert2 < wert3): print(“das trifft zu”
Können wir formulieren als:
if wert1 < wert2: if wert2 < wert3): print(“das trifft zu”
AND können wir auflösen, indem wir zwei IF-Statements verschachteln.
OR Bedingung vereinfachen:
Den Trick gibt es auch für OR:
if (wert1 < wert2 or wert2 < wert3): print(“das trifft zu”
Können wir formulieren als
if (wert1 < wert2: print(“das trifft zu” if wert2 < wert3): print(“das trifft zu”
Statt OR, können wir zwei IF hintereinanderschalten.
Fazit:
Bool’sche Logik resp. Bool’sche Algebra haben einen großen Einfluss auf die Programmierung.
True entspricht ‘wahr’ oder auch 1.
False entspricht ‘false’ oder auch 0.
AND entspricht der Multiplikation OR entspricht der Addition, NOT dreht die Werte um, ist also eine Invertierung.
Punkt kommt vor Strich – die Klammerregeln gelten.
Logische Ausdrücke sollten vorsichtig formuliert werden.
Und die praktischen Tipps:
AND kann aufgelöst werden durch verschachtelte IF-Statements
OR kann aufgelöst werden durch hintereinandergeschaltete IF-Statements