listes et suites finies

51
9 avril 2001 Listes et Suites Finies • Représentation • Propriété • Accès aux éléments • Récursivité • Construction • Sous-suites et arbres représentatifs • Application : les analyseurs

Upload: bruis

Post on 16-Jan-2016

37 views

Category:

Documents


0 download

DESCRIPTION

Listes et Suites Finies. Représentation Propriété Accès aux éléments Récursivité Construction Sous-suites et arbres représentatifs Application : les analyseurs. Introduction. Tout au long du chapitre, utilisation d’un même exemple tiré du programme menu du TD1. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Listes et Suites Finies

9 avril 2001

Listes et Suites Finies

• Représentation

• Propriété

• Accès aux éléments

• Récursivité

• Construction

• Sous-suites et arbres représentatifs

• Application : les analyseurs

Page 2: Listes et Suites Finies

9 avril 2001

Introduction

• Tout au long du chapitre, utilisation d’un même exemple tiré du programme menu du TD1.– Avant : une règle associée à chaque élément du

menu (entrée, plat, dessert)– Maintenant : on va regrouper ces données et

considérer la suite des entrées, la suite des plats et la suite des desserts

Page 3: Listes et Suites Finies

9 avril 2001

Représentation (1)

• A une suite, ordonnée ou non, on associe la liste de ses éléments.– Utilisation du symbole fonctionnel binaire « . »

• suite {e1, e2, …} ==> liste (e1.(e2.(…)))

• Exemples :– suite des variables X et Y ==> (X.Y)

– suite {gateau, fruit, glace} ==>(gateau.(fruit.glace))

Page 4: Listes et Suites Finies

9 avril 2001

Représentation (2)

– La liste vide est notée « nil ». Elle sert souvent à marquer la fin de liste.

• Il est préférable de noter la liste précédente sous la forme : (gateau.(fruit.(glace.nil)))

• Cela définit le sens du parenthésage du symbole fonctionnel « . ».

• Les listes peuvent alors être représentées sous forme d ’arbres.

Page 5: Listes et Suites Finies

9 avril 2001

Représentation (3)

• Exemples :

.

X Y

.

.

.

gateau

fruit

glace nil

Page 6: Listes et Suites Finies

9 avril 2001

Représentation (4)

– Lorsque la liste comporte un trop grand nombre d'éléments, on admet le codage sans parenthèses

• Exemples :– X.Y

– gateau.fruit.glace.nil

Page 7: Listes et Suites Finies

9 avril 2001

Propriété fondamentale (1)

• Jusqu’à présent : arbres particuliers avec des branches gauches sans ramification.– On utilise le terme de peigne pour les désigner.

• Exercice : – résoudre l'équation X.Y = gateau.fruit.glace.nil– par identification on a la solution :

• {X = gateau; Y = fruit.glace.nil}

Page 8: Listes et Suites Finies

9 avril 2001

Propriété fondamentale (2)

• La notation X.Y représente une liste dont la tête (le 1er élément) est X et la queue (le reste de la liste) est Y.

• Cela constitue la base de l’utilisation des listes dans les programmes Prolog.

• Attention : considérez la liste X.Y. Si Y ne se termine pas par nil, on ne connaît pas le type de Y (élément si pas de nil à la fin, liste si nil à la fin), d’où l'intérêt de nil pour s’assurer que Y est une liste.

Page 9: Listes et Suites Finies

9 avril 2001

Propriété fondamentale (3)

• Exemple du programme menu :entrees(sardine.pate.melon.avocat.nil).

viandes(poulet.roti.steack.nil).

poissons(merlan.colin.loup.nil).

desserts(gateau.fruit.glace.nil).

• Et si on pose la question : entrees(E).

• L’effacement de ce but (synonyme de question) provoque l’affectation suivante :

E=sardine.pate.melon.avocat.nil

Page 10: Listes et Suites Finies

9 avril 2001

Propriété fondamentale (4)

– Nous savons donc affecter une liste à une variable.

– Nous avons aussi besoin de pouvoir considérer les éléments d’une liste de façon individuelle, par exemple pour récupérer une entrée particulière.

• Supposons que l’on dispose du prédicat :

element-de(X, L) capable d’extraire un objet X d’un peigne L.

Page 11: Listes et Suites Finies

9 avril 2001

Propriété fondamentale (5)

