94
Licence STS/MIPE/UE19 Informatique GEN Une initiation au génie logiciel Version 2.1 Décembre 2005 D . H ERMAN 96

D HERMAN - Freeherman.daniel.free.fr/Editions-des-noisettes-et-des-sen... · 2010. 5. 18. · de l’art de la programmation, ce n’est pas le résultat qui compte mais ce qu’on

  • Upload
    others

  • View
    0

  • Download
    0

Embed Size (px)

Citation preview

  • L i c e n c e S T S / M I P E / U E 1 9

    I n f o r m a t i q u e G E N

    U n e i n i t i a t i o n a u g é n i e l o g i c i e l

    Ve r s i o n 2 . 1

    D é c e m b r e 2 0 0 5

    D . H E R M A N

    9 6

  • Génie logiciel : buts, méthodes et outils

    Daniel HERMAN

    Objectifs

    Ce cours, qui correspond à une UE1 optionnelle proposé en seconde année d’une licence STS2. prolonge des cours d’initiation à la programmation (méthodes de programmation : ap-proche fonctionnelle, approche itérative) qui sont supposés acquis.

    Nous nous sommes donnés pour but d’initier le lecteur à une discipline couramment appelée génie logiciel, en anglais software engineering. Le terme initiation doit être retenu : le public visé n’est pas, a priori, engagé dans des études professionnelles en informatique. Il s’agit donc, en premier lieu, de faire comprendre que la production de logiciel pose des problèmes spécifiques et, par conséquent, fait appel à tout un corpus de connaissances, de méthodes et d’outils qui doivent être intégrés. En second lieu il s’agit de donner une très légère idée de ce que sont ces connaissances, méthodes et outils, sans évidemment prétendre à l’exhaustivité.

    Compte tenu de ces buts, le lecteur ne s’étonnera pas que les outils utilisés ne soient pas des outils professionnels : la mise en œuvre de tels outils est lourde et l’organisation des études au niveau L23 peu adaptée à la conduite de projet. En revanche, et c’est un des paris de ce cours, nous pensons qu’il est possible, avec des outils simples, de faire comprendre pourquoi la production de logiciel relève de l’ingénierie et non de l’artisanat.

    Organisation pratique

    D’un point de vue pratique l’enseignement comporte trois pans qui peuvent sembler quelque peu hétéroclites :

    • un projet ;

    • un enseignement de théorie des langages ;

    1. UE : Unité d'Enseignement

    2. Licence STS : licence sciences, technologies, santé

    3. Deuxième année de licence

    Licence STS/MIPE/UE19 Une initiation au génie logiciel 3

  • • un enseignement de logique.

    Il n’est pas étonnant de trouver un projet dans cette liste : nous imaginons mal de parler de génie logiciel sans un logiciel à produire. Les deux autres items peuvent surprendre, mais toute discipline d’ingénierie utilise, entre autres, des outils de modélisation qui relèvent des mathématiques. Les raisons qui nous ont poussé à mettre en avant ces domaines sont un ca-ractère bien particulier qu’ils ont en commun : il s’agit de modèles qualitatifs et non quantita-tifs. Ils jouent en outre un rôle privilégié en informatique.

    La forme prise par l’enseignement est originale, du moins au niveau L2. La base de ce cours est le projet qui représente le travail de fond pendant toutes les séances de TP et une bonne partie de celles de TD. En revanche, il ne s’agit pas de faire un logiciel de A à Z : le produit en question a été conçu et réalisé par l’équipe enseignante. L’étudiant doit donc maîtriser, com-prendre la complexité des divers modules qui lui sont fournis et sa propre production se limi-te à deux d’entre eux.

    Les deux autres sujets, qui sont donc des mathématiques, sont présentés comme des outils et le projet a été conçu pour les utiliser. Le domaine étant vaste, nous nous contentons d’en don-ner des rudiments. La théorie des langages apporte des outils nécessaire à la réalisation du se-cond module. La logique nous sert à cerner les limitations du produit livré au client.

    Remerciements

    La mise au point de cet enseignement a été, bien évidemment, un travail d’équipe. Je tiens à remercier tous ceux qui y ont participé et, en particulier Philippe INGELS sur qui repose inté-gralement le projet qui nous sert de fil conducteur et qui assume, avec son efficacité habituel-le, la charge de l’organisation induite.

    Architecture générale du polycopié

    Le cours comporte 8 chapitres, une bibliographie et une annexe ; la table des matières est à la fin de l’ouvrage.

    • CHAPITRE 1 Génie logiciel 5

    • CHAPITRE 2 Le logiciel Félin 9

    • CHAPITRE 3 Langages et grammaires 25

    • CHAPITRE 4 Automates déterministes à nombre fini d’états 41

    • CHAPITRE 5 Langages de type 3 et automates à nombre fini d’états 49

    • CHAPITRE 6 Systèmes formels 59

    • CHAPITRE 7 Calcul des propositions 65

    • CHAPITRE 8 Conclusions 85

    • CHAPITRE 9 Bibliographie 87

    • Table des matières 91

    4 Une initiation au génie logiciel Licence STS/MIPE/UE19

  • CHAPITRE 1 Génie logiciel

    1.1 Buts du cours

    Ce cours, qui vise à initier le lecteur à une discipline couramment appelée génie logiciel, comporte trois volets :

    • un projet ;

    • un enseignement de théorie des langages ;

    • un enseignement de logique.

    Malgré le caractère disparate de ces éléments, le lecteur est prié d’admettre qu’aucune des trois parties ne joue un rôle indépendant. Le projet, qui sert de toile de fond, n’est que peu abordé dans la partie magistrale de l’enseignement ; il est cependant l’élément fédérateur qui doit permettre de comprendre l’utilité des deux domaines mathématiques abordés. Ce serait une grossière erreur que de se dispenser de l’effort qu’il demande car, dans l’apprentissage de l’art de la programmation, ce n’est pas le résultat qui compte mais ce qu’on a appris en le construisant.

    1.2 Génie logiciel : les problèmes

    Parmi les messages du cours de première année il en est un qui peut être résumé par la maxi-me « un programme est un objet d’étude ».

    Un gros programme (les anglo-saxons disent programming in large) est aussi un objet d’étu-de, mais c’est également un produit industriel. D’où, des contraintes de coût, des exigences de qualité, qui impliquent des techniques et des méthodes de production, et qui posent des problèmes de gestion de production.

    Toutefois la production de logiciel présente des caractéristiques désagréables :

    • On a souvent du mal à préciser ce qu’on veut exactement faire. Cette imprécision a deux causes différentes : d’une part le client exprime mal ses besoins et, d’autre part, on a du mal à codifier ces besoins dans un document suffisamment précis pour être opérationnel.

    Licence STS/MIPE/UE19 Une initiation au génie logiciel 5

  • Génie logiciel

    • Les outils de prévision et de suivi des délais et des coûts de production sont peu fiables. La complexité de la tâche (on considère que les plus gros logiciels actuels font partie des plus grands projets jamais menés) requiert un grand nombre d’intervenants alors qu’il s’agit d’une production intellectuelle difficilement mesurable donc difficilement partageable.

    • La maîtrise de la qualité relève souvent de la profession de foi : quand on a du mal à expri-mer ce qu’on veut faire il n’est pas étonnant d’avoir du mal à savoir si ce qu’on a fait con-vient. En outre, il y a quelque théorèmes tout à fait démobilisateurs ; ainsi, par exemple, on n’a aucun moyen général de déterminer l’équivalence de deux programmes suffisamment complexes.

    • La production de logiciel ne se prête que très imparfaitement à la taylorisation : quand on a fabriqué le premier exemplaire d’un logiciel la production des suivants a un coût à peu près nul (les délinquants qui piratent des logiciels abusent de cette propriété). On se re-trouve finalement dans une situation qui ressemble assez au problème de la conception de prototypes. On peut comprendre facilement que le coût du prototype de la prochaine Re-nault est sans commune mesure avec celui de la production d’une Clio de plus… Dans ces conditions l’effort de rationalisation de la production se porte sur la réutilisation de com-posants, sur le contrôle de la qualité.

    • Les logiciels évoluent après leur livraison au client. Cette évolution est inéluctable, et ceci pour deux raisons : tout logiciel contient des erreurs (cet axiome est confirmé par l’expé-rience) mais surtout les besoins changent et ce changement nécessite des adaptations.

    1.3 Cycle de développement et cycle de vie

    Dans tout processus de production plus la détection d’une erreur est tardive plus elle coûte cher. Cette constatation s’applique évidemment au domaine des logiciels, et ceci d’autant plus que les erreurs y sont fréquentes. On décompose donc la tâche de production en diverses étapes — le cycle de développement —chaque étape étant conçue pour diminuer le risque d’erreur ultérieur. Dans un tel cycle tout retour arrière est coûteux. Le cycle que nous présen-tons est idéal (sans retour arrière). Dans la pratique les choses sont souvent plus complexes.

    Notre cycle simple comprend les étapes suivantes :

    1. Spécifications2. Conception préliminaire

    3. Conception détaillée4. Codage5. Test unitaire

    6. Intégration7. Validation

    SpécificationsLe résultat de cette étape est une mise en forme du cahier des charges. Cette mise en forme (qui utilise parfois des langages adaptés) vise à être opérationnelle pour la suite : on doit pou-voir l’utiliser pour vérifier que les objectifs sont atteints mais aussi pour réaliser les étapes suivantes.

    Pour se faire une idée, on peut admettre que donner le type d’une fonction et indiquer ce que doit être son résultat en fonction de ses paramètres est une spécification. Toutefois, les spéci-fications fonctionnelles trouvent vite leurs limites (entrées/sorties…).

    Conception préliminaireEn utilisant les spécifications on isole les grandes fonctions du logiciel et on les spécifie à leur tour. A ce stade, des choix stratégiques ont été faits sur lesquels il sera difficile de reve-

    6 Une initiation au génie logiciel Licence STS/MIPE/UE19

  • Outils, techniques et méthodes

    nir. En revanche, les étapes ultérieures se prêtent à des travaux menés en parallèle par des équipes différentes.

    Conception détailléeOn itère le processus précédent sur chacune des fonctions issues de l’étapes précédente jus-qu’à obtention d’un ensemble de fonctions raisonnablement programmables. Les interfaces entre toutes ces fonctions doivent évidemment être précises et détaillées pour que leurs pro-grammations soient indépendantes.

    CodageLe codage est la phase de programmation proprement dite.

    Test unitaireChaque fonction ou, souvent, chaque module (un module est un ensemble de fonctions ayant des liens mutuels) est alors mis au point indépendamment des autres. Pour ce faire, on est amené à construire des environnements de test. On notera qu’il n’est pas du tout obligatoire que les phases de codage et de test unitaire soient faits par les mêmes personnes.

    IntégrationLes modules sont intégrés progressivement et il faut admettre que, malheureusement, on dé-couvre des erreurs à ce stade.

    ValidationOn applique à ce stade des procédures visant à établir la conformité du produit avec ses spé-cifications, avant livraison au client.

    Le cycle que nous venons de présenter est le cycle de développement. Pour des raisons évo-quées plus haut (maintenance, évolution) la vie du produit de s’arrête pas à la livraison. Pour préparer la suite on doit intervenir très tôt dans le processus d’où la notion de cycle de vie, le développement n’étant qu’une des étapes du cycle de vie.

    1.4 Outils, techniques et méthodes

    Comme tout processus de production, la production de logiciel peut être en partie automati-sée. Trois grands axes d’intervention peuvent être retenus.

    • production automatique de code ;

    • analyses statiques ;

    • gestion des ressources.

    Production automatique de codeLe simple fait d’utiliser un compilateur montre que la production du code machine est en par-tie automatisée. On peut aller plus loin et imaginer des traducteurs de spécifications en code exécutable. Sans être aussi ambitieux, de nombreux problèmes restreints peuvent être expri-més à l’aide de langages adéquats et traduits de manière systématique, voire automatique. Nous utilisons dans ce cours de tels procédés.

    La production automatique ne se limite pas au code et on peut imaginer une production de documentation, d’outils de maintenance…

    Licence STS/MIPE/UE19 Une initiation au génie logiciel 7

  • Génie logiciel

    Analyses statiquesLe contrôle de type effectué par un compilateur est un exemple d’analyse automatique per-mettant de découvrir des erreurs. On peut imaginer des extensions au niveau d’un projet : co-hérences mutuelles des modules, conformité partielle aux spécifications…

    Gestion des ressourcesOn peut imaginer des programmes d’aide à la gestion des diverses ressources, humaines, ma-térielles et logicielles d’un projet : gestion de bases de programmes réutilisables, suivi des coûts, évaluation de la complexité, outils de communication…

    Ces divers axes d’intervention ont un point commun : il supposent l’usage d’outils mathéma-tiques particuliers qui relèvent, pour la plupart, des mathématiques discrètes :

    • logique

    • théorie des langages

    • combinatoire

    • recherche opérationnelle

    • …

    1.5 Suite du cours

    Il n’est évidemment pas possible, en Deug, de faire une étude raisonnable de tous les points évoqués dans les paragraphes qui précèdent. Pour ce qui concerne le développement du pro-jet, celui-ci commence à l’issue de la phase de conception détaillée : l’architecture complète du logiciel est définie et tous les modules sont spécifiés. On demande donc aux étudiants une participation aux phases de codage, test unitaire et intégration pour deux des modules. Les autres sont fournis. On ne s’étonnera pas du fait que le source1 des programmes utilisés ne soit pas accessible : il s’agit de conditions tout à fait réalistes pour un travail normal. Le coda-ge du premier module permet d’appréhender le travail d’intégration dans une architecture complexe. Pour le codage du second, nous utilisons un outil automatique de production de code (production d’un analyseur lexical à partir d’une grammaire régulière décorée d’actions sémantiques).

    1. On appelle code source, ou plus simplement source, le texte des programmes avant compilation.

    8 Une initiation au génie logiciel Licence STS/MIPE/UE19

  • CHAPITRE 2 Le logiciel Félin

    2.1 Introduction aux systèmes experts

    2.1.1 GénéralitésUn système expert est un logiciel qui vise à offrir à ses utilisateurs les deux fonctionnalités suivantes:

    • modéliser un sous-ensemble du monde réel,

    • obtenir, par déduction, des informations sur ce sous-ensemble.

    Les domaines d’application de ce type de produit sont divers : finance, économie, médecine, maintenance…

    Il n’est évidemment pas raisonnable d’écrire un logiciel adéquat pour chaque problème rencontré :

    • L’investissement pour une application particulière serait trop lourd et, par conséquent, ce type de produit moins répandu.

    • L’évolutivité du produit serait problématique.

    Ce qui a assuré le succès des systèmes experts c’est l’apparition de méta-outils, les moteurs d’inférences. Un moteur d’inférence est capable d’effectuer des déductions à partir d’une connaissance qui lui est explicitement fournie (la connaissance est externe au moteur), ce qu’on peut résumer par la formule :

    moteur d’inférences + connaissance = système expert

    Licence STS/MIPE/UE19 Une initiation au génie logiciel 9

  • Le logiciel Félin

    On distingue donc deux type d’utilisateur, l’expert, qui détermine les connaissances utiles au moteur, et le consommateur, qui exploite le système expert.

    Les moteurs d’inférences travaillent en général sur une description du monde faite à l’aide de faits et de règles, qui, du moins dans le cas général, comportent des inconnues. La déduction est faite en sélectionnant, en fonction de l’état de travail et de la base de faits, une des règles applicables ; l’application de cette règle modifie l’état de travail, d’où le cycle de base:

    répéter déterminer les règles applicables choisir une des règles applicables répercuter les modifications associées

    finrépéter

    Le choix, parmi les règles applicables, de la règle à appliquer, est d’une grande importance pour les performances du moteur d’inférences. En effet, on peut voir l’algorithme ci-dessus comme un algorithme non déterministe (au niveau du choix) et une implantation exhaustive de ce choix a toutes les chances d’être intolérable au niveau du temps de réponse si la con-naissance est complexe. Pour cette raison, les bons moteurs permettent au moins de sélec-tionner une stratégie de choix parmi plusieurs possibles. Dans les bons cas, diverses stratégies peuvent être définies par l’expert lui-même.

    Pour illustrer le fonctionnement d’un moteur d’inférences, nous prenons, dans ce chapitre, un exemple simple qui sert de guide aux diverses notions et techniques introduites. A la fin du cours (cf. Félin propositionnel page 82), la logique mathématique, permet de donner un sup-port conceptuel plus ferme.

    2.1.2 Description du mondeLe monde est décrit à l’aide de faits initiaux et de règles. Par exemple:

    Faits initiauxf1: tim ronronne f2: tim est familier

    Base de connaissances

    Méta-connaissances Mot

    eur

    d’in

    fére

    nces

    Saisie de la connaissance

    Saisie des connaissancessur la déduction (méta-connaissances)

    Demande d’informations

    Explications

    Exp

    ert

    Co

    nso

    mm

    ateu

    r

    10 Une initiation au génie logiciel Licence STS/MIPE/UE19

  • Introduction aux systèmes experts

    f3: tim vit à la maison f4: tim est le père de félix

    Règlesr1: si x ronronne alors x est un chat r2: si x ronronne et x est familier et x vit à la maison

    alors x est un animal domestique et x est dorloté r3: si x est un chat

    alors x est un mammifère et x a des griffes r4: si x est le père de y et x a la propriété p

    alors y a la propriété p

    LangageLe langage à l’aide duquel on exprime la connaissance comporte divers ingrédients :

    • des variables, comme x, y ou p

    • des constantes, comme tim ou félix

    • des prédicats, comme ronronne, est un chat, est le père de

    • des hypothèses, comme si x est un chat ou si x ronronne et x est familier et x vit à la mai-son

    • des conclusions comme alors x est un chat ou alors x est un mammifère et x a des griffes

    AnecdoteSelon le type des variables qu’on peut utiliser, il existe une classification des moteurs d’infé-rence.

    • Les moteurs sans variables sont de type 0.

    • Les moteurs où les variables ne désignent que des constantes sont des moteurs de type 1.

    • Les moteurs où les variables peuvent désigner des constantes et des propriétés sont des moteurs de type 2.

    TermesLes règles utilisent des énoncés comme, félix est dorloté, x est dorloté, tim est le père de félix qui ont tous la même structure : un prédicat relie plusieurs arguments qui sont des cons-tantes ou des variables. Pour pouvoir travailler sur ces énoncés nous leur donnons une struc-ture syntaxique plus rigide : dorloté(félix), dorloté(x), père(tim, félix). Ce sont des cas particuliers de ce qu’en logique on appelle des termes.

    Définition 2.1 Les termes1 sont composés d’un identificateur (la propriété) suivi, entre parenthèses, des arguments (constantes ou variables) sur lesquels elle s’applique. Les argu-ments sont séparés par des virgules.

    Définition 2.2 Un terme clos est un terme sans variable.

    Le monde étant décrit, on veut obtenir des informations, par exemple savoir si la propriété « félix est un chat » est vraie.

    Pour ce faire on distingue deux classes de méthodes, le chaînage avant et le chaînage arriè-re.

    1. Attention, cette définition est très restrictive par rapport aux termes de la logique.

    Licence STS/MIPE/UE19 Une initiation au génie logiciel 11

  • Le logiciel Félin

    2.1.3 DéductionQu’un moteur fonctionne en chaînage avant ou en chaînage arrière, chaque étape de son cal-cul consiste à utiliser une règle, c’est ce qu’on appelle faire une inférence.

    2.1.3.1 Chaînage avantA partir de faits précédemment établis, en utilisant des règles, on cherche à produire de nou-veaux faits.

    Exemples

    • f1 et r1 permettent de produire chat(tim)

    • f1, f2, f3 et r2 permettent de produire domestique(tim) et dorloté(tim)

    Pour établir une propriété P, on « construit le monde » à l’aide de déductions élémentaires comme celle de l’exemple, en itérant le procédé jusqu’à trouver P ou jusqu’à saturation (le moteur se révèle incapable de produire de nouveaux faits).

    2.1.3.2 Chaînage arrièreA partir de P (le but) on cherche une règle dont un élément de la conclusion « ressemble » à P (si on prend pour P la propriété Est-ce que félix est un chat ?, r1 est une telle règle). Les prémisses de la règle donnent alors des (sous) buts dont la démonstration suffit pour établir P. Ainsi r1 (si ronronne(x) alors chat(x)) peut s’interpréter comme « pour établir que félix est un chat il suffit d’établir que félix ronronne ».

    On itère le procédé avec les sous-buts produits jusqu’à ce qu’ils soient tous démontrés (un but est démontré lorsqu’il est un des faits du monde).

    2.1.3.3 RemarqueLorsqu’on découvre ces deux méthodes on est souvent victime d’une intuition erronée: on pense, à tort, que le chaînage avant est une méthode largement pire (au plan des performan-ces) que l’autre. Ce n’est pas le cas: les performances dépendent avant tout et du cas particu-lier et de la stratégie de sélection employée.

    2.1.3.4 InférenceUtiliser une règle (faire une inférence) consiste donc à « descendre » des hypothèses aux conclusions (chaînage avant) ou à « remonter » des conclusions aux hypothèses (chaînage ar-rière). Dans les deux cas (on remarquera qu’hypothèses et conclusions ont la même structu-re) il faut déterminer si la règle est applicable. Nous illustrons le procédé dans le cas du chaînage avant.

    1. Considérons l’hypothèse de la règle r2 :si ronronne(x) et familier(x) et maison(x)

    2. Si on substitue à la variable x la valeur félix, on obtient :si ronronne(félix) et familier(félix) et maison(félix)

    3. Si on a précédemment établi les faits :ronronne(félix), familier(félix), maison(félix)

    4. On peut effectuer l’inférence proprement dite qui consiste à utiliser la conclusion et la substitution pour produire les faits qui correspondent à la conclusion de r2 (domesti-que(x) et dorloté(x)) c’est à dire :

    domestique(félix), dorloté(félix)

    2.1.3.5 FiltragePour présenter plus formellement ces notions nous introduisons les notions de termes, substi-tution et filtrage.

    12 Une initiation au génie logiciel Licence STS/MIPE/UE19

  • Produit Félin : cahier des charges

    Définition 2.3 Une substitution est un ensemble de couples .

    Ainsi S = {, } est une substitution.

    Définition 2.4 Le résultat de l’application d’une substitution S à un terme T est un terme TS obtenu en remplaçant dans T les variables par les termes qui leurs sont associés dans S.

    L’application de S à dorloté(x) donne dorloté(tim), de S à domestique(y) donne domesti-que(félix).

    Définition 2.5 Filtrer 1 un ensemble de termes H sur une base de termes clos B c’est cal-culer une substitution qui, appliquée à tous les termes de H, ne produit que des termes B.

    ExempleB = {ronronne(tim), ronronne(félix), familier(tim), maison(tim)}

    H1 = {ronronne(x), familier(x), maison(x)}

    H2 = {ronronne(y), familier(x), maison(x)}

    On peut filtrer H1 sur B ; on obtient alors S = {x = tim}. On peut filtrer H2 sur B ; ce filtrage peut donner deux résultats, S1 = {x = tim, y = tim} et S2 = {x = tim, y = félix}.

    Dans le cadre dans lequel nous nous plaçons, le travail du moteur consiste donc à faire évo-luer un ensemble de termes clos (l’état de travail) et l’opération élémentaire qui modifie l’état de travail est ce qu’on appelle une inférence.

    Définition 2.6 Effectuer une inférence consiste à filtrer une des deux parties d’une règle sur l’état du travail et à modifier cet état en exploitant le résultat de l’application de la substi-tution obtenue sur l’autre partie de la règle.

    2.2 Produit Félin : cahier des charges

    2.2.1 Présentation généraleLe logiciel Félin permet d’effectuer certains raisonnements sur un ensemble de connaissan-ces préalablement décrit. Il offre les outils permettant à la fois de saisir les connaissances ini-tiales du domaine, de spécifier les règles de déductions utilisables, d’indiquer les raisonnements à effectuer.

    Une interface avec l’utilisateur permet d’enchaîner ces diverses activités, on peut saisir des faits connus, des règles, demander des déductions, puis rajouter des faits ou des règles, etc...

    2.2.2 Enoncé des faits initiauxLes faits, connaissances établies, sont des propriétés portant sur des objets. Les propriétés, comme les objets, sont désignées par des noms (identificateurs). Un fait est un terme : l’iden-tificateur de la propriété, suivi de la liste, entre parenthèses, des identificateurs des objets concernés.

    1. Lorsque les termes de B ne sont pas clos, on peut étendre le procédé : on dit alors qu’on réalise une unification, ce qui est le vocable employé dans la littérature. Le filtrage est donc un cas particulier (et simple) d’unification.

    Licence STS/MIPE/UE19 Une initiation au génie logiciel 13

  • Le logiciel Félin

    Exemples

    chat(tim) l’objet tim possède la propriété chat père(jean,jacques) Les objets jean et jacques sont liés par

    la propriété père

    Les faits de Félin sont des cas particuliers de termes clos. En effet, la notion de terme englobe des termes comme père(paul, père(jean, jacques)). On se limite donc à un niveau de paren-thésage.

    2.2.3 Enoncé des règlesLes règles de déduction permettent d’établir de nouveaux faits, à partir des faits déjà connus. Une règle énonce que, si des propriétés sont vérifiés (les hypothèses), d’autres propriétés sont également vraies (les conclusions). Comme on souhaite avoir des règles générales, ces pro-priétés peuvent porter non pas sur des objets particuliers, mais sur des variables, désignant tout objet ayant les caractéristiques requises. Un identificateur de variable commence par le caractère ?.

    Exemple

    chat(?x) ?x désigne tout objet ayant la propriété chat

    Les hypothèses et conclusions sont constituées d’une suite de propriétés, séparées par le mot réservé et, qui signifie que ces propriétés sont toutes simultanément vérifiées.

    Exemples• p(?x) et q(?x): ?x désigne tout objet ayant à la fois

    les propriétés p et q

    • ?p(félix) ?p désigne toute propriété vérifiée par félix

    • ?p(?x) ?x désigne tout objet ayant une propriété quelconque ?p

    Une règle peut porter un nom, les parties hypothèses et conclusions sont introduites par les mots réservés si et alors, la règle se termine par le mot réservé fsi. Une règle à donc une des deux formes suivantes :

    • nom : si alors fsi

    • si alors fsi

    Exemple

    r2: si ronronne(?x) et familier(?x) et maison(?x) alors domestique(?x) et dorloté(?x) fsi

    On apporte toutefois une limitation sur les variables utilisées dans les conclusions : elles doi-vent impérativement apparaître dans la partie hypothèses.

    2.2.4 DéductionsA partir de faits initiaux et de règles on peut demander deux types de déductions :

    • On peut obtenir toutes les propriétés démontrables à partir des faits initiaux, en utilisant les règles données (saturer).

    14 Une initiation au génie logiciel Licence STS/MIPE/UE19

  • Produit Félin : cahier des charges

    • On peut demander si une propriété particulière peut être démontrée, à partir des faits ini-tiaux, en utilisant les règles données (démontrer).

    2.2.5 Principales limitations de Félin

    2.2.5.1 Caractère syntaxique des propriétésLes propriétés de Félin n’ont pas de sens particulier et Félin les traite dans chercher à les in-terpréter. Pour illustrer ce propos nous utilisons un exemple.

    ExempleFaits initiaux :père(tim, félix), père(tim, jules)

    Règle : si père(?x, ?y) et père(?x, ?z) alors frère(?y, ?z) et frère(?z, ?y) fsi

    La saturation donne les résultats suivants :

    père(tim, félix), père(tim, jules), frère(félix, félix), frère(jules, jules), frère(félix, jules), frère(jules, félix)

    On pourrait souhaiter changer la règle pour avoir un résultat plus réaliste. Cependant, si on opte pour la règle :

    Règle : si père(?x, ?y) et père(?x, ?z) et différent(?y, ?z) alors frère(?y, ?z) et frère(?z, ?y) fsi

    la saturation délivre :

    père(tim, félix), père(tim, jules)

    car aucun filtrage ne donne de résultat. Félin est donc incapable d’interpréter le prédicat dif-férent (ce qui n’est pas étonnant).

    Il existe des moteurs qui reconnaissent et interprètent correctement quelques propriétés pré-définies, mais ce n’est pas le cas de Félin.

    Remarquons qu’on peut toutefois tourner la difficulté en donnant une connaissance plus éla-borée.

    ExempleFaits initiaux :père(tim, félix), père(tim, jules),

    différent(félix, jules), différent(félix, tim), différent(tim, jules)

    Règle : si père(?x, ?y) et père(?x, ?z) et différent(?y, ?z) alors frère(?y, ?z) et frère(?z, ?y) fsi,

    si différent(?x, ?y) alors différent(?y, ?x) fsi

    2.2.5.2 Usage du ouMalgré les apparences, on peut, en Félin, entrer une connaissance de la forme

    si chat(?x) ou chien(?x) alors carnivore(?x) fsi

    Il suffit d’utiliser deux règles.

    Licence STS/MIPE/UE19 Une initiation au génie logiciel 15

  • Le logiciel Félin

    si chat(?x) alors carnivore(?x) fsi si chien(?x) alors carnivore(?x) fsi

    En revanche, il est impossible de spécifier une connaissance comme

    si échec(?x, ?y) alors mauvais(?x) ou mauvais(?y) fsi

    2.2.5.3 Usage des quantificateursUne règle comme si chat(?x) alors père(?y, ?x) fsi est interdite en Félin : une variable uti-lisée les conclusions de la règle n’est pas présente dans les hypothèses.

    Il est toutefois clair qu’on pourrait donner un sens à une telle règle, par exemple « tout chat a un père »…

    2.2.5.4 Caractère fini du monde FélinLe résultat d’une saturation comporte toujours un nombre fini de faits. Ce fait s’explique par la limitation à un seul niveau des termes.

    Le lecteur concevra facilement qu’un monde décrit par :

    entier(0) si entier(?x) alors entier(suc(?x)) fsi

    donnerait un nombre infini de faits.

    2.2.6 Interface utilisateurLa conception d’interfaces conviviales est une tâche ardue qui fait appel à des techniques qui débordent largement du cadre de ce cours. Il importe toutefois de distinguer :

    • les possibilités de dialogue offertes par le logiciel

    • la forme externe prise par le dialogue.

    Les logiciels modernes utilisent une forme externe spectaculaire (fenêtres, souris…). Cette forme de convivialité, plus qu’utile certes, ne doit pas masquer une autre forme de convivia-lité plus fondamentale : l’utilisateur devrait, à tout moment, être capable de faire ce qu’il a envie de faire, si toutefois cette envie a un quelconque fondement logique. Cette seconde propriété est largement indépendante de la forme externe. Le lecteur est prié d’admettre que ce n’est pas la forme externe qui pose le plus de difficultés.

    Pour ce qui est de Félin, la forme externe est fruste (pas de gestion sophistiquée de l’écran et des divers périphériques) et les possibilités offertes sont minimales. Cependant, on insistera sur le fait que tout système de dialogue doit prendre en compte le fait que l’utilisateur fait des erreurs et que ces erreurs ne doivent pas bloquer le système.

    Quand on appelle le logiciel Félin, il ne connaît ni fait, ni règle. L’utilisateur dispose de cinq commandes, qu’il peut utiliser quand le logiciel l’y invite :

    f : saisie d’un fait initial. r : saisie d’une règle s : demande de saturation d : demande de démonstration q : sortie du logiciel Félin

    Chacune de ces commandes introduit un dialogue, permettant à l’utilisateur de fournir les in-formations nécessaires, et au logiciel de produire les résultats demandés.

    16 Une initiation au génie logiciel Licence STS/MIPE/UE19

  • Produit Félin : cahier des charges

    Commande f : saisie d’un faitL’utilisateur doit fournir l’énoncé d’un fait, le logiciel lui signale si celui-ci n’est pas formé correctement. Si l’énoncé est correct, le fait est enregistré.

    Commande r : saisie d’une règleL’utilisateur doit fournir l’énoncé d’une règle, le logiciel lui signale si celui-ci n’est pas for-mé correctement. Si l’énoncé est correct, la règle est enregistrée.

    Commande s : demande de saturationLe logiciel affiche l’ensemble des faits démontrables à partir de l’état courant des faits et rè-gles.

    Commande d : demande de démonstrationL’utilisateur doit fournir l’énoncé du fait à démontrer, si cet énoncé est incorrect le logiciel le signale, s’il est correct le logiciel affiche vrai ou faux, suivant que la propriété énoncée peut être démontrée ou non, à partir de l’état courant des faits et règles.

    Commande q : sortieL’utilisateur sort du logiciel Félin.

    Le lecteur est invité à réfléchir sur un ensemble de commandes plus réaliste : visualisation de l’état de la connaissance, édition…

    2.2.7 Exemple d’utilisationLa séquence suivante décrit un exemple de session de travail avec Félin. Les textes affichés par le logiciel sont en caractères gras.

    donner une commande (f,r,s,d,q) f chat(tim) donner une commande (f,r,s,d,q) f chat(felix) donner une commande (f,r,s,d,q) r si chat(?x) alors ronronne(?x) fsi donner une commande (f,r,s,d,q) s chat(tim) chat(felix) ronronne(tim) ronronne(felix) donner une commande (f,r,s,d,q) d chat(jean) faux donner une commande (f,r,s,d,q) q

    Licence STS/MIPE/UE19 Une initiation au génie logiciel 17

  • Le logiciel Félin

    2.3 Produit Félin : Spécifications et découpage modulaire

    2.3.1 Conception préliminaire

    2.3.1.1 FonctionnalitésAu premier stade de la conception on essaie d’ordinaire de répartir les fonctionnalités du lo-giciel selon leur nature.

    Comme Félin assure trois fonctionnalités principales il est légitime de songer à trois modules :

    • L’interface utilisateur, qui contrôle l’exécution, lit les commandes, dirige les dialogues complémentaires, et fait appel aux autres modules pour réaliser le travail demandé.

    • Le module de traduction, qui reconnaît les faits et règles sous leur forme externe, et pro-duit la forme interne correspondante, qui pourra être utilisée par le moteur d’inférence.

    • Le module inférence, qui effectue les déductions par chaînage avant, à partir des faits et règles sous leur forme interne.

    La question qui se pose ensuite porte sur la nature des communications entre ces trois modu-les.

    Dans l’application qui nous intéresse, il est clair que c’est l’utilisateur qui pilote l’enchaîne-ment des diverses fonctions du logiciel :

    • Il lance le produit, et donc active le module de dialogue. Le module interface doit donc of-frir au moins un point d’entrée, exec-félin.

    • Selon la demande de l’utilisateur, le module interface va solliciter le module traduction(trad-fait ou trad-règle) ou le module inférence (saturer ou démontrer).

    Les communications entre traduction et inférence sont moins explicites : ces deux modules ne s’appellent pas directement mais, manifestement, communiquent par certaines structures de données créées par le module traduction et exploitées par le module inférence.

    On est donc naturellement conduit à introduire un quatrième module, le module types géné-raux.

    2.3.1.2 Le module type générauxOn doit trouver dans le module types généraux des structures de données permettant de re-présenter les objets manipulés extérieurement par le logiciel Félin. L’état de travail courant consiste en :

    • un ensemble de faits qui sont des termes,

    • un ensemble de règles.

    Ces objets étant des ensembles, on peut définir un type générique Ens-T qui permet d’obtenir les deux types dont nous avons besoin, Ens-terme et Ens-règle.

    Pour définir les types terme et règle on est amené à introduire des sous-types, N-uplet et Ato-me.

    18 Une initiation au génie logiciel Licence STS/MIPE/UE19

  • Produit Félin : Spécifications et découpage modulaire

    Les fonctions d’accès des types qui le composent caractérise l’interface du module, par exemple :

    Type Terme

    type terme définition Un terme est la représentation d’un prédicat, il est constitué d’un nom et d’une liste d’arguments. Le nom, ainsi que chaque argument, sont des atomes. accès

    t-nom : terme → atome t-nom(x) = le nom du terme x

    t-arg : terme → n-uplet t-arg(x) = la liste des arguments de x

    t-cons : atome x n-uplet → terme t-cons(x,y) = le terme de nom x, et dont la liste d’arguments est y

    fin définition

    Licence STS/MIPE/UE19 Une initiation au génie logiciel 19

  • Le logiciel Félin

    2.3.1.3 Structure générale de FélinOn peut donc donner le résultat du travail de conception préliminaire, qui est résumé par la figure suivante :

    2.3.2 Conception détaillée

    2.3.2.1 GénéralitésAu stade de la conception détaillée on considère chaque module, on étudie ses diverses fonc-tionnalités afin de définir des sous-modules et on itère le processus jusqu’à obtenir un ensem-ble de modules dont les points d’entrée sont spécifiés sans ambiguïté et qui doivent avoir une taille raisonnable. On doit également être en mesure de donner le graphe d’appel complet.

    Structure générale

    général/types page 3

    général/trad page 14 général/inf page 7

    général/interface/ic1 page 25

    interface utilisateur

    traduction moteur d’inférence

    types généraux

    exec-felin

    trad-fait trad-regle saturer demontrer

    20 Une initiation au génie logiciel Licence STS/MIPE/UE19

  • Produit Félin : Spécifications et découpage modulaire

    Nous n’étudions pas ici la conception de tout le logiciel (qui sera reprise en TD) mais nous traitons, à titre d’exemple, le module traduction.

    2.3.2.2 Module traductionPour des raisons qui sont explicitées à l’occasion des chapitres traitant de la théorie des lan-gages, un module ayant des fonctionnalités telles que le module de traduction peut être faci-lement décomposé en deux parties :

    • L’analyse lexicale lit une suite de caractères, et la découpe en unités lexicales (suite de ca-ractères ayant un sens global).

    • L’analyse syntaxique traite cette suite d’unités, en vérifiant que la suite d’unités lexicales est correcte, et en produisant la structure de donnée interne correspondante.

    Comme nous devons traduire des faits et des règles, comme ces deux objets ont des sous-structures communes, on peut mettre en facteur l’analyse lexicale et concevoir deux sous-modules d’analyse syntaxique. Enfin, il est clair que ces trois sous-modules utilisent des structures de données communes. On obtient donc le schéma général qui suit.

    Licence STS/MIPE/UE19 Une initiation au génie logiciel 21

  • Le logiciel Félin

    Intitulé : Structure générale de la partie traduction

    La partie “traduction” analyse des chaînes de caractères, lues par la partie”interface”, et produit si possible les structures de données correspondantes (règles ou faits).

    général/trad/types1 page 15

    général/trad/lex1 page 16

    général/trad/as1 page 17

    général/trad page 20

    traduction

    analyse lexicale

    analyse syntaxique

    trad-fait trad-regle

    anaLexCh

    regle

    types pour la traduction

    fait

    général/trad/fctTraduction1 page 19

    fonctions de traduction

    22 Une initiation au génie logiciel Licence STS/MIPE/UE19

  • Produit Félin : Spécifications et découpage modulaire

    2.3.2.3 Spécification des modulesUn module est spécifié en décrivant l’ensemble de ses fonctions d’accès :

    Intitulé : Module de traduction

    Ce module effectue la traduction des chaînes de caractères représentant les faits et les règles lues. Pour cela on ef-fectue d’abord une analyse syntaxique qui permet de produire la représentation interne des faits ou des règles, puis on vérifie certaines propriétés sur ces structures, propriétés non prises en compte dans la grammaire :

    5. un fait doit être totalement instancié (il ne contient pas de variable)

    6. une règle doit être conforme (toute variable apparaissant en partie conclusion doit figurer en partie hy-pothèses).

    Ce module a deux point d’entrée : trad-regle et trad-fait.

    trad-regle : chaîne-car → règle ou "echec"ch → fournit la représentation interne de la règle reconnue s’il est possible de reconnaitre une

    règle dans ch et si elle est conforme ; sinon rend "echec".

    trad-fait : chaîne-car → terme ou "echec"ch → fournit la représentation interne du fait reconnu, s’il est possible de reconnaitre un fait

    dans ch et s’il est totalement instancié ; sinon rend "echec".

    nu-sans-var? : n-uplet → boolx → vrai si x ne contient pas de variable, faux sinon

    nu-ens-var : n-uplet → ens-atomex → ensemble des variables figurant dans x

    t-sans-var? : terme → boolx → vrai si x ne contient pas de variable, faux sinon

    t-ens-var : terme → ens-atomex → ensemble des variables figurant dans x

    lt-ens-var : ens-terme → ens-atomex → ensemble des variables figurant dans x

    r-conforme? : règle → boolx → vrai si x est conforme, faux sinon

    Licence STS/MIPE/UE19 Une initiation au génie logiciel 23

  • Le logiciel Félin

    2.3.3 Le document de conception détailléeLe document de conception détaillée est donné en annexe. Il comprend des éléments très nor-malisés, comme ceux que nous venons de voir : documents de structure, spécifications de ty-pes, spécifications de modules…

    On remarquera l’importance des références croisées.

    24 Une initiation au génie logiciel Licence STS/MIPE/UE19

  • CHAPITRE 3 Langages et grammaires

    Le français est un langage, Pascal également. Nous cherchons, dans ce chapitre, à donner un modèle de ce qu’est un langage. Pour ce faire nous utilisons l’outil de base des scientifiques : les mathématiques. Cependant, le modèle que nous donnons est un modèle qualitatif et non quantitatif. Enfin, il faut admettre d’emblée le caractère réducteur, donc incomplet, de toute modélisation.

    Nous demandons à notre modèle de nous aider à résoudre deux problèmes étroitement liés :

    • être capable de décrire un langage ;

    • fabriquer une machine capable de reconnaître les textes qui appartiennent à un langage donné.

    Ces deux problèmes, description et reconnaissance, recèlent une difficulté intrinsèque : il faut donner une description finie d’un objet en général infini. Il y a en effet une infinité de textes français, une infinité de programmes Pascal.

    3.1 Définitions de base

    3.1.1 Vocabulaire et motsLa réalité est multiple :

    • Les mots du français sont composés en mettant les uns derrière les autres des caractères d’imprimerie.

    • Une phrase française est composée en mettant les uns derrière les autres des mots du fran-çais.

    • Un programme Pascal est obtenu en mettant les uns derrière les autres des mots-clés du langage Pascal.

    Mettre les uns derrière les autres des éléments semble être une fonctionnalité de base d’un langage. D’où l’idée de retenir, dans le modèle, une généralisation.

    Licence STS/MIPE/UE19 Une initiation au génie logiciel 25

  • Langages et grammaires

    Définition 3.1 Un vocabulaire V (ou alphabet, ou lexique) est un ensemble fini de sym-boles (ou caractères).

    Définition 3.2 Un mot (ou phrase) sur un vocabulaire V est une séquence finie d’élé-ments de V.

    Exemples

    Il y a un mot particulier, la séquence vide ; on l’appelle le mot vide et nous le notons ε.

    Étant donné un mot m, on note |m| sa longueur, c’est à dire le nombre de symboles qui le composent.

    RemarqueIl ne faut pas confondre la terminologie du modèle (vocabulaire, mot) et la terminologie pro-pre au langage étudié (mot, phrase, programme…). Ainsi, si on s’intéresse au langage fran-çais, Les misérables de Victor HUGO pourra être considéré comme :

    • un mot sur le vocabulaire de l’imprimerie ;

    • un mot sur le vocabulaire du lexique français.

    Etant donné un vocabulaire V, on note V*, l’ensemble des mots sur V. On peut munir V* d’une loi de composition interne : en mettant deux mots à la suite l’un de l’autre on obtient un nouveau mot.

    Définition 3.3 L’opération de concaténation ■ est définie par :

    ■ : V* x V* → V* a, b → le mot commençant par les symboles de a suivis des

    symboles de b.

    On notera souvent a ■ b par ab. On remarque que |a ■ b| = |a| + |b|.

    L’opération de concaténation est associative et admet un élément neutre, le mot vide, ce qui confère à V* une structure de monoïde : on appelle V* le monoïde libre engendré par V. Le qualificatif libre tient au fait que les symboles sont considérés en dehors de toute significa-tion

    RemarqueSur V = {chat, te, chatte}, il est clair que chat ■ te est différent de chatte.

    3.1.2 LangagesPour un problème donné (le français, Pascal…) les mots de V* ne sont pas tous intéressants (cf. les exemples de mots donnés plus haut). D’où la définition de ce qu’est un langage.

    Vocabulaire Mots

    {a, b} aaaa, aabb

    {un, le, beau, féroce, chat, rat, mange, aime, qui}

    un beau chat mangeun le un le aime aime

    {if, then, else, begin, end, :=, ;, (, ), A, B, C, 1, 2}

    if A then B := 1 else C := 2if if if A begin

    26 Une initiation au génie logiciel Licence STS/MIPE/UE19

  • Grammaires

    Définition 3.4 Un langage L sur V est une partie de V*.

    Un langage est donc, tout simplement, un ensemble de mots.

    Exemples

    Pour aller plus loin, il nous faut un moyen de décrire sans ambiguïté ce qu’est un langage ; la notion de grammaire a été introduite à cette fin1.

    3.2 Grammaires

    3.2.1 Présentation informelleReprenons les trois exemples qui précèdent.

    • aabb un mot de L1 peut être un a, suivi d’un mot de L1, suivi d’un b.

    • le chat mange le rat une phrase peut être un groupe nominal suivi d’un groupe verbal.

    • if A then B := 1 une conditionnelle Pascal peut être if suivi d’une expression, suivi de then, suivi d’une instruction.

    Ces trois exemples sont des règles de grammaire.

    3.2.2 VocabulairesPour donner les trois règles qui précèdent nous avons utilisé :

    • des éléments du vocabulaire du langage : if, then…

    • d’autres éléments (instruction, expression, groupe nominal…) qui ne sont pas quelconques.

    Ces deux ingrédients de base sont deux vocabulaires, le vocabulaire terminal V et le vocabu-laire non-terminal N. Ces deux vocabulaires sont choisis disjoints, pour éviter certaines ambiguïtés ; en d’autres termes, nous préférons, dans les deux phrases qui suivent, la secon-de.

    Vocabulaire Langage

    {a, b} L1 = {anbn | n >= 0} = { ε, ab, aabb, aaabbb, …}

    {un, le, beau, féroce, chat, rat, mange, aime, qui}

    L2 = ensemble des phrases françai-ses qu’on peut construire sur le lexi-

    que défini par le vocabulaire considéré

    {if, then, else, begin, end, :=, ;, (, ), A, B, C, 1, 2}

    L3 = ensemble des conditionnelles Pascal limitées au lexique défini par

    le vocabulaire considéré

    1. On remarquera toutefois que certains langages ne peuvent pas être décrits par une grammaire.

    Licence STS/MIPE/UE19 Une initiation au génie logiciel 27

  • Langages et grammaires

    • « verbe est un nom, nom est un nom, manger n’est pas un nom mais un verbe ».

    • « verbe est un , nom est un , manger n’est pas un mais un ».

    Deux systèmes de notation sont souvent utilisés.

    • On réserve les majuscules pour N, les minuscules pour V : A ∈ N et a ∈ V.• On note les non-terminaux entre chevrons : ∈ N et truc ∈ V.

    A l’aide des deux vocabulaires on peut faire des mots sur N ∪ V (on les désigne d’ordinaire par une lettre grecque, α ∈ (N ∪ V)*.

    Exemples

    • if then

    • qui

    3.2.3 RèglesDéfinition 3.5 Une règle α → β met en relation une partie gauche, α et une partie droi-te, β, qui sont deux éléments de (N ∪ V)*.

    Exemples

    • → if then • → qui

    3.2.4 Réécriture (dérivation)Les règles permettent de réécrire des mots sur N ∪ V.

    Exemple

    Les réécritures peuvent aboutir à des mots de V*. Si on sait de quoi partir, on sait donc pro-duire des mots de V*. Le point de départ est appelé axiome.

    Règles utilisées Mots sur N ∪ V

    ;

    → if then

    if then ;

    → if then ;

    → if then ;

    → A if A then ;

    … …

    28 Une initiation au génie logiciel Licence STS/MIPE/UE19

  • Grammaires

    Exemple

    A partir de l’axiome, on peut réécrire, à l’aide des règles de G, les mots ε, ab, aabb…

    • S ⇒G ε• S ⇒G aSb ⇒G aaSbb ⇒G aabb

    On constate que tous les mots de V* ainsi produits sont de la forme anbn.

    3.2.5 RésuméDéfinition 3.6 Une grammaire est un quadruplet G = (N, V, S, P) où

    • V est un vocabulaire dit terminal qui est le vocabulaire du langage,

    • N est un vocabulaire dit non-terminal,

    • N ∩ V = ∅• S, appelé axiome, est un élément de N,

    • P est un ensemble de règles de la forme α → β, où α et β appartiennent à (N ∪ V)*

    Définition 3.7 Etant donné une grammaire G et deux mots ω1βω2 et ω1αω2 de (N ∪V)*, on dit que ω1βω2 dérive directement de ω1αω2 si et seulement si α → β ∈ P.

    Lorsque γ dérive directement de δ, on utilisera la notation δ ⇒G γ et on dira aussi (autre ter-minologie) que δ se réécrit en γ.

    Définition 3.8 Etant donné une grammaire G et deux mots α0 et αn de (N ∪ V)*, on dira que αn dérive de α0 (ou encore que α0 se réécrit en αn), ce qu’on notera α0 ⇒G* αn, si et seulement si :

    • soit α0 = αn• soit α0 ⇒G α1 et α1 ⇒G* αn

    Définition 3.9 Etant donné une grammaire G, le langage L(G) engendré par G est défi-ni par :

    • L(G) = { m ∈ V* | S ⇒G* m}

    3.2.6 Exemples

    3.2.6.1 Sur V = {a, b}

    • Langage des palindromes

    S → a S a S → b S b S → a S → b S → ε

    • Langage des mots comportant autant de a que de b

    N V Règles Axiome

    {S} {a, b} S → εS → aSb

    S

    Licence STS/MIPE/UE19 Une initiation au génie logiciel 29

  • Langages et grammaires

    S → a B A → a B → b S → b A A → a S B → b S S → ε A → b A A B → a B B

    Plutôt que de noter in extenso toutes les règles, on factorise d’ordinaire les parties gauches, en utilisant la notation qui suit.

    S → a B | b A | ε A → a | a S | b AA B → b | b S | a B B

    On remarque que plusieurs grammaires peuvent décrire le même langage.

    S → a S b S | b S a S | ε

    3.2.6.2 Sur V = {a, b, c}

    • Langage anbncn, n ≥ 1

    S → a S B C C B → B C a B → a b S → a B C b B → b b

    b C → b c c C → c c

    3.2.6.3 Conditionnelles PascalLe vocabulaire du langage Pascal (norme de base) comporte 95 symboles :

    • 26 lettres

    • 10 chiffres

    • 24 symboles de ponctuation : + - * / < > = . , ; : ( ) [ ] { } ' ↑ >=

  • Grammaires

    3.2.6.4 BonchatbonratOn considère le vocabulaire V 1 = {un, le, beau, féroce, chat, rat, mange, aime, qui}.

    Les règles qui suivent définissent un sous-ensemble des phrases françaises.

    → → → qui | ε → | → | ε → un | le → chat | rat → aime | mange → beau | féroce

    La phrase « le chat féroce aime un beau rat qui mange » est engendrée, à partir de l’axiome , par cette grammaire. On remarque qu’il en est de même pour la phrase « le chat qui aime le chat qui aime le chat qui aime le chat qui aime aime ».

    Cette remarque illustre bien une des difficultés de la modélisation d’une langue naturelle. C’est l’usage de la récursivité qui permet de donner une description finie d’un ensemble infi-ni de mots. Il se trouve que, pour une langue naturelle, on a envie d’ajouter des critères esthé-tiques pour restreindre l’usage de la récursivité.

    3.2.6.5 SchemeLe débutant de bonne foi aura remarqué que la syntaxe de Scheme est plus simple que celle de Pascal.

    → | ( ) → | ε

    On constate qu’on peut donner d’autres grammaires pour le même langage. Par exemple :

    → | | | | |

    → ( ) → ( lambda ( ) ) → ( cond ) → ( define ) → ( quote ) …

    Par rapport à la première, la seconde grammaire présente l’avantage de décrire les grandes fonctions du langage en les distinguant. Cette propriété est importante (cf. § 3.5).

    1. On remarquera que ce vocabulaire est conçu en fonction d’un seul genre et d’un seul nombre. Cette propriété expli-que le fait que la grammaire ne comporte pas de règle d’accord.

    Licence STS/MIPE/UE19 Une initiation au génie logiciel 31

  • Langages et grammaires

    3.3 Exploration d’une grammaire

    Nous nous posons ici le problème de l’écriture d’un programme Scheme produisant les mots d’un langage. Si le langage est infini, un tel programme manque passablement d’intérêt prati-que, aussi nous choisissons plutôt d’écrire un programme Scheme produisant “au hasard” un mot d’un langage donné.

    Pour ce faire on dispose de la fonction prédéfinie random :

    random : entier → entier n → un entier au hasard entre 0 et n

    (répartition uniforme)

    On peut donc construire facilement la fonction UnSur :

    UnSur : entier → bool n → vrai avec une probabilité de 1/n,

    faux avec une probabilité de (n-1)/n

    (define UnSur (lambda (n) (= (random (- n 1)) 0 )))

    On décide de représenter un mot par une liste plate d’éléments de V et on se limite aux gram-maires dont les règles sont toutes de la forme A → α (un non-terminal en partie gauche).

    L’idée de base consiste à associer à chaque non-terminal A de la grammaire une fonction Scheme sans paramètre dont le résultat est un mot (au hasard !) qui dérive de A. Pour explo-rer la grammaire, on utilisera évidemment la fonction associée à l’axiome.

    Exemple 1 : anbn

    S → a S b | ε

    (define S (lambda () (cond

    ((Unsur 2) (append '(a) (S) '(b))) (t nil))))

    Exemple 2: Bonchatbonrat → → → qui | ε → | → | ε → un | le → chat | rat → aime | mange → beau | féroce

    (define Phrase (lambda () (append (Gn) (Gv))))

    (define Gn (lambda () (append (Det) (Sa) (Nom) (Sa) (Relative))))

    (define Relative (lambda () (cond

    32 Une initiation au génie logiciel Licence STS/MIPE/UE19

  • Classes de langages

    ((UnSur 8) (append '(qui) (Gv))) (#t nil))))

    (define Gv (lambda () (cond

    ((UnSur 2) (Verbe)) (#t (append (Verbe) (Gn))))))

    (define Sa (lambda () (cond

    ((UnSur 3) (Adj)) (#t nil))))

    (define Det (lambda () (cond

    ((UnSur 2) '(le)) (#t '(un)))))

    (define Nom (lambda () (cond

    ((UnSur 2) '(chat)) (#t '(rat)))))

    (define Verbe (lambda () (cond

    ((UnSur 2) '(aime)) (#t '(mange)))))

    (define Adj (lambda () (cond

    ((UnSur 2) '(beau)) (#t '(feroce)))))

    3.4 Classes de langages

    3.4.1 Classification des grammairesLes grammaires peuvent être plus ou moins compliquées. Une hiérarchie a été proposée par CHOMSKY. Cette classification dépend de la forme des règles. Pour des raisons difficiles à expliquer à ce niveau de l’exposé, les dérivation vides A → ε sont exclues des types 1 à 3, avec une seule exception, l’éventuelle règle S → ε, nécessaire quand le langage contient le mot vide ; dans ce cas, on impose à S de ne jamais apparaître en partie droite de règle.

    Définition 3.10 Hiérarchie de CHOMSKY

    • Toutes les grammaires sont de type 0.

    Si on admet la seule exception citée plus haut :

    • Toutes les grammaires dont les règles α → β vérifient | α |

  • Langages et grammaires

    contrainte que nous avons introduite. Elle ne simplifie donc que la démonstration de l’inclu-sion des classes. Nous utilisons donc indifféremment les définitions :

    Définition 3.11 Une grammaire de type 2 est une grammaire dont les règles sont de la forme A → β, où β est quelconque.

    Définition 3.12 Une grammaire de type 3 est une grammaire dont les règles sont de la forme A → ε ou A → a ou encore A → aB.

    Définition 3.13 Une grammaire est dite linéaire droite si toutes ses règles sont de la for-me A → mB ou A → m, avec m ∈ V*.

    Etant donné une grammaire linéaire droite, on peut toujours trouver une grammaire de type 3 équivalente.

    3.4.2 Classes de langageDéfinition 3.14 Un langage est dit de type i s’il peut être décrit par une grammaire de type i.

    On constate également une inclusion de ces diverses classes de langage. Un langage de type i « strict » est un langage qui peut être décrit par une grammaire de type i et qui ne peut pas être décrit par une grammaire de type i + 1. Nous serons parfois amenés à prendre des liber-tés avec cette définition en omettant, si le contexte s’y prête, le qualificatif strict.

    3.4.3 Quelques paradigmes

    Langages de type 3

    • identificateurs Pascal

    • Félin

    • anbn, n ≤ 6

    Langages de type 2

    • anbn, n < k

    • anbn, n ≥ 0• L’ensemble des programmes Pascal tels que le compilateur ne signale pas d‘erreurs dites

    « de syntaxe ».

    Langages de type 1

    • anbncn, n ≥ 0

    Il est plus difficile de donner des exemples de langages de type 0 et de langages qui ne sont même pas de type 0 (on ne peut pas les décrire par une grammaire).

    Le langage des fonctions Scheme à un paramètre est un langage de type 2. On peut numéro-ter ces fonctions f0, f1…(par exemple en rangeant leurs textes par tailles croissantes, l’odre lexicographique étant utilisé pour ordonner deux fonctions dont les textes ont la même taille). A l’aide de ces fonctions on peut définir deux langages :

    • L = {an | fn(n) s’arrête}

    • L’ = {an | fn(n) ne s’arrête pas}

    On admettra que L est un langage de type 0 alors que L’ n’est même pas de type 0.

    34 Une initiation au génie logiciel Licence STS/MIPE/UE19

  • Arbres syntaxiques

    3.5 Arbres syntaxiques

    Ce paragraphe ne concerne que les grammaires de type 2 et 3.

    3.5.1 Notion d’arbre syntaxiqueDéfinition 3.15 Un arbre A est un arbre syntaxique pour une grammaire G = (N, V, P, S) de type 2 ou 3 si et seulement si :

    • Soit A est une feuille étiquetée ε, et dans ce cas la règle S → ε est dans P.• Soit l’étiquette de la racine de A est S et ses descendants directs A1,…, An ont pour éti-

    quettes X1, …, Xn, et dans ce cas :

    ■ la règle S → X1, …, Xn ∈ P ;■ pour tous les Xi qui sont des non-terminaux, tous les Ai sont des arbres

    syntaxiques pour les grammaires Gi = (N, V, P, Xi).

    Exemple 1

    S

    Sa b

    a bε

    S → aSb | ε

    Licence STS/MIPE/UE19 Une initiation au génie logiciel 35

  • Langages et grammaires

    Exemple 2

    3.5.2 Grammaires ambiguësLorsqu’on énumère les feuilles d’un arbre syntaxique en parcours descendant gauche-droit on obtient un mot du langage. Réciproquement, on peut se poser la question de déterminer, à partir d’un mot, un arbre syntaxique.

    Définition 3.16 Une grammaire est dite ambiguë si on peut trouver, pour un même mot, deux arbres syntaxiques différents.

    Les deux grammaires qui suivent sont équivalentes.

    • G1 = ({E}, {1, -}, {E → E - E | (E) | 1}, E)• G2 = ({E, T}, {1, -}, {E → E - T | T, T → (E) | 1}, E)

    → → qui | ε → | → | ε

    le ε chat féroce ε mange le beau rat ε qui aime

    36 Une initiation au génie logiciel Licence STS/MIPE/UE19

  • Grammaire vs automates

    G1 est ambiguë, G2 ne l’est pas. En effet :

    Sur cet exemple on constate qu’une grammaire non-ambiguë peut être remarquablement por-teuse d’information : les règles usuelles d’associativité du moins sont reflétées par les arbres syntaxiques de G2.

    3.5.3 Arbres syntaxiques de type 2 et de type 3On constate, par rapport à la terminologie introduite en première année que :

    • Les arbres syntaxiques d’une grammaire de type 2 stricte sont bien des arbres, au sens plein du terme.

    • Les arbres syntaxiques d’une grammaire de type3 stricte sont des cas particuliers d’arbres : des listes.

    Cette distinction, profonde, fait que l’analyse des langages de type 3 est relativement facile.

    3.6 Grammaire vs automates

    Un automate est un algorithme (une machine) prenant en entrée un mot et donnant une ré-ponse oui (l’automate accepte le mot) ou non (l’automate refuse le mot). Un automate est donc un moyen de caractériser un langage (les mots acceptés). On dit qu’une grammaire est un procédé génératif alors qu’un automate fonctionne en reconnaissance.

    E → E - E | (E) | 1

    1 - 1 - 1

    E E

    E

    E E

    1 - 1 - 1

    E E

    E

    E E

    E → E - T | T, T → (E) | 1

    1 - 1 - 1

    E T

    E

    E T

    Licence STS/MIPE/UE19 Une initiation au génie logiciel 37

  • Langages et grammaires

    Un des problèmes liés à la notion d’automate, c’est celui qui consiste à savoir si l’automate donne toujours une réponse oui/non en un temps fini. Si c’est le cas, on dispose de ce que nous appelons un oracle.

    3.6.1 Problème de l’oraclePour tout langage de type 1, 2 ou 3, on sait qu’on dispose d’un oracle. En effet, compte tenu des restrictions imposées sur les dérivations vides par la définition 3.10, aucune règle autre que la règle S → ε ne peut « raccourcir », lorsqu’on l’utilise pour effectuer une dérivation, le mot dont on part. Cette propriété permet de calculer, en un temps fini, tous les mots d’une longueur donnée qui dérivent de l’axiome.

    Pour les langages de type 0, il n’est pas toujours possible d’avoir un oracle. Ainsi, pour le langage L du paragraphe 3.4.3, on dispose, du moins théoriquement, d’un automate : c’est la machine Scheme. Si un mot appartient à L, cet automate donne une réponse positive en un temps fini. Dans le cas contraire, l’automate boucle mais on n’a aucun moyen de s’en rendre compte ! En effet, on ne sait jamais s’il ne suffirait pas d’attendre un peu plus pour avoir une réponse positive.

    L’oracle suggéré plus haut pour les types 1, 2 et 3 est non praticable, car trop lent. Les types 2 et 3 se prêtent à la définition d’automates performants.

    3.6.2 AutomatesLes automates classiques pour les langages de type 3 (resp. 2) sont les automates à nombre fini d’états (resp. automates à pile). La théorie des langages permet d’obtenir certains résultats :

    • équivalence grammaire/automate et algorithmes de traduction ;

    • déterminisation (dans certain cas), équivalence (toujours dans certains cas) ce qui permet de produire des analyseurs performants.

    L’idée de base, du point de vue du génie logiciel, consiste donc à donner une grammaire res-pectant des contraintes plus ou moins fortes et à produire automatiquement un programme d’analyse (génération automatique d’analyseurs). Le procédé de traduction étant prouvé, les programmes ainsi produits sont corrects par construction.

    La classe des applications qui se prêtent à une telle approche est vaste ; elle comprend en particulier :

    • les programmes qui demande un dialogue homme/machine élaboré pour obtenir les don-nées sur lesquelles ils travaillent (c’est le cas de Félin) ;

    • les traducteurs de tous ordres, donc, en particulier, les compilateurs.

    A titre d’exemple, nous donnons la structure d’un compilateur Pascal. Un tel programme comporte au moins quatre étages :

    • la reconnaissance des terminaux du langage Pascal, c’est l’analyse lexicale ;

    • le contrôle de la validité syntaxique du programme, c’est l’analyse syntaxique ;

    • le contrôle de la correction du programme (déclarations, types…), c’est l’analyse sémantique ;

    • la génération de code et l’optimisation.

    Les deux premières étapes correspondent à des analyseurs de type 3 (analyse lexicale) et de type 2 (analyse syntaxique) et sont donc automatisables.

    38 Une initiation au génie logiciel Licence STS/MIPE/UE19

  • Grammaire vs automates

    Dans la suite du cours nous donnons, pour le type 3, les éléments nécessaires pour compren-dre et maîtriser ce type de techniques que le lecteur aura l’occasion d’appliquer dans le cadre de Félin.

    Licence STS/MIPE/UE19 Une initiation au génie logiciel 39

  • Langages et grammaires

    40 Une initiation au génie logiciel Licence STS/MIPE/UE19

  • CHAPITRE 4 Automates déterministes à nombre fini d’états

    4.1 Grammaires de type 3

    Nous donnons ci-après quelques exemples de langages et de grammaires de type 3. Ces exemples nous servent à introduire une distinction entre deux sous-classes de grammaires que nous qualifions respectivement de déterministes et d’indéterministes.

    • G1. Langage des mots qui comptent un nombre impair de a

    S → b S | a A A → b A | a S | ε

    • G2. Langage des identificateurs

    Ι → lettre S S → lettre S | chiffre S | _ S | ε

    • G3. Langage des mots qui se terminent par un a

    S → a S | b S | a A A → ε

    • G4. Langage des mots de la forme m1abam2 où m1 et m2 appartiennent à {a, b}*

    S → a S | b S | a A A → b B B → a C C → a C | b C| ε

    Les grammaires G1 et G2 sont dites déterministes : lorsqu’on fabrique l’arbre syntaxique d’un mot du langage, le terminal le plus à gauche permet de sélectionner, sans ambiguïté une règle et une seule. Les grammaires G3 et G4 n’ont pas cette propriété.

    Licence STS/MIPE/UE19 Une initiation au génie logiciel 41

  • Automates déterministes à nombre fini d’états

    4.2 Automates à nombre fini d’états

    4.2.1 Présentation informelleLe dessin qui suit représente un automate déterministe à nombre fini d’états (ANFED) qui re-connaît le langage des mots sur {a, b}* qui comptent un nombre impair de a.

    A tout instant, cette machine est dans un des états (0 ou 1) et possède une tête de lecture qui repère un des caractères du mot à analyser.

    Au départ, la machine est dans l’état initial (repéré par une flèche), la tête de lecture sur le premier caractère du mot.

    La machine effectue une suite de transitions, gouvernées par les flèches étiquetées du dessin, l‘étiquette d’une flèche devant correspondre au caractère sous la tête de lecture pour permet-tre une transition. A chaque transition la tête est déplacée d’un caractère vers la droite.

    Lors de l’arrêt, la machine est dans l’une des trois configurations suivantes :

    • Le mot n’est pas entièrement lu mais aucune transition n’est possible. Le mot est rejeté.

    • Le mot a été lu, et l’état dans lequel se trouve la machine est un état final (les états finaux sont notés par un double cercle). Le mot est accepté.

    • Le mot a été lu, mais l’état dans lequel se trouve la machine n’est pas un état final. Le mot est rejeté.

    On remarque que l’automate que nous avons dessiné est une traduction assez littérale de G1 : L’état 0, état initial, correspond à l’axiome S, l’état 1 à A. Chaque arc correspond à une règle non terminale. Le fait que l’état 1 soit final traduit l’existence de la dérivation vide à partir de A.

    4.2.2 DéfinitionDéfinition 4.1 Un automate déterministe M à nombre fini d’états est un quintuplet M = (Q, V, δ, q0, F) où

    • Q est ensemble fini d’états

    • V est un vocabulaire

    • δ une fonction de transition de Q x V dans Q• q0, l’état initial est un élément de Q

    • F, l’ensemble des états finaux, est inclus dans Q

    0 1

    b b

    a

    a

    42 Une initiation au génie logiciel Licence STS/MIPE/UE19

  • Automates à nombre fini d’états

    La fonction de transition de l’automate qui précède est la suivante :

    4.2.3 Autres exemplesL’automate qui correspond à la grammaire G2 des identificateurs est le suivant.

    Sa fonction de transition est une fonction partielle.

    On peut la compléter en introduisant un état supplémentaire.

    δ a b

    0 1 0

    1 0 1

    δ lettre chiffre, _

    1 2 indéfinie

    2 2 2

    δ lettre chiffre, _

    1 2 3

    2 2 2

    3 3 3

    lettre

    lettre, chiffre, _

    21

    Licence STS/MIPE/UE19 Une initiation au génie logiciel 43

  • Automates déterministes à nombre fini d’états

    On obtient alors le dessin suivant.

    L’état qui a été ajouté est traditionnellement appelé état puits.

    4.2.3.1 Langage accepté par un automateDéfinition 4.2 Une configuration d’un automate est un couple (q, w) où q est l’état cou-rant et w le mot qui reste à analyser.

    Définition 4.3 Une transition d’un automate relie deux configurations successives : (q, aw) →M (p, w) ssi δ(q, a) = p

    Définition 4.4 Une séquence de transitions relie deux configurations : (q, w) ⇒M (p, v) si et seulement si

    • soit q = p et w = v

    • soit (q, w) →M (r, u) et (r, u) ⇒M (p, v)

    Définition 4.5 Le langage L(M) accepté par un automate M est défini par : L(M) = {w | (q0, w) ⇒M (f, ε) avec f ∈ F}

    4.3 Grammaires et automates

    4.4 Programmation par automates

    4.4.1 Un problème de programmationOn se pose le problème de programmation suivant : une liste contient des atomes qui sont des entiers ou h, mn ou s. Si elle alterne entiers et marques (h, mn, s) on peut la lire comme une durée (12 h 3 mn 2 s 3h 5 mn 5 mn) et vouloir connaître sa valeur en secondes.

    Durée : liste → entier ∪ indéfini l → un nombre de secondes si l est correcte, résultat

    indéfini sinon

    lettre

    lettre, chiffre, _

    21

    3

    chiffre, _

    lettre, chiffre, _

    44 Une initiation au génie logiciel Licence STS/MIPE/UE19

  • Programmation par automates

    4.4.2 ReconnaissanceOn ne s’intéresse, dans un premier temps, qu’à la correction. On peut modéliser le problème en donnant une grammaire qui décrit les listes correctes.

    Pour simplifier l’exposé de la méthode, nous remplaçons les entiers par le terminal e. Nous reviendrons sur le problème dans sa généralité au paragraphe 4.4.4.

    V = {e, h, mn, s} G = ({D, R}, V, D, P)

    P = {D → e R | ε, R → h D | mn D | s D}

    G correspond directement à un automate déterministe. On peut traduire G en un programme Scheme. Pour ce faire, on associe à chaque non terminal de la grammaire une fonction Sche-me.

    D : liste → {vrai} ∪ indéfini l → vrai si l dérive de D dans G,

    résultat indéfini sinon

    R : liste → {vrai} ∪ indéfini l → vrai si l dérive de R dans G,

    résultat indéfini sinon

    Pour programmer D (ou R), il suffit de remarquer que, la grammaire étant déterministe, le terminal qui est en tête de l suffit pour décider de la règle à appliquer.

    Pour traiter les cas d’erreur (résultat indéfini) nous utilisons la fonction prédéfinie Scheme Error qui s’apparente à ce qui, dans d’autres langages, s’appelle une exception : un message est affiché et l’exécution est interrompue.

    Error : message → indéfini m → affiche m, rend le contrôle au programmeur

    (define D (lambda (l) ; D → e R | ε

    (cond ((null? l) #T) ((integer? (car l)) (R (cdr l))) (#T (Error "entier attendu")))))

    (define R (lambda (l) ; R → h D | mn D | s D

    (cond ((null? l) (Error "marque attendue")) ((equal? (car l) ‘h) (D (cdr l))) ((equal? (car l) ‘mn) (D (cdr l))) ((equal? (car l) ‘s) (D (cdr l))) (#T (Error "marque attendue"))))

    4.4.3 CalculsNotre problème initial consistait à donner un résultat lorsque la liste est correctement écrite. Il suffit de prévoir que D et R donnent un résultat et de modifier en conséquence le program-me Scheme précédent.

    Licence STS/MIPE/UE19 Une initiation au génie logiciel 45

  • Automates déterministes à nombre fini d’états

    Comme nous essayons de définir un procédé systématique, il convient de remarquer que ce qui suit peut être déduit de la grammaire sans le moindre effort d’imagination de la part du programmeur.

    Informations extraites de la grammaire

    • D et R donnent un résultat

    D : liste → résultatD R : liste → résultatR

    • Pour chaque règle de la forme X → aY on a besoin d’une fonction XaY qui calcule le ré-sultat de X à partir du résultat de Y.

    DeR : résultatR → résultatD Dvide: → résultatD RhD : résultatD → résultatR RmnD : résultatD → résultatR RsD : résultatD → résultatR

    • On peut donc produire automatiquement le programme :

    (define D (lambda (l) ; D → e R | ε

    (cond ((null? l) (Dvide)) ((equal? (car l) ‘e) (DeR (R (cdr l)))) (#T (Error "entier attendu")))))

    (define R (lambda (l) ; R → h D | mn D | s D

    (cond ((null? l) (Error "marque attendue")) ((equal? (car l) ‘h) (RhD (D (cdr l)))) ((equal? (car l) ‘mn) (RmnD (D (cdr l)))) ((equal? (car l) ‘s) (RsD (D (cdr l)))) (#T (Error "marque attendue"))))

    Expression du calculPour exprimer le calcul, le programmeur n’a donc qu’à judicieusement choisir les types des résultats des fonctions et à programmer les fonctions XaY.

    • Choix des types : il est assez naturel de penser que le résultat de D est une durée. Pour R, on constate qu’un mot dérivant de R commence par une marque et est suivi d’une durée, d’où l’idée que R rend un couple .

    résultatD :entier ∪ indéfini résultatR :doublet({3600, 60, 1}, entier) ∪ indéfini

    • Programmation des fonctions XaY

    (define DeR (lambda (r) (+ (* e (car r)) (cdr r))))

    (define Dvide (lambda () 0))

    (define RhD (lambda (d)

    (cons 3600 d))) (define RmnD (lambda (d)

    (cons 60 d)))

    46 Une initiation au génie logiciel Licence STS/MIPE/UE19

  • Conclusions

    (define RsD (lambda (d) (cons 1 d)))

    Il ne reste plus qu’à adapter ce programme pour traiter le fait que le terminal e, en réalité, est un entier.

    4.4.4 Traitement des entiersOn peut imaginer deux classes de solutions : soit passer en paramètre aux procédures XaY le terminal a, soit partir d’une grammaire qui décrit les entiers à l’aide des chiffres.

    Terminaux en paramètreLe type des fonctions qui calculent le résultat a donc la forme générale suivante :

    XaY : RésultatY x terminal → RésultatX

    Il faut donc que la production automatique des fonctions D et R soit modifiée en conséquen-ce. La fonction DeR peut alors s’écrire :

    (define DeR (lambda (r e) (+ (* e (car r)) (cdr r))))

    Grammaire complèteOn donne une définition de G sur un vocabulaire qui contient les dix chiffres.

    V’ = {0,…, 9, h, mn, s} G’ = ({D, N}, V, D, P)

    P’ = {D → 1N | … | 9N | ε, N → 0N | … | 9N | h D | mn D | s D}

    Le lecteur est invité à appliquer le procédé sur G’.

    4.5 Conclusions

    Lorsqu’un problème de programmation repose sur l’analyse d’un langage de type 3, on dis-pose donc d’une méthode de production du programme qui peut en partie être automatisée.

    1. Donner une grammaire de type 3 déterministe décrivant le langage en question.

    2. Appliquer le procédé de traduction de la grammaire en un programme qui met en œuvre l’automate déterministe associé.

    3. Compléter l’analyseur obtenu à l’étape 2 en fournissant les fonctions qui réalisent le cal-cul pendant l’analyse.

    L’étape 2 est purement mécanique et il est possible de la faire réaliser par un programme ap-pelé générateur d’automate. Si le générateur d’automate fonctionne correctement (il est utile d’investir sur ce programme qui est d’un usage très général) il produit programme correct. L’effort du programmeur se porte donc sur ce qui est important : la description du langage et la description des calculs.

    De tels procédés techniques (utiliser un programme pour produire des programmes à partir de descriptions plus proches des problèmes posés) sont d’un usage fréquent en génie logiciel.

    Licence STS/MIPE/UE19 Une initiation au génie logiciel 47

  • Automates déterministes à nombre fini d’états

    Dans le cadre de Félin, nous utilisons un générateur d’automate, ce qui explique le caractère particulier des spécifications de l’analyseur syntaxique de Félin (Voir “général/trad/as1” à la page 109.).

    Cette méthode peut être améliorée au niveau de l’étape 1. En effet, si le langage est comple-xe, la grammaire risque d’être peu lisible et la probabilité de se tromper augmente.

    Il convient donc de disposer de moyens de structurer la description du langage.

    48 Une initiation au génie logiciel Licence STS/MIPE/UE19

  • CHAPITRE 5 Langages de type 3 et automates à nombre fini d’états

    5.1 Opérations sur les langages

    Nous nous posons le problème de structurer la définition d’un langage de type 3. Comme toujours en informatique, un bon moyen de maîtriser la complexité d’un problème est de le décomposer en sous problèmes plus simples, d’où l’idée de définir un langage en combinant des langages déjà définis.

    5.1.1 Langages rationnelsDéfinition 5.1 La classe des langages rationnels (ou encore, selon une terminologie que certains trouvent désuette, réguliers) ne contient que les langages obtenus à partir de langa-ges finis (ie. qui comportent un nombre fini de mots) en utilisant un nombre fini de fois trois opérations de base :

    • l’union de deux langages

    • le produit de deux langages

    • la fermeture d’un langage

    5.1.1.1 DéfinitionsL’union et le produit correspondent à des opérations assez naturelles.

    Définition 5.2 L’union L1 + L2 de deux langages est l’union ensembliste habituelle. Elle est donc définie par :

    • L1 + L2 = {m | m ∈ L1 ∨ m ∈ L2}

    Définition 5.3 Le produit L1L2 de deux langages est défini par :

    • L1L2 = {m1m2 | m1 ∈ L1 ∧ m2 ∈ L2}

    Définition 5.4 La fermeture L* d’un langage L correspond intuitivement à une itération. Elle comprend :

    • le mot vide (pas 0)

    • tous les mots de L (pas 1)

    Licence STS/MIPE/UE19 Une initiation au génie logiciel 49

  • Langages de type 3 et automates à nombre fini d’états

    • tous les mots de L suivi d’un mot de L (pas 2)

    • ...

    Le langage Li défini au pas i est donc LLi-1 (avec L0 = {ε}) et L* est l’union infinie des Li.

    5.1.1.2 Exemples

    • L1 = {a} + {b}

    • L2 = L1* est le monoïde libre en entier.

    • L3 = {a}L2{a} est l’ensemble des mots qui commencent et qui finissent par a.

    • L4 = {b}L2{b} est l’ensemble des mots qui commencent et qui finissent par b.

    • L5 = L3 + L4 est l’ensemble des mots qui soit commencent et finissent par a, soit com-mencent et finissent par b.

    • L6 = L2L5L2 est l’ensemble des mots qui comportent au moins soit 2 a soit 2 b.

    5.1.1.3 Expressions rationnellesDéfinition 5.5 Expressions rationnelles Les expressions rationnelles (ou encore régulières) sont définies par :

    ■ ∅ est une expression rationnelle qui représente le langage ∅.■ Si a ∈ V, a est une expression rationnelle qui représente le langage {a}.■ ε est une expression rationnelle qui représente le langage {ε}.■ Si a et b sont des expressions rationnelles qui représentent les langages A

    et B, (a + b) est une expression rationnelle qui représente le langage A + B.

    ■ Si a et b sont des expressions rationnelles qui représentent les langages A et B, (a b) est une expression rationnelle qui représente le langage AB.

    ■ Si a est une expression rationnelle qui représente le langage A, (a)* est une expression rationnelle qui représente le langage A*.

    ■ Il n’y a pas d’autres expressions rationnelles.

    Pour alléger l’écriture on adopte des conventions de parenthésage, les opérateurs étant munis d’une priorité. Dans l’ordre décroissant : *, produit, +

    Exemples

    • (a + b)* représente tous les mots sur {a, b}

    • (a + b)*aa(a + b)* représente tous les mots ayant au moins 2 a consécutifs

    • lettres = A + … + Z + a + … + z

    • chiffres = 0 + … + 9

    • lettres(lettres + chiffres)* représente le langage des identificateurs.

    On peut réécrire L6 ainsi : (a + b)*(a(a +b)*a + b(a + b)*b)(a + b)*

    Par construction, les expressions rationnelles décrivent les langages rationnels.

    5.2 Une propriété fondamentale des langages de type 3

    Propriété 5.1 Un langage rationnel est un langage de type 3 et réciproquement.

    50 Une initiation au génie logiciel Licence STS/MIPE/UE19

  • Une propriété fondamentale des langages de type 3

    5.2.1 Opérations sur les grammairesPour montrer qu’un langage rationnel est un langage de type 3, il suffit de constater que tout langage fini est un langage de type 3 et de montrer que les trois opérations conservent la pro-priété.

    A partir de grammaires de type 3 G1 et G2 pour des langages L1 et L2, on peut obtenir des grammaires de type 3 pour les langages L1 + L2, L1L2 et L1*. Le procédé général est un peu long à expliciter (car technique) mais assez naturel. Nous nous contentons de donner des exemples sur V = {a, b} en laissant au lecteur le soin de réfléchir à la généralisation.

    Union

    L1 = ab(ab)* G1 = ( {S1, T1}, V, {S1 → a T1, T1 → b S1 | b}, S1) L2 = bb(bb)* G2 = ( {S2, T2}, V, {S2 → b T2, T2 →b S2 | b}, S2) L = L1 + L2 G = ( {S, S1, T1, S2, T2}, V,

    { S → a T1 | b T2, S1 → a T1, T1 → b S1 | b, S2 → b T2, T2 → b S2 | b

    }, S)

    Produit

    L1 = ab(ab)* G1 = ( {S1, T1}, V, {S1 → a T1, T1 → b S1 | b}, S1) L2 = bb(bb)* G2 = ( {S2, T2}, V, {S2 → b T2, T2 →b S2 | b}, S2) L = L1L2 G = ( {S1, T1, S2, T2}, V,

    { S1 → a T1, T1 → b S1 | b S2, S2 → b T2, T2 → b S2 | b

    }, S1)

    Fermeture

    L1 = ab + bb G1 = ( {S1, T1, T2}, V, {S1 → a T1 | b T2, T1 → b, T2 → b}, S1) L = L1* G = ( {S1, T1, T2}, V,

    { S1 → a T1 | b T2 | ε, T1 → b S1, T2 → b S1

    }, S1)

    Dans le cas général, on constate toutefois que la grammaire obtenue n’est pas obligatoire-ment déterministe.

    5.2.2 Équations rationnellesPour la réciproque (tout langage de type 3 est rationnel) nous nous contentons de donner une idée de la démonstration.

    Licence STS/MIPE/UE19 Une initiation au génie logiciel 51

  • Langages de type 3 et automates à nombre fini d’états

    1) Equation rationnelle à une inconnueL’équation X = pX + q dont l’inconnue représente une expression rationnelle, a une « plus petite » solution : p*q. En effet p*q = pp*q + q.

    Exemple :Aux règles S → aS | bS | c | d, on peut associer l’équation S = (a + b)S + (c + d). Sa solution est (a + b)*(c + d).

    2) Système d’équations rationnelles à plusieurs inconnuesConsidérons le système :

    (1) X = aX + bY + c (2) Y = a’X + b’Y + c’

    (1) donne (3) X = aX + (bY +c) donc X = a*(bY + c) qui, reporté dans (2) donne (4) Y = a’a*(bY + c) + b’Y + c’ donc, Y = (a’a*b + b’)Y + (a’a*c + c’), d’où la solution du système (5) Y = (a’a*b + b’)*(a’a*c + c’) (6) X = a*(b((a’a*b + b’)*(a’a*c + c’) + c)

    On peut généraliser ce procédé à des systèmes plus gros.

    ApplicationGrammaire :

    S → bS | aA A → bS | aF | a F → aF | bF | a | b

    Equations :

    S = bS + aA A = bS + aF + a F = aF + bF + a + b F = (a+ b)F +(a + b) donc F = (a+ b)*(a + b) S = bS + abS + aaF + aa donc S = (b + ab)*(aaF + aa)

    Donc S = (b + ab)*(aa (a+ b)*(a + b) + aa) qui peut encore s’écrire S = (a + b)*aa(a + b)*

    5.2.3 BilanNous disposons donc d’un moyen de structurer la description d’un langage de type 3 (unions, produits et fermetures de langages plus simples) et d’un langage particulièrement lisible (les expressions rationnelles) pour exprimer cette structuration.

    Cependant, si on s’intéresse aux grammaires finales ainsi obtenues, nous sommes obligés de constater qu’elles ne sont pas obligatoirement déterministes.

    5.3 Automates indéterministes

    5.3.1 Déterminiser une grammaire ?Considérons les grammaires G3 et G4 du paragraphe 4.1.

    • G3. Langage des mots qui se terminent par un a

    52 Une initiation au génie logiciel Licence STS/MIPE/UE19

  • Automates indéterministes

    S → a S | b S | a A A → ε

    • G4. Langage des mots de la forme m1abam2 où m1 et m2 appartiennent à {a, b}*

    S → a S | b S | a A A → b B B → a C C → a C | b C| ε

    Ces deux grammaires sont indéterministes. On peut donner des grammaires déterministes qui décrivent les mêmes langages.

    • G’3. Langage des mots qui se terminent par un a

    S → b S | a A A → a A | b S | ε

    • G4. Lang