Université de Caen Basse-Normandie M1 informatique, 2009–2010
Département d’informatique Unité UE5
Logique et programmation logique
TD. Problème de satisfaisabilité (correction)
Bruno Zanuttini
1 Introduction
On cherche à observer le comportement de l’algorithme DPLL pour le problème de
satisfaisabilité, ainsi que ses variantes et améliorations, sur un exemple.
À fins de concision, on utilise les notations suivantes. La clause (x1∨ ¬x2∨ ¬x3), par
exemple, est notée (1¯
2¯
3). La formule CNF (x1∨ ¬x2∨ ¬x3)(¬x1x4), par exemple,
est notée (1¯
2¯
3)(¯
14). Dans tout le TD, nous considérerons la formule CNF suivante, sur
les variables x1, . . . , x9.
ϕ= (178)(2¯
7¯
8)(12¯
78)(7¯
8)(¯
2¯
7)(¯
2¯
8)(34)(3¯
5¯
6)(¯
4¯
9)(956)(¯
56)(5¯
6)
Toujours à fins de concision, en écrivant la suite des affectations explorées par un al-
gorithme de type DPLL, on pourra écrire les branches successives explorées, avec entre
parenthèses les littéraux déduits par résolution unitaire.
Ainsi, si l’on considère un algorithme de type backtrack utilisant la propagation unitaire
et choisissant les variables dans l’ordre de leurs indices, en commençant par le littéral
négatif, les affectations qu’il explore sur la formule ϕex = (1¯
25)(2¯
3)(34)(3¯
4) seront
notées :
¯
1¯
2(¯
3)(4,¯
4) (1)
¯
12(5)¯
3(4,¯
4) (2)
¯
12(5)3 (3)
Cette notation signifie que l’algorithme essaie d’abord d’affecter x1à faux, puis x2à
faux, qu’il en déduit ¬x3par propagation unitaire, puis qu’il déduit à la fois x4et
¬x4par propagation unitaire. Il détecte alors une contradiction, ce qui termine donc
la branche (1) de l’arbre de recherche. L’algorithme backtracke donc et revient sur
l’affectation de x2à faux, puis explore la branche (2), etc. Il finit par trouver un modèle
qui met à vrai les littéraux ¬x1, x2, x3, x5, et qui affecte une valeur quelconque à x4, car
la formule obtenue en propageant ces affectations est vide, donc trivialement satisfaite.
Si la formule avait été insatisfaisable, la dernière branche aurait encore mené à un échec.
1
Note importante Ces exercices cherchent simplement à illustrer le comportement
des différentes variantes de l’algorithme DPLL pour le problème de satisfaisabilité. On
ne peut en aucun cas déduire de ces exemples que telle variante est meilleure qu’une
autre.
Par exemple, dans la pratique, les prouveurs modernes n’utilisent pas la règle des lit-
téraux purs, car détecter ces littéraux est trop coûteux. De même, choisir la bonne
variable ou la bonne valeur de façon dynamique peut être très coûteux, et les prouveurs
modernes optent plutôt pour des structures de données légères (faciles à maintenir),
quitte à utiliser des heuristiques moins sophistiquées.
2 Procédure DPLL originale
La procédure DPLL originale explore les affectations avec un ordre statique quelconque
sur les variables et les valeurs. Lorsqu’elle affecte une valeur à une variable, elle simplifie
la formule en conséquence. En outre, elle maintient la formule saturée pour la résolu-
tion unitaire et propage les littéraux purs (voir ci-dessous). Le backtrack prend place
lorsqu’une contradiction évidente est détectée, c’est-à-dire lorsque la formule courante
contient la clause vide.
Question 1 Faire tourner la procédure DPLL, sans utiliser la propagation des littéraux
purs, sur la formule ϕ. On affectera les variables dans l’ordre naturel de leurs indices,
et on branchera toujours sur la valeur négative d’abord.
Les branches explorées sont les suivantes :
¯
1¯
2¯
3(4)(¯
9)¯
5(6,¯
6) (4)
¯
1¯
2¯
3(4)(¯
9)5(¯
6,6) (5)
¯
1¯
23¯
4¯
5(¯
6)(9)¯
7(8,¯
8) (6)
¯
1¯
23¯
4¯
5(¯
6)(9)7(8,¯
8) (7)
¯
1¯
23¯
45(6)¯
7(8,¯
8) (8)
¯
1¯
23¯
45(6)7(¯
8,8) (9)
¯
1¯
234(¯
9)¯
5(6,¯
6) (10)
¯
1¯
234(¯
9)5(6)¯
7(8,¯
8) (11)
¯
1¯
234(¯
9)5(6)7(¯
8,8) (12)
¯
12(¯
7,¯
8)(8) (13)
1¯
2¯
3(4)(¯
9)¯
5(6,¯
6) (14)
1¯
2¯
3(4)(¯
9)5(¯
6,6) (15)
1¯
23¯
4¯
5(¯
6)(9)¯
7(¯
8) (16)
La formule obtenue après les affectations de la dernière branche est trivialement satis-
faite (elle est vide), on a donc trouvé le modèle qui met à vrai les littéraux x1,¬x2,x3,
2
¬x4,¬x5,¬x6,¬x7,¬x8,x9.
Question 2 La règle des littéraux purs est la suivante. Si une variable apparaît toujours
avec la même polarité dans une formule, on peut lui affecter la valeur correspondante,
sans explorer l’autre valeur. Par exemple, si à un moment dans la recherche ¬xiappa-
raît dans la formule courante, mais pas xi, on affecte xià faux, sans brancher sur le
littéral positif. Faire tourner l’algorithme DPLL comme à la question 1, en ajoutant la
propagation des littéraux purs.
On voit que dans la formule initiale, les littéraux x1et x3sont purs. L’algorithme affecte
donc les deux variables à vrai. Après propagation, on obtient donc la formule :
(2¯
7¯
8)(7¯
8)(¯
2¯
7)(¯
2¯
8)(¯
4¯
9)(956)(¯
56)(5¯
6)
Dans cette formule, les littéraux ¬x4et ¬x8sont purs. L’algorithme affecte donc les
deux variables à faux. Après propagation, on obtient la formule :
(¯
2¯
7)(956)(¯
56)(5¯
6)
Les littéraux ¬x2,¬x7et x9sont alors purs. On obtient alors la formule :
(¯
56)(5¯
6)
L’algorithme essaie alors d’affecter x5à faux, et déduit ¬x6par propagation unitaire.
La formule est alors satisfaite, et on a trouvé le(s) même(s) modèle(s) qu’à la question 1.
Remarques Même si dans l’exemple on trouve le même modèle que sans propagation
des littéraux purs, ce n’est pas nécessairement le cas. Notons aussi que la procédure
DPLL avec propagation des littéraux purs ne peut pas trouver tous les modèles de la
formule ; elle manque ceux qui affectent la valeur opposée aux littéraux purs. Mais elle
est bien cohérente et complète pour le problème de satisfaisabilité, en ce sens qu’elle
trouve un modèle si et seulement s’il en existe un.
3 Backtrack intelligent et apprentissage
Une des plus grandes avancées dans la résolution pratique du problème de satisfaisabilité
a été l’introduction du backtrack non chronologique. En effet, lorsque la procédure
DPLL originale détecte un conflit, elle revient sur sa dernière décision, alors que celle-
ci peut n’être pour rien dans le conflit détecté. Choisir intelligemment la décision sur
laquelle on revient peut alors supprimer une grande partie inutile de l’arbre de recherche.
Par exemple, si la formule est telle qu’affecter x1et x2à faux empêche de trouver des
valeurs qui satisfassent toutes les clauses sur x4, x5, l’algorithme peut détecter un échec
sur toutes les branches commençant par ¯
1¯
2¯
3. Le backtrack chronologique revient alors
3
3
9
8
3
9
78
¯
2
¯
4
¯
5¯
6
¯
7¯
8
¯
1¯
1
¯
2
¯
4
¯
5
¯
8
¯
6
Fig. 1 – Graphe des propagations unitaires pour les branches ¯
1¯
23¯
4¯
5(¯
6)(9)¯
7(8,¯
8)
gauche) et ¯
1¯
23¯
4¯
5(¯
6)(9)7(8,¯
8) (à droite).
sur l’affectation de x3à faux, et explore alors, au pire, toutes les branches commençant
par ¯
1¯
23. Le backtrack non chronologique, quant à lui, détecte que tous les conflits
obtenus dans les branches commençant par ¯
1¯
2¯
3ont été provoqués par la résolution
unitaire avec les affectations de x1et x2à faux. Il revient donc sur l’affectation de x2à
faux, sans explorer les branches commençant par ¯
1¯
23. Pour détecter ces coupables, on
utilise un graphe représentant les affectations impliquées dans les résolutions unitaires.
Question 3 Faire tourner la procédure DPLL avec backtrack non chronologique sur
la formule ϕcomme à la question 1, sans la règle des littéraux purs.
Jusqu’à la détection du premier conflit, la procédure se comporte comme la procédure
DPLL. Elle explore donc la branche 4 : ¯
1¯
2¯
3(4)(¯
9)¯
5(6,¯
6). Étant donné que la dernière
décision (¯
5) est la première valeur pour x5, la procédure revient donc sur cette décision
et explore la branche 5 : ¯
1¯
2¯
3(4)(¯
9)5(¯
6,6).
Un conflit est à nouveau détecté. Les deux valeurs pour x5ayant été explorées, la der-
nière décision est maintenant ¯
3. Or, on peut voir que dans le premier conflit l’affectation
6est provoquée par ¯
5et ¯
9, via la clause (956). Or, l’affectation ¯
9est obtenue par pro-
pagation unitaire de 4, elle-même obtenue par propagation de ¯
3. La décision ¯
3est donc
impliquée dans au moins un des conflits, et comme c’est la plus récente on doit revenir
sur elle.
L’algorithme explore alors les branche 6 : ¯
1¯
23¯
4¯
5(¯
6)(9)¯
7(8,¯
8), puis 7 : ¯
1¯
23¯
4¯
5(¯
6)(9)7(8,¯
8).
La dernière décision est ici ¯
5, mais on peut voir sur les graphes des propagations uni-
taires (figure 1) que les affectations ¯
1et ¯
2suffisent à expliquer tous les conflits. On
revient donc sur l’affectation ¯
2. L’algorithme explore alors les branches 13 à 16 de la
question 1. Il a au final exploré 5branches inutiles de moins que l’algorithme avec
backtrack chronologique.
Question 4 L’apprentissage de clauses va plus loin que le backtrack non chronologique,
en créant de nouvelles clauses, aussitôt ajoutées à la formule, pour expliquer les conflits.
Pour cela, comme pour le backtrack non chronologique, à chaque conflit détecté le graphe
des propagations unitaires est analysé, et une clause minimale expliquant le conflit est
ajoutée à la formule. Faire tourner la procédure DPLL avec apprentissage de clauses sur
la formule ϕcomme à la question 1, sans la règle des littéraux purs et avec backtrack
4
4
6
¯
1¯
2¯
3¯
5
¯
9¯
6
Fig. 2 – Graphe des propagations unitaires pour la branche ¯
1¯
2¯
3(4)(¯
9)¯
5(6,¯
6).
non chronologique.
L’algorithme commence à nouveau comme à la question 1, et explore donc la branche 4 :
¯
1¯
2¯
3(4)(¯
9)¯
5(6,¯
6). Un conflit est détecté, et le graphe de propagations unitaires (figure 2)
montre que les affectations de x3et x5à faux suffisent à expliquer le conflit. La clause
(35) est donc ajoutée à la formule. Un backtrack chronologique prend alors place,
puisque x5fait partie de l’explication du conflit, et l’algorithme explore alors la branche
¯
1¯
2¯
3(4)(¯
9)(5)(¯
6,6). Un conflit est à nouveau détecté, et en explorant le graphe des pro-
pagations unitaires, on s’aperçoit que ¯
3en est seul responsable (5en est maintenant
une conséquence par propagation unitaire, du fait de la nouvelle clause apprise (35).
La clause (3) est donc impliquée par la formule, et l’algorithme l’y ajoute. Il revient
ensuite sur sa décision ¯
3et explore la branche ¯
1¯
2(3)¯
4¯
5(¯
6)(9)¯
7(8,¯
8). Il apprend alors
la clause (17), puis explore la branche ¯
1¯
2(3)¯
4¯
5(¯
6)(9)(7)(8,¯
8). La clause (12) est alors
apprise, et de fait le backtrack non choronologique prend place jusqu’à la décision ¯
2.
L’algorithme explore alors la branche ¯
12(7)(3)(¯
7), apprend la clause (1), revient sur sa
décision ¯
1et explore finalement la branche 1(3)¯
2¯
4¯
5(¯
6)(9)¯
7(¯
8), qui fournit un modèle de
la formule. Au final, l’algorithme a exploré 6branches, au lieu de 13 pour un DPLL
simple (sans règle des littéraux purs) et 8pour un DPLL simple avec backtrack non
chronologique.
4 Heuristiques de choix de variable et de valeur
Orthogonalement aux améliorations précédentes, les algorithmes peuvent aussi choisir,
une fois pour toutes ou dynamiquement, quelle variable placer en haut de l’arbre, et
quelle valeur choisir en premier.
Question 5 Faire tourner la procédure DPLL sur la formule ϕcomme à la question 1,
sans la règle des littéraux purs, sans backtrack non chronologique et sans apprentissage
de clauses, en choisissant de façon statique l’ordre des variables et de façon dynamique
la valeur à leur affecter. On calculera une fois pour toutes le nombre d’occurrences de
chaque variable dans les clauses de chaque taille, et on les explorera par ordre lexicogra-
phique, celles apparaissant souvent dans des clauses de petite taille d’abord. La valeur
5
1 / 6 100%