– Nous avions :menu(X, Y, Z) :- entree(X), plat(Y), dessert(Z).

plat(X) :- viande(X).

plat(X) :- poisson(X).

• Avec la nouvelle déclaration commune des entrées comme liste, ce programme échouera. Il faut donc le modifier. Pour cela nous allons construire une nouvelle définition du prédicat entree (ne pas confondre avec le prédicat entrees).

Page 12: Listes et Suites Finies

9 avril 2001

Propriété fondamentale (6)

• On utilise la propriété suivante : si X est une entrée, alors X est un élément quelconque de la liste des entrées. On peut donc écrire :

entree(X) :- entrees(E), element-de(X, E).

• Et de façon analogue :viande(X) :- viandes(V), element-de(X, V).

poisson(X) :- poissons(P), element-de(X, P).

dessert(X) :- desserts(D), element-de(X, D).

Page 13: Listes et Suites Finies

9 avril 2001

Accès aux éléments d’une liste(1)

• Il s’agit de rechercher les règles qui vont assurer le fonctionnement du prédicat element-de(X, L) qui signifie que X est l’un des éléments de L.

• Méthode de base mais trop particulière : X est élément de L si X est le premier élément, ou le deuxième, … ou le dernier. Cela nécessite la connaissance de la longueur de la liste.

Page 14: Listes et Suites Finies

9 avril 2001

Accès aux éléments d’une liste(2)• Autre méthode indépendante de la taille de L : on

utilise la remarque selon laquelle toute liste peut se décomposer simplement en deux parties, la tête et la queue de liste. Cela conduit à distinguer deux cas :

* X est élément de L si X est la tête de L.

* X est élément de L si X est élément de la queue de L.

• Ce qui se traduit directement en Prolog par :– R1 : element-de(X, L) :- est-tete(X, L).

– R2 : element-de(X, L) :- element-de-la-queue(X,L).

– R1 et R2 sont là en tant que repères et ne rentrent pas dans les règles.

Page 15: Listes et Suites Finies

9 avril 2001

Accès aux éléments d’une liste(3)

• Mais on peut aller plus loin car L peut toujours être représentée sous la forme U.Y, ce qui nous donne :

– Si X est en tête de U.Y alors X = U.

– Si X est un élément de la queue de U.Y alors X est élément de Y.

• D’où la version finale :– R1 : element-de(X, X.Y).

– R2 : element-de(X, U.Y) :- X\=U, element-de(X, Y).

Page 16: Listes et Suites Finies

9 avril 2001

Accès aux éléments d’une liste(4)

• Commentaires :– On interprète ces deux règles de la façon suivante :

* R1 : X est élément de toute liste qui commence par X.

* R2 : X est élément de toute liste dont la queue est Y, si X est élément de Y.

– Le second membre de R2 provoque un nouvel appel à R1 et R2. Il s’agit donc d’un appel récursif. La plupart des problèmes sur les listes ont des solutions mettant en jeu la récursivité.

Page 17: Listes et Suites Finies

9 avril 2001

Récursivité (1)

• On observe deux types de règles et deux types d'arrêt :

• Une ou plusieurs règles provoquent la récursivité, généralement sur des données assez simples, et assurent le déroulement de la boucle. Dans notre exemple, il s’agit de la règle R2.

• Une ou plusieurs règles stoppent la boucle. Dans notre exemple, c’est R1 qui s’en charge.

• Sauf impératif contraire, les règles d'arrêt sont placées en tête.

Page 18: Listes et Suites Finies

9 avril 2001

Récursivité (2)

• Conseils pour l’écriture de programmes récursifs :

• Chaque règle doit être, sautant que possible, conçue comme une déclaration ou une définition, indépendamment de toute forme d'exécution.

• L’ordre des règles peut être déterminé par l'exécution du programme (et pas seulement pour les parties récursives du programme).

Page 19: Listes et Suites Finies

9 avril 2001

Récursivité (3)

• Il apparaît deux types d'arrêt :• Un arrêt explicite. Par exemple, dans R1, l'identité

entre l'élément cherché et la tête de la liste fournie, ce qu’exprime la notation X et X.Y.

• Un arrêt implicite. En particulier par la rencontre d’un terme impossible à effacer.

• Il existe cependant une forme d’erreur pour laquelle ces deux blocages se révèlent insuffisants, c’est la rencontre de listes infinies.

