Das Erfüllbarkeitsproblem der Aussagenlogik (SAT, von englisch satisfiability „Erfüllbarkeit“) ist ein Entscheidungsproblem der theoretischen Informatik. Es beschäftigt sich mit der Frage, ob eine gegebene aussagenlogische Formel erfüllbar ist. Mit anderen Worten: Existiert eine Belegung der Variablen von mit den Werten wahr oder falsch, sodass zu wahr ausgewertet wird?
SAT gehört zur Komplexitätsklasse NP der Probleme, die von einer nichtdeterministischen Turingmaschine in polynomieller Zeit gelöst werden können. Außerdem war SAT das erste Problem, für das NP-Vollständigkeit nachgewiesen wurde (Satz von Cook). Damit kann jedes Problem aus NP in polynomieller Zeit auf SAT zurückgeführt werden (Polynomialzeitreduktion). NP-vollständige Probleme stellen also eine Art obere Schranke für die Schwierigkeit von Problemen in NP dar.
Eine deterministische Turingmaschine (etwa ein konventioneller Computer) kann SAT in exponentieller Zeit entscheiden, zum Beispiel durch das Aufstellen einer Wahrheitstabelle. Es ist kein effizienter Algorithmus für SAT bekannt und es wird allgemein vermutet, dass ein solcher Polynomialzeitalgorithmus nicht existiert. Die Frage, ob SAT in polynomieller Zeit gelöst werden kann, ist äquivalent zum P-NP-Problem, einem der bekanntesten offenen Probleme der theoretischen Informatik.
Ein Großteil der Forschung beschäftigt sich mit der Entwicklung möglichst effizienter Verfahren zur Lösung von SAT in der Praxis (sogenannter SAT-Solver). Moderne SAT-Solver können Instanzen mittlerer Schwierigkeit mit hunderten Millionen Variablen oder Klauseln in praktikabler Zeit lösen. Das ist ausreichend für praktische Anwendungen, z. B. in der formalen Verifikation, in der künstlichen Intelligenz, in der Electronic Design Automation und in verschiedenen Planungs- und Schedulingalgorithmen.
Sie gehören zu den Constraint Satisfaction Problems (CSP).
Eine aussagenlogische Formel besteht aus Variablen, Klammern und den aussagenlogischen Verknüpfungen Konjunktion („und“, oft notiert mit ∧), Disjunktion („oder“, ∨) und Negation („nicht“, ¬). Eine Variable kann entweder den Wert wahr oder den Wert falsch annehmen. Ein Literal ist ein Auftreten einer Variable (positives Literal) oder ihrer Negation (negatives Literal). Ein Literal heißt pur, wenn es nur in einer Ausprägung, also entweder positiv oder negativ, vorkommt. Ein Monom ist eine endliche Menge von Literalen, die ausschließlich konjunktiv verknüpft sind. Eine Klausel ist eine endliche Menge von Literalen, die ausschließlich disjunktiv verknüpft sind. Eine Einheitsklausel ist eine Klausel, die nur aus einem einzelnen Literal besteht. Eine Horn-Klausel ist eine Klausel mit höchstens einem positiven Literal.
Eine aussagenlogische Formel ist in konjunktiver Normalform (KNF), wenn sie nur aus Konjunktionen von Klauseln besteht. Eine Horn-Formel ist eine konjunktive Normalform, die ausschließlich aus Horn-Klauseln besteht. Die Formel befindet sich in konjunktiver Normalform. Da nur die erste und die dritte Klausel Horn-Klauseln sind, ist sie aber keine Horn-Formel. Die dritte Klausel ist eine Einheitsklausel.
Eine aussagenlogische Formel ist in disjunktiver Normalform (DNF), wenn sie nur aus Disjunktionen von Monomen besteht. Die Formel befindet sich in disjunktiver Normalform.
Eine Formel heißt genau dann erfüllbar, wenn eine Zuweisung von Werten wahr oder falsch zu jeder Variable existiert, sodass die Formel wahr ist. Formal ist SAT definiert als die formale Sprache
ist aussagenlogische Formel und erfüllbar
In der Praxis versteht man unter SAT meistens das Problem, herauszufinden ob eine Formel erfüllbar ist. Es existieren zahlreiche Varianten und für die meisten Komplexitätsklassen existiert eine Variante von SAT, die bezüglich dieser Klasse vollständig ist.
Das Problem 3-SAT schränkt die Anzahl Literale auf 3 Literale pro Klausel ein. Trotz dieser Einschränkung ist 3-SAT NP-vollständig, da SAT sich in polynomieller Zeit auf 3-SAT reduzieren lässt. Dasselbe gilt für alle Probleme k-SAT mit k > 3.
Eine Instanz des Problems 3-SAT, bestehend aus p Variablen und q Klauseln, lässt sich auch mittels eines Graphen mit (p + q) vielen Knoten darstellen. Eine Formel ist in P3-SAT, wenn sie in 3-SAT ist und dieser Graph planar ist. P3-SAT ist NP-vollständig.
Das Problem MAX-SAT besteht darin, die maximale Anzahl erfüllbarer Klauseln einer gegebenen Formel zu bestimmen. MAX-SAT ist NP-vollständig und sogar APX-vollständig. Daraus folgt, dass kein PTAS für MAX-SAT existieren kann, falls P ≠ NP.
MAJ-SAT ist das Problem zu entscheiden, ob die Mehrzahl aller möglichen Variablenbelegungen die Formel erfüllt. MAJ-SAT ist PP-vollständig.
QBF verallgemeinert SAT für quantifizierte, aussagenlogische Formeln, also Formeln, die Quantoren enthalten. QBF ist PSPACE-vollständig.
Da SAT NP-vollständig ist, sind ausschließlich Exponentialzeitalgorithmen für SAT bekannt. Seit den 2000er Jahren werden aber effiziente und skalierbare Algorithmen (SAT-Solver) entwickelt, die praktikables SAT-Solving für zahlreiche Anwendungen erlauben. Beispiele für Anwendungen sind formale Verifikation, Künstliche Intelligenz, Electronic Design Automation und verschiedene Planungs- und Schedulingalgorithmen.
SAT-Solver können aufgrund ihrer Funktionsweise in verschiedene Klassen eingeteilt werden.
Ein grundlegender randomisierter Algorithmus zur Lösung des k-SAT-Problems stammt von Uwe Schöning (1999), die Randomisierung konnte später von Robin A. Moser vollständig entfernt werden (um 2009). Der schnellste bekannte (randomisierte) Algorithmus für allgemeines k-SAT ist PPSZ (Ramamohan Paturi, Pavel Pudlák, Michael E. Saks, Francis Zane), entstanden aus dem Vorläufer PPZ von 1999, der nicht so gut wie der Algorithmus von Schöning war, und basierend auf Encoding. 2014 gab Timon Hertli Verbesserungen für den Fall unique 3-SAT.
Der Davis-Putnam-Logemann-Loveland-Algorithmus (DPLL oder DLL) aus den 1960er Jahren war der erste SAT-Solver, der eine systematische Suche mittels Backtracking implementierte. Er ist nicht zu verwechseln mit dem Davis-Putnam-Algorithmus, auf dem er basiert. Viele moderne Ansätze basieren auf dem gleichen Konzept und optimieren oft lediglich die Effizienz des Algorithmus für bestimmte Klassen von Eingaben, wie z. B. zufällige SAT-Instanzen oder Instanzen, die in Anwendungen der Industrie auftreten. DPLL löst das CNF-SAT-Problem. Das bedeutet, die aussagenlogischen Formeln müssen in der konjunktiven Normalform vorliegen (Menge von Klauseln).
Ein grundlegender Backtracking-Algorithmus für eine Formel funktioniert wie folgt:
Der Algorithmus terminiert, wenn eine Klausel leer wird (nicht erfüllbar, ihr letztes Literal wurde falsch) oder wenn alle Variablen belegt sind (erfüllbar).
DPLL verbessert den simplen Backtracking-Algorithmus durch zwei Regeln.
Tritt eine Einheitsklausel auf, so muss ihr einziges Literal wahr sein. Weise dem Literal den entsprechenden Wahrheitswert zu und entferne alle Klauseln, die enthalten. Entferne Vorkommen des Literals aus allen Klauseln.
In der Praxis führt Einheitsresolution oft dazu, dass wiederum Einheitsklauseln erzeugt werden und somit der naive Suchraum signifikant verkleinert wird.
Kommt ein Literal als pures Literal vor, so kann ihm ein Wert zugewiesen werden, sodass alle Klauseln, die das Literal enthalten, wahr werden. Entferne diese Klauseln.
Der Algorithmus zusammengefasst im Pseudocode:
function DPLL(F : set of clauses)
# Konsistent bedeutet, es kommt ausschließlich ¬l oder l vor
if F is a consistent set of literals then
# Hier können zusätzlich die Literale zurückgegeben werden
return true;
if F contains an empty clause then
return false;
for every unit clause {l} in F do
F ← unit-propagate(l, F);
for every literal l that occurs pure in F do
F ← pure-literal-assign(l, F);
l ← choose-literal(F);
# Mit Kurzschlussauswertung für das Oder
return DPLL({F : l = true}) or DPLL({F : l = true}); #
Dabei wenden unit-propagate(l, F) und pure-literal-assign(l, F) die beiden Regeln entsprechend an und geben die vereinfachte Formel zurück.
Die Effizienz von DPLL hängt sehr stark von der Auswahl des Literals (Branching Literal) ab. Für manche Instanzen kann diese Wahl den Unterschied zwischen konstanter und exponentieller Laufzeit ausmachen. Darum definiert DPLL vielmehr eine ganze Familie von Algorithmen, die unterschiedliche Heuristiken für die Wahl von verwenden.
Die Probleme von DPLL können in drei Punkten zusammengefasst werden:
In der Praxis werden diese Probleme gelöst durch
Modernes Conflict-driven Clause Learning (CDCL) erweitert DPLL um die Konzepte Clause Learning und Backjumping, implementiert Two Watched Literals (TWL, 2WL), um die Suche nach Einheitsklauseln zu beschleunigen und verwendet Random Restarts, um schwierigen Situationen nach einer Reihe von schlechten Entscheidungen für Variablenbelegungen zu entfliehen.
Bei CDCL findet das Backtracking nicht mehr chronologisch statt, sondern es werden Ebenen des Suchbaumes übersprungen. Außerdem werden Informationen über Variablenbelegungen, die in Kombination einen Konflikt verursachen, als Klausel der Klauselmenge hinzugefügt.
Um Backjumping zu ermöglichen, merkt sich CDCL, welche Zuweisungen von Wahrheitswerten zu Variablen willkürlich waren und welche Zuweisungen durch Unit Propagation erzwungen wurden. In der Praxis funktioniert das mittels eines Implikationsgraphen.
Ein Implikationsgraph ist ein gerichteter, azyklischer Graph . Jeder Knoten besteht dabei aus einem Tupel oder einem Element . Während das Tupel für eine Zuweisung von wahr oder falsch für ein Literal auf Ebene des Suchbaumes steht, steht für einen aufgetretenen Konflikt. Ein Konflikt tritt auf, wenn ein Literal gleichzeitig den Wert wahr und den Wert falsch annehmen müsste.
Wenn der Algorithmus ein Literal willkürlich mit einem Wahrheitswert belegt, wird der entsprechende Knoten mit dem Tupel, das diese Zuweisung repräsentiert, zu hinzugefügt. Erzwingt diese Zuweisung durch Unit Propagation eine weitere Zuweisung, so wird ein weiterer Knoten und eine Kante zum Graphen hinzugefügt.
Im Folgenden ein Beispiel mit der Formel: ( ∨ ) ∧ ( ∨ ∨ ) ∧ ( ∨ ∨ ) ∧ ( ∨ ) ∧ ( ∨ ∨ ) ∧ ( ∨ ∨ ) ∧ ( ∨ ∨ ) ∧ ( ∨ ∨ )
Der Algorithmus analysiert nun den Konflikt mithilfe des Implikationsgraphen und entscheidet, welche Klausel gelernt werden soll und zu welchem Entscheidungslevel im Suchbaum zurückgesprungen werden soll. In Frage kommende Klauseln heißen conflict clause und sollen verhindern, dass die Fehlentscheidung des Algorithmus, die zum Konflikt geführt hat, wiederholt wird. Eine solche conflict clause wird zur Klauselmenge hinzugefügt. Das maximale Entscheidungslevel der Variablen aus der conflict clause bestimmt das Entscheidungslevel für das Backjumping.
Eine abstrakte Beschreibung von CDCL im Pseudocode sieht wie folgt aus:
function CDCL(F : set of clauses)
G <- Implikationsgraph();
if unit-propagate(F, G) findet Konflikt then
return false;
level ← 0;
while F hat nicht zugewiesene Variablen do
level ← level + 1;
choose-literal(F, G);
while unit-propagate(F, G) findet Konflikt do
# Ermittle Ebene für Backjump und zu lernende Klausel
(d, c) ← analyzeConflict(G);
# Lerne
F ← F ∪ {c};
# Wenn der Konflikt nicht aufgelöst werden kann
if d < 0 then
return false;
else
backjump(F, d);
level ← d;
return true;
Dabei aktualisieren unit-propagate(F, G) und choose-literal(F, G) jeweils entsprechend den Implikationsgraphen. Die Funktion analyzeConflict(G) wird durch die Strategie des clause learning bestimmt.

