L`algorithme DPLL

publicité
MIT 1re année - 2011/12
Module Logique et Calculabilité
L’algorithme DPLL
1
Introduction
On rappelle que le problème SAT est le suivant : étant donnée une formule CNF (conjonctive normal form) du calcul propositionnel à n variables, existe-t-il une valuation des n
variables qui satisfait la formule ? Ce problème est NP-Complet (Théorème de Cook). Un
algorithme naı̈f consiste à construire la table de vérité de la formule.
L’algorithme DPLL (Davis-Putnam-Logemann-Loveland) est une procédure de décision
de SAT. Un objectif de ce projet est d’implémenter (par versions successives) cet algorithme en OCaml. Une autre part du projet consiste à prouver certaines propriétés de
l’algorithme et des résultats en rapport avec la problématique. Le sujet est organisé en sections thématiques, qui suivent une progression algorithmique et technique. Chaque section
est composée d’explications, de questions (qui ne nécessitent pas d’implémentation) et/ou
de consignes d’implémentation. La Section 6 indique les fonctions offertes par les librairies
fournies. La Section 7 donne des consignes générales.
2
Mise en forme CNF
En pratique, les formules dont on veut décider la satisfiabilité ne sont pas en forme CNF
et doivent donc être converties en instances de SAT. Une solution consiste à la convertir
en une formule CNF logiquement équivalente.
Question 1 Donner un algorithme de mise en forme CNF qui préserve l’équivalence logique. Démontrer que dans le pire cas, la taille de la formule croı̂t de façon exponentielle
(par convention, la taille d’une formule est son nombre de littéraux).
2.1
Transformation de Tseitin
L’équivalence logique sur la formule obtenue est inutilement contraignante. On peut en
effet se contenter d’une formule équisatisfiable (satisfiable si et seulement si la formule
d’origine l’ est). Il existe de telles transformations et qui n’augmentent que linéairement la
taille de l’entrée. L’une d’entre elle est la transformation de Tseitin (1968).
Le principe est d’associer à chaque sous-formule de F de la forme ¬A ou (A α B), α ∈
{∧, ∨, ⇒, ⇔} une variable propositionnelle fraı̂che x (i.e. n’apparaissant pas dans F ), qui
! définit " cette sous-formule (on parle de definitional conjonctive normal form). Dans F ,
la sous-formule est ainsi remplacée par cette variable, et la contrainte (x ⇔ (A α B)) (mise
en CNF) est ajoutée par conjonction.
1
MIT 1re année - 2011/12
Module Logique et Calculabilité
Illustrons cette transformation dans le cas où F est
(a ∧ b) ∨ ((c ∨ d) ∧ ¬e), ce que l’on peut représenter
par l’arbre ci-contre.
On associe respectivement x1 , x2 , x3 et x4 aux sousformules a ∧ b, c ∨ d, x2 ∧ ¬e et x1 ∨ x3 . Puis, on met
en forme CNF, avec les méthodes traditionnelles la
conjonction de x1 ⇔ a ∧ b, x2 ⇔ c ∨ d, x3 ⇔ x2 ∧ ¬e
et x4 ⇔ x1 ∨ x3 . La transformation de Tseitin T est
définie par T (F ) = xF ∧ T’(F ) avec :

true




T’(G) ∧ Cnf(xF ⇔ ¬xG )



T’(G) ∧ T’(H) ∧ Cnf(xF ⇔ xG ∧ xH )
T’(F ) =
T’(G) ∧ T’(H) ∧ Cnf(xF ⇔ xG ∨ xH )




T’(G) ∧ T’(H) ∧ Cnf(xF ⇔ (xG ⇒ xH ))



T’(G) ∧ T’(H) ∧ Cnf(xF ⇔ (xG ⇔ xH ))
%
F
si F est une
et xF =
variable fraı̂che sinon
∨
∧
∧
a
∨
b
c
si
si
si
si
si
si
F
F
F
F
F
F
¬e
d
est une variable
= ¬G
=G∧H
=G∨H
=G⇒H
=G⇔H
variable
Pour simplifier le raisonnement, on suppose que toutes les négations de la formule ne
s’appliquent qu’à ses variables.
Question 2 Montrez que T ne fait croı̂tre la taille de la formule que linéairement.
Question 3 Montrez que F et T (F ) ne sont pas équivalentes mais équisatisfiables. Indication. On pourra chercher une condition nécessaire et suffisante pour la propriété : la
valuation ϕ satisfait T ! (F ).
&
Remarque : Dans la suite, on représente la formule CNF F = i∈I Ci de la façon suivante :
chaque clause Ci est représentée par l’ensemble de ses littéraux, et F par l’ensemble de ses
clauses. Dans l’implémentation, des listes seront proposées (voir Section 6).
2.2
Benchmarks
Pour comparer l’efficacité des différents algorithmes que vous programmerez, il est nécessaire
de disposer de formules complexes. Un moyen est de générer aléatoirement des formules
d’une taille donnée, mais il est difficile de prévoir leur satisfiabilité et la difficulté d’une telle
décision. Enfin, les problèmes qu’encodent de telles formules présentent moins d’intérêt que
des vrais problèmes (historiques, ou industriels).
Dans les librairies fournies, deux fonctions vous sont données, qui génèrent des formules
complexes, structurées, et dont on connaı̂t (pour certaines) la satisfiabilité. Elles sont
décrites dans les paragraphes suivants. D’autres benchmarks existent et sont disponibles
sur internet. Ils utilisent un format de CNF standard dans la communauté des SATcompétiteurs (DIMACS). Attention, la taille des instances peut être impraticable pour
une implémentation réalisée dans le temps imparti.
2
MIT 1re année - 2011/12
Module Logique et Calculabilité
Test de primalité Les formules de la logique propositionnelle peuvent être mises en correspondance avec les circuits digitaux, et peuvent donc encoder des fonctions arithmétiques
complexes. L’algorithme de test de primalité d’un naturel donné peut être encodé par un
tel circuit. La fonction prime de la librairie génère la formule associée. La formule prime n
est une tautologie si et seulement si n est premier.
Nombres de Ramsey Le nombre de Ramsey Rs,t est défini comme le nombre d’invités
minimum qu’il faut inviter à une fête pour qu’au moins s personnes se connaissent ou qu’au
moins t ne se connaissent pas. Le problème peut se traduire en terme de graphes : c’est le
nombre minimum de sommets qu’un graphe simple non orienté doit comporter pour qu’il
contienne une s-clique (sous-graphe complet à s sommets) ou un t-stable (sous-graphe à t
sommets sans arête). Les nombres de Ramsey ne sont pas tous connus. Dans la librairie,
la fonction ramsey vous permet de construire des tautologies : (ramsey s t n) est une
tautologie si et seulement si Rs,t ≤ n. La formule construit tous les graphes à n sommets
et vérifie qu’ils satisfont les contraintes sur les arêtes. Google est votre ami pour trouver
les valeurs de s et t pour lesquels on connaı̂t la valeur ou un encadrement de Rs,t .
3
L’algorithme DP
La version initiale de l’algorithme est proposée en 1960 par Davis et Putnam (algorithme
DP), et une amélioration est apportée en 1962 par Davis, Logemann et Loveland (algorithme DLL ou DPLL, voir Section 4). L’idée de base de DP est d’appliquer des règles
de transformations sur la formule d’entrée F en CNF, qui préservent sa satisfiabilité et sa
forme clausale. Les trois règles sont les suivantes :
UP (Unit propagation) Si F contient une clause unitaire (Ci = {l}), toutes les clauses
contenant le littéral l peuvent être supprimées et le littéral complément de l peut être
supprimé de chaque clause le contenant.
PL (Pure literal) Si un littéral l n’apparaı̂t que positivement (ou négativement) dans F ,
toutes les clauses le contenant peuvent être supprimées.
R (Resolution) Résolution entre deux clauses, par coupure sur un littéral l (cf. cours).
Question 4 Montrez que les règles UP et PL préservent la satisfiabilité de la formule (la
preuve pour R a déjà été faite en cours).
L’algorithme consiste à appliquer les règles UP et PL tant que possible, avant d’appliquer
la règle R, sur un littéral l, en produisant toutes les résolvantes possibles (approche par
saturation). On décide ensuite récursivement de la satisfiabilité de ce nouvel ensemble de
clauses. Appliquer R nécessite de choisir un littéral sur lequel résoudre. Un critère de choix
possible est de minimiser l’augmentation du nombre de clauses résultantes. L’algorithme
s’arrête dès que la formule est vide ou qu’elle contient la clause vide.
Implémentation 1 (Algorithme DP)
Implémentez l’algorithme DP. Vous veillerez à la définition de fonctions auxiliaires bien
choisies pour ne pas alourdir la fonction principale. Par exemple, vous écrirez une fonction
par règle de transformation de formule.
– Vous écrirez une fonction dp rendant un résultat booléen qui détermine la satisfiabilité
d’une formule sous forme CNF.
3
MIT 1re année - 2011/12
Module Logique et Calculabilité
– De même, vous écrirez une fonction satdp : prop formula -> bool qui prend en
entrée une formule quelconque (non CNF).
– Comparez en efficacité votre algorithme avec l’algorithme naı̈f (fonction satisfiable
donnée dans la librairie).
4
L’algorithme DPLL
L’amélioration de DP en DPLL consiste à remplacer l’utilisation de la règle R par une
stratégie d’exploration avec backtracking. Dans l’algorithme DPLL, le backtracking est
assez simple (chronologique). Une stratégie plus efficace fera l’objet de la Section 5.
4.1
Variables de décision
Une notion d’affectation de variable est utilisée dans (les versions efficaces de) DPLL.
Plusieurs notions utilisées dans DP sont ajustées pour intégrer la notion d’affectation.
Nous y reviendrons en Sous-Section 4.2.
Lorsque les deux règles UP et PL ne s’appliquent plus, une variable x de la formule est
choisie, que l’on appellera variable de décision, à laquelle sera affectée une valeur de vérité.
La formule F est d’abord SAT-décidée (par DPLL) dans un contexte où la variable x à
été affectée à faux. Si F n’est pas satisfiable dans ce contexte, il faut encore décider si ce
n’est pas le cas lorsque x vaut vrai. Les affectations ne modifient pas la composition de la
formule, mais sont une information annexe, représentant la construction progressive de la
valuation satisfaisant la formule.
4.2
Révision de UP
La notion de variable de décision vient modifier légèrement quelques notions introduites
en Section 3. Une affectation ne modifie pas la structure de la formule, mais elle vient
modifier la notion de clause unitaire. Les clauses unitaires comprennent maintenant en
plus les clauses dont un seul littéral n’est pas affecté et tous les autres sont affectés à faux.
Ainsi, les clauses {x} et {x, ¬y, z} sont toutes deux unitaires si y a été affectée à vrai, z à
faux, et x n’est pas encore affectée.
Les clauses unitaires devant être satisfaites, elles induisent des affectations. Par exemple,
avec les mêmes affectations que plus haut, pour satisfaire {x, ¬y, z}, on doit affecter vrai
à x. Ainsi, on ajoute à la notion de unit propagation précédemment définie les affectations
induites. Pour autant, les variables concernées ne sont pas des variables de décision.
4.3
Backtracking
L’historique des affectations est tracé dans une structure de données auxiliaire (plusieurs
choix sont possibles : pile, arbre. . .). Pour illustrer le propos, on choisit ici un arbre. L’arbre
contient pour chaque affectation la variable concernée et sa valeur de vérité courante. Plus
formellement, une affectation est la donnée d’une variable x et d’une valeur de vérité
v ∈ {0, 1} (représentant faux et vrai). On note une affectation x = v.
4
MIT 1re année - 2011/12
Module Logique et Calculabilité
Ci-contre, un exemple d’exploration des valuations
x
possibles pour une formule contenant (au moins) les
variables x, y et z. Une branche gauche (resp. droite)
de l’arbre représente une affectation à 0 (resp. 1 ) de
y
y
la variable portée par le noeud. Seules les variables
de décision ont été représentées.
On appelle conflit une clause de la formule dont tous
z
solution
les littéraux sont falsifiés. Lors d’une détection de conflit1
conflit, le backtracking a lieu : on remonte dans l’historique à la variable de décision la plus récemment
conflit2
conflit3
affectée. Dans l’exemple, lors du premier conflit, la
dernière variable de décision affectée est y. Lors du
conflit 3, il s’agit de z, mais les deux branches ont déjà été explorées pour z et y, il faut
donc remonter jusqu’à la variable de décision x. Notons qu’entre deux affectations peuvent
avoir lieu des utilisations des règles UP et PL.
Implémentation 2 (DPLL)
Proposez un type permettant de gérer l’affectation de variable. Présentez la stucture de
donnée choisie pour gérer l’historique, ainsi que son utilisation. Comme précédemment,
vous veillerez à écrire des fonctions auxiliaires (par exemple une pour le backtrack).
– Vous écrirez une fonction dpll à résultat booléen implémentant DPLL. La formule passée
en paramètre est en CNF.
– Vous écrirez une fonction satdpll : prop formula -> bool décidant le problème pour
une formule quelconque.
– Vous comparerez (en efficacité) votre algorithme avec satdp.
5
Optimisation NCB
Pour des instances de SAT générées aléatoirement, le backtracking chronologique est relativement efficace. En revanche, pour des problèmes réels (c’est à dire des formules structurées), il ne suffit plus. Ainsi, les SAT-solvers actuels basés sur DPLL intègrent un
mécanisme de backtracking plus sophistiqué : le backtracking non-chronologique (NCB).
Analyse des conflits Cette stratégie d’exploration permet d’identifier les affectations
qui sont à l’origine des conflits, et de remonter dans l’historique jusqu’à une des causes du
conflit (la variable en cause la plus récemment affectée). Ainsi, les sous-arbres menant au
même conflit ne seront pas explorés inutilement.
Lors d’un conflit, il est possible de trouver une clause qui en est à l’origine (appellée clause
conflictuelle). Une propriété d’une clause conflictuelle est que si elle n’est pas satisfaite,
alors le conflit aura lieu. Cette clause peut être en plus ajoutée à la formule à SAT-décider
(la clause correspondante est apprise pour faire naı̂tre les conflits plus tôt). Une clause
conflictuelle ne doit inclure que des variables de décision (les applications de UP et PL ne
sont que conséquence des affectations).
5
MIT 1re année - 2011/12
Module Logique et Calculabilité
Illustrons le principe sur un exemple. Ci-contre
est donné un arbre d’exploration, où les variables
c, f, h, i et a sont des variables de décision. Lorsque
le premier conflit est atteint, supposons que la clause
apprise soit {a, c, f }. Cela signifie que le conflit est
provoqué par le fait que les affectations courantes ne
satisfont pas {a, c, f }. On remonte alors au noeud a,
la plus récente décision en cause. Lors du deuxième
conflit, si l’on apprend la clause {c, f }, on pourra
remonter jusqu’au noeud f , élagant ainsi les sousarbres de i et h.
c
f
h
i
a
conflit1
{a, c, f }
conflit2
{c, f }
Apprentissage Plusieurs techniques existent pour
déterminer une clause conflictuelle associée à un
conflit donné. Une possibilité est de maintenir une
structure de données annexe qui traduit les dépendances entre affectations (affectation
des variables de décision et affectations induites). Il s’agit du graphe d’implications
(Définition 2).
Définition 1 (Affectations précédentes)
Soit une variable x dont l’affectation a été induite par la clause unitaire ω. L’ensemble des
affectations précédentes Aω (x) est l’ensemble des affectations des variables distinctes de x
dont les littéraux sont dans ω.
Intuitivement, les affectations précédentes correspondent aux affectations responsables de
celle de la variable considérée. Par exemple, pour la clause ω = {x, y, ¬z}, on a, si ω est
unitaire pour x, Aω (x) = {y = 0, z = 1}. Si ω est unitaire pour y, Aω (y) = {x = 0, z = 1}.
Définition 2 (Graphe d’implication)
Le graphe d’implication est un graphe orienté tel que :
– les sommets sont des affectations x = v ou des conflits (dénotés par κi , i ∈ N)
– les prédécesseurs d’un sommet x = v sont les éléments de Aω (x),
– les affectations faites sur les variables de décision n’ont pas d’antécédent dans le graphe,
– les arcs (a, x = v), où a ∈ Aω (x) sont étiquetés ω,
– les prédécesseurs des κi sont les affectations de variables qui forcent une clause ω à être
insatisfaite, et sont définis comme les éléments de l’ensemble Aω (κi ),
– les arcs (a, κi ), où a ∈ Aω (κi ) sont étiquetés ω.
Question 5 Exploitez le graphe d’implication pour déduire d’un conflit une clause conflictuelle. Expliquez votre raisonnement.
Implémentation 3 (Algorithme DPLL+NCB)
Incorporez la gestion du graphe d’implication à l’algorithme, et implémentez la gestion
des conflits (apprentissage de clauses et niveau de backtrack). Vous écrirez les fonctions
dpllncb et satdpllncb : prop formula -> bool opérant respectivement sur une formule CNF et quelconque, et comparerez votre algorithme à satdpll en efficacité sur des
formules complexes.
6
MIT 1re année - 2011/12
6
Module Logique et Calculabilité
Sources
Téléchargez l’archive contenant les sources et librairies OCaml sur
http://www.irisa.fr/celtique/demange/ens/lc/dpll/tp_dpll.tar.gz.
Makefile Un Makefile vous est fourni. Les deux cibles sont :
– un exécutable main construit à partir du fichier main.ml,
– un fichier .ocamlinit, chargé automatiquement par la commande ocaml lançant le
toplevel. Toutes les librairies sont chargées et ouvertes, de manière à ce que vous n’ayiez
pas à vous soucier des modules avec lesquels préfixer les fonctions des librairies.
Vous pourriez avoir besoin de redéfinir les variables NUMS et TL du Makefile. Elles définissent
les chemins d’accès aux librairies nums.cma et toplevellib.cma.
Librairies Voici les fonctions proposées par les librairies (fichier doc.mli).
(* Type for formulas *)
type ’a formula =
False
| True
| Atom of ’a
| Not of ’a formula
| And of ’a formula * ’a formula
| Or of ’a formula * ’a formula
| Imp of ’a formula * ’a formula
| Iff of ’a formula * ’a formula
(* Parameter type for propositional formulas *)
type prop = P of string;;
(* Apply a function to the atoms, otherwise keeping structure.*)
val onatoms : (’a -> ’a formula) -> ’a formula -> ’a formula
(* Return the set of propositional variables in a formula.*)
val atoms : ’a formula -> ’a list
(* Code to print out truth tables.*)
val print_truthtable : prop formula -> unit
(* Check whether a formula is a tautology, naive algorithm. *)
val tautology : ’a formula -> bool
(* Check whether a formula is unsatisfiable, naive algorithm. *)
val unsatisfiable : ’a formula -> bool
(* Check whether a formula is satisfiable, naive algorithm. *)
val satisfiable : ’a formula -> bool
(* Conjunctive normal form (CNF), list of list representation. *)
val purecnf : ’a formula -> ’a formula list list
(* Conjunctive normal form (CNF), list of list representation,
using simplifications. *)
val simpcnf : ’a formula -> ’a formula list list
7
MIT 1re année - 2011/12
Module Logique et Calculabilité
(* Conjunctive normal form (CNF), using simplifications. *)
val cnf : ’a formula -> ’a formula
(* Definitional Normal Form (DCNF), list of list representation. *)
val defcnfs :
prop formula -> prop formula list list
(* Definitional normal form (DCNF). *)
val defcnf : prop formula -> prop formula
(* Build complex propositional formulas corresponding to
an inequality test on an approximation on Ramsey numbers. *)
val ramsey : int -> int -> int -> prop formula
(* Build complex propositional formulas corresponding to the primality
test of a given int. *)
val prime : int -> prop formula
(* Print time execution of a function applied to its argument. *)
val time : (’a -> ’b) -> ’a -> unit
7
Consignes générales
Les algorithmes que vous aurez à programmer ne sont pas triviaux. Veillez donc à commenter votre code, et à l’organiser correctement (en fichiers, modules, fonctions. . .).
Pré-rapport Vous enverrez par mail le 7 Mars, avant 23h59 (1pt de pénalité par
heure de retard), à [email protected] un pré-rapport structuré et court (5 pages
maximum) dans lequel vous répondrez aux quatre premières questions. Une attention particulière sera portée sur la clarté de vos explications et la rigueur de vos raisonnements.
Rapport final Vous enverrez par mail le 6 Avril 2012, avant 23h59 (1pt de pénalité
par heure de retard) votre code et un rapport (6 pages maximum) dans lequel vous
répondrez aux questions restantes, expliquerez vos choix d’implémentation, et donnerez
un mode d’emploi de votre exécutable/toplevel. Une attention particulière sera portée sur
la clarté de vos explications, et sur la lisibilité de votre code. En particulier, prenez soin
de faire figurer dans le nom de l’archive rendue vos noms, et que le désarchivage se fasse
dans un répertoire racine indiquant également vos noms.
A retenir N’hésitez pas à utiliser la même adresse mail qu’au paragraphe précédent en
cas de problème (installation des dépendances, problèmes théoriques ou techniques. . .).
8
Téléchargement