Page 20: Listes et Suites Finies

9 avril 2001

Construction d’une liste (1)

• Nous avons vu comment parcourir une liste.

• Nous allons voir comment en construire une.– Examinons le problème suivant : L une liste

contenant un nombre pair d'éléments.– Par exemple : L = 0.1.2.3.4.5.nil

– Cherchons à construire une nouvelle liste W en prenant les éléments de rang impair dans L.

Page 21: Listes et Suites Finies

9 avril 2001

Construction d’une liste (2)

– Dans notre exemple cela donnerait :– W = 0.2.4.nil

– Nous disposons de deux outils : le découpage d’une liste et la récursivité. Méthode à suivre :

– Création d’un appel récursif.

– Modification des règles pour obtenir le résultat désiré.

elements-impairs(L) :- queue(L, Y), queue(Y, Y1),

elements-impairs(Y1).

Page 22: Listes et Suites Finies

9 avril 2001

Construction d’une liste (3)

– On a L = X1.Y ce qui nous donne :

elements-impairs(X1.Y) :- queue(X1.Y, Y),

queue(Y, Y1), elements-impairs(Y1).

– La première condition est alors inutile. De plus la décomposition de L peut etre repetee avec Y = X2.Y1. On a donc :

elements-impairs(X1.X2.Y1) :- elements-impairs(Y1).– Nous avons donc notre règle récursive. Il reste à trouver la

règle d'arrêt. Il faut s'arrêter à la liste vide :

elements-impairs(nil).

Page 23: Listes et Suites Finies

9 avril 2001

Construction d’une liste (4)– D’où le programme :

R1 : elements-impairs(nil).

R2 : elements-impairs(U.V.Y) :- elements-impairs(Y).

– Il reste à modifier le programme de façon à construire la nouvelle liste à partir du parcours de l’ancienne. D’où le programme final :

R1 : elements-impairs(nil, nil).

R2 : elements-impairs(U.V.Y, U.M) :- elements-impairs(Y, M).

Page 24: Listes et Suites Finies

9 avril 2001

Construction d’une liste (5)

– Interprétation de ces deux règles : • R1 : prendre un élément sur deux dans la liste vide

donne la liste vide

• R2 : prendre un élément sur deux dans la liste U.V.Y donne la liste U.M si prendre un élément sur deux dans la liste Y donne la liste M.

– Remarque : les éléments dans la liste résultat sont rangés dans le même ordre que dans la liste initiale.

Page 25: Listes et Suites Finies

9 avril 2001

Construction d’une liste (6)

• Construction d’une liste au moyen d’une liste auxiliaire :– Problème : soit D une liste donnée, R est la liste

D inversée. On est dans une situation différente la précédente à cause de l’ordre inverse des éléments. Nous allons donc utiliser une liste auxiliaire pour ranger les éléments au fur et à mesure de leur lecture en attendant de pouvoir les utiliser.

Page 26: Listes et Suites Finies

9 avril 2001

Construction d’une liste (7)

– Boucle de récursivité :renverser(D) :- tete(X, D), queue(Y, D), renverser(Y).

• Comme précédemment, on remplace D par X.Y ce qui donne :

renverser(X.Y) :- renverser(Y).

renverser(nil).

– Nous allons maintenant ajouter deux arguments à ces règles, la liste auxiliaire et la liste résultat R.

Page 27: Listes et Suites Finies

9 avril 2001

Construction d’une liste (8)– On obtient les règles suivantes :

R2 : renverser(D, L, R) :- renverser(Y, X.L, R).

R1 : renverser(nil, L, R) :- transformer(L, R).

– Il faut déterminer la transformation à effectuer sur L pour obtenir R.

• Au lancement L est vide.

• Chaque fois qu’un élément apparaît en tête de D, il est retiré et placé en tête de L. Il y a donc inversion de l’ordre des éléments donc L et R sont identiques. Il n’y a pas de transformation à effectuer.

Page 28: Listes et Suites Finies

9 avril 2001

Construction d’une liste (9)

– Le programme final est donc :R1 : renverser(nil, L, L).

R2 : renverser(X.Y, L, R) :- renverser(Y, X.L, R).

– Interprétation de ces deux règles :• Renverser la liste vide, à partir de la liste auxiliaire

L, donne la liste résultat L.

