Partie 1 : SAT solveur
François Thiré
January 16, 2017
1 Introduction
Le projet logique de cette année va se découper en trois parties plus ou moins
indépendantes. L’objectif est à chaque fois de vous faire découvrir comment la
logique peut-être utilisée pour résoudre des problèmes. Il existe de nombreuses
façon différentes d’utiliser la logique et il n’est pas possible en un semestre de
présenter toutes ces façons. Cependant, voici 5grandes catégories1:
Les SAT solveurs
Les SMT solveurs
Les démonstrateurs automatiques
Les assistants de preuve
La programmation logique
Les SAT solveurs : ce sont des outils qui permettent de répondre au prob-
lème de la satisfiabilité d’une formule exprimée en logique propositionnelle. La
première partie du projet s’intéresse à cette catégorie et elle sera donc détaillée
ci-dessous.
Les SMT solveurs : ces outils sont également des solveurs mais cette fois
du premier ordre auquel on a rajouté des théories. Des théories, il en existe des
dizaines, mais on peut notamment citer :
l’arithmétique
l’arithmétique linéaire (sans la multiplication)
les nombre flottants
1les points soulignés en gras sont ceux qui vont nous concerner
1
Les SMT solveurs sont en général basés sur un SAT solveur auquel on
a rajouté une procédure de décision pour chaque théorie. Dans le cas de
l’arithmétique linéaire par exemple, cette procédure est généralement l’algorithme
du simplex que vous verrez si vous faites le cours Algorithmique 2. En se plaçant
dans cette théorie, par exemple vous pouvez donner la formule suivante à un
SMT solveur :
x, y, z, 2xy+ 4z2x+ 3z3(y+ 1) 7y+ 3 6x+ 4z
et il vous répondra que c’est effectivement un théorème (était-ce évident ?).
Le problème aussi bien avec les SAT solveurs que les SMT solveurs, c’est
qu’ils intègrent seulement une procédure de décision. Autrement dit leur réponse
peut-être :
Oui
Non
Je ne sais pas
Mais imaginez que le SMT solveur ait un bug dans son code et qu’une fois
de temps en temps il se trompe, comment peut-on le savoir ? Afin d’augmenter
notre degré de confiance il peut-être plus intéressant de fournir une preuve (ou un
trace de preuve) dudit théorème. C’est l’objet des démonstrateurs automatiques.
Les démonstrateurs automatiques : ce sont des outils qui à l’instar des
SMT solveurs prennent en entrée un énoncé mathématique mais cette fois es-
sayent aussi de trouver une preuve (voir un contre-exemple). La contre-partie
c’est que trouver la preuve d’un énoncé peut prendre beaucoup plus de temps
que les procédures de décision que l’on trouve dans un SMT solveur.
Les assistants de preuve : ce sont des outils qui comme les démonstrateurs
automatiques construisent des preuves mais non plus de façon automatique mais
en interagissant avec un utilisateur. On ne peut pas attendre (en tout cas
aujourd’hui) des démonstrateurs automatiques de trouver des preuves de gros
théorèmes (petit théorème de Fermat, théorème de Feit-Thompson, théorème de
Fermat-Wiles). Heureusement, il est cependant possible d’écrire cette preuve
formellement et d’avoir un outil qui vérifie si la preuve est correct. C’est ce
qu’on étudiera dans la seconde partie de ce projet.
La programmation logique : c’est un autre paradigme de programmation
qui est très intéressant car il contient intrinsèquement du non-déterminisme.
Autrement dit, on a gratuitement un algorithme qui permet de faire du back-
tracking (ce dont on avait besoin pour le solveur du projet Fling par exemple).
Ce paradigme permet ainsi d’écrire en très peu de code des solveurs basiques
pour de nombreux problèmes (notamment tous les problèmes logiques comme
le sudoku, les dérivés de carrés latins, ...). Mais il est aussi utilisé en bio-
informatique ou bien en traitement automatique de la langue. C’est ce qu’on
verra dans la dernière partie de ce cours.
2
2 Description du projet
Cette partie s’intéresse aux SAT solveurs. Un SAT solveur est un outil qui
prend en entrée une formule exprimée en logique propositionnelle et renvoie une
réponse :
SAT si la formule est satisfiable (accompagné généralement d’un environ-
nement qui satisfasse la formule)
UNSAT si la formule est insatisfiable (parfois avec une trace de preuve)
Ce projet va se découper en trois phases:
Implémenter une procédure de décision correcte et complète (DPLL) pour
le problème
Tester cette implémentation sur un ou plusieurs problèmes
Comparer les performances avec les outils actuellement sur le marc
3 Consignes
Pour ce projet, le langage n’est pas imposé. Par contre, si vous souhaitez utiliser
un autre langage qu’Ocaml, prévenez-moi avant afin que je donne mon aval.
Cependant, je vous recommande d’utiliser Ocaml qui est tout à fait adapté pour
ce projet. Le sujet est volontairement succint et peu détaillé afin que vous soyez
un maximum libre dans vos choix.
4 Un solveur naïf
Avant d’implémenter l’algorithme DPLL, je vous conseille d’abord de faire un
solveur très naïf afin de se mettre en jambe. Ce dernier pour résoudre une
formule propositionnelle portant sur un ensemble de variables Xva énumérer
toutes les fonctions possibles de X7→ Btant qu’il n’a pas trouvé un modèle.
Ce solveur s’avèrera très vite inefficace mais il pourra être utile pour déboguer
DPLL ainsi que pour faire des comparaisons dans la dernière partie. Cependant,
je vous conseille de ne pas passer plus d’une séance sur ce solveur, c’est juste
histoire de s’échauffer un peu.
Bonus: Si vous cherchez un peu de challenge, je vous invite à implémenter
ce solveur avec seulement des fonctions récursives terminales (et évidemment de
façon purement fonctionnelle).
En testant rapidement le solveur naïf, on se rend compte qu’il n’est pas
possible d’aller très loin. On va donc maintenant voir comment implémenter un
algorithme un peu plus malin que le solveur précédent.
3
5 Vers un solveur un peu plus malin : DPLL
L’algorithme DPLL2a été publié pour la première fois en 1962 et reste un élé-
ment essentiel dans les implémentations des SAT-solveurs aujourd’hui. L’efficacité
de cet algorithme repose sur trois critères simples appliqués aux formules en
forme normale conjonctive3. Ces critères sont :
Si la formule cnf contient une clause vide, alors la formule est insatisfiable
Si la formule cnf contient une clause contenant un unique littéral, alors la
valeur de ce littéral est déterminée pour la suite de la recherche
Si la formule cnf contient une variable qui apparait uniquement positive-
ment ou uniquement négativement, alors on peut supprimer toutes les
clauses où cette variable apparaît.
Si aucun de ces critères n’est applicable, il faut revenir à une méthode naïve.
Pour cela l’algorithme est paramétré par une méthode choose_variable qui
choisit une variable sur laquelle on branche:
Premier cas on met la valeur de cette variable à true et on simplifie selon
les critères ci-dessus
De même, en mettant la valeur de la variable à false
A vous de jouer maintenant. Si vous souhaitez tester votre programme,
je vous conseille d’implémenter le format DIMACS4. Vous trouverez pléthore
d’exemples dans ce format.
6 Transformer un problème en une formule propo-
sitionnelle
Dans le monde académique, afin de tester la rapidité des solveurs SAT, il existe
des concours pour comparer les meilleurs solveurs existants. Cependant, avec
notre algorithme très simple on n’ira pas très loin dans ce genre de concours.
Je vous propose donc dans cette partie de créer d’autres exemples afin de com-
parer vos solveurs. Pour cela on va prendre des problèmes logiques que l’on va
transformer en une formule propositionnelle de telle sorte que le problème a une
solution si et seulement si la formule propositionnelle est satisfiable. Je vous
propose dans cette partie plusieurs idées de problèmes qui peuvent être intéres-
sants à regarder. Je vous demande d’en implémenter un. L’idéal, serait que
vous vous répartissiez les problèmes afin que l’on puisse comparer les résultats
à la fin. Les étoiles sont une indication du temps à y passer.
Eternity II (***,*,-)
2https://en.wikipedia.org/wiki/DPLL_algorithm
3https://en.wikipedia.org/wiki/Conjunctive_normal_form
4http://people.sc.fsu.edu/~jburkardt/data/cnf/cnf.html
4
Sudoku (*,*,**)
Démineur (*,*,-)
Picross (***,*,**)
Alcazar (***,**,**)
Towers (*,*,-)
Loopy (**,**,**)
Tents (**,*,**)
Tracks (**,**,**)
Pour chacun de ces problèmes, il y a deux tâches à faire plus une optionnelle
(bonus) :
Encoder le problème vers une formule SAT
Générer aléatoirement des instances du problème (cela peut nécessiter la
partie une)
Vérifier l’unicité de la solution
Les étoiles indiquent la difficulté (ou plutôt) le temps nécessaire que j’estime
pour chacune de ces trois tâches. Ce n’est qu’une idée car je n’ai pas implémenté
tous ces problèmes. Evidemment, si vous vous attaquez à des problèmes plus
compliqués, cela influera positivement sur votre note (si vous arrivez à la fin).
7 Benchmark
Lorsqu’on a implémenté DPLL, on a vu qu’on pouvait paramétriser l’algorithme
par le choix d’une variable. Il serait intéressant que vous implémentiez plusieurs
choix5afin de voir les différences :
littéral le plus présent
littéral le plus présent dans une clause minimale
UP/GUP/SUP
JW rule
Pour ces différents algorithmes + l’algorithme naïf, je vous demande de faire
tourner vos programmes sur les exemples générés à la partie 2 et de faire une
comparaison (idéalement dans un tableau). N’hésitez-pas à laisser des commen-
taires pour expliquer ce que vous observez si vous le pouvez. N’hésitez-pas non
plus à comparer vos solveurs. Cependant, ceci est pertinent seulement si vous
utilisez le même langage et le même compilateur.
5https://www.cs.ubc.ca/~hutter/EARG.shtml/earg/papers07/lagoudakis01learning.
pdf
5
1 / 5 100%