Folien: https://www.imn.htwk-leipzig.de/~waldmann/lehre.html
Quelltexte, Diskussionen Hausaufgaben: https://gitlab.dit.htwk-leipzig.de/johannes.waldmann/fmw-ws25
Software: ghc, cabal; minisat, ersatz; z3, hasmt; Agda
nachfolgend: Beispiele für Hausaufgaben (Zweck: Wiederholung Prädikaten- und Aussagenlogik)
WS 25: 1b, 5, 4a, 2.
Pierluigi Crescenzi, Viggo Kann A compendium of NP optimization problems
https://web.archive.org/web/20200227195925/http://www.nada.kth.se/~viggo/problemlist/compendium.html
Beispiele:
Minimum File Transfer Scheduling (node195).
Minimum Dynamic Storage Allocation (node163).
Erläutern Sie die Spezifikation an einem Beispiel. Geben Sie eine lösbare Instanz sowie dafür zwei Lösungen mit unterschiedlichem Maß an.
Aufgabe: formalisieren Sie Math Magic Februar 2007.
Was ist dabei für Springer und König einfacher als für Dame, Läufer, Turm?
(allgemein für Math Magic: offene Fragen
Aufgabe: formalisieren Sie Wolkenkratzer oder Towers (was ist der Unterschied?) https://www.janko.at/Raetsel/Wolkenkratzer https://www.chiark.greenend.org.uk/~sgtatham/puzzles/js/towers.html
\(B=\{0,1\dots,n-1\}\), Unbekannte: \(h_{x,y}\in B\) für \(x,y\in B\)
Constraint für eine Zeile \(x\): (entspr. für Spalte)
\(\bigvee_{p\in\text{Permutationen}(0,\dots,n-1), p \text{kompatibel mit Vorgaben}} \bigwedge_{y\in\{0,\dots,n-1\}} (h_{x,y} = p(y))\)
Bsp: \(n=4\), Vorgabe links 2, rechts 1, kompatibel sind \([0,2,1,3],[2,0,1,3],[2,1,0,3],[2,1,0,3]\).
diese Formel wird exponentiell groß (wg. Anzahl Permutationen),
Folge-Aufgabe: geht das auch polynomiell?
Geben Sie eine Aufgabenstellung der Größe \(w\times w\) an mit \(4\cdot w\) Vorgaben (d.h., alle Vorgaben), die mehr als eine Lösung hat.
…für \(w=4\), für größere \(w\) (einige, alle)
(offene Frage?) Geben Sie eine eindeutig lösbare Instanz mit möglichst wenigen Vorgaben an. (Sind \(w-1\) Vorgaben für \(w\times w\) immer möglich?)
Modellierung von Puzzles (aus Tatham-Collection)
geben Sie ein Modell an für Pegs (Solitaire). Hinweise:
Zustand \(=\) Boolesche Matrix,
Schritt \(=\) Relation zwischen Matrizen,
Lösung \(=\) Schrittfolge (\(\Rightarrow\) Zustandsfolge). Wieviele Schritte?
Modell für Unruly. (keine Zustandsfolge, sondern direkt die Lösung. Welches sind die Unbekannten, welches sind ihre Beziehungen, untereinander und zur Vorgabe)
modellieren Sie Untangle
Vergleichen Sie mit den tatsächlichen Quelltexten
Constraint für monotone kompatible Bewertungsfunktion:
lösen Sie mit Z3 (ist im Pool installiert, vgl. https://www.imn.htwk-leipzig.de/~waldmann/etc/pool/)
eine kleinste Lösung finden (Summe von \(P,Q,R,S\) möglichst klein) — dafür Assert(s) hinzufügen.
Abstieg der so gefundenen Bewertungsfunktion nachrechnen für \(abab\to baab \to baba\to bbaa\)
gibt diese Bewertungsfunktion die maximale Schrittzahl genau wieder? (nein)
Folge-Aufgabe: entspr. Constraint-System für Bewertungsfunktion für \(ab\to bba\) aufstellen und lösen.
…zur Spezifikation, Analyse (Verifikation), Synthese von Hard- und Softwaresystemen.
für (geplantes) System \(S\) (Bsp: CPU, Programm)
formales Modell \(M\) angeben (Bsp: logische Schaltung, endl. Automat)
gewünschte System-Eigenschaft \(E\) angeben
(Bsp: Boolesche Formel, reguläre Sprache)
Analyse: mit Werkzeug(unterstützung) feststellen, ob das Modell die Eigenschaft hat (Bsp: \(M\Rightarrow E\), \(M\subseteq E\))
Synthese (Constraint-Programmierung): Werkzeug konstruiert aus Constraint \(E\) ein passendes Modell \(M\)
Schritt von System \(S\) zu Modell \(M\) ist Abstraktion (es werden Details ignoriert), das ist
teils nützlich (verbessert die Übersicht, Einsicht),
teils notwendig (nur wenn \(M\subseteq E\) entscheidbar oder \(M\) aus \(E\) berechenbar, kann überhaupt ein Werkzeug zur Analyse bzw. Synthese implementiert werden)
in den einfachen Beispielen (besonders am Anfang der VL) beginnen wir die Betrachtung bereits bei \(M\) (damit wir sehen, welche Theorien angewendet werden sollen)
das Abstrahieren muß aber auch geübt werden, es ist aber eine anwendungsspezifische Kunst
Verifikation von Schaltkreisen
(bevor man diese tatsächlich produziert)
\(F = \text{S-Implementierung}(x) \neq \text{S-Spezifikation}(x)\)
wenn \(F\) unerfüllbar (\(\neg \exists x.F\)), dann ist Impl. korrekt
Verifikation von Software durch model checking:
Programmzustände abstrahieren durch Zustandsprädikate, Programmabläufe durch endliche Automaten.
z. B. Thomas Ball et al. 2004: Static Driver Verifier
benutzt Constraint-Solver Z3 (Nikolaj Björner et al., 2007–)
automatische Analyse des Resourcenverbrauchs von Programmen
Termination (jede Rechnung hält)
Komplexität (…nach \(O(n^2)\) Schritten)
mittels Bewertungen von Programmzuständen:
\(W : \text{Zustandsmenge} \to \mathbb{N}\)
wenn \(z_1 \to z_2\), dann \(W(z_1)>W(z_2)\).
Parameter der Bewertung werden durch Constraint-System beschrieben.
vgl. Carsten Fuhs: Automated Termination Analysis…, Intl. School on Rewriting, 2022
Berechnungsmodell: Wortersetzung (\(\approx\) Turingmaschine)
Programm: \(ab \to ba\) (\(\approx\) Bubble-Sort)
Beispiel-Rechnung: \(abab \to baab \to baba \to bbaa\)
Bewertung \(W\) durch Interpretation: lineare Funktionen \(f_a(x) = Px+Q, f_b(x)=Rx+S\) mit \(P,Q,R,S\in \mathbb{N}\)
\(W(abab) = f_a(f_b(f_a(f_b(0)))), \ldots\)
Interp. ist monoton: \(x > y \Rightarrow f_a(x) > f_a(y) \wedge f_b(x)>f_b(y)\)
Interp. ist kompatibel mit Programm: \(f_a(f_b(x) > f_b(f_a(x))\)
resultierendes Constraint-System für \(P,Q,R,S\),
Lösung mittels Z3
(set-logic QF_NIA)(set-option :produce-models true)
(declare-fun P () Int) (declare-fun Q () Int)
(declare-fun R () Int) (declare-fun S () Int)
(assert (and (< 0 P) (<= 0 Q) (< 0 R) (<= 0 S)))
(assert (> (+ (* P S) Q) (+ (* R Q) S)))
(check-sat)(get-value (P Q R S))
Constraint-System: eine prädikatenlogische Formel \(F\)
\(0 < P\wedge \dots \wedge P\cdot S + Q > R \times Q + S\)
Lösung: Interpretation (Var.-Belegung), für die \(F\) wahr ist
CP ist eine Form der deklarativen Programmierung.
Vorteil: Benutzung von allgemeinen Suchverfahren (bereichs-, aber nicht anwendungsspezifisch).
Nikoli (1980–, the first puzzle magazine in Japan.)
Erich Friedman: Math Magic 1998–2020
Simon Tatham’s Portable Puzzle Collection
Angela und Otto Janko:
,
Donald Knuth: A Potpourri of Puzzles, 2022,
TAOCP, Band 4, Pre-Faszikel 9b,
für aussagenlogische Formeln:
http://www.satcompetition.org/
(SAT \(=\) satisfiability)
für prädikatenlogische Formeln
(SMT \(=\) satisfiability modulo theories)
Theorien: \(\mathbb{Z}\) mit \(\le\), Plus, Mal; \(\mathbb{R}\) mit \(\le\), Plus; …
Termination und Komplexität
Aussagenlogik
zur Modellierung (SAT-Kodierung) von Systemen mit endlichem Zustandsraum, begrenzter Schritt-Zahl (bounded model checking)
Werkzeuge: SAT-Kompiler (Tseitin-Transformation), SAT-Solver (Propagation, Backtracking, Lernen)
eingeschränkte Prädikatenlogik
Unbekannte aus unendlichen Bereichen (Zahlen)
Werkzeuge: SMT-Solver (SAT modulo Theory)
allgemeine Beweis-Systeme
zur Modellierung beliebiger (unbeschränkter) Systeme
Methode: Typisierung (Curry-Howard-Isomorphie, program \(=\) proof), Werkzeuge: interaktive Beweiser
jede Woche 1 Vorlesung \(+\) 1 Übung
Hausaufgaben (Haus bedeutet: zuhause bearbeiten, in der Übung diskutieren)
Aufgaben im Skript
Aufgaben in autotool
Prüfungszulassung: regelmäßiges und erfolgreiches Bearbeiten von Hausaufgaben
Klausur (2 h, keine Hilfsmittel).
Quelltexte, Planung und Diskussion der Übungsaufgaben
(Projekt-Mitgliedschaft beantragen, Zugang wird dann auf Mitglieder eingeschränkt)
Cerone, A., Roggenbach, M., Schlingloff, B.-H., Schneider, G., Shaikh, S.A.: Teaching formal methods for software engineering - ten principles, Informatica Didactica, Nr. 9, (2015). https://www.informaticadidactica.de/uploads/Artikel/Schlinghoff2015/Schlinghoff2015.pdf
Uwe Schöning, Jacob Toran: Das Erfüllbarkeitsproblem SAT , Lehmanns (2012)
Christel Baier, Joost Katoen: Principles of Model Checking. MIT Press, Cambridge (2008)
Samuel Mimram: Program \(=\) Proof, https://www.lix.polytechnique.fr/Labo/Samuel.Mimram/teaching/INF551/course.pdf
WS 25: 1b, 5, 4a, 2.
Pierluigi Crescenzi, Viggo Kann A compendium of NP optimization problems
https://web.archive.org/web/20200227195925/http://www.nada.kth.se/~viggo/problemlist/compendium.html
Beispiele:
Minimum File Transfer Scheduling (node195).
Minimum Dynamic Storage Allocation (node163).
Erläutern Sie die Spezifikation an einem Beispiel. Geben Sie eine lösbare Instanz sowie dafür zwei Lösungen mit unterschiedlichem Maß an.
Aufgabe: formalisieren Sie Math Magic Februar 2007.
Was ist dabei für Springer und König einfacher als für Dame, Läufer, Turm?
(allgemein für Math Magic: offene Fragen
Aufgabe: formalisieren Sie Wolkenkratzer oder Towers (was ist der Unterschied?) https://www.janko.at/Raetsel/Wolkenkratzer https://www.chiark.greenend.org.uk/~sgtatham/puzzles/js/towers.html
\(B=\{0,1\dots,n-1\}\), Unbekannte: \(h_{x,y}\in B\) für \(x,y\in B\)
Constraint für eine Zeile \(x\): (entspr. für Spalte)
\(\bigvee_{p\in\text{Permutationen}(0,\dots,n-1), p \text{kompatibel mit Vorgaben}} \bigwedge_{y\in\{0,\dots,n-1\}} (h_{x,y} = p(y))\)
Bsp: \(n=4\), Vorgabe links 2, rechts 1, kompatibel sind \([0,2,1,3],[2,0,1,3],[2,1,0,3],[2,1,0,3]\).
diese Formel wird exponentiell groß (wg. Anzahl Permutationen),
Folge-Aufgabe: geht das auch polynomiell?
Geben Sie eine Aufgabenstellung der Größe \(w\times w\) an mit \(4\cdot w\) Vorgaben (d.h., alle Vorgaben), die mehr als eine Lösung hat.
…für \(w=4\), für größere \(w\) (einige, alle)
(offene Frage?) Geben Sie eine eindeutig lösbare Instanz mit möglichst wenigen Vorgaben an. (Sind \(w-1\) Vorgaben für \(w\times w\) immer möglich?)
Modellierung von Puzzles (aus Tatham-Collection)
geben Sie ein Modell an für Pegs (Solitaire). Hinweise:
Zustand \(=\) Boolesche Matrix,
Schritt \(=\) Relation zwischen Matrizen,
Lösung \(=\) Schrittfolge (\(\Rightarrow\) Zustandsfolge). Wieviele Schritte?
Modell für Unruly. (keine Zustandsfolge, sondern direkt die Lösung. Welches sind die Unbekannten, welches sind ihre Beziehungen, untereinander und zur Vorgabe)
modellieren Sie Untangle
Vergleichen Sie mit den tatsächlichen Quelltexten
Constraint für monotone kompatible Bewertungsfunktion:
lösen Sie mit Z3 (ist im Pool installiert, vgl. https://www.imn.htwk-leipzig.de/~waldmann/etc/pool/)
eine kleinste Lösung finden (Summe von \(P,Q,R,S\) möglichst klein) — dafür Assert(s) hinzufügen.
Abstieg der so gefundenen Bewertungsfunktion nachrechnen für \(abab\to baab \to baba\to bbaa\)
gibt diese Bewertungsfunktion die maximale Schrittzahl genau wieder? (nein)
Folge-Aufgabe: entspr. Constraint-System für Bewertungsfunktion für \(ab\to bba\) aufstellen und lösen.
aussagenlogische Formel:
elementar: Variable \(v_1,\ldots\)
zusammengesetzt: durch Operatoren
einstellig: Negation
zweistellig: Implikation, Äquivalenz, Antivalenz,
mehrstellig möglich: Konjunktion, Disjunktion,
damit auch Quantifikation über endlichen Bereich \(E\)
\((\forall x\in E: F)\) ist (endliche!) Konjunktion \(\bigwedge_{x\in E} F\)
Wertebereich \(\mathbb{B}=\{0,1\}\), Halbring \((\mathbb{B},\vee,\wedge,0,1)\)
Übung: weitere Halbringe mit 2 Elementen?
Belegung ist Abbildung \(b: V \to \mathbb{B}\)
Wert einer Formel \(F\) unter Belegung \(b\): \(\operatorname{val}(F,b)\)
wenn \(\operatorname{val}(F,b)=1\), dann ist \(b\) ein Modell von \(F\), Schreibweise: \(b \models F\)
Modellmenge \(\operatorname{Mod}(F)=\{b \mid b\models F\}\)
\(F\) erfüllbar, wenn \(\operatorname{Mod}(F)\neq\emptyset\)
Modellmenge einer Formelmenge: \(\operatorname{Mod}(M) = \{ b \mid \forall F \in M: b\models F\}\)
Autoren: Edward Kmett et al.,
import Prelude hiding ((&&),(||),not )
import Ersatz
main = do
ans <- solveWith minisat $ do
p <- exists @Bit ; q <- exists @Bit
assert $ (p || not q) && (not p || q)
return [p,q]
case ans of (Satisfied, Just res) -> print res
Unbekannte erzeugen (exists), Formel konstruieren
(&&,…), assertieren, lösen, Antwort
benutzen
zu Implementierung vgl.
Eingabeformat: SAT-Problem in CNF:
Variable \(=\) positive natürliche Zahl
Literal \(=\) ganze Zahl (\(\neq 0\), mit Vorzeichen)
Klausel \(=\) Zeile, abgeschlossen durch \(0\).
Formel \(=\) Header
p cnf <#Variablen> <#Klauseln>,
danach Klauseln
Beispiel: die (konj. Normal-)Formel \((v_1\vee \neg v_2)\wedge(\neg v_1\vee v_2)\):
p cnf 2 2
1 -2 0
-1 2 0
Löser (Bsp.):
minisat input.cnf output.text
Niklas Eén, Niklas Sörensson: An Extensible SAT Solver, 2003, https://minisat.se/,
stelle möglichst viele Damen auf \(N\times
N\)-Schachbrett,
die sich nicht gegenseitig bedrohen.
Unbekannte: \(q_{x,y}\) für \((x,y)\in P = \{1,\ldots,N\}^2\)
mit Bedeutung: \(q_{x,y}\iff\) Position \((x,y)\) ist belegt
Constraint: \(\displaystyle \bigwedge_{a,b\in F, \text{$a$ bedroht $b$}} \neg q_a\vee\neg q_b\).
möglichst viele läßt sich hier vereinfachen zu:
in jeder Zeile genau eine.
vereinfachen zu: …wenigstens eine.
wir schreiben Programm,
Hilfsfunktionen für Boolesche Matrizen mit
import qualified Ersatz.Relation as R
queens n = do
out <- solveWith (cryptominisat5Path "kissat") $ do
b <- R.relation ((1,1),(n,n))
assert $ flip all (rows b) $ \ r -> or r
assert $ flip all (R.indices b) $ \ p ->
flip all (R.indices b) $ \ q ->
encode (reaches p q) ==> not (b R.! p && b R.! q)
return b
case out of
(Satisfied, Just b) -> do putStrLn $ R.table b
(vollst. Quelltext: siehe Repo)
innerhalb von solveWith steht Befehlsfolge, Befehl
ändert Zustand (Variablenzähler, Klausel-Ausgabe)
exists @Bit :: MonadSAT s m => m Bit,
R.relation _
konstruiert neue Variable(n)
assert :: Bit -> m ()
übersetzt Formel in CNF, gibt Klauseln aus
der Typ Bit beschreibt aussagenlogische Formeln
(genauer: Schaltkreise), d.h., symbolische Repräsentation von
(unbekannten) Wahrheitswerten
Typ Bool beschreibt konkrete (bekannte)
Wahrheitswerte
booleschen Operatoren (
import Ersatz
) sind polymorph
not :: Boolean b => b -> b,
instance Boolean Bool,
instance Boolean Bit
gesucht ist Kanten-2-Färbung des \(K_5\) ohne einfarbigen \(K_3\).
Aussagenvariablen \(f_{i,j} =\) Kante \((i,j)\) ist rot (sonst blau).
Constraints:
\(\forall p: \forall q: \forall r: (p<q \wedge q<r) \Rightarrow ( (f_{p,q}\vee f_{q,r} \vee f_{p,r}) \wedge \dots)\)
das ist ein Beispiel für ein Ramsey-Problem
(F. P. Ramsey, 1903–1930) http://www-groups.dcs.st-and.ac.uk/~history/Biographies/Ramsey.html
diese sind schwer, z. B. ist bis heute unbekannt: gibt es eine Kanten-2-Färbung des \(K_{43}\) ohne einfarbigen \(K_{5}\)?
Spielzug: Stein überspringen und entfernen,
Aufgabe: existiert Zugfolge von Initial (gegeben)
zu Final (genau ein Stein übrig)
Beispie: Initial ist volles Rechteck minus ein Stein
(Wdhlg.) aussagenlog. Modell als Folge von Relationen \([B_0, B_1,\dots,B_n]\), für die gilt \(\forall k: \operatorname{step}(B_k,B_{k+1})\).
eine Realisierung: \(\operatorname{move}(S,m,d,T)\) mit: \(S,T\) Brett,
\(m\) Position (des übersprungenen
Steins), \(d\) Richtung
und \(\operatorname{step}(S,T) =\displaystyle\bigvee_{m,d}\operatorname{move}(S,m,d,T)\)
Finalität von \(B_n\) ist einfach: das Zählen muß nicht SAT-kodiert werden—warum?
WS 25: 2,3,4 (5, 7, 8 siehe Repo)
unterschiedliche Halbringe auf zwei Elementen?
für die Formel \(S(b,h)\) (abhängig von Parametern \(b,h\in \mathbb{N}\))
Variablen: \(v_{x,y}\) für \(1\le x\le b, 1\le y \le h\)
Constraints:
für jedes \(x\) gilt: wenigstens einer von \(v_{x,1},v_{x,2},\dots,v_{x,h}\) ist wahr
und für jedes \(y\) gilt: höchstens einer von \(v_{1,y},v_{2,y},\dots,v_{b,y}\) ist wahr
unter welcher Bedingung an \(b,h\) ist \(S(b,h)\) erfüllbar?
Für den erfüllbaren Fall: geben Sie ein Modell an.
Für den nicht erfüllbaren Fall: einen Beweis.
Erzeugen Sie (eine konjunktive Normalform für) \(S(b,h)\) durch ein Programm (Sprache/Bibliothek beliebig)
( \(b,h\) von der Kommandozeile, Ausgabe nach stdout)
Lösen Sie \(S(b,h)\) durch minisat (kissat, Z3, …), vergleichen Sie die Laufzeiten (auch im nicht erfüllbaren Fall).
Für \(S(b,h)\) (vorige Aufgabe): Formel-Konstruktion, Löser-Aufruf mit Ersatz.
\(v\) vom Typ
Relation Int Int (vgl. \(N\) Damen)
für jedes \(x\): verwenden Sie
rows
für jedes \(y\): schreiben und
verwenden Sie entsprechende Fkt. columns
höchstens einer: verwenden Sie keine zwei.
Für \(a,b\ge 2\): die Ramsey-Zahl \(R(a,b)\) ist die kleinste Zahl \(n\), für die gilt: jede rot-blau-Kantenfärbung eines \(K_n\) enthält einen roten \(K_a\) oder einen blauen \(K_b\).
(Der Satz von Ramsey ist, daß es für jedes \(a,b\) tatsächlich solche \(n\) gibt.)
Beweisen Sie:
\(R(a,b)=R(b,a)\)
\(R(2,b)=b\)
\(R(a+1,b+1)\le R(a,b+1)+R(a+1,b)\)
(das liefert einen Beweis des Satzes von Ramsey)
wenn dabei beide Summanden rechts gerade Zahlen sind, dann \(R(a+1,b+1)< \dots\)
Bestimmen Sie damit obere Schranken für \(R(3,3), R(3,4), R(4,4)\) und vergleichen Sie mit den unteren Schranken durch SAT-Kodierung.
SAT-Kodierung für \(R(a,b)\) mit Ersatz:
main = ramsey 3 3 5
ramsey a b n = do
out <- solveWith (cryptominisat5Path "kissat") $ do
r <- R.symmetric_relation ((1,1),(n,n))
assert $ flip all (subs a [1 .. n]) $ \ c ->
flip any (subs 2 c) $ \ [x,y] ->
r R.! (x,y)
assert $ flip all (subs b [1 .. n]) $ \ c ->
flip any (subs 2 c) $ \ [x,y] ->
not $ r R.! (x,y)
return r
...
Hilfsfunktion: verteilten Teilfolgen gegebener Länge:
Beispiel: subs 3 [1,2,3,4,5]
= [[1,2,3],[1,2,4],[1,2,5],...,[3,4,5]] (nicht notwendig in
dieser Reihenfolge)
subs :: Int -> [a] -> [[a]]
subs 0 xs = [ [] ] ; subs k [] = []
subs k (x:xs) = map _ _ <> subs k xs
mit subs a [1 .. n] zur Auswahl des \(K_a\) sowie subs 2 c zur
Auswahl der Kanten.
Diskutieren Sie Existenz (obere Schranke) und SAT-Kodierung für dreifarbigen Ramsey:
\(R(a,b,c):=\) das kleinste \(n\) mit: jeder Kanten-3-Färbung des \(K_n\) enthält einen roten \(K_a\) oder einen grünen \(K_b\) oder einen blauen \(K_c\).
Ergänzen und beweisen: \(R(a,b,c)\le R(a,R(b,c))\), anwenden für \(R(3,3,3)\).
Modellierung als aussagenlogisches Constraint:
Rösselsprung (\(=\) Hamiltonkreis)
ABCEndView (oder ähnlich) https://www.janko.at/Raetsel/AbcEndView/
Vorgehen bei Modellierung:
welches sind die Unbekannten, was ist deren Bedeutung?
(Wie rekonstruiert man eine Lösung aus der Belegung, die der Solver liefert?)
welches sind die Constraints?
(wie stellt man sie in CNF dar? — falls nötig)
Unruly (S. Tatham Puzzles)
u1 = M.fromList -- eine Aufgabe (8 x 8)
$ map (,False) [(1,7),(3,2),(5,1),(5,3),(5,4),(5,7),(6,7)]
<> map (,True) [(1,4),(6,2),(6,3),(7,5),(8,4),(8,5)]
unruly u = do
let bnd = ((1,1),(8,8))
out <- solveWith (cryptominisat5Path "kissat") $ do
b <- R.relation bnd
assert $ flip all (M.toList u) $ \ (k,v) ->
b R.! k === encode v
assert $ flip all (rows b <> columns b) $ \ rc ->
balanced rc && mixed 3 rc
...
wie kann man feststellen, daß es genau eine Lösung gibt? (Solver nochmals aufrufen für modifizierte Formel.)
Peg (S. Tatham Puzzles)
peg b = do
let bnd = ((1,1),(b,b))
full = A.genArray bnd $ \ i -> True
start :: A.Array (Int,Int) Bool
start = full A.// [((1,2), False)]
out <- solveWith (cryptominisat5Path "kissat") $ do
boards <- replicateM (b*b - 1) $ R.relation bnd
assert $ R.equals (head boards) (encode start)
assert $ all step $ zip boards $ drop 1 boards
return boards
...
type Board = R.Relation Int Int
step :: (Board, Board) -> Bit
move :: Board -> (Int,Int) -> (Int,Int) -> Board -> Bit
model checking: feststellen, ob
ein Modell eines realen Hard- oder Softwaresystems
(z.B. Zustandsübergangssystem f. nebenläufiges Programm)
eine Spezifikation erfüllt
(z.B. gegenseitiger Ausschluß, Liveness, Fairness)
symbolic model checking:
symbolische Repräsentation von Zustandsfolgen
im Unterschied zu tatsächlicher Ausführung (Simulation)
bounded: für Folgen beschränkter Länge
Armin Biere et al.: Symbolic Model Checking without BDDs, TACAS 1999, http://fmv.jku.at/bmc/
Software damals: Übersetzung nach SAT, später: SMT
(QB_BV), Solver: http://fmv.jku.at/boolector/
Daniel Kroening und Ofer Strichman: Decision Procedures, an algorithmic point of view, Springer, 2008. http://www.decision-procedures.org/
Software: http://www.cprover.org/cbmc/
Nikolaj Bjørner et al.: Program Verification as Satisfiability Modulo Theories, SMT-Workshop 2012, http://smt2012.loria.fr/
System mit zwei (gleichartigen) Prozessen \(A,B\):
A0: maybe goto A1
A1: if l goto A1 else goto A2
A2: l := 1; goto A3
A3: [critical;] goto A4
A4: l := 0; goto A0
B0: maybe goto B1
B1: if l goto B1 else goto B2
B2: l := 1; goto B3
B3: [critical;] goto B4
B4: l := 0; goto B0
Schließen sich A3 und B3 gegenseitig aus?
(Nein.)
(nach: Donald E. Knuth: TAOCP, Vol. 4 Fasz. 6, S. 20ff)
Zustände:
jeder Zustand besteht aus:
Inhalte der Speicherstellen (hier: \(l\in\{0,1\}\))
Programmzähler (PC) jedes Prozesses
(hier: \(A\in\{0 \dots 4\},B\in\{0 \dots 4\}\))
Initialzustand: \(I = \{l=0,A=0,B=0\}\)
Menge der Fehlerzustände: \(F = \{A=3, B=3\}\)
Übergangsrelation (nichtdeterministisch): für \(P\in \{A,B\}\):
\(P\) führt eine Aktion aus (schreibt Speicher, ändert PC)
Aussagenlog. Formel für \(I \to^{\le k} F\) angeben,
deren Erfüllbarkeit durch SAT- oder SMT-Solver bestimmen
\(p\in\{0 \dots 4\}\) symbolisch repräsentieren durch Folge \([p_0,\dots, p_4]\) von symbolischen Wahrheitswerten
…von denen genau einer wahr ist
Bsp: \(p=3\) kodiert durch \([0,0,0,1,0]\).
das ist die one hot-Kodierung (eine Stelle ist hot \(=\) stromführend)
eine Realisierung ist \((\bigvee_i p_i) \wedge \bigwedge_{i<j}(\neg p_i\vee \neg p_j)\)
es gibt andere Kodierungen für endliche Bereiche (z.B.: binär: benötigt weniger Unbekannte, aber evtl. größere Formeln)
überprüfe 1. gegenseitigen Ausschluß, 2. deadlock, 3. livelock (starvation) für weitere Systeme, z.B.
E. W. Dijkstra, 1965: https://www.cs.utexas.edu/~EWD/transcriptions/EWD01xx/EWD123.html#2.1.
G. L. Peterson, Myths About the Mutual Exclusion Problem, Information Processing Letters 12(3) 1981, 115–116
\(\textsf{Count}_{\le k}(x_1,\ldots,x_n):= (\sum_i x_i) \le k\).
\(\textsf{AMO}\) (at most one): \(=\textsf{Count}_{\le 1}\), entspr. \(\textsf{ALO}\), \(\textsf{EXO}\)
Schubfach-Constraint (als Testfall, erfüllbar gdw. \(B\le H\))
\(\bigwedge_{1\le i\le H} \textsf{AMO}(x_{ij}|1\le j \le B) \wedge \bigwedge _{1\le j\le B} \textsf{ALO}(x_{ij}|1\le i\le H)\)
Schubfach für \(B=H\): dann ist \(x\) Permutationsmatrix,
repräsentiert Bijektion von \(\{1,\dots,B\}\) auf sich
Anwend.: Rösselsprung, Hamiltonkreis in \(G=(V,E)\)
Pfad \(p\) in \(G\) als Bijektion von Indexmenge \(\{1,\ldots,|V|\}\) in Knotenmenge \(V\) mit \(\bigwedge_i (p(i),p(i+1))\in E\).
let n = height * width; places = [0 .. n-1]
let decode p = divMod p width
edge p q =
let (px,py) = decode p; (qx,qy) = decode q
in 5 == (px-qx)^2 + (py-qy)^2
rotate (x:xs) = xs <> [x]
a <- replicateM n $ replicateM n $ exists @Bit
assert $ all exactly_one a
assert $ all exactly_one $ transpose a
assert $ flip all (zip a $ rotate a) $ \ (e, f) ->
flip all places $ \ p -> e!!p ==>
flip any (filter (edge p) places) (\ q -> f!!q)
quadratisch: \(\textsf{AMO}(x_1,\ldots,x_n)= \bigwedge\{ \overline{x_i}\vee\overline{x_j} | 1\le i < j \le n\}\)
\({n \choose 2}\) Klauseln, keine zusätzlichen Variablen
linear: mit Kodierung \(\textsf{enc}: x\mapsto(x_e,x_z)=(x\ge 1, x\ge 2)\):
\(0\mapsto (0,0), 1\mapsto (1,0), 2, 3,\dots \mapsto (1,1)\)
Addition: \((x_e,x_z)+_{\textsf{enc}}(y_e,y_z)=\dots\)
so daß \(\textsf{enc}(x+y)=\textsf{enc}(x)+_{\textsf{enc}}\textsf{enc}(y)\)
\(\textsf{AMO}(x_1,\ldots,x_n) =\texttt{let~} (s_e,s_z)=\sum_{\textsf{enc}} \textsf{enc}(x_i) \texttt{~in~} \dots\)
\(\textsf{AMO}(x)=\exists h: (x_i \Rightarrow (i=h))\)
\(h\) binär repräsentiert mit \(\log n\) Bits.
Bsp. \(\textsf{AMO}(x_0,\dots,x_3)=\exists h_1,h_0: \begin{array}{cc} & (\overline x_0\vee \overline h_1)\wedge(\overline x_0 \vee \overline h_0) \\ \wedge & (\overline x_1\vee \overline h_1)\wedge(\overline x_1 \vee h_0) \\ \wedge & (\overline x_2\vee h_1)\wedge(\overline x_2 \vee \overline h_0) \\ \wedge & (\overline x_3\vee h_1)\wedge(\overline x_3 \vee h_0) \end{array}\)
\(n \log n\) Klauseln, \(\log n\) zusätzliche Variablen
die Hilfsvariablen \(h_0,h_1\) sind keine Funktionen der Eingangsvariablen. (wenn alle \(x_i\) falsch, dann \(h_i\) beliebig)
Ü: man kann eine Skolem-Funktion trotzdem einfach angeben
für \(\textsf{AMO}(x)\): die \(x\) in einem Rechteck anordnen,
\(z_i:=\bigvee_j x_{ij}\) (Zeile \(i\)), \(s_j:=\bigvee_i x_{ij}\) (Spalte \(j\)),
dann \(\textsf{AMO}(x)=\textsf{AMO}(z)\wedge\textsf{AMO}(s)\).
Jingchao Chen: A New SAT Encoding of the At-Most-One Constraint 10th Workshop Constraint Modeling and Reformulation, 2010
Formelgröße \(f(n)=\Theta(n) + 2f(\sqrt n)\), mit \(\Theta(\sqrt n)\) Hilfsvar.
Lineare Faktoren sind klein. Ü: wenn
assert (amo xs),
kann man einige Klauseln weglassen. Welche?
amo_quad bs = and $ do
(b : cs) <- L.tails bs; c <- cs
return $ not b || not c
benutzt
L.tails [1,2,3] = [[1,2,3],[2,3],[3],[]]
erster (äußerer) Generator
(b : cs) <- L.tails bs
es werden der Reihen nach gebunden:
b=1,cs=[2,3], dann b=2,cs=[3], dann
b=3,cs=[].
zweiter (innerer) Generator c <- cs
für b=1, cs=[2,3] werden der Reihe nach gebunden:
c=2, dann c=3.
x :: [[Bit]] <-
replicateM h $ replicateM b $ exists @Bit
replicateM: wiederholt Aktion, liefert Liste der
Resultate
exists @Bit: liefert eine neue Variable
replicateM b $ ...: liefert \(b\) Variablen (\(=\) eine Zeile)
replicateM h $ ...: liefert \(h\) Zeilen (\(=\) eine Matrix)
L.transpose transponiert Matrix
L.transpose [[1,2,3],[4,5,6]] = [[1,4],[2,5],[3,6]]
Anw.: flip all x alo, bedeutet \(\forall e\in x: \texttt{alo}(e)\)
benutzt Funktionen
flip :: (a -> b -> c) -> b -> a -> c
all :: (Boolean b, Foldable t)
=> (a -> b) -> t a -> b
dabei \(t\) ein Containertyp (über den man iterieren kann)
das flip nur, damit Argumentreihenfolge wie bei Quantor
bzw. Zählschleife (erst Bereich, dann Prädikat)
eine mögliche Implementierung dafür ist
all f x = and $ do e <- x ; return f e
entsprechend any für endlichen
Existenz-Quantor
Anw.: foldMap enc bs, realisiert \(\sum_{b \in \texttt{bs}}
\texttt{enc}(b)\)
wobei Addition die durch (<>) definierte
Verknüpfung ist (mit neutralem Element mempty)
benutzt Funktion und Typklassen
foldMap :: (Foldable t, Monoid m)
=> (a -> m) -> t a -> m
class Semigroup a where
(<>) :: a -> a -> a
class Semigroup a => Monoid a where
mempty :: a : mappend :: a -> a -> a
vgl. https://www.imn.htwk-leipzig.de/~waldmann/etc/list/ (Lists that are really not there)
WS 25: 2, 7, 11
Modellierung Sudoku: Kodierung eines (ausgefüllten) Schemas durch \(9\times 9\times 9\) unbekannte Bit mit \(u_{x,y,z} \iff\) auf Koordinate \((x,y)\) steht Zahl \(z\).
für welche Teilmengen gelten EXO-Constraints?
Hinweis: für \(9^2 + 3\cdot 9^2\) Mengen, jede mit 9 Elementen.
geben Sie Beispiele aus Rätsel-Sammlungen von Nikoli, Janko, Tatham, bei deren SAT-Kodierung AMO- oder EXO-Constraints vorkommen sollten
Vergleiche Sie die commander-Kodierung für AMO von Klieber und Kwon, Int. Workshop Constraints in Formal Verification, 2007, mit Kodierungen aus dem Skript.
a) auf dem Papier, b) praktisch: mit ersatz implementieren, Formelgrößen messen, auch nach Vorverarbeitung durch minisat
für AMO-log: geben Sie eine Skolem-Funktion für \(\forall x_0,\ldots \exists h_0,\ldots:\ldots\) an.
d.h., die eine erfüllende Belegung der \(h_i\) bestimmt, falls \(\textsf{AMO}(x_0,\dots)\) wahr ist.
für \(\textsf{AMO}\) über \(2^k\) Argumente: verwenden Sie sqrt-Kodierung für Rechteck mit Abmessungen \(2 \times 2^{k-1}\), dann rekursiv über \(2^{k-1}\).
Vergleichen Sie mit der log-Kodierung.
für AMO-lin: untersuchen Sie den Unterschied zwischen der
Verwendung von foldr (von rechts) und foldb
(balanciert)
welche Maße der erzeugten Formel stimmen überein, welche unterscheiden sich?
vergleichen Sie Formelgrößen und Solver-Laufzeiten für unterschiedliche AMO-Kodierungen für die Spalten in den unlösbaren Schubfach-Formeln \(S(n+1,n)\).
für die AMO-Kodierungen linear und sqrt: wie kann man mit möglichst wenig Zusatz-Aufwand EXO erhalten?
ordnen Sie die EXO-Kodierung im Bounded Model Checker (boumchak) in die Systematik der VL ein.
Für den Rösselsprung (Code in fmw-24/leap)
gegebene EXO-Implementierung diskutieren, durch andere ersetzen, Formelgröße/Solverlaufzeit beobachten
zusätzliches assert $ a !! 0 !! 0
diskutieren
andere Sprung-Distanzen (Giraffe usw., siehe unten)
Kamel (1,3)-Sprung (auf nur schwarzen? oder weißen?) Feldern implementieren
andere Kodierung für Hamiltonkreis: Neng-Fa Zhou: In Pursuit of an Efficient SAT Encoding for the Hamiltonian Cycle Problem, CP 2020, ModRef 2019, https://www.sci.brooklyn.cuny.edu/~zhou/
Anwendung: George Jelliss: Leapers at Large, 2001, 2022 http://www.mayhematics.com/t/pl.htm
Resultate zur Existenz von Hamilton-Pfaden (HP) und -Kreisen (HC) nachrechnen und ergänzen, Bsp.:
HP für Giraffe \((1,4)\) auf 11\(\times\) 11?
(Nein—unsat nach 6 Stunden)
HP für Zebra \((2,3)\) auf 13 \(\times\) 13?
HP für Antilope \((3,4)\) auf 20 \(\times\) 20?
vgl. Donald Knuth: Leaper Graphs, 1994, https://arxiv.org/abs/math/9411240
Plan SAT-Kodierung Skyline (Towers, Wolkenkratzer)
Jede Zahl (jedes Haus) wird one-hot-kodiert, dann
type Haus=[Bit];type Zeile=[Haus];type Stadt=[Zeile]
(ohne Vorgaben) welche AMO-Constraints gelten? Eine Matrix, die diese Constraints erfüllt, heißt lateinisches Quadrat (Anzahl der lateinischen Quadrate: https://oeis.org/A002860)
(mit Vorgaben) Implementieren Sie die Berechnung der (von links)
sichtbaren Dächer einer Zeile sicht :: Zeile -> [Bit].
Das Resultat soll der Bitvektor \(s\)
sein mit \(s_i\iff\) Dach der Höhe
\(i\) ist sichtbar.
für die anderen Blickrichtungen: die Funktion sicht
bleibt, die Stadt wird transformiert. Wie?
Benutzen Sie eine SAT-Kodierung, um zu beweisen: jedes lateinische Quadrate der Seitenlänge 6 enthält wenigstens eine Zelle, die von keiner Seite sichtbar ist.
SAT-Kodierungen für das \(N\)-Damen-Problem:
naiv \(N^4\)
für alle \(a\) aus Spielfeld: für alle \(b\) aus Spielfeld: sich \(a\) und \(b\) sehen, dann \(\neg a \vee \neg b\)
besser \(N^3\)
für alle \(a\) aus Spielfeld: für alle \(b\), die von \(a\) gesehen werden: …
noch besser \(N^2\)
AMO-Constraints (jeweils lineare Formelgröße) über geeigneten (linear vielen) Mengen
Definitionen:
Variable: \(v_1, \ldots\) Literal: \(v\) oder \(\neg v\)
DNF-Klausel: Konjunktion von Literalen
DNF-Formel: Disjunktion von DNF-Klauseln
CNF-Klausel: Disjunktion von Literalen
CNF-Formel: Konjunktion von CNF-Klauseln
Disjunktion als Implikation: diese Formeln sind äquivalent:
\((x_1\wedge \ldots \wedge x_m)\to(y_1\vee\ldots\vee y_n)\)
\((\neg x_1\vee \ldots\vee \neg x_m \vee y_1\vee\ldots\vee y_n)\)
Def: Formeln \(F\) und \(G\) heißen äquivalent, wenn \(\operatorname{Mod}(F)=\operatorname{Mod}(G)\).
Satz: zu jeder Formel \(F\) existiert äquivalente Formel \(G\) in DNF.
Satz: zu jeder Formel \(F\) existiert äquivalente Formel \(G'\) in CNF.
aber …wie groß sind diese Normalformen?
Def: \(F\) und \(G\) erfüllbarkeitsäquivalent, wenn \(\operatorname{Mod}(F)\neq\emptyset \iff \operatorname{Mod}(G)\neq\emptyset\).
Satz: es gibt einen Polynomialzeit-Algorithmus, der zu jeder Formel \(F\) eine erfüllbarkeitsäquivalente CNF-Formel \(G\) berechnet.
(Zeit \(\ge\) Platz, also auch \(|G| = \text{Poly}(|F|)\))
Beweis (folgt): Tseitin-Transformation
Vor-Überlegung: warum gibt es keine vergleichbare Aussage für DNF?
Grigori Tseitin, On the Complexity of Derivation in propositional calculus, 1966
Spezifikation:
Geg.: \(F\), ges,: erfüllbarkeitsäquivalentes \(G\) in CNF.
wir verschärfen das zu: \(\operatorname{Var}(F)\subseteq\operatorname{Var}(G)\) und \(\forall b: b\models F \iff \exists b' : b \subseteq b' \wedge b'\models G\).
Plan:
für jeden nicht-Blatt-Teilbaum \(T\) des Syntaxbaumes von \(F\) eine zusätzliche Variable \(n_T\) einführen,
so daß \(\forall b'\in \operatorname{Mod}(G): \operatorname{val}(n_T,b') = \operatorname{val}(T,b)\).
Realisierung:
(Bsp.) \(T=L \vee R\), dann \(n_T \leftrightarrow (n_L \vee n_R)\) als CNF
für jeden der \(|F|\) Knoten: \(\le 8\) Klauseln mit \(3\) Literalen
beschriebenes Verfahren funktioniert ebenso für Schaltkreise (azyklische gerichtete Graphen, mit Booleschen Operatoren markiert)
Schaltkreis entsteht aus Baum durch Identifikation (sharing) von Knoten
für jeden Knoten eine neue Variable angelegen und deren Wert lokal durch eine CNF bestimmen
Ersatz realisiert observable sharing durch
Adress-Vergleich von Syntaxbaumknoten (des Typs Bit)
-- (xor a b) wird nur einmal T-transformiert:
let {s = (xor a b)} in (c || s ) && (not c || not s)
Beispiel
import qualified Ersatz.Bit.Display as D
D.display $ do
a <- exists ; b <- exists; c <- exists
return $ let {s = (xor a b)}
in (c || s ) && (not c || not s)
zu zeichnende Formel steht nach return
so ausprobieren:
ghci> runSAT' $ do
x <- exists; y <- exists @Bit; assert (x === y)
((),SAT 4 ((1) & (-4 | -3 | -2) & (-4 | 2 | 3)
& (-2 | 3 | 4) & (-3 | 2 | 4) & (-4)) mempty)
zu transformierende Formel steht nach assert (nicht:
nach return, wie bei display)
Tseitin-Transformation nach jedem assert (ohne
assert: keine Ausgabe einer CNF)
Aufgabe: damit observable sharing bestätigen
Aufgabe: CNF zu assert (x /== (y /== z))
(XOR)
(die Frage ist nicht, ob AMD Epyc in SP5-Sockel paßt)
Def. Schaltkreis (circuit): gerichteter kreisfreier markierter Graph, als symbolische Repräsent. einer Booleschen Fkt.
Def. Abmessung (complexity):
Def. Größe (size): Anzahl der Knoten
bei Hardware: Material-Aufwand
für SAT-Kodierung: (nach Tseitin-T.) Größe der CNF
Def. Tiefe (depth): Länge eines längsten Pfades
bei (paralleler!) Hardware: Rechenzeit
bei SAT-Kodierung: Länge von Abhängigkeitsketten von (Hilfs)variablen, beeinflußt Solver-Laufzeit
Bsp: XOR \(N\)-stellig: \(O(N)\) Größe, \(O(\log(N))\) Tiefe
SAT-Kodierung: man möchte immer die (Teil)Formel, für die der Solver am schnellsten die Erfüllbarkeit entscheiden kann
das läßt sich sehr schwer vorhersagen, abhängig von
Lösungsverfahren auf Teilformeln
nicht-lokale Kombination von Teil-Lösungen
betrachten stattdessen die Größe der Eingabe (CNF, Größen sind: Anzahl Variablen, Anzahl Klauseln)
in vielen Publikationen so durchgeführt (siehe AMO)
…stattdessen Größe eines Schaltkreises
mit beschränktem Eingangsgrad (z. B. 2)
unbeschränkt nur f. Disjunktion, Konjunktion
für diese Formeln:
\((x_1 \leftrightarrow x_2) \leftrightarrow (x_3 \leftrightarrow x_4)\)
Halb-Adder (2 Eingänge \(x,y\), 2 Ausgänge \(r,c\))
\((r\leftrightarrow (\neg(x\leftrightarrow y))) \wedge (c \leftrightarrow (x\wedge y))\)
Full-Adder (3 Eingänge, 2 Ausgänge)
jeweils:
führe die Tseitin-Transformation durch
gibt es kleinere erfüllbarkeitsäquivalente CNF? (deren Modelle Erweiterungen der Original-Modelle sind)
data Bit hat weitere Konstruktoren (Xor, Mux).
Wo werden diese benutzt?
Helfen sie tatsächlich bei der Erzeugung kleiner CNFs?
Eingabe: eine Formel in CNF
,[-4,-3,11],[-11,3],[-11,4],[-11],[3,4,13],[-13,-3],[-13,-4],[-2,12,13],[-12,2],[-13,-12],[-12],[-7,-6,14],[-14,6],[-14,7],[-14],[6,7,16],[-16,-6],[-16,-7],[-5,15,16],[-15,5],[-16,-15],[-15],[-10,-9,17],[-17,9],[-17,10],[-17],[9,10,19],[-19,-9],[-19,-10],[-8,18,19],[-18,8],[-19,-18],[-18],[2,5,8,20],[-20,-2],[-20,-5],[-20,-8],[-20],[3,6,9,21],[-21,-3],[-21,-6],[-21,-9],[-21],[4,7,10,22],[-22,-4],[-22,-7],[-22,-10],[-22]]
Ausgabe:
eine erfüllende Belegung
oder ein Beweis für Nichterfüllbarkeit
benutzt die Schnittstelle aus ersatz
minisat :: Solver SAT IO
type Solver s m
= s -> m (Result, IntMap Bool)
data Result
= Unsolved | Unsatisfied | Satisfied
class DIMACS t where
dimacsNumVariables :: t -> Int
dimacsClauses :: t -> Seq IntSet
data SAT; instancs DIMACS Satvollständige Suche (alle Belegungen, vollst. Binärbaum)
unvollständige Suche (einige Belegungen)
evolutionär (Genotyp \(=\) Belegung)
lokale Suche (Selman, Kautz, Cohen 1993: Walksat)
verbesserte vollständige Suche (Erkennen und Abschneiden sinnloser Teilbäume)
DPLL (Davis, Putnam, Logeman, Loveland 1960/61)
weitere Verbesserungen durch
Lernen (und Vergessen!) von zusätzlichen Klauseln
Vorverarbeitung zum Entfernen von Variablen
Parallelisierung
(Kommunikation mehrerer Suchverfahren)
Genotyp: Bitfolge \([x_1, \ldots, x_n]\) fester Länge
Phänotyp: Belegung \(b = \{ (v_1,x_1),\ldots,(v_n,x_n)\}\)
Fitness: z. B. Anzahl der von \(b\) erfüllten Klauseln
Operatoren:
Mutation: einige Bits ändern
Kreuzung: one/two-point crossover?
Problem: starke Abhängigkeit von Variablenreihenfolge
Bart Selman, Cornell University,
Henry Kautz, University of Washington
https://web.archive.org/web/20070311005144/http://www.cs.rochester.edu/u/kautz/walksat/
Algorithmus:
beginne mit zufälliger Belegung
wiederhole: ändere das Bit, das die Fitness am stärksten erhöht
Problem: lokale Optima — Lösung: Mutationen.
Davis, Putnam (1960), Logeman, Loveland (1962),
Zustand \(=\) partielle Belegung
Decide: eine Variable belegen
Propagate: alle Schlußfolgerungen ziehen
Beispiel: Klausel \(x_1\vee x_3\), partielle Belegung \(x_1=0\),
Folgerung: \(x_3=1\)
bei Konflikt (widersprüchliche Folgerungen)
(DPLL original) Backtrack (zu letztem Decide)
(DPLL mit CDCL) Backjump (zu früherem Decide)
für partielle Belegung \(b\) (Bsp: \(\{(x_1,1),(x_3,0)\}\)): Klausel \(c\) ist
erfüllt, falls \(\exists l\in c: b(l)=1\), Bsp: \((\neg x_1\vee x_2\vee \neg x_3)\)
Konflikt, falls \(\forall l\in c: b(l)=0\), Bsp: \((\neg x_1\vee x_3)\)
unit, falls \(\exists l\in c: b(l)=\bot \wedge \forall l'\in (c\setminus\{l\}): b(l')=0\),
Bsp: \((\neg x_1 \vee \neg x_2 \vee x_3)\). Dabei ist \(l=\neg x_2\) das Unit-Literal.
offen, sonst. Bsp: \((x_2\vee x_3\vee x_4)\).
Eigenschaften: für CNF \(F\) und partielle Belegung \(b\):
wenn \(\exists c\in F\) : \(c\) ist Konflikt für \(b\), dann \(\neg \exists b'\supseteq b\) mit \(b'\models F\)
(d.h., die Suche kann dort abgebrochen werden)
wenn \(\exists c\in F\): \(c\) ist Unit für \(b\) mit Literal \(l\), dann \(\forall b'\supseteq b: b'\models F \Rightarrow b'(l)=1\)
(d.h., \(l\) kann ohne Suche belegt werden)
Eingabe: CNF \(F\),
Ausgabe: Belegung \(b\) mit \(b\models F\) oder UNSAT.
\(\operatorname{DPLL}(b)\) (verwendet Keller für Entscheidungspunkte):
(success) falls \(b\models F\), dann halt (SAT), Ausgabe \(b\).
(backtrack) falls \(F\) eine \(b\)-Konfliktklausel enthält, dann:
falls Keller leer, dann halt (UNSAT)
sonst \(v := pop()\) und \(\operatorname{DPLL}(b_{<v} \cup \{(v,1)\}\).
dabei ist \(b_{<v}\) die Belegung vor decide\((v)\)
(propagate) falls \(F\) eine \(b\)-Unitklausel \(c\) mit Unit-Literal \(l\) enthält: \(\operatorname{DPLL}(b\cup\{(\text{variable}(l),\text{polarity}(l))\})\).
(decide) sonst wähle \(v\notin\operatorname{dom}b\), push\((v)\), und \(\operatorname{DPLL}(b\cup\{(v,0)\})\).
Termination: DPLL hält auf jeder Eingabe
Korrektheit: wenn DPLL mit SAT hält, dann \(b\models F\).
Vollständigkeit: wenn DPLL: UNSAT, dann \(\neg\exists b: b\models F\)
wird bewiesen durch Invariante
\(\forall b': b'\in\operatorname{Mod}(F) \Rightarrow b\le_\text{lex}b'\)
(wenn DPLL derzeit \(b\) betrachtet, und wenn \(F\) ein Modell \(b'\) besitzt, dann ist \(b'\) unterhalb oder rechts von \(b\))
dabei bedeutet: \(b\le_\text{lex}b'\):
\(b\subseteq b'\) oder \(\exists v: b(v)=0 \wedge (b_{<v}\cup\{(v,1)\})\subseteq b'\)
Satz (Ü): für alle endlichen \(V\): \(<_\text{lex}\) ist eine wohlfundierte Relation auf der Menge der partiellen \(V\)-Belegungen:
[[2,3],[3,5],[-3,-4],[2,-3,-4]
,[-3,4],[1,-2,-4,-5],[1,-2,4,-5]]
decide belegt immer die kleinste freie Variable, immer zunächst negativ
[[2,3],[3,5],[-3,-4],[2,-3,-4]
,[-3,4],[1,-2,-4,-5],[1,-2,4,-5]]
[Dec (-1),Dec (-2),Prop 3,Prop (-4),Back
,Dec 2,Dec (-3),Prop 5,Prop (-4),Back
,Dec 3,Prop (-4),Back,Back,Back
,Dec 1,Dec (-2),Prop 3,Prop (-4),Back
,Dec 2,Dec (-3),Prop 5]
Grundlage ist effiziente Impl. von UP und Konflikt-Erkennung
Methoden:
Wahl der nächsten Entscheidungsvariablen
(kommt am häufigsten in aktuellen Konflikten vor)
Lernen von Konflikt-Klauseln (erlaubt Backjump)
Vorverarbeitung (Variablen und Klauseln eliminieren)
alles vorbildlich implementiert und dokumentiert in Minisat http://minisat.se/ (Niklas Een, Niklas Sorenson) (seit ca. 2005 sehr starker Solver)
später übernimmt diese Rolle: Cadical, Kissat https://fmv.jku.at/kissat/ (Armin Biere)
Geben Sie eine erfüllbare CNF an, für die monotone lokale Suche
improve n cnf b0 = ...
let b1 = S.insert (negate l) $ S.delete l b0
if badness cnf b1 <= badness cnf b0
then improve n cnf b1
else improve n cnf b0
nicht funktioniert: es gibt eine Belegung \(b_0\), von der aus keine zulässige Schrittfolge zu einer erfüllenden Belegung führt. Hinweis: z.B., weil es überhaupt keine erlaubten Schritte gibt.
Wie behandeln gsat/walksat diesen Fall?
wenden Sie den SAT-Solver mit lokaler Suche auf realistische CNFs an, z.B. aus Kodierung Rösselsprung.
wie werden in minisat (kissat, …) Einheits- und Konfliktklauseln erkannt? (Hinweis: two watched literals)
unit propagation (UP) implementieren:
Einheitsklauseln erkennen:
type Literal = Int
units :: CNF -> [Literal]
units [[1,2],[-3],[3,4]] = [-3]
ein Literal belegen:
assign :: Literal -> CNF -> CNF
assign (-3) [[1,2],[-3],[3,4]] = [[1,2],[4]]
Wo stehen die entsprechenden Funktionen im Quelltext der Autotool-Aufgabe zu DPLL?
bisher:
(unvollst.) stochastische lokale Suche (gsat, walksat)
vollständige Suche (DPLL)
jetzt und folgend:
(jedes Verfahren) beschleunigen durch Vorverarbeitung (preprocessing): Variablen-Elimination
DPLL beschleunigen durch Klausel-Lernen (CDCL)
Zertifikate für UNSAT
gemeinsame Grundlage: Resolution
Def: eine Formel \(F\) folgt aus einer Formelmenge \(M\), geschrieben \(M\models F\), falls \(\operatorname{Mod}(M)\subseteq\operatorname{Mod}(F)\).
Bsp: \(\{x_1\vee\overline x_2,x_2\vee
x_3\}\models (x_1\vee x_3)\),
Beweise (lt. Def.) z.B. durch Vergleich der Wertetabellen
(d.h., explizites Aufzählen der Modellmengen)
Eigenschaften (Übungsaufgaben):
\(M \models \mathsf{True}\)
\((M\models \mathsf{False}) \iff (\operatorname{Mod}(M)=\emptyset)\)
\((M\models F) \iff (\operatorname{Mod}(M\cup\{\neg F\})=\emptyset)\)
wird bei CDCL benutzt: wir lernen nur Klauseln \(F\),
die aus der CNF (Klauselmenge) \(M\)
folgen:
\((M\models F) \iff (\operatorname{Mod}(M)=\operatorname{Mod}(M\cup\{F\}))\)
Definition: für Literal \(l\) : die Resolvente \(\operatorname{\textsf{Res}}_l(c,d)\)
der Klausel \(c\) mit \(l \in c\), und der Klausel \(d\) mit \(\neg l\in d\):
ist die Klausel \((c\setminus \{l\}) \cup (d\setminus\{\neg l\})\).
Bsp. \(l=\overline {x_2}, c=(x_1\vee \overline{x_2}), d=(x_2\vee x_3)\),
\(\operatorname{\textsf{Res}}_l(c,d) = (x_1\vee x_3)\).
Satz (Korrektheit): \(\{c,d\}\models \operatorname{\textsf{Res}}_l(c,d)\).
Beweis: für jede Belegung \(b\in \operatorname{Mod}({c,d})\):
vollst. Fallunterscheidung: \(b(l)=0\) oder \(b(l)=1\).
Anwendung: Hinzufügen einer Resolvente ändert die Modellmenge nicht, kann Propagationen ermöglichen
Bsp: CNF \(F=\{1\overline 2 3,2\overline 4 5, \overline 3 5\}\), partielle Bel. \(b=\{\overline 1, 4\}\) \(\operatorname{\textsf{Res}}_{\overline 2}(1\overline 2 3,2\overline 4 5)=1 3 \overline 4 5\), \(\operatorname{\textsf{Res}}_3(1 3 \overline 4 5, \overline 3 5)=\dots\) ist Unit
für Formel (Klauselmenge) \(F\) und Variable \(v\):
\(\operatorname{\textsf{Pos}}_v(F) =\{c | c\in F, v\in c\}\); \(\operatorname{\textsf{Neg}}_v(F) =\{c | c\in F, \neg v\in c\}\)
\(\operatorname{\textsf{Res}}_v(F)=\bigcup_{p\in\operatorname{\textsf{Pos}}_v(F),n\in\operatorname{\textsf{Neg}}_v(F)} \operatorname{\textsf{Res}}_v(p,n)\)
Bsp: \(F=\{ 12, \overline{1} 3, 2\overline{3},\overline{2}\overline{4}, \overline{3}4\}\), \(\operatorname{\textsf{Pos}}_3(F)=\{\overline{1} 3\},\operatorname{\textsf{Neg}}_3(F)=\{ 2\overline{3}, \overline{3}4\}\), \(\operatorname{\textsf{Res}}_3(F)=\{\overline{1} 2, \overline{1} 4\}\).
Satz: \(F\) ist erfüllbarkeitsäquivalent zu \(G\)
mit \(G := F\setminus (\operatorname{\textsf{Pos}}_v(F)\cup \operatorname{\textsf{Neg}}_v(F))\cup \operatorname{\textsf{Res}}_v(F)\).
Bsp (fortgesetzt) \(G= \{12, \overline{2}\overline{4},\overline{1} 2, \overline{1} 4\}\).
Beweis (aus \(b'\models G\) konstruiere \(b\models F\))
das \(b\) ist eines von \(b_0:=b'\cup\{(v,0)\}, b_1:=b'\cup\{(v,1)\}\).
Falls \(b_0\not\models \operatorname{\textsf{Pos}}_v(F)\) und \(b_1\not\models \operatorname{\textsf{Neg}}_v(F)\),
dann Widerspruch zu \(b'\models \operatorname{\textsf{Res}}_v(F)\).
ein Eliminationsschritt \(F_i \to (F_i\setminus (\operatorname{\textsf{Pos}}_v(F_i)\cup \operatorname{\textsf{Neg}}_v(F_i))\cup \operatorname{\textsf{Res}}_v(F_i))= F_{i+1}\)
erhält Erfüllbarkeit, verringert Variablenanzahl
mit \(n=|\operatorname{Var}(F)|\): \(F\to^n F_n\) mit \(\operatorname{Var}(F_n)=\emptyset\),
also \(F_n=\emptyset\) (SAT) oder \(F_n=\{\emptyset\}\) (UNSAT)
ist vollständiges Lösungsverfahren!
aber unpraktisch, weil \(|F_{i+1}|\gg |F_i|\) möglich ist: \(|F_{i+1}| =\)
\(|F_i| - (|\operatorname{\textsf{Pos}}_v(F_i)| + |\operatorname{\textsf{Neg}}_v(F_i)|) + |\operatorname{\textsf{Pos}}_v(F_i)|\cdot |\operatorname{\textsf{Neg}}_v(F_i)|\).
nur solange, wie \(|F_{i+1}|\le|F_i| + \Delta\) (für passende Variable)
Een und Biere: Effective Preprocessing …, SAT 2005,
dort weitere Vorverarbeitungs-Verfahren
conflict driven clause learning –
bei jedem Konflikt eine Klausel \(C\) hinzufügen, die
aus der Formel folgt (d.h. Modellmenge nicht ändert)
den Konflikt durch Propagation verhindert
Eigenschaften/Anwendung:
danach backjump zur vorletzten Variable in \(C\).
(die letzte Variable wird dann propagiert, das ergibt die richtige Fortsetzung der Suche)
\(C\) führt hoffentlich auch später zu Propagationen, d.h. Verkürzung der Suche
…wenn nicht: gelernte Klauseln kann man auch vergessen
beim Lösen der Formel (Klauselmenge) \(F\):
partielle Belegung \(b\), die eine Konfliktklausel hat,
wurde durch Entscheidungen und Propagationen erreicht
\(B :=\) die Konjunktion dieser Entscheidungsliterale
man kann die Klausel \(C=\neg B' =\) Disjunktion der negierten Entscheidungsliterale lernen (hinzufügen)
es gilt \(\operatorname{Mod}(F\cup B)= \emptyset\), also \(F\models C\)
backjump für dieses \(C\) ist backtrack (die letzte Entscheidung wird durch UP mit \(C\) negiert)
dieses \(C\) enthält mglw. Literale, die am Konflikt nicht beteiligt sind, deswegen besser (folgende Folie)
resolviere Konfliktklausel mit den Kl., die seit der letzten Entscheidung für Propagationen verwendet wurden.
c := Konflikt-Klausel // für aktuelle Bel. b
while (...) { // inv: für alle l' in c: b(l')=0
l := das in c zuletzt belegte Literal
d := Unit-Klausel, durch die var(l) belegt wurde
c := resolve_l (c,d); }
diese Resolution ist immer möglich, denn es gilt
\(b(l)=0,l\in c\) (ist Konflikt), \(b(\overline{l})=1, \overline{l}\in d\) (ist Unit)
Schleife verlassen (und \(c\) lernen), wenn \(c\) nur noch ein Literal \(l_h\) der aktuellen Entscheidungstiefe enthält.
dann Backjump zu nächst-höherer Entscheidung in \(c\).
von dort wird \(l_h\) unit-propagiert.
für CNF \(F\): Antwort SAT hat Zertifikat (Belegung \(b\)), das in Polynomialzeit überprüft werden kann (nachrechnen, daß \(b\models F\))
wie kann man Antwort UNSAT überprüfen, ohne die gesamte (erfolglose) Suche zu wiederholen?
ein Zertifikat für UNSAT ist eine Resolutionsableitung der leeren Klausel, ein solches muß existieren, denn es gilt
Satz (Widerlegungsvollständigkeit der Resolution):
für jede CNF \(F\): \(\operatorname{Mod}(F)=\emptyset \iff F\vdash \emptyset\).
alle Schritte von DPLL und CDCL können durch Resolutions-Schlüsse begründet werden
Satz für jede CNF \(F\): \(\operatorname{Mod}(F)=\emptyset \iff F\vdash \emptyset\).
Beweis durch Induktion nach Variablenanzahl \(|\operatorname{Var}(F)|\)
Anfang: \(\operatorname{Var}(F)=\emptyset\), dann \(F=\{\emptyset\}\)
Schritt: wähle beliebig \(v\in\operatorname{Var}(F)\).
\(F\) UNSAT, also auch \(F_0=F[v:=0]\) (\(v\) belegen und Formel vereinfachen) UNSAT, nach I.V. gilt \(F_0 \vdash \emptyset\)
zu jeder Klausel der Ableitung \(F_0\vdash \emptset\) das Literal \(\neg v\) hinzufügen: ergibt Ableitung \(F\vdash \{\neg v\}\)
enstpr. \(F_1=F[v:=1]\) ist UNSAT, …\(F\vdash \{v\}\)
zusammensetzen zu \(\{\{\neg v\},\{v\}\}\vdash\emptyset\)
auf diese Weise kann ein DPLL-Solver ein UNSAT-Zertifikat aus erfolglosem Decide-Knoten herstellen
es gibt CNF \(F\in\text{UNSAT}\), für die jede Resolutions-Ableitung von \(\emptyset\) exponentiell lang ist
Armin Haken, TCS 1985,
hätte jedes \(F\in\text{UNSAT}\) eine polynomiell lange Ableitung von \(\emptyset\), dann wäre \(\text{UNSAT}\in\text{NP}\), also \(\text{SAT}\in \text{co-NP}\), also \(\text{SAT}\in \text{NP}\cap\text{co-NP}\),
das glaubt die Fachwelt nicht, denn für jedes \(L\in\text{NP}\cap\text{co-NP}\) wurde schließlich \(L\in\text{P}\) gezeigt
(Bsp: Agraval et al.: PRIMES is in P, 2004)
das kann für SAT nicht passieren, denn \(\text{SAT}\in\text{NPc}\), und dann wäre \(\text{P}=\text{NP}\), das glaubt kaum jemand.
(Knuth Aufgabe 254) Für \(\{ 12, \overline{1} 3, 2\overline{3},\overline{2}\overline{4}, \overline{3}4\}\): nach der Entscheidung \(1\): welche Klausel wird gelernt?
D. E. Knuth, TAOCP Vol. 4, Fasc. 6, Satisfiability, 2015.
für die vorige CNF: lösen durch iterierte vollständige Elimination
Schleife verlassen, wenn \(c\) nur noch ein Literal der aktuellen Entscheidungstiefe …:
wieso ist die Bedingung anfangs falsch? (es kann nicht sein, daß die originale Konflikt-Klausel \(c\) gelernt wird)
wieso wird diese Bedingung wahr? (es kann nicht sein, daß es immer \(\ge 2\) solche Literale sind oder plötzlich gar keines)
wieso wird immer eine Klausel gelernt, die bisher nicht zur Klauselmenge gehört?
(Knuth Aufgabe 378) blocked clause elimination:
Für Klauselmenge \(F\): eine Klausel \(C=(l \vee l_1\vee \dots\vee l_k)\)
heißt blockiert durch Literal \(l\),
falls für jede Klausel \(D\in F\) mit \(\overline{l}\in D\) gilt: \(\exists i: \overline{l_i}\in D\).
ein Beispiel angeben.
beweisen: \(F\setminus\{C\}\) erfüllbar \(\Rightarrow\) \(F\) erfüllbar.
ist jedes Modell \(b\) von \(F\setminus\{C\}\) auch ein Modell von \(F\)?
hier besprochene Heuristiken und Ergänzungen
in den Protokollen von minisat, kissat wiederfinden
(z.B. wieviele Klauseln werden gelernt? wie groß sind diese? wann vergessen?)
durch Optionen von kissat o. cadical an/abschalten
conflict clause minimization (Sörenson, SAT 2005,
Ein Beispiel angeben.
einen SAT-Solver, der UNSAT-Beweise ausgeben kann, auf Schubfach-Formeln anwenden und Beweis-Länge betrachten. (Diese sollte exponentiell ansteigen.)
reverse unit propagation (RUP) für CNF \(M\), Klausel \(C\)
\(\overline{C}:=\) die Menge der Negationen der Literale aus \(C\),
\((M\cup\overline{C})\vdash_U \emptyset\), dabei nur unit-propagations-Schritte.
Beweisen: dann folgt \(M\models C\). Beispiel angeben.
Beispiel angeben für eine gültige Folgerung, die so nicht beweisbar ist (UP-Schritte reichen nicht aus)
NB: in autotool-Aufgabe zu CDCL wird für (behauptete) gelernte Klausel geprüft, ob sie durch RUP folgt.
halfAdder
:: Bit -> Bit -> (Bit, Bit)
halfAdder x y = (xor x y, x && y)fullAdder
:: Bit -> Bit -> Bit -> (Bit, Bit)
fullAdder x y z =
let (s1, c1) = halfAdder x y
(s2, c2) = halfAdder _ _
in (_, _)für CNF \(F\) auf Variablen \(V=\{v_1,\ldots,v_n\}\):
Definition: \(F\) erkennt Widersprüche durch UP (unit prop.):
für jede partielle Belegung \(b\) gilt:
wenn keine vollst. Belegung \(b'\supseteq b\) existiert mit \(b'\models F\),
dann führt UP auf \(F\) von \(b\) aus zu einem Konflikt
Bsp: \(F=\{123,\overline 1\overline 2, 1\overline 2 \overline 3, 2 \overline 3, \overline 2 3\}\), \(b=\{\overline 1\}\).
Ü: gilt diese Eigensch. für Produkt-Kodierung von \(\textsf{AMO}\)?
Zu betrachten ist, ob für jede Belegung \(b=\{(x_i,1),(x_j,1)\}\) durch UP ein Konflikt erreicht wird.
für CNF \(F\) auf Variablen \(V=\{v_1,\ldots,v_n\}\) und evtl. Hilfsvariablen \(H\):
Def.: \(F\) ist (generalized) arc-consistent (GAC) (forcing):
für jede partielle Belegung \(b\) mit \(\operatorname{dom}b\subseteq V\)
und jedes \(v\in V\) mit \(v\notin\operatorname{dom}b\):
wenn \(v\) in allen Modellen \(b'\supseteq b\) von \(F\) den gleichen Wert hat, dann folgt dieser Wert bereits durch UP.
Bsp: Produkt-Kodierung von \(\textsf{AMO}(x)\): Betrachte \(b = \{(x_i,1)\}\).
Alle anderen \(x_j\) müssen dann falsch sein.
Wird das durch UP erreicht?
Ist die Kodierung des Halb-Addierers \(\textsf{HA}(x,y;c,r)\) durch \((r\leftrightarrow x \oplus y) \wedge (c \leftrightarrow x\wedge y)\) (Tseitin-Kodierung ohne weitere Hilfsvariablen) forcing?
Ist die Kodierung des Voll-Addierers \(\textsf{FA}(x,y,z;c,r)\) durch \(\textsf{HA}(x,y;c_1,r_1)\wedge\textsf{HA}(r_1,z;c_2,r)\wedge (c\leftrightarrow c_1\vee c_2)\) forcing?
Desgl. für die Kodierung von \(\textsf{ITE}(i,t,e;x)\) (if-then-else) durch \((i\wedge t\rightarrow x)\wedge (i\wedge \overline t\rightarrow \overline x) \wedge (\overline i\wedge e\rightarrow x)\wedge (\overline i\wedge \overline e\rightarrow \overline x)\)
Lesen Sie dazu auch Een und Sörenson: Translating Pseudo-Boolean Constraints into SAT, JSAT 2006, (http://minisat.se/Papers.html) Abschnitt 5.1.
Vergleichen Sie mit den Quelltexten von ersatz.
in Ersatz: data Bits = Bits [Bit], beginnt mit
LSB!
Ordnung (Ü: fehlende Fälle in eq, Ü: Orderable)
instance Equatable Bits where
Bits xs === Bits ys = eq xs ys where
eq [] [] = true
eq (x:xs) (y:ys) = (x === y) && eq xs ys
Addition (Ü: fehlende Fälle in add) Formelgröße linear
instance Num Bits where
Bits xs + Bits ys = Bits $ add false xs ys where
add cin (x:xs) (y:ys) =
let (s,cout) = fullAdder cin x y
in s : add cout xs ys
Neng-Fa Zhou: …Efficient SAT Encoding for the Hamiltonian Cycle Problem, CP 2020, ModRef 2019,
für jedes Feld \(p\) des Schachbretts eine unbekannte Zahl \(t_p\), die den Zeitpunkt angibt, zu dem \(p\) besucht wird.
Hamiltonkreis/pfad in \(G=(V,E)\) wird erzwungen durch
\(\forall p\in V: \exists q\in V: pq\in E \wedge (t_p+1 = t_q)\)
(Vorsicht: das ist nur die Idee, muß modifiziert werden)
\(t_p\) binär repräsentiert, Nachfolger binär implementiert.
im Vgl. zu Kodierung mit Permutationsmatrix (früher): weniger Variablen/Klauseln, aber schwerer lösbar
\([x_0,\ldots]_2 \cdot [y_0,\ldots]_2=[z_0,\ldots]_2\),
Schulmethode: \(z=\sum 2^i \cdot x_i \cdot y\) (sequentielle Summation)
Verbesserungen: C.S. Wallace (1964), L. Dadda (1965),
benutze full-adder für verschränkte Summation,
(ähnlich zu carry-save-adder)
verringert Anzahl der Gatter und Tiefe des Schaltkreises
vgl. Townsend et al.:A Comparison of…, 2003
scheint für CNF-Kodierung wenig zu helfen
Testfall: Faktorisierung.
wir kennen: exactly/at-most-one
wir wünschen: exactly/at-most-\(k\)
(jetzt) triviale Lösung: die Bits binär addieren
aber in der passenden Klammerung (balancierter Additionsbaum), damit die Bitbreite des Resultats vernünftig ist
so realisiert in Ersatz.Counting
geht das besser? (\(\Rightarrow\) Bachelorarbeit (wenigstens))
Binärkodierung ist ein Beispiel für bit blasting
dieses Verfahren zerstört semantische Information, diese muß (vom SAT-Solver) teuer rekonstruiert werden, Bsp.
x <- unknown 10; y <- unknown 10
assert $ x * y /== y * x -- > 1 min für UNSAT
semantische Eigenschaften (Assoz., Kommut., Distr.) arithemtischer Operatoren können durch Solver nur verwendet werden, wenn Constraint-System diese Operatoren tatsächlich benutzt
dazu wird Prädikatenlogik benötigt (boolesche Kombination von atomaren Constraints, diese sind Relationen auf Termen)
WS25: 3,4,6,7, 8
zu alternative Kodierung Rösselsprung: welches Constraint-System entsteht, wenn die unbekannten \(t_p\) one-hot-kodiert werden?
ist Implementierung von atmost-1, atmost-\(k\) durch binäre Addition forcierend?
für Binärzahlen (Typ Bits): implementieren Sie
min, max
Vorgänger (:: Bits -> (Bits, Bit), zusätzlich ein
Bit, das Unterlauf anzeigt, d.h., falls Argument \(=0\))
Auswahl (if-then-else
:: Bit -> Bits -> Bits -> Bits)
Kodierung von vorzeichenbehafteten Zahlen (mit variabler Bitbreite): zur Basis -2, Bsp. \(-5 = 1 -2 +4 -8= 1\cdot (-2)^0 + 1\cdot(-2)^1 + 1\cdot(-2)^3 + 1\cdot(-2)^3\)
Instanzen für Ersatz (Codec, Equatable, Orderable, Num)
benutzen Sie microsat (Repo dieser VL) (evtl. passend modifiziert), um experimentell zu überprüfen:
Konflikt wird durch UP erkannt?
x <- unknown 10; y <- unknown 10
assert $ x + y /== y + x
Lösung wird durch UP bestimmt?
x <- unknown 10;
assert $ encode 13 + x === encode 31
ähnlich für Multiplikation
Implementieren Sie die Multiplikation für Binarzahlen nach der
Schulmethode. (Anders als plus:) Die Funktion
times ist rekursiv und benutzt keine lokale
Hilfsfunktion.
times :: Boolean b => [b] -> [b] -> [b]
times [] ys = _
times (x:xs) ys = _
instance Num Nat where
...
Nat xs * Nat ys = Nat (times xs ys)
Anwendungen:
Finden Sie eine ganzzahlige Lösung von \(x^2 - Dy^2=1 \wedge y\neq 0\)
für: \(D=5\), \(D=13\), \(D=61\), \(D=71\).
Finden Sie eine (oder die kleinste) natürliche Zahl, die auf zwei verschiedene Weisen als Summe von Kuben darstellbar ist.
Implementieren Sie die Funktion
sumBits :: [Bit] -> Nat mit der Eigenschaft:
sumBits xs ist die (Binärdarstellung der) Anzahl der wahren
Bit aus xs.
Das geht offensichtlich mit foldl oder
foldr, aber ein balaciertes fold ist besser, warum?
(Betrachten Sie die notwendige und tatsächliche Bitbreite des
Resultates.)
(ab 1. Dez. 16 Uhr, täglich) https://www.mathekalender.de/wp/de/kalender/ Adventskalender, Technische Universität Berlin, The Berlin Mathematics Research Center MATH+
In der Übung können jederzeit Aufgabenlösungen mit Methoden der Vorlesung präsentiert und diskutiert werden.
1. Prädikatenlogik (Syntax, Semantik)
3. existentielle konjunktive Constraints
in verschiedenen Bereichen, z. B.
Gleichungen und Ungleichungen auf Zahlen \((\mathbb{Z},\mathbb{Q},\mathbb{R})\)
existentiell mit beliebigen Boolesche Verknüpfungen:
2. hinschreiben: SAT modulo \(T\) (\(=\) SMT),
4. lösen: DPLL(\(T\))
0. Bit-blasting (SMT \(\to\) SAT)
5. volle Prädikatenlogik (auch universelle Quant.)
Signatur: Name und Stelligkeit für
Funktions-
und Relationssymbole
Term:
Funktionssymbol mit Argumenten (Terme)
Variable
Formel
atomar: Relationssymbol mit Argumenten (Terme)
Boolesche Verknüpfungen (von Formeln)
Quantor Variable Formel
gebundenes und freies Vorkommen von Variablen
Sätze (\(=\) geschlossene Formeln)
Universum, Funktion, Relation,
Struktur, die zu einer Signatur paßt
Belegung, Interpretation
Wert
eines Terms
einer Formel
in einer Struktur, unter einer Belegung
die Modell-Relation \((S,b) \models F\) sowie \(S\models F\)
Erfüllbarkeit, Allgemeingültigkeit (Def, Bsp)
\(P > 0 \wedge Q \ge 0 \wedge R > 0 \wedge S \ge 0 \wedge P\cdot S + Q > R\cdot Q+S\)
(set-logic QF_NIA)(set-option :produce-models true)
(declare-fun P () Int) (declare-fun Q () Int)
(declare-fun R () Int) (declare-fun S () Int)
(assert (and (< 0 P) (<= 0 Q) (< 0 R) (<= 0 S)))
(assert (> (+ (* P S) Q) (+ (* R Q) S)))
setLogic "QF_NIA"
[p,q,r,s] <- replicateM 4 $ var @IntSort
assert $ p >? 0 && q >=? 0 && r >? 0 && s >=? 0
assert $ p * s + q >? r * q + s
QF_BV)Grundbereich: Bitfolgen (mit fixierte Länge \(w\)),
arithmetische Operationen modulo \(2^w\)
mögliche Implementierung: bit-blasting
Solver benutzt zusätzlich Aussagen und Umformungs-Regeln für Arithmetik
Bsp: Laufzeit (vgl. mit bit-blasting, vorige Woche)
setLogic "QF_BV"
[x,y] <- replicateM 2 $ var @(BvSort Unsigned 100)
assert $ not $ x + y === y + x
Ü/Vorsicht:
assert $ x /== 0 && 13 * x === x
SMT: Erfüllbarkeitsproblem für beliebige boolesche Kombination von atomaren Formeln aus einer Theorie
Beispiel: \((x\ge 3 \vee \neg (x+y\le 4)) \leftrightarrow x> y\)
Verfahren: 1. (wirklich) ersetze jedes T-Atom \(a_i\)
durch eine boolesche Unbekannte \(u_i\), erhalte Formel \(F\)
2. (naiv) für jedes boolesche Modell \(b\models F\):
entscheide, ob die Konjunktion der entsprechenden (ggf. negierten) Atome
in T erfüllbar ist
(2. besser) DPLL modulo Theory: Verschränkung der booleschen Suche mit T-Erfüllbarkeit für partielle Modelle
Hilfsmittel dabei: Tseitin (ähnliche) Transformation
Standard-Modellierungssprache, Syntax/Semantik-Def:
Aufgabensammlung: https://smtlib.cs.uiowa.edu/benchmarks.shtml
Kombinatorik, Scheduling, Hard- und Software-Verifikation, … crafted, industrial, (random?)
Wettbewerb: https://smt-comp.github.io/
typische Solver (Beispiele)
Z3 (Nikolas Bjorner, Leo de Moura et al.) https://github.com/Z3Prover/z3/
CVC5 (Clark Barrett, Cesare Tinelli et al.) https://cvc5.github.io/
queen10-1.smt2 aus SMT-LIB(set-logic QF_IDL) (declare-fun x0 () Int)
(declare-fun x1 () Int) (declare-fun x2 () Int)
(declare-fun x3 () Int) (declare-fun x4 () Int)
(assert (let ((?v_0 (- x0 x4)) (?v_1 (- x1 x4))
(?v_2 (- x2 x4)) (?v_3 (- x3 x4)) (?v_4 (- x0 x1))
(?v_5 (- x0 x2)) (?v_6 (- x0 x3)) (?v_7 (- x1 x2))
(?v_8 (- x1 x3)) (?v_9 (- x2 x3))) (and (<= ?v_0 3)
(>= ?v_0 0) (<= ?v_1 3) (>= ?v_1 0) (<= ?v_2 3) (>=
?v_2 0) (<= ?v_3 3) (>= ?v_3 0) (not (= x0 x1))
(not (= x0 x2)) (not (= x0 x3)) (not (= x1 x2))
(not (= x1 x3)) (not (= x2 x3)) (not (= ?v_4 1))
(not (= ?v_4 (- 1))) (not (= ?v_5 2)) (not (= ?v_5
(- 2))) (not (= ?v_6 3)) (not (= ?v_6 (- 3))) (not
(= ?v_7 1)) (not (= ?v_7 (- 1))) (not (= ?v_8 2))
(not (= ?v_8 (- 2))) (not (= ?v_9 1)) (not (= ?v_9
(- 1)))))) (check-sat) (exit)
http://www.cs.nyu.edu/~barrett/smtlib/?C=S;O=D
QF_BV_DisjunctiveScheduling.zip 2.7G
QF_IDL_DisjunctiveScheduling.zip 2.4G
incremental_Hierarchy.zip 2.1G
QF_BV_except_DisjunctiveScheduling.zip 1.6G
QF_IDL_except_DisjunctiveScheduling.zip 417M
QF_LIA_Hierarchy.zip 294M
QF_UFLRA_Hierarchy.zip 217M
QF_NRA_Hierarchy.zip 170M
QF_LRA_Hierarchy.zip 160M
QF: quantifier free,
I: integer, R: real, BV: bitvector
D: difference, L: linear, N: polynomial
der arktische Halbring: \(\mathbb{A}=(\{-\infty\}\cup\mathbb{N},\max,+,-\infty,0)\)
\(\mathbb{A}^{d\times d}\): quadratische Matizen über \(\mathbb{A}\),
\(P>Q\) falls \(\forall i,j: (P_{i,j}>Q_{i,j}) \vee (P_{i,j}=-\infty=Q_{i,j})\).
Matrix-Interpretation: \(i:\Sigma\to\mathbb{A}^{d\times d}\) mit \(\forall c: i(c)_{1,1}\ge 0\)
Interpretation von Wörtern: \(i(c_1 \ldots c_n):=i(c_1)\circ\ldots \circ i(c_n)\)
Bsp: \(i: a\mapsto \begin{pmatrix}0 &0 \\ 1 & 2 \end{pmatrix} , b\mapsto \begin{pmatrix}0 &-\infty \\ -\infty & -\infty \end{pmatrix}\)
\(i\) kompatibel mit \(R\), falls \(\forall (l,r)\in R: i(l)>i(r)\).
Bsp (Fortsetzg.) \(i\) kompatibel mit \(\{aa \to aba\}\)
dann terminiert \(R\), denn jede \(R\)-Ableitung von \(w\) aus hat \(\le i(w)_{1,1}\) Schritte
für gegebenes \(R\) und \(d\): Kompatibilitä von \(i\) ist Constraint-System in
QF_LIA.
die Constraint-Sprache \(C\) dient zur Kommunikation mit Solver (nicht: mit Anwender/Anwendungsprogrammierer)
Programm in einer Gastsprache \(G\) für
Konstruktion des Constraint-Systems
Verarbeitung des Resultates (des Modells)
dabei müssen übersetzt werden
Namen in \(C\), Namen in \(G\)
Werte in \(C\) (symbolisch), Werte in \(G\) (tatsächlich)
Typen in \(C\) (Bsp:
Bit), in \(G\)
(Bsp:Bool)
Entwurfs-Ziele:
symbolisches Programm (in \(C\)) sieht aus wie tatsächliches Programm (in \(G\))
notwendige Übersetzungen möglichst unsichtbar
(let b = True in solveWith minisat $ do
p <- exists @Bit; assert (p === encode b)
return p
) >>= \ case (Satisfied, Just (p :: Bool)) -> ...class Codec c where
type Decoded c
encode :: Decoded c -> c
decode :: Belegung -> c -> Decoded c
instance Codec Bit where
type Decoded Bit = Bool; ...Ü: überprüfen Sie die Design-Ziele, geben Sie die technischen Mittel an, durch die diese erreicht werden
L = {0:[1,2], 1:[2], 2:[1,0]} # Beispiel-Graph
cv = [Int('cv%s'%i) for i in range(L)]
s = Solver() ; s.add(cv[0]==0)
for i in range(L):
s.add(Or([cv[j]==(cv[i]+1)%L for j in gr[i]]))
s.check(); print (s.model())
Design-Ziele überprüfen:
Namen, Typen, Ausdrücke, Übersetzungen, Sichtbarkeit
beachte: hier wird keine SMTLIB-Datei erzeugt, sondern API des Solvers aufgerufen.
Iavor S. Diatchki:
s <- newSolver "cvc4" ["--lang=smt2"] Nothing
setLogic s "QF_LIA"
x <- declare s "x" tInt
assert s (add x (int 2) `eq` int 5)
check s
print =<< getExprs s [x]
\(C\)-Namen sind sichtbar
\(C\)-Typen (tInt)
erscheinen nicht statisch in \(G\)-Typen
\(C\)- und \(G\)-Operatoren: add,
+
explizite Rück-Übersetzung (getExprs)
Henning Günther: https://hackage.haskell.org/package/smtlib2
withBackend (createPipe "z3" ["-smt2","-in"]) $ do
x <- declareVar int; y <- declareVar int
assert $ x .+. y .==. cint 5
assert $ x .>. cint 0; assert $ y .>. cint 0
checkSat
IntValue vx <- getValue x; IntValue vy <- getValue y
return (vx,vy)
\(C\)-Typen erscheinen statisch in \(G\)-Typen, Bsp:
(.>.) :: (Embed m e, IsSMTNumber tp, HasMonad a, HasMonad b
, MatchMonad a m, MatchMonad b m
, MonadResult a ~ e tp, MonadResult b ~ e tp)
=> a -> b -> m (e BoolType)
Julian Bruder: Hasmtlib https://hackage.haskell.org/package/hasmtlib
…encoding your problem, marshaling the data to an external solver and parsing and interpreting the result into Haskell types. It is highly inspired by ekmett/ersatz
res <- solveWith @SMT (solver z3) $ do
setLogic "QF_NIA"
[p,q,r,s] <- replicateM 4 $ var @IntSort
assert $ p >? 0 && q >=? 0 && r >? 0 && s >=? 0
assert $ p * s + q >? r * q + s
return [p,q,r,s]
print res
WS 25: 1, 2, 3
für jede der Logiken QF-LIA, LRA, NIA: ein kleines Constraint-System (mit kleinen Koeffizienten) angeben, das erfüllbar ist, aber nur durch Modelle mit sehr großen Zahlen.
Bestimmen Sie:
die kleinste natürliche Zahl, die sich auf zwei verschiedene Weisen als Summe von zwei Kuben schreiben läßt
mit einem SMT-Solver. Schreiben Sie das Constraint-System von Hand.
Benutzen Sie Logiken QF_NIA (Polynom-Arithmetik) (Warum
nicht QF_LRA?)
Hinweis: die Bedingung die kleinste kann man nicht hinschreiben, aber durch systematisches Probieren realisieren
die vorige Aufgabe mit QF_BV (Bitvektoren). Dabei
müssen Überläufe durch weitere Constraints verhindert werden. Wie geht
das?
Dieses Beispiel in QF_NIA ist wohl zu schwer für
heutige Solver:
Andrew R. Booker, Andrew V. Sutherland: On a question of Mordell, https://arxiv.org/abs/2007.01209
John Pavlus: Sum-of-Three-Cubes Problem Solved for ‘Stubborn’ Number 33, https://www.quantamagazine.org/sum-of-three-cubes-problem-solved-for-stubborn-number-33-20190326/
wählen Sie zufällig in SMTLIB eine (quantorenfreie) Logik und dort eine Benchmark. Erklären Sie die Benchmark.
Beispiel: Queens (siehe Folie)
Wenden Sie verschiedene SMT-Solver an (z.B. Z3, CVC5, opensmt) und vergleichen Sie Laufzeiten.
Ändern Sie die Formel (vorsichtig), erläutern Sie die Änderungen der Belegung oder Erfüllbarkeit.
Erzeugen Sie das Constraint durch Hasmtlib.
die zitierte Hamiltonkreis-Kodierung (oder die früher zitierte MIP-Kodierung dafür) in SMTLIB-Syntax hinschreiben (in möglichst einfacher Logik) und ausprobieren.
Eine kompatible arktische Matrix-Interpretation für \(aa\to aba\) (das Bsp. auf Folie) durch
Lösen eines LIA-Systems bestimmen
Desgl. für \(a^2 b^2\to b^3 a^3\) (größere Dimension verwenden).
Warum gibt es keine solche Interpretation für \(ab\to ba\)?
Hinweis: weil diese Regel quadratische lange Ableitungen gestattet (von welchen Startwörtern?),
aber solche können bei arktischen Interpretationen nicht vorkommen (warum?)
Adventskalender der DMV https://www.mathekalender.de/wp/de/kalender/
Wenden Sie SAT oder SMT an, um Aufgaben zu modellieren und zu lösen.
für jedes T.Atom \(A =
P(t_1,\ldots,t_k)\)
eine boolesche Unbek. \(p_A \leftrightarrow
A\).
naives Vorgehen:
für jede Lösung des SAT-Problem für diese Variablen \(p_*\):
bestimme Erfüllbarkeit dieser Konjunkt. von T-Literalen
Realisierung mit DPLL(T):
decide, \(T\)-solve (Konjunktion von \(T\)-Literalen)
Konflikte (logische und \(T\)-Konfl.): backtrack
logische Propagationen, Lernen
\(T\)-Propagation (\(T\)-Deduktion)
Theorie ist: lineare Ungleichungen über \(\mathbb{Q}\)
Formel \(\in\) CNF(T) \(=\) Konjunkt. v. Disjunkt. von Literalen
data Atom = Theory_Atom ( FM.Atom Variable )
| Boolean_Atom Variable
data Literal =
Literal { polarity :: Bool, atom :: Atom }
type Clause = [ Literal ]
type CNF = [ Clause ]
Beispiel: \(b \le x \wedge c \le x \wedge (b \ge x \vee c \ge x)\)
[ [ 0 <= -1 * b + x ]
, [ 0 <= -1 * c + x ]
, [ 0 <= + b -1 * x, 0 <= + c -1 * x ] ]
Beschreibung, Test, Verbesserung : Bachelor-Arbeit
Zustand d. Beweis-Suche (wie DPLL): Menge (Konjunktion) \(b\) v. Literalen, Keller \(k\) v. Entscheidungen
Lösung ist Schrittfolge, jeder Schritt ändert Zustand
data Step = Decide Literal
| Conflict Conflict | Backtrack
| Propagate { use :: Conflict, obtain :: Literal }
| SAT | UNSAT
neu (für DPLL(T)): Theorie-Konflikte.
data Conflict = Boolean Clause | Theory
Propagation (Wdhlg.) ist eine Entscheidung \(p\) (Belegung eines Atoms), deren Gegenteil \(\neg p\) einen Konflikt \(c\) erzeugt
wenn \((b \wedge \neg p)\not\models c\), dann \((b \wedge c)\Rightarrow p\).
Literatur: Robert Niewenhuis et al.: https://www.cs.upc.edu/~roberto/papers/IJCAR2012Slides.pdf
Univ. Barcelona, Spin-Off: Barcelogic, Bsp:
https://barcelogic.com/en/sports-planning/
…software for professional sports scheduling. It has been successfully applied during the last five years in the Dutch professional football (the main KNVB Ere- and Eerste Divisies).
An adequate schedule is not only important for sportive and economical fairness among teams and for public order. It also plays a very important role reducing costs and increasing revenues, e.g., the value of TV rights.
Beispiel: das Wortersetzungssystem \(R=\{aa\to bbb, bb\to a\}\) terminiert.
Beweis: definiere \(h: \Sigma\to\mathbb{N}: a\mapsto 5, b\mapsto 3\)
und setze fort zu \(h^* : \Sigma^* \to \mathbb{N}: h(c_1\ldots c_n)=\sum h(c_i)\).
Dann gilt \(u \to_R v\Rightarrow h^*(u)>h^*(v)\) wegen \(\forall (l\to r)\in R: h^*(l)>h^*(r)\).
Die Gewichtsfunktion \(h\) erhalt man als Lösung des linearen Ungleichungssystems
\(2a > 3b \wedge 2b > a \wedge a\ge 0 \wedge b\ge 0\).
Aufgabenstellung im LP-Format (http://lpsolve.sourceforge.net/5.0/CPLEX-format.htm)
Minimize
obj: a + b
Subject To
c1: 2 a - 3 b >= 1
c2: 2 b - a >= 1
End
lösen mit glpsol (GNU Linear Programing Kit, https://www.gnu.org/software/glpk/, 2000-2020, Andrew
Makhorin)
glpsol --lp lin/lpex.cplexlin. (Un-)Gleichungssystem \(\to\) \(\bigwedge_{i=1}^n\) Constraint
Constraint \(\to\) Ausdruck Relsym Ausdruck
Relsym \(\to ~=~ \mid ~ \le ~ \mid ~ \ge\)
Ausdruck \(\to\) Zahl \(+ \sum_{i=1}^n\) (Zahl \(\cdot\) Unbekannte)
Zahlenbereich: \(\mathbb{Q}\) (rational)
Beispiel: \(4y \le x \wedge 4x\le y-3 \wedge x+y \ge 1 \wedge x-y \ge 2\)
Semantik: Wertebereich für Unbekannte ist \(\mathbb{Q}\) (äquiv: \(\mathbb{R}\))
Beispiel:
\(4y \le x \wedge 4x\le y-3 \wedge x+y \ge 1 \wedge x-y \ge 2\)
Normalform: \(\bigwedge_i \sum_j a_{i,j} x_j \ge b_i\) \[\begin{aligned} x - 4y &\ge& 0 \\ \dots \end{aligned}\]
Matrixform: \(A x^T \ge b^T\)
\(A\) ist linearer Operator.
Lösung von linearen (Un-)Gl.-Sys. mit Methoden der linearen Algebra
Warum funktioniert das alles?
lineares Gleichungssystem:
Lösungsmenge ist (verschobener) Unterraum, endliche Dimension
lineares Ungleichungssystem:
Lösungsmenge ist Simplex (Durchschnitt von Halbräumen, konvex), endlich viele Seitenflächen
Wann funktioniert es nicht mehr?
nicht linear: keine Ebenen
nicht rational, sondern ganzzahlig: Lücken
Lösung nach Gauß-Verfahren:
eine Gleichung nach einer Variablen umstellen,
diese Variable aus den anderen Gleichungen eliminieren (\(=\) Dimension des Lösungsraumes verkleinern)
Ü: es gibt kein solches Verfahren für CNF-SAT (es gibt keine Operation, die der Subtraktion entspricht)
…aber für XOR-SAT (Konjunktion von XOR-Klauseln)
Mate Soos, Karsten Nohl, Claude Castelluccia: Extending SAT Solvers to Cryptographic Problems SAT 2009
…we extended the solver’s input language to support the XOR operation
Entscheidungsproblem:
Eingabe: Constraintsystem,
gesucht: eine erfüllende Belegung
Optimierungsproblem:
Eingabe: Constraintsystem und Zielfunktion (linearer Ausdruck in Unbekannten)
gesucht: eine optimale erfüllende Belegung (d. h. mit größtmöglichem Wert der Zielfunktion)
Standard-Form des Opt.-Problems:
\(A\cdot x^T=b, x^T\ge 0\), minimiere
\(c\cdot x^T\).
Ü: reduziere OP auf Standard-OP, reduziere EP auf OP
Simplex-Verfahren (für OP) (George Dantzig et al., 1947)
Schritte wie bei Gauß-Verfahren für Gleichungssysteme (\(=\) entlang einer Randfläche des Simplex zu einer besseren Lösung laufen)
Einzelheiten siehe Vorlesung Numerik/Optimierung
exponentielle Laufzeit im schlechtesten Fall (selten)
polynomielle Algorithmen: Leonid Kachiyan, 1979, Narendra Karmakar 1984.
Fourier (1826)-Motzkin (1936)-Verfahren (für EP)
vgl. mit Elimination durch vollständige Resolution
exponentielle Laufzeit (häufig)
Def.: eine Ungls. ist in \(x\)-Normalform, wenn jede Ungl.
die Form \(x\) (\(\le \;\mid\; \ge\)) (Ausdruck ohne \(x\)) hat
oder \(x\) nicht enthält.
Satz: jedes Ungls. besitzt äquivalente \(x\)-Normalform.
Def: für Ungls. \(U\) in \(x\)-Normalform:
\(U_x^\downarrow := \{ A \mid (x\ge A) \in U\},~ U_x^\uparrow := \{ B \mid (x\le B) \in U\},\)
\(U_x^- = \{ C \mid C\in U, \text{$C$ enthält $x$ nicht} \}.\)
Def: (\(x\)-Eliminations-Schritt) für \(U\) in \(x\)-Normalform:
\(U \to_x \{ A \le B \mid A\in U_x^\downarrow, B\in U_x^\uparrow \} \cup U_x^-\)
Satz: (\(U\) erfüllbar und \(U\to_x V\)) \(\iff\) (\(V\) erfüllbar).
FM-Verfahren: Variablen nacheinander eliminieren.
import qualified Data.Map as M
data Linear v = Linear (M.Map (Maybe v) Rational)
linf = Linear $ M.fromList
[(Nothing, 5%2),(Just "x",-3%7), (Just "y", 4%1)]
plus (Linear p) (Linear q) =
Linear $ M.filter (/= 0) $ M.unionWith (+) p q
$ cabal repl autotool-collection -w /opt/ghc-9.8.4/bin/ghc
ghci> :l Fourier_Motzkin
ghci> scale 2 linf
Datenmodell für Konjunktion von Ungl.
data Atom v = NonNegative {linear :: Linear v}
| Positive {linear :: Linear v}
type Constraint v = [Atom v]
-- | f == 0 , where f contains x, is transformed to
-- f' == x , where f' does not contain x
remove :: Ord v => v -> Atom v -> Linear v
Elimination einer/aller Variablen
resolve :: Ord v => v -> Constraint v -> Constraint v
satisfiable :: Ord v => Constraint v -> Bool
ghci> resolve "y" $ resolve "x" unsat
WS 24: 1, 2, 5
Finden Sie eine monotone Interpretation durch eine Gewichtsfunktion für das Wortersetzungssystem
(RULES
a a a -> b b,
b b b -> c d ,
c -> a a ,
d -> c )
(Quelle: SRS/Zantema/z116.srs aus https://www.lri.fr/~marche/tpdb/tpdb-2.0/, vgl. https://termination-portal.org/wiki/TPDB)
Stellen Sie das passende Ungleichungssystem auf, geben Sie eine (geratene) Lösung an.
Führen Sie das Fourier-Motzkin-Verfahren für dieses Ungleichungssystem durch.
Bestimmen Sie eine Lösung mit GLPK
Bestimmen Sie eine Lösung mit hmatrix-glpk.
Alberto Ruiz, Dominic Steinitz, 2010-2018, Simple interface to linear programming functions provided by GLPK. https://hackage.haskell.org/package/hmatrix-glpk
Finden Sie weitere Systeme aus SRS/Zantema/z101 …z112 mit Gewichtsfunktion.
Vergleichen Sie mit den Lösungen, die in der letzten Termination Competition gefunden wurden. https://termination-portal.org/wiki/Termination_Competition
Vorverarbeitung eines Terminationsproblems durch sparse tiling, dann Gewichtsfunktion: siehe Geser, Hofbauer, Waldmann FSCD 2019 https://drops.dagstuhl.de/opus/volltexte/2019/10528/
beruht auf einer alten und einfachen Idee, Beispiel: 2-Kachelung für \(aa\to aba\) ergibt \(\{[aa]\to[ab][ba]\}\), Anzahl der \([aa]\) nimmt ab,
das klappt aber nicht immer so einfach (wann nicht?), läßt sich leicht reparieren (wie?)
in zitierter Quelle: Einschränkung der Kachelmenge
die Curry (1960)-Howard (1969)-Isomorphie:
Typ \(=\) Behauptung (Proposition), Programm \(=\) Beweis
Behauptung: Typ \(T\) ist nicht leer,
Beweis dafür: ein Ausdruck (Programm) \(P\) mit Typ \(T\).
dann ist Beweis-Prüfung \(=\) Typ-Prüfung
diese kann automatisiert werden (Bsp: Sprache Agda)
…die Beweis-Suche aber nicht (volle Prädikatenlogik, Wahrheit ist nicht entscheidbar)
Unterstützung (interact. proof assistant, Bsp: Agda Emacs mode) für die schrittweise Beweis-Konstruktion
\((A\wedge B)\) ist wahr gdw. \(A\) wahr und \(B\) wahr
Typ \((A\wedge B)\) nicht leer gdw. \(A\) nicht leer und \(B\) nicht leer
data Und (a b : Set) : Set where
beide : a -> b -> Und a bdas ist die generalized algebraic data type (GADT)-Notation für
den Haskell-Typ data Pair a b = Beide a b
in Agda: Typ-Argumente müssen deklariert werden,
Groß/Klein-Schreibung ist frei wählbar,
Operatoren (->, :) benötigen
Leerzeichen,
denn a->b ist ein gültiger Name
wenn \((A \to B)\) wahr ist, und \(A\) wahr ist, dann ist \(B\) wahr
modus ponens (Abtrennungsregel) \(\displaystyle\frac{A\to B, A}{B}\)
Implikation \(A \to B\) realisiert durch Funktionstyp \(A\to B\)
Beispiel: wir behaupten und zeigen \((A\wedge B) \to (B \wedge A)\)
Behauptung:
prop : {a b : Set} -> Und a b -> Und b a
Beweis: eine Implementierung
prop (beide x y) = ?
Syntax: in geschweiften Klammern (im Typ):
implizite Argumente (weglassen in Impl.)
\(A\vee B\) ist wahr gdw. \(A\) wahr oder \(B\) wahr ist
Typ \(A\vee B\) ist nicht leer gdw. \(A\) nicht leer oder \(B\) nicht leer
data Oder (a b : Set) : Set where
links : a -> Oder a b
rechts : a -> Oder a bein Distributivgesetz \((A\vee B)\wedge C \to (A\wedge C)\vee (B\wedge C)\)
dist : {a b c : Set} -> Und (Oder a b) c
-> Oder (Und a c) (Und b c)Beweis durch vollständige Fallunterscheidung
dist (beide (links x) z) = ?
...
Lücken im Beweis schreiben als ?
C-c C-l (load) Modul kompilieren
C-c C-, Ziel (Typ der Lücke) und Kontext (Typen der
gebundene Namen) anzeigen C-u C-u C-c C-, desgleichen, mit
expandierten (normalisierten) Typen
C-c C-c (case) vollständige
Fallunterscheidung
C-c C-SPC (give) Lücke füllen
C-c C-r (refine) ersetzt ? durch
f ? ... ? (mit passender Anzahl neuer Lücken)
C-c C-a (auto)
Ziel: Lücken in Programmen durch diese Befehle nach unten (in Teilterme) schieben und schließlich entfernen
das ist ja wie eine richtige KI: Jein. Andersherum ist wahr: funktionale Programmierung und symbolische KI zur Programmkonstruktion seit ca. 1960 (LISP)
die derzeit gehypten Textmodelle (LLM) verstehen Programmieraufgaben nur so weit, wie sie dazu vermutete Hausaufgabenlösungen auf Stackoverflow memorisiert haben
das LLM kann einen Agenten steuern (Interpreter oder Compiler) und Glück haben, wenn dabei erzeugte Fehlermeldungen auf Stackoverflow standen.
das funktioniert um so besser, je genauer die Fehlermeldungen sind. Die Fehlermeldungen werden umso genauer, je genauer die Spezifikation ist.
Wenn die Spezifikation allerdings nur aus vom LLM selbst geratenen Testfällen besteht, nützt sie gar nichts.
bei ausdrucksstarken statischen Typsystemen steht die Spezifikation (als Typ) exakt da (proposition \(=\) type).
dann ist es auch egal, woher die Implementierungs- bzw. Beweisvorschläge (program \(=\) proof) kommen, denn der Compiler prüft diese exakt.
die Fehler des ahnungslosen Programmierens (vibe coding) können nur durch formale Methoden und Werkzeuge festgestellt werden, und auch vermieden:
denn diese machen das Text-basierte Raten überflüssig:
Bsp. C-c C-a zählt Beweiskandidaten der Größe nach auf
und prüft Typkorrektheit.
Die Jugend Von Heute kann das gern agentic coding nennen, Hauptsache, sie kommt in die FMW-Vorlesung.
Aussage \(A\) wahr gdw. Type \(A\) nicht leer,
also: \(A\) falsch gdw. \(A\) leer, d.h., ohne Konstruktoren
data Absurd : Set, Bezeichung auch \(\bot\) (bottom).
dieses Programm hat nicht den Typ Absurd
f : Absurd ; f = f (in Haskell: statisch korrekt, in Agda:
wegen Nichttermination abgelehnt)
vgl. das Wahre:
data Unit : Set where unit : Unit
, auch \(\top\) (top).
exfalso : Absurd -> Unit
Beweis: exfalso () das ist keine Gleichung
(Implementierung), sondern die Behauptung, daß es keine gibt.
eine Art der Negation \(\neg A\) ist definiert als \((A \to \bot)\).
not : Set -> Set ; not a = a -> Absurd
Bezeichnung: das ist intuitionistische Logik
Vorsicht, dafür gilt \(A\to \neg\neg A\) (Ü), aber nicht \(\neg\neg A \to A\)
Ü: \(\neg\neg\neg A \to \neg A\)
de Morgan: \(\neg (A \vee B) \to (\neg A\wedge \neg B)\)
Ü: andere Varianten dieser Aussage. nicht alle klassische wahren sind auch intuitionistisch wahr.
den Typ schreiben wir genauso wie früher in Haskell
data Nat : Set where zero : Nat ; succ : Nat -> Nat
Funktionen auch (Fallunterscheidung, Rekursion)
plus : Nat -> Nat -> Nat
plus zero y = y ; plus (succ x) y = succ (plus x y)
Unterschiede zu Haskell: Vollständigkeit, Termination (Beispiele!)
Bsp: die Eigenschaft ist gerade.
wir rechnen nicht einen Wahrheitswert aus,
sondern geben Beweismöglichkeiten an:
data even : Nat -> Set where
even-zero : even zero
even-succ : {x : Nat}
-> even x -> even (succ (succ x))
Typ v. even-succ ist dependent
(daten-abhängig, von x)
Beweis (vollständige ! Fallunterscheidung)
even-plus
: (x y : Nat) -> even x -> even y -> even (plus x y)
even-plus zero y ex ey = ey
even-plus (succ (succ x)) y (even-succ ex) ey = ?
dependently typed functional programming language: has inductive families (data types which depend on values) proof assistant: interactive system for writing and checking proofs. based on intuitionistic type theory,
Per Martin-Löf, Constructive Mathematics and Computer Programming, 1979
Wadler, Kokke, Siek: Programming Language Foundations in Agda
Samuel Mimram: Program \(=\) Proof
exakt formalisieren, Beweis schrittweise entwickeln
Code aus VL verwenden (d.h., keine Standardbibliothek)
(möglichst viel C-c .., möglichst wenig selbst
schreiben)
Assoziativität des Oder
\(\neg\neg\neg a \to \neg a\)
Varianten von de Morgan
für Nat: definiere odd (ungerade)
(direkt, nicht als Negation von gerade), zeige:
{x : Nat} -> even x -> odd x -> Falsch
zeige: ungerade plus ungerade ergibt gerade
definiere Multiplikation,
zeige: ungerade mal ungerade ergibt ungerade
Note: Assoziativität der Addition (usw.) noch nicht, weil wir die Gleichheit noch nicht definiert haben.