• Renverser la liste X.Y, à partir de la liste auxiliaire L, donne la liste résultat R, si renverser la liste Y, à partir de la liste auxiliaire X.L, donne la même liste R.

Page 29: Listes et Suites Finies

9 avril 2001

Construction d’une liste (10)

– Exercice classique : concaténation de deux listes

• Plusieurs possibilités :– récursivité

– découpage de la liste

– construction directe

– utilisation d ’une liste auxiliaire

– passage final de paramètre (méthode précédente)

Page 30: Listes et Suites Finies

9 avril 2001

Listes et sous-suites (1)

• Utilisation du programme menu :• Volonté de poursuivre le regroupement des données.

• Liste unique qui regrouperait tous les mets du menu» L= sardine.melon…glace.nil

• Cette représentation n’est pas adéquate car il n’y a pas de distinction entre entrée, plat ou dessert.

• Il est donc nécessaire de découper la liste en sous-listes qui rassembleront les entrées, plats et desserts. La sous-liste des plats sera elle-même divisée en deux parties, les viandes et les poissons.

Page 31: Listes et Suites Finies

9 avril 2001

Listes et sous-suites (2)

• Cela nous donne la structure :

L = (sardines.pate.melon.celeri.nil).((poulet.roti.steack.nil).(merlan.colin.loup.nil)).(gateau.fruit.glace.nil).nil

L est de la forme : L = L1.L2.L3.nil

• Exercices : – Construire l’arbre associé à la liste L.

– Résoudre les équations : L=X.Y, L=X.Y.Z, L=X.Y.Z.T, L=X.(U.V).Y, L=(X.Y).Z, L=X.((U.V).Y).Z, L=X.(U.V).Y.Z

Page 32: Listes et Suites Finies

9 avril 2001

Application : les analyseurs (1)

• Voici deux exemples de grammaires :• G1 = {S --> c ; S --> aSb}

• G2 = {S --> AB ; A --> 0A ; A --> 0 ; B --> 1B ;

B --> 1}

• Exercice : écrire des mots de ces deux grammaires.

• Exercice : G1 étant donné, construire un analyseur reconnaissant les mots de L(G1). On fournira au programme une chaîne sous forme de liste, par exemple : ``a ``.``a``.``c``.``b``.``b``.nil

Page 33: Listes et Suites Finies

9 avril 2001

Application : les analyseurs (2)

• Approche naturelle :• Les règles du programme doivent définir la structure

des mots de L(G1). Elles doivent donc rendre compte des règles de G1.

• S --> c s ’exprime sans difficulté : une chaîne est dérivable de S si cette chaîne se réduit à ``c``.nil, soit :

– R1 : derivable-de-S(X) :- se-reduit-a(``c``.nil, X).

se-reduit-a signifie simplement que X est la chaîne ``c``.nil

Page 34: Listes et Suites Finies

9 avril 2001

Application : les analyseurs (3)• S --> aSb est plus difficile à traduire.

– Il nous faut dire que la chaîne d'entrée X se décompose en trois parties U, V, W, avec les caractéristiques suivantes: U est le caractère ``a``, V est une chaîne qui dérive de S, et W est le caractère ``b``. La concaténation de U, V et W doit redonner X.

– Problème : on ne sait que concaténer les chaînes et non les caractères seuls. Il faut donc modifier U et W en ``a``.nil et ``b``.nil. On peut alors écrire :

» R2 : derivable-de-S(X) :- se-reduit-a(``a``.nil, U), derivable-de-S(V), se-reduit-a(``b``, W), concatener(U, V, Y), concatener(Y, W, X).

Page 35: Listes et Suites Finies

9 avril 2001

Application : les analyseurs (4)• On peut alors remplacer U et W par leur valeur, ce

qui donne :– R1 : derivable-de-S(``c``.nil).

– R2 : derivable-de-S(X) :- derivable-de-S(V), concatener(``a``.nil, V, Y), concatener(Y,``b``.nil, X).

• Concaténer ``a``.nil à la liste V donne la liste ``a``.V, on peut donc substituer ``a``.V à Y. d’où la version finale :

– R1 : derivable-de-S(``c``.nil).

– R2 : derivable-de-S(X) :- derivable-de-S(V), concatener(``a``.V,``b``.nil, X).

Page 36: Listes et Suites Finies

9 avril 2001

Application : les analyseurs (5)

– Interprétation :• R1 : la chaîne ``c``.nil est dérivable de l’axiome