Um eine conflict clause zu ermitteln untersucht man Schnitte im Implikationsgraphen. Ein Schnitt generiert eine conflict clause genau dann, wenn er den Graph so in zwei Hälften partitioniert, dass eine Hälfte (die decision side) alle decision nodes enthält und die andere Hälfte den Konfliktknoten. Die decision nodes sind dabei die willkürlichen Entscheidungen, die zum Konflikt geführt haben.
Aus dem Implikationsgraphen wird ersichtlich, dass z. B. für und eine willkürliche Entscheidung getroffen wurde, aber die Entscheidung für die Belegung von eine Konsequenz aus der Entscheidung für die Belegung von und war. Die Knoten für , , sind also die decision nodes.
Ein Beispiel für einen Schnitt, der eine conflict clause generiert, ist ein Schnitt durch die eingehenden Kanten des Konfliktknotens (roter Schnitt in der Abbildung). Die Knoten auf der decision side repräsentieren die Ursache des Konfliktes, nämlich . Durch Kontraposition erhält man , ein Beispiel für eine conflict clause. Eine andere Möglichkeit stellt der blaue Schnitt durch die ausgehenden Kanten der decision nodes dar. Er generiert die conflict clause . Diese Variante wurde in Rel_sat implementiert, einem der ersten CDCL SAT-Solver. Eine fortgeschrittene Variante wird von der Implementierung GRASP eingesetzt.
Es bleibt das Problem, Einheitsklauseln für die Unit Propagation und Konflikte effizient zu finden. Lange Zeit haben Solver dafür die Anzahl Literale, die in einer Klausel noch nicht mit Wahrheitswerten belegt worden sind, mitgezählt. Wenn sich dieser Zähler von 2 auf 1 ändert wendet man Unit Propagation an. Da uns der genaue Wert des Zählers aber eigentlich nicht interessiert, sondern wir nur wissen müssen, wann sich die Zahl auf eins ändert, verfolgen wir nicht die Klauseln selbst, sondern jeweils zwei Literale pro Klausel – die two watched literals. TWL ist also eine Datenstruktur, die die Suche nach Konflikten oder Einheitsklauseln beschleunigt.
Jede Klausel, die noch nicht erfüllt ist, besitzt zwei watched literals. Die Information wird dabei nicht von den Klauseln gespeichert, sondern von den Literalen selbst. Jeder Literal besitzt also eine Liste mit Klauseln, in denen er vorkommt. Diese Klauseln werden in einer Liste verkettet, der watch list.
Die TWL einer Klausel erfüllen folgende Invariante:
„Solange kein Konflikt gefunden wurde darf ein watched literal nur false sein, solange der andere watched literal true ist und alle unwatched literals false sind.“
Die Invariante führt dazu, dass die Belegung eines unwatched literals mit einem Wahrheitswert niemals zu einer unit propagation oder einem Konflikt führen wird. Wenn wir nun aber einem watched literal einen Wahrheitswert zuweisen, müssen wir eventuell die Invariante reparieren, unit propagation anwenden oder einen Konflikt auflösen. Betrachten wir die Klauseln, in denen die Negation von , also vorkommt. Diese können durch die watch list effizient gefunden werden. Wir verfahren für diese wie folgt:
TWL wurde für den SAT-Solver Chaff entwickelt, um die unit propagation in der Praxis zu optimieren.
Random Restarts setzen alle Variablenbelegungen zurück und starten die Suche mit einer anderen Reihenfolge der Variablenbelegung neu. Damit wird das Problem umgangen, dass manche dieser Zuweisungsreihenfolgen zu sehr viel länger andauernden Berechnungen mit vielen Konflikten führen, während geeignete Reihenfolgen das Problem schneller lösen. Dabei werden gelernte Klauseln und die aktuell zugewiesenen Werte der Variablen übernommen. Wann ein Restart durchgeführt wird bestimmt eine Strategie, z. B. fixed nach n Konflikten, in Abständen, die einer Reihe wie der geometrischen Reihe folgen oder dynamisch, wenn sich Konflikte beginnen zu häufen. Restart-Strategien sind häufig an eine bestimmte Klasse von Instanzen angepasst und aggressivere Strategien haben sich in vielen Fällen als effizient herausgestellt.
SAT-Solver, die auf dem Prinzip der lokalen Suche basieren, führen im Grunde folgende Schritte aus:
Die aussagenlogische Formel ist dabei als konjunktive Normalform gegeben. Unterschiede zwischen SAT-Solvern, die lokale Suche implementieren, finden sich vor allem bei der Wahl der Variable, die negiert wird.
GSAT negiert die Variable, die die Zahl an nicht erfüllten Klauseln minimiert oder wählt mit einer gewissen Wahrscheinlichkeit eine zufällige Variable.
WalkSAT wählt eine zufällige, nicht erfüllte Klausel und negiert eine Variable. Dabei wird die Variable ausgewählt, die am wenigsten bereits erfüllte Klauseln nicht erfüllt werden lässt. Die Wahrscheinlichkeit, dass eine falsche Variablenzuweisung korrigiert wird, ist der Kehrwert der Anzahl der Variablen in der Klausel. Mit einer gewissen Wahrscheinlichkeit wird auch hier einfach eine zufällige Variable der Klausel ausgewählt.
Beide Varianten erlauben zufällige Zuweisungen mit einer gewissen Wahrscheinlichkeit, um das Problem der lokalen Maxima zu umgehen. Außerdem werden zufällige Neustarts erlaubt, wenn für eine zu lange Zeit keine Lösung gefunden wurde.
Parallele SAT-Solver können in drei Kategorien eingeteilt werden: Portfolio, Divide-and-conquer und parallele lokale Suche.
Portfolio SAT-Solver beruhen auf der Tatsache, dass die meisten SAT-Solver auf bestimmten Probleminstanzen effizient sind, aber auf anderen Instanzen langsamer sind als andere Algorithmen. Gegeben eine beliebige Instanz von SAT, so gibt es keine verlässliche Möglichkeit, um vorherzusagen, welcher Algorithmus die Instanz am schnellsten lösen wird. Der Portfolio-Ansatz verwendet nun verschiedene Ansätze parallel, um die Vorteile verschiedener SAT-Solver zu kombinieren. Ein Nachteil der Methode ist natürlich, dass alle parallelen Prozesse im Prinzip die gleiche Arbeit verrichten. Trotzdem haben sich Portfolio-Solver in der Praxis als effizient herausgestellt.
Divide-and-conquer Algorithmen beruhen auf dem Ansatz, ein Problem in kleinere Teilprobleme aufzuteilen, diese rekursiv zu bearbeiten und die Teilergebnisse zu kombinieren. DPLL und CDCL sind divide-and-conquer Algorithmen, die den Suchraum bei jeder Entscheidung für eine Variablenbelegung in zwei Hälften aufteilen. Durch unit propagation und pure literal elimination können diese Hälften aber sehr unterschiedlich schwer zu lösende Teilinstanzen von SAT darstellen. CDCL verschärft dieses Problem durch die Anwendung weiterer Techniken. Cube-and-conquer ist ein Ansatz, der dieses Problem in zwei Phasen löst.

Für die Cube Phase wird in der Regel ein Look-Ahead-Solver eingesetzt, da diese sich für kleine, aber schwere Probleme bewährt haben und globaler arbeiten als z. B. CDCL.
Parallele lokale Suche ist leicht zu parallelisieren: Flips von verschiedenen Variablen werden parallel durchgeführt oder ein Portfolio-Ansatz wird verwendet, indem unterschiedliche Strategien für die Variablenauswahl gleichzeitig angewandt werden.
Die SAT-Competition ist ein Wettbewerb für SAT-Solver, der jährlich im Rahmen der International Conference on Theory and Applications of Satisfiability Testing stattfindet. In verschiedenen Disziplinen werden unterschiedliche Qualitäten von SAT-Solvern evaluiert:
Die SAT-Association ist eine Vereinigung, die sich zum Ziel gesetzt hat, Forschung im Bereich SAT, SAT-Solver und der formalen Verifikation voranzubringen und die SAT-Community zu repräsentieren. Sie beaufsichtigt die Organisation der genannten Konferenzen und Wettbewerbe und gibt das Journal on Satisfiability, Boolean Modeling, and Computation (JSAT) heraus.