Pourquoi n'est-il pas simple de compter le nombre de mots dans une langue régulière?

8

Étant donné un DFA, A, soit L (A) le nombre de mots que A accepte. Je pense qu'il est facile de calculer L (A): Traduisez l'encodage de A en une expression régulière. Si l'étoile Kleene apparaît n'importe où dans l'expression - le langage est infini. Sinon: Parcourez et comptez toutes les combinaisons de mots qu'il est possible de faire en utilisant l'expression (en gros, s'il y a un opérateur + sur l'expression, multipliez la quantité de mots légaux par la quantité de chaînes connectées par le + ..)

Est-ce mal? Merci d'avance

user67573
la source
3
ε n'est pas une langue infinie.
David Richerby

Réponses:

12

Oui, c'est faux, à cause de l'ambiguïté.

Considérez le langage suivant: .(a+aa)+a(a+ϵ)

Avec votre méthode, nous voyons 4 mots, . Mais nous avons des doublons! Il existe plusieurs façons de créer le même mot dans l'expression régulière donnée.a,aa,aa,a

Une meilleure méthode consiste à utiliser la programmation dynamique sur un DFA minimal pour votre langue, sans état "mort". Si le DFA minimal est cyclique, le langage est infini, nous pouvons donc supposer qu'il n'y a pas de cycle. L'utilisation d'un DFA est essentielle, car le déterminisme signifie qu'il y a exactement un chemin à travers le DFA pour chaque mot.

Ce que vous faites est de créer une récurrence pour le nombre de mots qui se terminent à un état donné:

  • 1 mot se termine à l'état de départ:ϵ
  • Pour chaque état , le nombre de mots se terminant là est la somme du nombre de mots se terminant à chaque état avec une transition en .qq

Le nombre total de mots est alors la somme du nombre de mots se terminant à chaque état final.

jmite
la source
2
Il convient de noter que ces récurrences peuvent toujours être résolues par l'algèbre informatique, par exemple pour les fonctions de génération. Alors oui, le langage ordinaire est en fait facile à compter.
Raphael
9

En complément de la réponse de jmite, il n'est pas trop difficile de calculer le nombre de mots dans une langue régulière, en utilisant la méthode de la «matrice de transfert». C'est la même chose que la programmation dynamique de jmite, mais la technique a d'autres applications telles que l'énumération asymptotique.

Étant donné un DFA, construisez une matrice (où est l'ensemble des états) dans laquelle est le nombre de lettres qui font que le DFA passe de l'état à l'état . Soit et les indicateurs de l'état initial et des états accepteurs, respectivement. Enfin, soit.Q×QMQM(i,j)ji1q01Fn=|Q|

Le nombre de mots de longueur est . Calculez pour . Si alors la langue acceptée par le DFA est infinie. Sinon, le nombre de mots dans la langue est .mcm:=1FMm1q0cm0m<2ncn++c2n1>0c0++cn1

(Lors du calcul des puissances de , il faut faire attention à la magnitude des entrées, qui est exponentielle en . Comme leur taille n'est que polynomiale, l'algorithme résultant s'exécute en temps polynomial.)Mm

Yuval Filmus
la source
2
J'adore cette approche. J'ai également constaté que le calcul des valeurs propres deMcorrespondent en fait aux racines du dénominateur dans l'approche de la fonction génératrice, et que, sans surprise, ces valeurs propres sont invariantes à la minimisation DFA. Cependant, je n'ai absolument aucune idée de la façon d'interpréter correctement cela.
Lee
1
Ce n'est pas si surprenant, étant donné que la fonction de génération est P(z)=n=01FMn1q0zn, ce qui simplifie P(z)=1F(IzM)11q0. Vous pouvez obtenir un résultat encore plus explicite en refaisant ce calcul en utilisant le formulaire Jordan deM, qui présente les valeurs propres.
Yuval Filmus
7

En fait, vous pouvez toujours dériver des formules de comptage pour des expressions régulières non ambiguës avec des étoiles Kleene à l'intérieur.

Étant donné la définition inductive d'une expression régulière comme:

eRe:=xΣe0 e1e0+e1e

Considérez la traduction suivante [[]]:ReC(z) qui prend une expression régulière et la traduit en une fonction rationnelle à valeurs complexes:

[[xΣ]]=z[[e0 e1]]=[[e0]]×[[e1]][[e0+e1]]=[[e0]]+[[e1]][[e]]=11[[e]]

Nous pouvons montrer que cette traduction renvoie une expression rationnelle en faisant une induction structurelle sur e, et notant que toutes les opérations utilisées à droite préservent la rationalité.

Supposons que l'expression régulière e que nous mettons est sans ambiguïté, alors nous trouverions que la fonction rationnelle dénotée par [[e]]C(z) est en fait la fonction génératrice de la famille de mots qui est acceptée par la langue sous-jacente e, classés selon leur longueur.

Par exemple, considérez la langue (ab), qui définit la langue des exécutions de a délimité par b. Maintenant, cette expression régulière est sans ambiguïté, nous pouvons donc exécuter notre astuce de traduction:

[[(ab)]]=11[[ab]]=11([[a]]×[[b]])=11(11[[a]]×z)=11z1z=12+124z

Il s'avère que, compte tenu de la fonction génératrice ci-dessus, son coefficient d'extraction sera

[zn][[(ab)]]=2n1+δ(n)2
δ(n)={1if n=00otherwise

En fait, depuis notre traduction [[]] génère des fonctions rationnelles, nous pouvons utiliser une décomposition de fraction partielle pour créer une formule d'énumération pour toute expression régulière non ambiguë.

Supposons que vous ayez une fonction rationnelle irréductible

r(z)+p(z)q(z)
r,p,q sont des polynômes, alors vous pouvez les décomposer en
r(z)+C0zq0++Cnzqn
qk sont les racines de q(z). Il y a un peu de cas d'angle techniques (comme la multiplicité des racines, etc.), mais il est relativement facile de faire une extraction de coefficient sur l'expression ci-dessus:
[zn]Czq=C×qn

En fait, la décomposition partielle de fraction se généralise en fonctions rationnelles multivariées, vous pouvez donc réellement construire des formules de comptage pour des requêtes telles que "Combien de mots y a-t-il là où il y en a?" n ale sable m bs? "

Malheureusement, la mesure dans laquelle cette méthode sera utile se termine lorsque vous avez une expression ambiguë.

Lee
la source