• R2 : la chaîne X est dérivable de l’axiome, si elle est la concaténation de la chaîne ``a``.nil, d ’une chaîne V dérivable de l’axiome, et de la chaîne ``b``.nil.

• Problème de la concaténation : peut être très coûteuse et cause de boucle infinie. Ici il y a un problème avec une boucle infinie. Il faut donc corriger le programme.

Page 37: Listes et Suites Finies

9 avril 2001

Application : les analyseurs (6)• L'exécution doit s'arrêter lorsque l’application de R1

conduit à une valeur correcte de X. On va donc modifier R1 :

– R1 : derivable-de-S(``c``.nil) :- /.

• Mais d’une part il vaut mieux éviter d’utiliser un cut, et d’autre part le programme obtenu ne fonctionne pas en synthèse.

• A retenir : la plupart des programmes qui demandent une concaténation dans une boucle de récursivité sont très lents à l'exécution.

Page 38: Listes et Suites Finies

9 avril 2001

Application : les analyseurs (7)

• Autre approche : approche par les graphes.• On peut considérer que le mot aacbb se caractérise

par cinq transitions successives entre six états. On a alors le schéma suivant (qui est un graphe orienté à six nœuds) :

1 2 3 4 5 6a a c b b

Page 39: Listes et Suites Finies

9 avril 2001

Application : les analyseurs (8)

• La chaîne à analyser prend une forme complexe : une suite de flèches étiquetées, entre des numéros de nœuds du graphe. Le plus simple pour spécifier cette chaîne est d’utiliser un ensemble d’assertions :

fleche(``a``, 1, 2).

fleche(``a``, 2, 3).

fleche(``c``, 3, 4).

fleche(``b``, 4, 5).

fleche(``b``, 5, 6).

Page 40: Listes et Suites Finies

9 avril 2001

Application : les analyseurs (9)• Nous allons maintenant caractériser chacune des

règles de la grammaire G1 par un graphe. Cela donne en Prolog :

R1 : fleche(``S``, i, j) :- fleche(``c``, i, j).

R2 : fleche(``S``, i, m) :- fleche(``a``, i, j), fleche(``S``, j, k), fleche(``b``, k, m).

• Amélioration du programme :– Pour un nœud du graphe, au lieu d’un numéro, on peut

utiliser la chaîne d'entrée elle-même. On désignera chaque nœud par la chaîne de caractères qui le suivent.

Page 41: Listes et Suites Finies

9 avril 2001

Application : les analyseurs (10)

• On a donc :

1 <=> ``a``.``a``.``c``.``b``.``b``.nil

2 <=> ``a``.``c``.``b``.``b``.nil

3 <=> ``c``.``b``.``b``.nil

4 <=> ``b``.``b``.nil

5 <=> ``b``.nil

6 <=> nil

Page 42: Listes et Suites Finies

9 avril 2001

Application : les analyseurs (11)

• On constate que deux nœuds successifs ne diffèrent que par un seul élément, et si le nœud numéro i <=> X.U, alors le nœud numéro i+1 <=>U. La différence entre les deux listes X.U et U est l'élément X qui étiquette la flèche entre les deux nœuds. On obtient donc :

R1 : fleche(``S``, ``c``.U, U) :- fleche(``c``, ``c``.U, U).

R2 : fleche(``S``, ``a``.U, V) :- fleche(``a``, ``a``.U, U), fleche(``S``, U, W), fleche(``b``, W, V).

Page 43: Listes et Suites Finies

9 avril 2001

Application : les analyseurs (12)

• On peut remarquer que W = ``b``.V ce qui donne :R2 : fleche(``S``, ``a``.U, V) :- fleche(``a``, ``a``.U, U),

fleche(``S``, U, ``b``.V), fleche(``b``, ``b``.V, V).

• fleche(``a``, ``a``.U, U) signifie qu’il doit exister une flèche étiquetée ``a`` entre les nœuds ``a``.U et U, ce qui est toujours vrai. On a donc le programme suivant :

R1 : fleche(``S``, ``c``.U, U).

R2 : fleche(``S``, ``a``.U, V) :- fleche(``S``, U, ``b``.V).

Page 44: Listes et Suites Finies

9 avril 2001

Application : les analyseurs (13)

