Forme normale conjonctive et transformation de Tseitin
Ce que ce chapitre apporte
- Reconnaître un littéral, une clause, une formule sous forme normale conjonctive.
- Expliquer pourquoi cette forme, et pas une autre, sert d'entrée aux solveurs.
- Mettre une formule en forme normale négative par les lois de De Morgan.
- Appliquer la distributivité, et montrer sur un exemple qu'elle explose.
- Appliquer la transformation de Tseitin et écrire les clauses de définition de mémoire.
- Justifier que Tseitin préserve l'équisatisfiabilité mais pas l'équivalence.
- Repérer les clauses qu'un solveur élimine à la lecture : répétitions, tautologies, subsomptions.
- Lire et écrire un fichier au format DIMACS.
Le vocabulaire, en trois lignes
Un littéral est une variable ou sa négation : et sont deux littéraux, dits opposés.
Une clause est une disjonction de littéraux : .
Une formule est en forme normale conjonctive, en abrégé CNF, si elle est une conjonction de clauses.
Deux cas limites qu'il faut avoir vus une fois, parce qu'ils apparaissent au milieu d'un calcul et déroutent :
- la clause vide, sans aucun littéral, est fausse. Ce n'est pas une convention arbitraire : une clause exige qu'au moins un de ses littéraux soit vrai, et s'il n'y en a aucun à l'intérieur, il est impossible d'en trouver un. La condition ne peut jamais être remplie. On la note ou , et la dériver est exactement ce que cherche une preuve d'insatisfiabilité ;
- la formule vide, sans aucune clause, est vraie : rien ne s'oppose à elle.
Un littéral est pur dans une formule si son opposé n'y apparaît nulle part.
Si est pur, aucune clause ne contient : poser satisfait toutes les clauses où figure, et n'en gêne aucune autre. On peut donc le faire sans risque, et sans avoir à revenir dessus.
D'où l'asymétrie qui gouverne tout le domaine : une seule clause falsifiée condamne l'affectation entière, alors qu'il faut passer en revue toutes les clauses pour se déclarer satisfait. Trouver l'échec est rapide, confirmer le succès est long.
Pourquoi cette forme, et pas une autre
Trois raisons, et la troisième est la vraie.
Elle est uniforme. Une clause est une liste de littéraux ; une formule est une liste de clauses. Aucune structure arborescente à parcourir, aucun cas particulier. Un solveur manipule des tableaux d'entiers.
Elle rend l'échec local. Une clause dont tous les littéraux sont faux suffit à condamner l'affectation, sans regarder le reste.
Elle rend la déduction locale. Une clause dont tous les littéraux sauf un sont faux force ce dernier. C'est la propagation unitaire, et c'est de loin l'opération la plus rentable d'un solveur : elle décide des variables sans jamais parier.
- c1(x∨¬y∨z)
- c2(¬x∨y)⇒ y = 1
- c3(¬z)⇒ z = 0
Propagation unitaire : y = 1, z = 0. Ces valeurs ne sont pas des choix, elles sont imposées.
Décider, c'est choisir une valeur sans y être forcé. C'est un pari, et il faudra peut-être le défaire.
Propager, c'est constater qu'une clause ne laisse plus qu'une possibilité. Ce n'est pas un pari : si l'affectation courante mène à un modèle, cette valeur en fait partie.
Un solveur moderne passe l'essentiel de son temps à propager. Le chapitre 7 chiffrera à quel point.
Ce qu'un solveur jette avant de commencer
Trois situations rendent une clause inutile, et tout solveur les élimine à la lecture du fichier, avant la moindre décision. Les connaître évite d'écrire des clauses qui ne servent à rien, et explique pourquoi le nombre de clauses annoncé par un solveur diffère parfois de celui du fichier.
Littéral répété. vaut . Une clause est un ensemble de littéraux, pas une liste.
Clause tautologique. Une clause qui contient à la fois et est toujours satisfaite : l'un des deux est vrai quoi qu'il arrive. Elle ne contraint rien et se supprime.
Subsomption. Si toute la clause est contenue dans la clause , alors est subsumée : satisfaire satisfait automatiquement. On garde la plus courte et l'on jette l'autre.
- c1(x∨¬x∨y)
- c2(x∨y)
- c3(x)⇒ x = 1
Propagation unitaire : x = 1. Ces valeurs ne sont pas des choix, elles sont imposées.
Le réflexe contraire est fréquent, parce qu'on associe spontanément « plus long » à « plus contraignant ». En logique propositionnelle c'est l'inverse : ajouter un littéral à une clause l'affaiblit, en lui donnant une façon de plus d'être satisfaite.
Les solveurs ne cherchent donc pas toutes les subsomptions. Ils en attrapent une partie à la lecture, et d'autres pendant la recherche sur les clauses qu'ils apprennent eux-mêmes. Le chapitre 9 y revient : le prétraitement est un compromis, pas une simplification exhaustive.
Mise en forme normale négative
Première étape de toute transformation : faire descendre les négations jusqu'aux variables.
et (De Morgan)
Une formule où toute négation porte directement sur une variable est dite en forme normale négative. Elle n'est pas encore une CNF, mais elle n'a plus que des et des à réorganiser.
Éliminer l'implication. devient , donc la formule est .
De Morgan sur le . , d'où .
Double négation. .
Résultat : , qui se lit « et sont vrais, et est faux ». C'est bien la seule façon de violer l'implication de départ, ce qui est un bon contrôle du calcul.
Sur , l'élimination du extérieur écrit deux fois le morceau , une fois dans chaque implication. Il faudra ensuite éliminer chacune de ces deux copies, et chacune se dédoublera à son tour. Une formule qui empile équivalences en produit ainsi copies après réécriture naïve.
C'est la première explosion du chapitre, et Tseitin la traitera comme les autres.
La distributivité, et son explosion
La règle qui transforme une forme normale négative en CNF tient en une ligne :
Elle est correcte, et elle préserve l'équivalence. Sur de petites formules, elle est même la bonne méthode.
devient : deux clauses, aucune variable nouvelle. Il n'y a rien de mieux à faire.
Elle compte variables et s'écrit en une ligne. Distribuer revient à choisir, dans chaque conjonction, lequel des deux littéraux on garde : il y a façons de choisir, donc clauses, chacune de littéraux.
Pour , cela fait clauses de 20 littéraux, soit une vingtaine de millions de littéraux, pour une formule de départ qui en comptait 40. Pour , aucune machine ne l'écrit.
Elle dit que la traduction est mauvaise. Un solveur ne verra jamais cette formule facile, parce qu'il aura fallu écrire un million de clauses avant de le lancer. Le coût est entièrement dans la mise en forme, et c'est exactement ce que Tseitin supprime.
La transformation de Tseitin
L'idée tient en une phrase : nommer chaque sous-formule par une variable nouvelle, et écrire ce que ce nom veut dire.
À chaque sous-formule de , on associe une variable fraîche , et l'on écrit les clauses qui traduisent en ne regardant que les fils immédiats de .
La formule finale est la conjonction de toutes ces clauses de définition, plus la clause unitaire qui impose que la racine soit vraie.
Ces clauses ne s'apprennent pas, elles se retrouvent. Un est une double implication, et il suffit d'écrire les deux sens séparément.
Prenons .
Premier sens, . Si le nom est vrai, la sous-formule l'est, donc est vrai et aussi. Cela fait deux implications, et , qui s'écrivent et .
Second sens, . Si la sous-formule est vraie, le nom l'est. En éliminant l'implication : , et De Morgan donne .
Trois clauses, et aucune n'a été mémorisée. Le même raisonnement, avec les rôles du et et du ou échangés, donne les autres lignes du tableau.
| Ce qu'on définit | Clauses |
|---|---|
| , | |
| , , | |
| , , | |
| , , |
Voici la formule vue comme un arbre. Chaque nœud interne va recevoir un nom.
Nommer les sous-formules. pour , pour , pour .
Écrire les définitions.
donne , , .
donne , , .
donne , , .
Imposer la racine. La clause unitaire .
Dix clauses, six variables. La figure ci-dessous les montre sous l'affectation , : la propagation reconstitue toute seule puis , ce qui est bien le comportement attendu d'une définition.
- c1(¬t1∨x)
- c2(¬t1∨y)
- c3(t1∨¬x∨¬y)⇒ t1 = 1
- c4(¬t2∨¬x)⇒ t2 = 0
- c5(¬t2∨z)
- c6(t2∨x∨¬z)
- c7(¬t3∨t1∨t2)
- c8(t3∨¬t1)
- c9(t3∨¬t2)
- c10(t3)⇒ t3 = 1
Propagation unitaire : t1 = 1, t2 = 0, t3 = 1. Ces valeurs ne sont pas des choix, elles sont imposées.
L'équivalence est perdue. La formule obtenue parle de variables que la formule de départ ne connaît pas. Elles ne peuvent pas avoir les mêmes modèles, ne serait-ce que parce qu'elles ne portent pas sur le même ensemble de variables.
L'équisatisfiabilité est conservée. Tout modèle de la formule de départ s'étend en un modèle de la formule transformée, en donnant à chaque la valeur de sa sous-formule. Réciproquement, tout modèle de la transformée, restreint aux variables d'origine, est un modèle de la formule de départ.
Le fichier, en entier
Numérotons dans l'ordre où les variables apparaissent : , , , , , . Voici ce qui part vraiment au solveur.
| 1 | c (x et y) ou (non x et z), apres Tseitin |
| 2 | c x=1 y=2 t1=3 z=4 t2=5 t3=6 |
| 3 | p cnf 6 10 |
| 4 | -3 10 |
| 5 | -3 20 |
| 6 | 3 -1 -20 |
| 7 | -5 -10 |
| 8 | -5 40 |
| 9 | 5 1 -40 |
| 10 | -6 3 50 |
| 11 | 6 -30 |
| 12 | 6 -50 |
| 13 | 60 |
Le faire écrire par un programme
Personne n'applique Tseitin à la main sur une formule réelle. Trente lignes suffisent, et elles montrent que la transformation est purement mécanique.
La taille reste linéaire, quelle que soit l'imbrication. La dernière boucle empile dix niveaux de « ou » et de « et » les uns dans les autres, et produit une soixantaine de clauses. La distributivité, sur la même formule, aurait explosé. C'est la propriété centrale de Tseitin, mesurée plutôt qu'affirmée.
Un solveur bien employé sait d'ailleurs le faire seul, et les formats de modélisation modernes conservent la correspondance pour ne pas rendre à l'utilisateur des noms qu'il n'a jamais écrits.
On obtient environ deux fois moins de clauses, et l'équisatisfiabilité tient toujours. Le prix se paie ailleurs : n'est plus égal à sa sous-formule, seulement lié à elle, ce qui interdit la transformation pour le comptage de modèles du chapitre 10. Une optimisation correcte pour une question, fausse pour une autre.
Le format DIMACS
C'est le format d'échange universel, compris par tous les solveurs depuis trente ans. Il est volontairement stupide.
Les variables sont des entiers strictement positifs. Un littéral négatif s'écrit avec un signe moins.
Une ligne d'en-tête p cnf <variables> <clauses> annonce les tailles.
Chaque clause tient sur une ligne et se termine par un zéro.
Une ligne commençant par c est un commentaire.
| 1 | c la formule (x1 ∨ ¬x2) ∧ (¬x1 ∨ x3) ∧ (x2 ∨ ¬x3) |
| 2 | p cnf 3 3 |
| 3 | 1 -20 |
| 4 | -1 30 |
| 5 | 2 -30 |
Oublier le zéro de la dernière clause est la faute d'écriture la plus fréquente, et elle se manifeste par une clause silencieusement fusionnée avec la suivante.
1.Une clause DIMACS s'écrit « 1 -2 3 ». Que manque-t-il ?
2.Après une transformation de Tseitin, le solveur rend un modèle où t1 = 1. Que faut-il en faire ?
3.Pourquoi préférer Tseitin à la distributivité ?
Exercices type
Mettre en forme normale conjonctive, par distributivité
Éliminer les implications, de l'extérieur vers l'intérieur :
De Morgan : , d'où .
Distribuer : .
Deux clauses. Contrôle rapide : avec les deux clauses sont satisfaites, ce qui est correct puisqu'une implication de conclusion vraie est vraie.
Combien de clauses produit Tseitin sur ?
Vingt conjonctions, chacune définie par 3 clauses : 60 clauses.
Les vingt noms obtenus sont réunis par un ou. En binarisant, dix-neuf disjonctions à 3 clauses chacune : 57 clauses. En traitant le ou comme une seule disjonction de vingt arguments, ce que font les implémentations réelles : une clause et vingt clauses , soit 21 clauses.
Plus la clause unitaire de la racine. Soit 82 clauses dans la seconde variante, contre par distributivité.
Le rapport est de l'ordre de treize mille, et il double à chaque conjonction ajoutée.
Écrire les clauses de , le ou exclusif
Quatre clauses, une par ligne de la table de vérité qu'il faut interdire :
: si est vrai, et ne peuvent pas être faux tous les deux.
: ni vrais tous les deux.
: si est vrai et faux, alors doit être vrai.
: symétriquement.
Le ou exclusif coûte donc quatre clauses là où le et et le ou en coûtent trois, et surtout ses clauses comptent trois littéraux au lieu de deux. Ce détail explique en partie pourquoi les instances issues de la cryptographie, saturées de ou exclusifs, résistent si bien aux solveurs.
Deux formules équisatisfiables sont-elles toujours équivalentes ?
Non, et un contre-exemple d'une ligne suffit.
et sont toutes deux satisfiables, donc équisatisfiables. Elles ne sont pas équivalentes : l'affectation satisfait la première et pas la seconde.
De même, et sont équisatisfiables, toutes deux insatisfiables, sans partager la moindre variable.
L'équisatisfiabilité ne compare que la réponse à la question SAT. C'est une relation beaucoup plus grossière que l'équivalence, et c'est précisément ce qui la rend utile.
Écrire en DIMACS la formule
Numéroter d'abord les variables : , , .
| 1 | c (a ∨ ¬b) ∧ (¬a) ∧ (b ∨ c) |
| 2 | p cnf 3 3 |
| 3 | 1 -20 |
| 4 | -10 |
| 5 | 2 30 |
L'en-tête annonce 3 variables et 3 clauses. Noter la deuxième clause, réduite à un seul littéral : c'est une clause unitaire, et elle impose avant même que le solveur ait commencé à chercher.
La méthode
- Éliminer les équivalences, puis les implications, dans cet ordre.
- Faire descendre les négations jusqu'aux variables par De Morgan.
- Compter les au-dessus des avant de distribuer : c'est ce qui décide de l'explosion.
- Distribuer seulement si la formule est petite et peu imbriquée.
- Appliquer Tseitin dans tous les autres cas, en nommant chaque connecteur.
- Ne jamais oublier la clause unitaire de la racine : sans elle, la formule est trivialement satisfiable.
- Restreindre le modèle rendu aux variables d'origine avant de le lire.
Synthèse
- Un littéral est une variable ou sa négation ; une clause est une disjonction de littéraux.
- Une CNF est une conjonction de clauses : tout à l'extérieur, au moins un à l'intérieur.
- La clause vide est fausse, la formule vide est vraie.
- La CNF est la forme d'entrée des solveurs parce qu'elle rend l'échec et la déduction locaux.
- Une clause dont tous les littéraux sauf un sont faux force ce dernier : c'est la propagation unitaire.
- , et les lois de De Morgan font descendre les négations.
- La distributivité préserve l'équivalence, et peut produire clauses.
- Tseitin nomme chaque sous-formule et produit au plus clauses pour connecteurs.
- Tseitin préserve l'équisatisfiabilité, pas l'équivalence : les variables fraîches l'interdisent.
- Une clause qui contient et est tautologique et se supprime ; une clause subsumée par une plus courte aussi.
- Ajouter un littéral à une clause l'affaiblit : la plus courte est la plus forte.
- DIMACS : variables entières positives, littéral négatif signé, clause terminée par un zéro.