Cet article est orphelin. Moins de trois articles lui sont liés (mai 2020).
[[Forme normale négative décomposable]]
En logique propositionnelle, dans le cadre de la compilation de connaissance, une fonction booléenne est passée d'un langage de représentation standard (par exemple une représentation CNF) vers un langage cible plus adapté pour répondre aux futures requêtes sur la fonction[1]. Les circuits booléens en forme normale négative décomposable — plus succinctement DNNF, de l'anglais Decomposable Negation Normal Form — constituent un de ces langages cibles. Toute fonction booléenne a au moins un circuit DNNF qui lui est équivalent. Les circuits DNNF sont parmi les représentations les plus compactes des fonctions qui permettent de réaliser des tests de cohérence (ou satisfaisabilité) en temps polynomial en la taille du circuit, en contre-partie de tels circuits sont souvent plus larges que les représentations standards de la fonctions, et par un facteur exponentiel.
Les circuits considérés ont un nombre fini d'entrées et une seule sortie booléenne. Les entrées sont des variables booléennes ou des constantes vrai (notée 1 {\displaystyle 1} ) ou faux (notée 0 {\displaystyle 0} ). On désigne par v a r ( C ) {\displaystyle var(C)} l'ensemble des variables en entrée du circuit C {\displaystyle C} . La taille de C {\displaystyle C} , notée | C | {\displaystyle \vert C\vert } , est le nombre de ses connexions entre portes. Un circuit sur n {\displaystyle n} variables est associé à une fonction booléenne f : { 0 , 1 } n → { 0 , 1 } {\displaystyle f:\{0,1\}^{n}\rightarrow \{0,1\}} dont les modèles (les affectations de variables pour lesquelles la fonction vaut 1 {\displaystyle 1} ) sont exactement les affectations de variables pour lesquelles la sortie du circuit est mise à 1 {\displaystyle 1} (vrai). Par extension on appelle également ces affectations des modèles du circuit, on utilise C − 1 ( 1 ) {\displaystyle C^{-1}(1)} pour désigner l'ensemble des modèles de C {\displaystyle C} .
Les portes utilisées par les circuits sous forme normal négative, ou NNF (de l'anglais Negation Normal Form), sont
Il n'y a pas de limite sur l'arité en sortie de ces portes. Il n'y a pas de limite sur l'arité en entrée des portes ET et OU.
Un circuit C {\displaystyle C} est sous forme NNF[1] si
Régulièrement on étend les entrées des circuits aux variables booléennes ( x {\displaystyle x} ) et à leurs compléments ( ¬ x {\displaystyle \neg x} ), de sorte qu'il n'y a plus de portes NEG dans les circuits NNF.
Une porte ET est décomposable si les sous-circuits branchés en entrée agissent sur des ensembles distincts de variables. Formellement, les circuits C 1 , C 2 , . . . , C m {\displaystyle C_{1},C_{2},...,C_{m}} branchés sur les entrées d'une porte ET décomposable vérifient v a r ( C i ) ∩ v a r ( C j ) = ∅ {\displaystyle var(C_{i})\cap var(C_{j})=\emptyset } pour tout i ≠ j {\displaystyle i\neq j} , autrement dit si la variable x {\displaystyle x} ou son complément est une entrée de C i {\displaystyle C_{i}} , alors ni x {\displaystyle x} ni ¬ x {\displaystyle \neg x} n'est une entrée C j {\displaystyle C_{j}} . Un circuit NNF décomposable, ou DNNF[2] (de l'anglais Decomposable Negation Normal Form) est un circuit NNF dont toutes les portes ET sont décomposables.
Certaines représentations de fonctions booléennes sont désignés comme des formules, par exemple des formules DNF ou CNF, en général on évite d'employer ce terme pour les NNF. Une formule booléenne désigne un circuit booléen dont chaque porte ne peut être l'entrée que d'une seule autre porte[3] (l'arité en sortie des portes est au plus 1). Cette condition est toujours remplie par les circuits CNF et DNF de sorte que les appellations « formules CNF » et « formules DNF » sont correctes. Cependant les NNF, et a fortiori les DNNF, ne requièrent pas de limite sur l'arité en sortie des portes, il est donc préférable de les désigner comme des circuits booléens.
Par définition, les DNNF forment une sous-classe des NNF, ce que l'on notera
Les DNNF englobent d'autres classes importantes de circuits, notamment les DNF (Disjunctive Normal Form, ou en français : Forme Normale Disjonctive) et certains types de BDD (Binary Decision Diagram, ou en français : Diagramme de Décision Binaires).
Les DNF sont des DNNF à condition d'être cohérentes : c'est-à-dire qu'aucun terme ne contient à la fois une variable x {\displaystyle x} et son complément ¬ x {\displaystyle \neg x} . Chaque terme cohérent d'une DNF forme une porte ET décomposable, les DNF sont donc des DNNF à deux étages : un premier étage de portes ET correspondant aux différents termes de la DNF, et un second étage composé d'une unique porte OU sur laquelle les portes ET des termes sont branchées en entrée.
Les diagrammes de décision binaires (BDD) ont une traduction NNF naturelle. Une méthode pour l'obtenir consiste à convertir les nœuds de décision de la BDD en circuits NNF comme indiqué sur la figure. Quand on atteint les nœuds terminaux 0 {\displaystyle 0} et 1 {\displaystyle 1} , ceux-ci sont transformés en entrées constantes 0 {\displaystyle 0} ou 1 {\displaystyle 1} . Comme le graphe orienté d'une BDD est acyclique et qu'aucune porte NEG n'est introduite dans la procédure sauf sur des entrées booléennes, le circuit obtenu est sous forme NNF. Si dans le cas représenté sur la figure, x {\displaystyle x} n'appartient ni à v a r ( C 0 ) {\displaystyle var(C_{0})} ni à v a r ( C 1 ) {\displaystyle var(C_{1})} alors le circuit pour ce nœud de décision est une DNNF.
On obtient donc des DNNF quand les BDD sont telles que chaque variable apparaît au plus une fois par chemin. Ces BDD forment la classe des FBDD[1],[4] (Free Binary Decision Diagram). Par souci de simplicité on considère directement les FBDD comme une sous-classe des DNNF. Une sous-classe importante des FBDD sont les OBDD[1],[4] (Ordered Binary Decision Diagram), pour lesquels l'ordre d'apparition des variables est le même pour chaque chemin. Les OBDD forment donc aussi une sous-classe de DNNF.
Différents circuits représentant une même fonction booléenne sont comparés selon leur taille (nombre de connexions entre portes). Soit deux classes des circuits L {\displaystyle {\mathcal {L}}} et L ′ {\displaystyle {\mathcal {L}}'} permettant de représenter n'importe quelle fonction booléenne, on dit que L {\displaystyle {\mathcal {L}}} permet des représentations plus compactes que L ′ {\displaystyle {\mathcal {L}}'} (noté L ⪯ L ′ {\displaystyle {\mathcal {L}}\preceq {\mathcal {L}}'} ) quand il existe une polynôme réel p {\displaystyle p} tel que pour chaque circuit C ′ ∈ L ′ {\displaystyle C'\in {\mathcal {L}}'} il existe un circuit équivalent C ∈ L {\displaystyle C\in {\mathcal {L}}} vérifiant | C ′ | ≤ p ( | C | ) {\displaystyle \vert C'\vert \leq p(\vert C\vert )} . La relation ⪯ {\displaystyle \preceq } est transitive. Il est clair que si L ′ ⊂ L {\displaystyle {\mathcal {L}}'\subset {\mathcal {L}}} , alors L ⪯ L ′ {\displaystyle {\mathcal {L}}\preceq {\mathcal {L}}'} , puisque chaque C ′ {\displaystyle C'} dans L ′ {\displaystyle {\mathcal {L}}'} appartient aussi à L {\displaystyle {\mathcal {L}}} et que donc la définition précédente s'applique avec p {\displaystyle p} le polynôme identité.On note L ≺ L ′ {\displaystyle {\mathcal {L}}\prec {\mathcal {L}}'} quand L ⪯ L ′ {\displaystyle {\mathcal {L}}\preceq {\mathcal {L}}'} mais que la relation inverse est fausse. C'est-à-dire que L ′ ⋠ L {\displaystyle {\mathcal {L}}'\npreceq {\mathcal {L}}} : il existe une famille F {\displaystyle {\mathcal {F}}} (nécessairement infinie) de circuits dans L {\displaystyle {\mathcal {L}}} et une fonction f {\displaystyle f} super-polynomiale (i.e., tout polynôme réel est dans o ( f ) {\displaystyle o(f)} , typiquement f ( n ) = Ω ( 2 n ) {\displaystyle f(n)=\Omega (2^{n})} ou f ( n ) = Ω ( n log n ) {\displaystyle f(n)=\Omega (n^{\log {n}})} ) telles que pour tout C ∈ F {\displaystyle C\in {\mathcal {F}}} et C ′ ∈ L ′ {\displaystyle C'\in {\mathcal {L}}'} équivalent à C {\displaystyle C} , on a | C ′ | ≥ f ( | C | ) {\displaystyle \vert C'\vert \geq f(\vert C\vert )} . Les relations de compacités entre les DNNF et les classes de circuits précédemment décrites sont strictes[1] :
Les OBDD formant une sous-classe de FBDD, on a aussi OBDD ≺ DNNF {\displaystyle {\textsf {OBDD}}\prec {\textsf {DNNF}}} par transitivité.
Le choix d'une classe de circuits pour représenter une fonction booléenne dépend des requêtes auxquelles la fonction sera sujette. Les requêtes peuvent être des problèmes de décision (par exemple déterminer si la fonction a un modèle) ou des tâches plus constructives (par exemple retourner la liste des modèles de la fonction). On dit que l'on satisfait une requête pour une classe de circuits L {\displaystyle {\mathcal {L}}} quand il existe un algorithme qui prend en entrée (entre autres) un circuit C {\displaystyle C} de L {\displaystyle {\mathcal {L}}} et retourne le résultat de la requête sur C {\displaystyle C} en temps polynomial.Certaines requêtes sont systématiquement étudiées en compilation de connaissance[1],[5]. Ces requêtes sont décrites dans le tableau suivant. Leur faisabilité pour la classe des DNNF est indiquée par un symbole en fin de ligne :
Tester l'existence d'un modèle n'est en général pas réalisable en temps polynomial pour n'importe quel circuit NNF[1]. Dans le cas des circuits DNNF, la décomposabilité des portes ET ( ∧ {\displaystyle \wedge } ) rend le test faisable en temps polynomial[2].
Soit g {\displaystyle g} une porte ET décomposable g = C 1 ∧ ⋯ ∧ C m {\displaystyle g=C_{1}\wedge \dots \wedge C_{m}} . Supposons pour tout i {\displaystyle i} , le sous-circuit C i {\displaystyle C_{i}} retourne vrai pour une affectation a i {\displaystyle a_{i}} des variables de v a r ( C i ) {\displaystyle var(C_{i})} . Par décomposabilité les ensembles v a r ( C 1 ) , … , v a r ( C m ) {\displaystyle var(C_{1}),\dots ,var(C_{m})} sont deux-à-deux disjoints, donc il ressort que a = a 1 ∧ ⋯ ∧ a m {\displaystyle a=a_{1}\wedge \dots \wedge a_{m}} est une affectation cohérente des variables de v a r ( g ) {\displaystyle var(g)} — c'est-à-dire que a {\displaystyle a} affecte une et une seule valeur à chaque variable de v a r ( g ) {\displaystyle var(g)} — et a {\displaystyle a} est clairement un modèle de g {\displaystyle g} . Ainsi un circuit dont la racine est une porte ET décomposable admet un modèle si et seulement si tous les sous-circuits en entrée admettent un modèle, cette condition est nécessaire mais en général pas suffisante pour les portes ET non décomposables.
Un algorithme possible, que l'on note A CO {\displaystyle A_{\textbf {CO}}} , pour tester l'existence de modèles d'une DNNF C {\displaystyle C} fonctionne récursivement selon le protocole suivant :
Chaque porte du circuit génère au plus autant d'appels récursifs que son arité en entrée, donc le nombre d'appels récursifs est en O ( | C | ) {\displaystyle O(\vert C\vert )} et A CO ( C ) {\displaystyle A_{\textbf {CO}}(C)} s'exécute en temps polynomial en | C | {\displaystyle \vert C\vert } .
Étant donné une clause γ = l 1 ∧ ⋯ ∧ l n {\displaystyle \gamma =l_{1}\wedge \dots \wedge l_{n}} sur les variables v a r ( γ ) = { x 1 , … , x n } {\displaystyle var(\gamma )=\{x_{1},\dots ,x_{n}\}} où chaque l i {\displaystyle l_{i}} représente x i {\displaystyle x_{i}} ou ¬ x i {\displaystyle \neg x_{i}} , on peut associer le terme ¬ γ {\displaystyle \neg \gamma } à une affectation des variables de v a r ( γ ) {\displaystyle var(\gamma )} (c'est l'unique modèle de ¬ γ {\displaystyle \neg \gamma } sur v a r ( γ ) {\displaystyle var(\gamma )} ).
Soit C {\displaystyle C} un circuit sur un sur-ensemble de v a r ( γ ) {\displaystyle var(\gamma )} . On désigne par C | ( ¬ γ ) {\displaystyle C\vert (\neg \gamma )} le circuit obtenu en remplaçant les variables d'entrée appartenant à v a r ( γ ) {\displaystyle var(\gamma )} par leur affectation ( 0 {\displaystyle 0} ou 1 {\displaystyle 1} ) dans ¬ γ {\displaystyle \neg \gamma } . On dit que l'on a conditionné C {\displaystyle C} sur ¬ γ {\displaystyle \neg \gamma } . Si C {\displaystyle C} est une DNNF, affecter des valeurs à certaines variables d'entrée n'impacte pas la décomposabilité des portes ET, donc C | ( ¬ γ ) {\displaystyle C\vert (\neg \gamma )} est encore une DNNF dont la taille n'est pas supérieure à celle de C {\displaystyle C} .
C {\displaystyle C} implique γ {\displaystyle \gamma } (noté C ⊨ γ {\displaystyle C\models \gamma } ) si et seulement si C ≡ C ∧ γ {\displaystyle C\equiv C\wedge \gamma } . Après conditionnement sur ¬ γ {\displaystyle \neg \gamma } des deux côtés, on obtient que C ⊨ γ {\displaystyle C\models \gamma } si C | ( ¬ γ ) ≡ 0 {\displaystyle C\vert (\neg \gamma )\equiv 0} . Donc pour tester C ⊨ γ {\displaystyle C\models \gamma } on peut simplement vérifier que C | ( ¬ γ ) {\displaystyle C\vert (\neg \gamma )} n'a pas de modèle. Si C {\displaystyle C} est une DNNF, un algorithme A CE {\displaystyle A_{\textbf {CE}}} pour le test de clause impliquée se réduit à un appel à A CO {\displaystyle A_{\textbf {CO}}} : A CE ( C , γ ) {\displaystyle A_{\textbf {CE}}(C,\gamma )} retourne vrai si et seulement si A CO ( C | ( ¬ γ ) ) {\displaystyle A_{\textbf {CO}}(C\vert (\neg \gamma ))} retourne faux. A CO ( C | ( ¬ γ ) ) {\displaystyle A_{\textbf {CO}}(C\vert (\neg \gamma ))} s'exécute en temps polynomial en la taille de C | ( ¬ γ ) {\displaystyle C\vert (\neg \gamma )} , laquelle est inférieure à | C | {\displaystyle \vert C\vert } , donc A CE ( C , γ ) {\displaystyle A_{\textbf {CE}}(C,\gamma )} s'exécute en temps polynomial en | C | {\displaystyle \vert C\vert } .
On veut énumérer tous les modèles d'un circuit C {\displaystyle C} sous forme DNNF. On peut déjà tester l'existence de modèles avec le test de cohérence sur C {\displaystyle C} . Par la suite si on détecte que C {\displaystyle C} a des modèles, on construit un arbre à n + 1 {\displaystyle n+1} niveaux dont chaque feuille (ici un nœud de niveau n {\displaystyle n} , la racine étant le niveau 0 {\displaystyle 0} ) correspond à un modèle du circuit[1]. Les nœuds de l'arbre de niveau i {\displaystyle i} correspondent à des affectations de variables sur { x 1 , … , x i } {\displaystyle \{x_{1},\dots ,x_{i}\}} (par convention vide pour la racine, qui est le niveau 0 {\displaystyle 0} ). La construction commence depuis la racine et suit la règle suivante : tant qu'il existe un nœud de niveau i < n {\displaystyle i<n} sans fils, soit a i {\displaystyle a_{i}} l'affectation de variables correspondante :
À noter qu'au moins un des deux tests réussi puisqu'on sait que le circuit de départ a des modèles. La construction prend fin quand tous les chemins sont de taille n {\displaystyle n} , les modèles de C {\displaystyle C} sont alors les affectations de variables correspondant aux feuilles.
Les circuits conditionnés C | ( a i ∧ x i + 1 ) {\displaystyle C\vert (a_{i}\wedge x_{i+1})} sont des DNNF de taille inférieure à | C | {\displaystyle \vert C\vert } donc tester l'existence de modèles se fait en temps polynomial avec A CO {\displaystyle A_{\textbf {CO}}} . En tout, l'algorithme fait O ( n | C − 1 ( 1 ) | ) {\displaystyle O(n\vert C^{-1}(1)\vert )} tests, d'où son temps d'exécution polynomial en | C | {\displaystyle \vert C\vert } et | C − 1 ( 1 ) | {\displaystyle \vert C^{-1}(1)\vert } .