• Il ne reste que les termes relatifs aux non-terminaux, qui interviennent de façon explicite, et non sous-forme de variable. C’est-à-dire que toutes les règles relatives au non-terminal N contiendront le caractère ``N`` comme premier argument, qui sert en quelque sorte à identifier la règle. On peut donc écrire :

R1 : fleche-S(``c``.U, U).

R2 : fleche-S(``a``.U, V) :- fleche-S(U, ``b``.V).

Page 45: Listes et Suites Finies

9 avril 2001

Application : les analyseurs (14)

• Ou puisque nous devons reconnaître des mots :R1 : mot(``c``.U, U).

R2 : mot(``a``.U, V) :- mot(U, ``b``.V).

• Interprétation 1: Au non-terminal S, nous avons fait correspondre l’identificateur mot d’un terme à deux arguments. Le premier est la liste des caractères de la chaîne, avant la reconnaissance du non-terminal, le second est la liste des caractères de la chaîne restante lorsque le non-terminal a été identifié.

Page 46: Listes et Suites Finies

9 avril 2001

Application : les analyseurs (15)

• On appelle aussi ces deux arguments « liste d'entrée » et « liste de sortie ». On en tire l'interprétation suivante :

– R1 : Avec la liste d'entrée ``c``.U on reconnaît un mot et il reste la liste de sortie U.

– R2 : Avec la liste d'entrée ``a``.U on reconnaît un mot et il reste la liste V, si on reconnaît un mot avec la liste d'entrée U et la liste de sortie ``b``.V.

Page 47: Listes et Suites Finies

9 avril 2001

Application : les analyseurs (16)

• Interprétation 2 : on peut aussi considérer que le non-terminal reconnu représente la différence entre la liste d'entrée et la liste de sortie. D’où une nouvelle façon d'interpréter les règles :

– R1 : on reconnaît un mot par différence entre les deux listes ``c``.U et U.

– R2 : on reconnaît un mot par différence entre les deux listes ``a``.U et V, si on reconnaît un mot par différence entre les deux listes U et ``b``.V.

Page 48: Listes et Suites Finies

9 avril 2001

Application : les analyseurs (17)

• Déroulement du programme :• (1) En analyse : la liste d'entrée est constituée de la

chaîne entière, et, lorsque cette chaîne aura été reconnue, la liste de sortie sera vide. Il faut donc lancer le programme par :

mot(``a``.``a``.``c``.``b``.``b``.nil, nil).

– On obtient la liste d’effacements :

mot(``a``.``c``.``b``.``b``.nil, ``b``.nil).

mot(``c``.``b``.``b``.nil, ``b``.``b``.nil).

fin

Page 49: Listes et Suites Finies

9 avril 2001

Application : les analyseurs (18)• (2) En synthèse : la chaîne d'entrée est inconnue, et

on veut la liste vide en sortie. Il faut donc donner comme but :

mot(X, nil).

– (a) R1 s’applique et donne {x=``c``.U1 ; U1 = nil} d’où la première réponse {X = ``c``.nil}

– (b) Remontée en (a) R2 s’applique, donne {X = ``a``.U1 ; V1 = nil} et laisse à effacer mot(U1, ``b``.nil).

– ( c ) R1 s’applique, donne {U1 = ``c``.U2 ; U2 = ``b``.nil} d’où la deuxième réponse {X = ``a``.``c``.``b``.nil}

– Par remontée en ( c ) on construira la troisième réponse, etc.

Page 50: Listes et Suites Finies

9 avril 2001

Application : les analyseurs (19)

• Conclusion : La construction de l’analyseur est quasiment automatique.

• Une règle Prolog par règle de la grammaire.

• Un terme par non-terminal.

• Pour chaque terme, deux arguments de la forme :– X.U et U pour une règle qui dérive un terminal X.

– X.Y.Z.U et V pour les terminaux X, Y, Z placés en tête du second membre.

– U et M.N.P.V pour les terminaux placés entre deux non-terminaux (ou à la fin de la règle).

Page 51: Listes et Suites Finies

9 avril 2001

Application : les analyseurs (20)

• Exercice : écrire l’analyseur associé à G2.mot(U, V) :- nonterminal-A(U, W),

nonterminal-B(W, V).

nonterminal-A(0.U, U).

nonterminal-A(0.U, V) :- nonterminal-A(U, V).

nonterminal-B(1.U, U).

nonterminal-B(1.U, V) :- nonterminal-B(U, V).