Pour une heuristique efficace, je suggère de consulter la littérature CAO sur le problème de codage d'état (attribution d'identificateurs binaires aux états d'un DFA pour minimiser la quantité de logique pour la fonction de transition d'état.) Devadas et Newton, "Décomposition et factorisation du fini séquentiel machines d'état ", IEEE TCAD , 8 (11): 1206-1217, 1989 souligne qu'il existe une relation étroite entre le codage d'état et la décomposition de la machine d'état.
Si pour un DFA avec N indique que vous attribuez un unique M identifiant d'état de bit pour chaque état (lg2N<M≤N), vous avez alors essentiellement décomposé le DFA en un réseau de Mmachines à deux états en interaction. De manière équivalente: vous avez défini un ensembleS avec M et attribué un sous-ensemble unique de Sà chaque état dans votre DFA d'origine. C'est aussi ce que fait l' algorithme de construction du jeu de puissance Rabin-Scott . Donc, en faisant un codage d'état sur le DFA, nous essayons de désosser l'ensemble à partir duquel l'algorithme de construction du jeu de puissance est parti.
Dans le problème de codage d'état traditionnel, tous les codages sont légaux et il existe une fonction objective (liée à la quantité de logique dans la fonction de transition d'état) que vous essayez de minimiser. Pour générer un NFA, vous devez résoudre une version contrainte du problème entrant où:
un encodage de Mles identificateurs de bits vers les états DFA représentent un NFA ssi pour chaque symbole de l'alphabet, la fonction de transition pour chaque bit est une simple disjonction de bits. (Aucune conjonction ou négation n'est autorisée.)
Vous pouvez donc énumérer tous les M encodages de bits pour tous lg2N<M≤Net vérifiez si chacun satisfait à la contrainte. (Notez que pourM=N l'encodage trivial "one-hot" satisfait toujours les contraintes et vous donne le DFA.) L'énumération est cependant ridiculement grande (le manuel de Di Micheli le donne comme quelque chose comme 2M!(2M−N)!M!.) La raison pour laquelle je suggère la littérature CAD est qu'il existe des techniques pour effectuer cette recherche implicitement plutôt que d'énumérer (par exemple, en utilisant des BDD, voir Lin, Touati et Newton, "Don't care minimisation of multi-level sequential. réseaux logiques, " Int'l Conf Comp-Aided Dsgn ICCAD-90: 414-417, 1990 .
Exemple
Prenez le DFA suivant, (avec un codage d'état que j'ai dérivé en trichant (j'ai généré le DFA à partir d'un NFA en utilisant Rabin-Scott, et le codage représente les sous-ensembles choisis par Rabin-Scott.))
Si nous appelons les bits dans l'affectation d'état ABCD, alors lorsque le symbole d'entrée est 1, la fonction de transition est A = A, B = A, C = B, D = C. Lorsque le symbole d'entrée est 0, la fonction de transition est A = A, C = B, D = C. Il s'agit d'une fonction de transition purement disjonctive sans conjonction ni négation, donc ce codage d'état nous donne un NFA. Les états dans le NFA correspondent un à un avec les bits du codage, et la fonction de transition est la suivante:
Formulation comme problème de satisfiabilité booléenne
La description informelle ci-dessus conduit directement à un codage comme un problème de satisfiabilité booléenne. Il existe un ensemble de variables qui décrit les transitions dans le NFA, et un ensemble de variables pour le codage d'état DFA qui serait dérivé de Rabin-Scott pour le NFA choisi. Les transitions du DFA spécifique que vous essayez de décomposer sont utilisées pour placer des contraintes sur les transitions NFA.
Supposons que l'on nous donne un DFA avec N états pour une langue avec S symboles, et nous aimerions en tirer un M état NFA, avec lg2N<M≤N. Nous utiliserons les variablesysft pour représenter les transitions possibles dans la NFA. ysftsera vrai si il y a une transition dans le NFA de l' état NFAf à l' état NFAtsur le symbole s. Dans l'exemple ci-dessus NFA, l'alphabet est de taille 2 et il y a 4 états NFA, donc il y aSM2=32 y variables et y0AA,y1AA, et y1AB sont tous vrais tout en y1DA c'est faux.
Nous utiliserons les variables xdn pour indiquer si l'algorithme Rabin-Scott doit inclure l'état NFA n dans l'ensemble des états étiquetant l'état DFA d. Dans l'exemple ci-dessus, nous avonsN=8 États DFA et M=4 NFA déclare donc il y a 32 xvariables. Dans l'exemple ci-dessus, supposons que l'état le plus bas (celui intitulé "1011") soit l'étatk, puis xkA, xkC, et xkD sont vrais tout xkB c'est faux.
Maintenant les contraintes. Tout d'abord, Rabin-Scott doit trouver un codage différent pour chaque état DFA, donc pour les états DFAi<j et tous les états NFA {A,B,⋯,D}:
(xiA≠xjA)+(xiB≠xjB)+⋯+(xiD≠xjD).
Ensuite, il doit être le cas que si Rabin-Scott a trouvé une transition de l'état DFA i à l'état DFA j sur le symbole s puis pour chaque état NFA k inclus dans le codage de j il doit y avoir un état NFA l de l'encodage de l'état DFA j de telle sorte que la NFA d'origine avait une transition de l à k. Dans l'exemple ci-dessus, sur le symbole "1" il y a une transition DFA de l'état DFA "1000" à l'état DFA "1100" donc il doit y avoir une transition NFA de l'état NFA A aux états NFA A et B et aucune transition NFA de NFA l'état A à l'état NFA C ou D. Donc, pour chacun deso(SN2) bords dans le DFA, nous avons les contraintes:
xjAxjBxjD===ysAAxiA+ysBAxiB+⋯+ysDAxiDysABxiA+ysBBxiB+⋯+ysDBxiD⋯ysADxiA+ysBDxiB+⋯+ysDDxiD.
Enfin, nous devons gérer le début et accepter les États. L'état de démarrage DFA est codé avec l'union des états de démarrage NFA, il est donc préférable de ne pas coder l'état de démarrage DFA avec l'ensemble vide.x0A+x0B+⋯+x0D. Et enfin, nous avons besoin d'un ensemble de variablesfnpour indiquer si chaque état NFA est un état d'acceptation NFA. Il doit être le cas que le codage pour chaque état DFA accepte contient au moins un état NFA accepte et que le codage pour chaque état DFA non accepté ne contient aucun état NFA accepte donc:xiAfA+xiBfB+⋯+xiDfD pour DFA accepte les états i et ¬(xjAfA+xjBfB+⋯+xjDfD) pour les États non acceptés par DFA j.