[Précédent]

1. Introduction

      Cette thèse, effectuée au sein du groupe de recherche 'Programmation Visuelle et Génie Logiciel' (PV-GL) 1  du Centre Universitaire d'Informatique (CUI) de l'Université de Genève, étudie la combinaison de deux paradigmes, flot de contrôle  2  et flot de données  3 , qui semblent être a priori incompatibles. Ils sont intégrés dans un langage de spécification visuel qui était au départ basé uniquement sur le flot de contrôle. La recherche faite sur ce thème aboutit à l'extension d'un environnement de programmation visuelle appelé DIVA (Développement Interactif et Visuel d'Application), que nous présentons dans le chapitre 3, et qui est un dérivé d'un projet appelé IDEAL (Interactive Development Environment for Assisted Learning) [Ibrahim89a][Ibrahim89b]. Cette thèse a un double centre d'intérêt, d'une part, présenter une façon simple de mettre ensemble ces deux paradigmes, et d'autre part montrer l'apport considérable de l'intégration de flot de donnée pour la conception d'application d'Enseignement Assisté par Ordinateur (EAO) avec un environnement purement de flot de contrôle tel que DIVA.


1.1 Position du problème

      D'une manière générale, la spécification d'une application doit tenir compte d'une part de l'ordre d'exécution des actions à effectuer, c'est à dire le flot de contrôle, et d'autre part des données manipulées ou utiles dans cette application et de leur utilisation, c'est à dire le flot de données. La plupart des langages de spécification (ou de programmation) visuelle privilégie l'un ou l'autre de ces aspects. L'aspect mis en position secondaire est alors souvent spécifié d'une façon complexe ou bien même ne l'est pas du tout. Ce qui diminue la puissance d'expression du langage.

      Dans le domaine de l'enseignement assisté par ordinateur, le Professeur Bork de l'Université de Californie à Irvine et son équipe ont conçu un formalisme permettant aux enseignants de spécifier, en utilisant des crayons et papiers, le déroulement d'une leçon [Bork86]. Quoique simple, ce formalisme permet une description complète et détaillée (en langue naturelle) d'une leçon: le dialogue entre l'ordinateur et l'étudiant (décrite en indiquant le texte qui doit être produit), les actions qui doivent être faites (des instructions au codeur) et l'ordre des opérations selon les réponses ou actions de l'utilisateur. La spécification ainsi obtenu est appelée script.

      Pour ne pas imposer des charges supplémentaires aux enseignants qui veulent développer des leçons d'EAO, l'approche a deux phases. Les enseignants spécifient le comportement d'une leçon dans un script détaillé (phase de conception pédagogique) et puis une équipe de codeurs implémentent ce script en utilisant un langage de programmation (phase de codage).

      Mais l'effort pédagogique produit par les concepteurs non informaticiens (les enseignants) lors de la phase de spécification est perdu à chaque nouvelle génération des logiciels. L'objectif initial du projet IDEAL (puis DIVA) est donc d'automatiser la saisie et le sauvegarde des scénarios qui se faisaient sur des pages A3 [Bork92b] [Ibrahim90a] [Ibrahim90b]. Une génération automatique de code devant assurer leur adaptation à des environnements différents.

      Mais ce formalisme de script est surtout approprié pour décrire le flot de contrôle d'une application, mais est très faible quand il faut faire la description du flot de données dans l'application. La raison de ceci est probablement que les programmes d'EAO développé à l'époque n'exigeaient pas beaucoup de manipulations de données.

      Un des projets du groupe PV-GL, la messagerie auto-éducative appelée 'Friendly Mailer' [Ibrahim93][Ibrahim95], a été conçu avec l'environnement DIVA. Il fut constaté que les applications qui étaient moins orientées EAO ont exigé plus de manipulations de données, et le manque de support de description et de manipulation de données dans le formalisme de spécification a été sérieusement senti.

      Nous pensons qu'un simple, mais puissant, formalisme pour décrire le flot de données (et éventuellement, des structures de données) mettrait en valeur considérablement l'applicabilité, dans d'autres contextes, du formalisme visuel semi-formel (combinaison de graphe orienté et de langage naturel) sur lequel l'environnement DIVA a été basé.


1.2 But de la recherche

      Les caractéristiques du formalisme de script permettent de le considérer comme un langage de spécification visuelle basé sur des représentations graphiques (des noeuds reliés par des arcs). Un langage visuel est un langage qui permet d'exprimer un programme (ou une spécification) à l'aide des éléments syntaxiques visuels (voir le chapitre 2 pour plus de détails sur la programmation visuelle et langages visuels).

      Le but principal de cette recherche est de trouver un moyen simple et efficace d'intégrer dans un langage de spécification visuelle les deux paradigmes flot de données et flot de contrôle. Plusieurs travaux ont été faits dans cette même direction mais ils sont presque tous, partis d'un langage basé sur le paradigme de flot de données pour y intégrer ensuite le paradigme de flot de contrôle [Hils92].

      Dans notre cas, le langage visuel de départ est un langage purement de flot de contrôle. Les rares données que les applications sont censées utiliser ou manipuler ont été donc décrites localement dans chacun des noeuds concernés. Ces données n'avaient pas de représentation visuelle. Et puisque le déroulement de l'application est géré par le flot de contrôle, les données n'étaient pas considérées dans les conditions d'activation des noeuds. Notre but dans cette intégration est de définir le formalisme visuel permettant de spécifier le flot de données et de déterminer la participation de données dans les conditions de déclenchement des noeuds.

      Nous nous posons donc plusieurs questions pour atteindre cet objectif. Quels sont les éléments dont nous aurons besoin dans le flot de données et comment allons-nous les représenter dans notre formalisme visuel? Quels sont leurs rôles? Quels sont les différents comportements que l'intégration du flot de données rend possibles? Comment ces comportements peuvent-ils être spécifiés visuellement? Comment allons-nous tenir compte de ces données dans le générateur de code qui fait parti de notre environnement? etc. ...

      La conséquence pratique de notre recherche est de fournir un environnement qui permet de rendre le développement d'application EAO plus complet en fournissant un moyen de tenir compte des données. Les données ainsi modélisées sont des ressources importantes pour des différentes utilisations dans l'application (diversification des exercices, suivi de l'état des apprenants, ...). Nous concrétisons les résultats de notre recherche sur l'environnement DIVA.

      Il faut bien noter que l'acteur principal dans le développement d'une application EAO avec le système DIVA est l'enseignant qui pourrait ne pas avoir des connaissances en informatique. L'environnement DIVA, qui est une sorte de gestionnaire de scénarios, lui permet de participer activement à la spécification de ses leçons.


1.3 Plan du mémoire

      Pour mettre les lecteurs dans le bain des domaines concernés par ce travail de thèse, pour apporter des réponses aux questions posées ci-avant, et pour présenter le résultat de notre travail ainsi que son extension possible, ce mémoire est organisé comme suit.

      Après ce présent chapitre où nous avons présenté le problème que nous voulons étudier et l'objectif que nous voulons atteindre en résolvant ce problème, nous allons présenter les différents domaines concernés, directement ou non, par notre travail. La première partie de ce deuxième chapitre présente les notions de programmation visuelle et de langage visuel. Nous y situons notre environnement DIVA. Nous décrivons les paradigmes flot de données et flot de contrôle en présentant les caractéristiques de chaque paradigme, leurs avantages et inconvénients, et présentons l'avantage d'un paradigme mixte. Nous finissons ce chapitre par la présentation de quelques langages de programmation visuelle qui ont été au départ basés sur le paradigme de flot de données mais qui sont enrichis par des constructions de contrôle. Pour chacun de ces langages, nous allons présenter comment les structures de contrôle sont intégrées. La deuxième partie de ce chapitre 2 parle du deuxième domaine concerné par notre recherche, l'Enseignement Assisté par Ordinateur. Nous présentons quelques lignes de recherches dans ce domaine, et l'originalité de notre travail.

      Avant de passer aux chapitres qui vont décrire notre solution en tenant compte des questions que nous nous sommes posées, le chapitre 3 décrit l'ensemble de notre environnement DIVA. Dans ce chapitre nous donnons une petite historique de cet environnement, nous parlons de ses caractéristiques et de son originalité. Cette description de l'environnement DIVA nous permet de déterminer les composants de ce système qui sont concernés par l'intégration du flot de données.

      Deux chapitres viennent ensuite pour présenter le nouveau formalisme visuel, sa sémantique et le modèle d'exécution qui est en quelque sorte la conséquence de la sémantique définie. Le chapitre 4 présente le but principal de l'intégration du flot de données. Nous allons ressortir les besoins et/ou les impacts de cette intégration. Ce chapitre contient les descriptions de chaque élément du nouveau formalisme, et les sémantiques liées à ces éléments. Nous y parlons aussi des deux modes de vue qui ont été adoptés dans notre système. Dans le chapitre 5, nous définissons les modèles d'exécution résultant des sémantiques définies dans le chapitre 4. Nous étudions l'impact de l'intégration aux générateurs automatiques de code.

      Les deux chapitres suivants donnent la concrétisation de notre résultat. Le premier, le chapitre 6, parle de notre choix d'implémentation et des différents modules nécessaires. Nous y décrivons les structures de données et l'impact de l'intégration sur la représentation interne des scripts. Nous présentons aussi dans ce chapitre l'heuristique de dessin de graphe que nous utilisons. Le deuxième, le chapitre 7, présente quelques exemples significatifs qui nous permettent de discuter les différents points étudiés précédemment et qui font ressortir l'apport original de notre méthode d'intégration.

      Avant de clore ce mémoire, le chapitre 8 résume les résultats de la thèse (en se rapportant aux questions/problèmes/buts originaux). Nous y fournissons aussi des suggestions pour les travaux futurs et les améliorations possibles. En particulier, on pourrait intégrer facilement le parallélisme. Il s'agit donc d'une conclusion évaluative et des perspectives pour les travaux futurs. Le dernier chapitre, chapitre 9, donne la conclusion générale de notre travail.

      Note

      Pour la suite du contenu de ce rapport, nous allons utiliser l'acronyme DIVA pour parler de notre ancien système (ou environnement) et l'acronyme DIVA-cd pour parler du système résultat de notre travail. L'extension cd signifie 'contrôle et données'.


2. Programmation Visuelle et Enseignement Assisté par Ordinateur

      Les recherches effectuées dans ce travail concernent deux domaines, la programmation visuelle 4  et l'enseignement assisté par ordinateur (EAO) 5 . L'outil (l'environnement) d'application de notre travail, le système DIVA, utilise un langage de spécification qui a des caractéristiques d'un langage de programmation visuelle, tandis que le domaine principal d'application de ce système est l'EAO.

      Ainsi ce chapitre est structuré de la façon suivante. La première partie présente les concepts de programmation visuelle et de langage visuel en donnant quelques définitions et classifications. La deuxième partie présente deux paradigmes utilisés dans les langages de programmation en général, le paradigme de flot de contrôle et le paradigme de flot de données. Nous allons présenter les caractéristiques de chaque paradigme, leurs avantages et inconvénients, et puis mettre en évidence l'intérêt d'un paradigme mixte. Pour terminer cette deuxième partie, nous présentons quelques langages qui sont basés sur le paradigme de flot de données mais qui sont enrichis par des constructions de contrôle. Nous étudions plus particulièrement leur façon d'intégrer les structures de contrôle.

      La dernière partie concerne le domaine d'application de notre travail, l'EAO. Elle donne une présentation simple de ce domaine. Nous y parlons de quelques avantages et problèmes de l'EAO, et présentons quelques outils.


2.1 Programmation visuelle et langages visuels

      Pour les humains, l'utilisation des images était et reste toujours une façon simple d'expression et de communication. Dès sa petite enfance, l'humain apprend la vie par les images et durant toute sa vie il pense en formant des images dans son esprit. Les recherches sur la programmation visuelle considèrent cette perception visuelle humaine pour concevoir des systèmes et des langages de programmation qui utilisent des images ou des symboles graphiques. Ces recherches sont favorisées par le progrès technologique des écrans graphiques.

      Plusieurs chercheurs (par exemple Glinert [Glinert85] et Scanlan [Scanlan89]) ont empiriquement établi l'avantage cognitif des méthodologies graphiques par rapport aux méthodologies textuelles. Le domaine de programmation visuelle regroupe des recherches sur les systèmes graphiques, les langages de programmation et les interactions homme-machine. Les études sont faites sur les représentations graphiques, sur les paradigmes, sur les caractéristiques du langage et sur son utilisation. Ces différents points permettent de classifier un langage visuel.


2.1.1 Définitions

      La définition probablement la plus générale de la programmation visuelle est celle donnée dans [Chang90]: c'est l'utilisation d'expressions visuelles (icônes, dessins, entrées gestuelles,...) dans le processus de programmation. Cette définition est adoptée par d'autres auteurs [Koelma92]. La programmation visuelle se rapporte au développement de logiciel où des notations graphiques et des composants logiciels manipulables en mode interactif sont principalement employés pour définir et composer des programmes. Le but de la programmation visuelle est de mettre en valeur la compréhensibilité des programmes et de simplifier la programmation elle-même. Les environnements de programmation visuelle fournissent donc des éléments graphiques ou iconiques qui peuvent être manipulés interactivement par l'utilisateur en fonction d'une grammaire spatiale spécifique pour construire un programme.

      Selon Myers [Myers90], le système de programmation visuelle se rapporte à n'importe quel système qui permet à l'utilisateur de spécifier un programme dans un mode bidimensionnel (ou plus). Bien que cette définition soit très large, les langages textuels conventionnels ne sont pas considérés comme bidimensionnels, étant donné que les compilateurs ou interpréteurs les traitent en flots unidimensionnels.

      Les environnements de programmation visuelle doivent être distingués des environnements de visualisation (visualisations de programme et visualisations de données). Chang définit la visualisation comme l'utilisation de représentations visuelles (images, graphiques, animations) pour illustrer la structure (les données) et le comportement des programmes [Chang90]. En d'autres termes, la visualisation de programme est une représentation graphique des aspects d'un programme qui a pu avoir été écrit dans un langage de programmation conventionnel (textuel) et la visualisation de données offre une vue des données manipulées par le programme.

      Compte tenu de ces définitions, un langage visuel est donc un langage qui manipule des informations visuelles, qui permet une interaction visuelle, ou qui permet de programmer à l'aide d'expressions visuelles.

      Note

      Les produits Microsoft dits 'visuels' tels que Visual Basic, Visual C++ etc.... ne sont pas, malgré leurs noms, des langages visuels. Ils sont des langages textuels qui utilisent des interfaces utilisateurs graphiques simplifiant ainsi les tâches des programmeurs.


2.1.2 Classifications

      Selon les définitions précédentes, il y a deux catégories de langages visuels: langages de programmation visuelle et langages supportant la visualisation (appelés aussi langages de visualisation). Certains langages font partie de ces deux catégories à la fois. La différence entre ces deux catégories de langages peut être basée sur le moment où les éléments visuels interviennent. C'est pendant la phase de spécification pour les langages de programmation visuelle et à l'exécution pour les langages de visualisation.

      Pour notre part, nous nous intéressons aux langages de programmation visuelle. Selon Newton [Newton90], les langages de programmation visuelle sont ceux qui utilisent des éléments visuels ou graphiques pour représenter directement la structure ou la logique du programme. Le programme est écrit dans un langage d'images ou de diagrammes. Ce n'est pas le cas pour les outils qui permettent aux utilisateurs de visualiser graphiquement la structure des programmes écrits dans des langages non visuels, et pour les outils qui sont conçus pour aider au développement d'interface utilisateur graphique (GUI).

      Un langage de programmation visuelle a les propriétés suivantes:

  1. il décrit des objets spécifiques (structures de données, objets graphiques, etc...) et le comportement de ces objets,
  2. il utilise des éléments lexicaux visuels (graphiques) et éventuellement textuels,
  3. il a une syntaxe spatiale et au moins une partie de la sémantique du langage est déterminée par la position et les relations spatiales des éléments lexicaux.

      L'équipe de Burnett [Burnett94] a développé un système standard de classification pour classifier les articles scientifiques résultant des recherches entreprises dans le domaine des langages de programmation visuelle. Ce système permet d'aider les chercheurs à trouver des travaux similaires et fournit une ligne de base pour comparer et évaluer différents systèmes. Il peut aussi servir de base pour classifier les langages de programmation visuelle.

      Deux points de vue transversaux sur les langages visuels permettent de les classer: l'un de l'extérieur, selon la représentation choisie pour les éléments manipulables, l'autre de l'intérieur, selon le paradigme de programmation sous-jacent qui définit le comportement des programmes. Une troisième classification des langages visuels est faite selon leur domaine d'utilisation.


2.1.2.1 Classification par l'extérieur

      Une première classification des langages de programmation visuelle est faite en fonction du type et du degré d'expression visuelle utilisée: langages à base d'icônes (ou langages iconiques) ou d'images, langages à base de diagrammes (ou diagrammatiques, le plus souvent des graphes orientés) et langages à base de formulaires ou de tableurs. Certaines langages combinent plusieurs primitives, par exemple un mélange de représentations iconiques et diagrammatiques.


2.1.2.1.a Langages à base d'icônes

      Pour les langages à base d'icônes, les icônes ou les images peuvent représenter soit des objets, soit des constructions de programme.

      Le langage de programmation visuelle HI-VISUAL [Hirakawa90] utilise les icônes pour représenter des objets qui existent dans le monde réel (des objets manipulés par le programme). Il n'y a pas d'icône pour les fonctions ou les procédures. Au lieu de cela, les opérations sont spécifiées par une combinaison d'objets en les mettant les uns sur les autres [Kado92].

      

Figure 2.1 Fenêtre d'édition avec BACCII

      Une approche différente a été adoptée pour le langage BLOX [Tanimoto86]. Chaque icône est une traduction d'une construction de langage textuel. Les icônes s'adaptent ensemble comme les morceaux d'un puzzle. Similairement, BACCII (Ben A. Calloni Coding Iconic Interface) permet à l'utilisateur de programmer avec des icônes représentant toutes les principales constructions de programmation, tels que les boucles, les branchement conditionnels, dans un environnement orienté syntaxe [Calloni94]. La Figure 2.1 présente la fenêtre d'édition de programme de BACCII, à gauche se trouve la liste de ses icônes.

      Cocoa [Heger98] est un environnement de programmation orienté objet qui utilise des images. Les utilisateurs créent des 'personnages', les placent sur une 'scène', et leur donnent les règles qui déterminent leur comportement dans une simulation. A chaque classe de personnage correspond alors une image bitmap. Cocoa est initialement appelé KidSim [Cypher95].


2.1.2.1.b Langages à base de diagrammes

      Les langages diagrammatiques sont représentés par des graphes ou des figures géométriques.

      Les noeuds des graphes indiquent des objets et les arcs représentent le rapport entre les objets. Les graphes conviennent aux langages basés sur le paradigme de flot de données ou de flot de contrôle, et ils sont largement utilisés. La sémantique des arcs qui relient les noeuds d'un graphe dépend du paradigme employé par le langage. Avec le paradigme de flot de données, les arcs transmettent les données à traiter. Pour les langages basés sur le paradigme de flot de contrôle, les arcs donnent les signaux de commande qui activent l'exécution des noeuds destinataires.

      Pour les langages utilisant des figures de géométrie élémentaire (cercle, rectangle, triangle, ...), leurs sémantiques sont exprimées par l'intermédiaire de leurs propriétés géométriques ou de leurs relations spatiales topologiques.

      Meander [Wirtz94a] est un langage diagrammatiques pour spécifier les programmes parallèles. Il intègre la représentation textuelle et graphique dans un langage. Son but est de faciliter la compréhension de codes parallèles en les représentant graphiquement. La syntaxe du graphe est simple et hiérarchique. Le code séquentiel est intégré en annotant un fragment valide de code c.-à-d. une liste non vide de constructions écrites en C formant une structure de bloc complète à chaque noeud séquentiel. Le parallélisme est présenté au moyen des fragments de graphe entre les noeuds spéciaux Create Child (CC) et Wait Child (WC). Le flot de données est représenté par les arcs qui relient les noeuds du graphe. Différents types d'arcs existent suivant leurs noeuds de départ et d'arrivée: arcs de type causal, arcs de création de processus, arcs de communication, arcs de synchronisation. La Figure 2.2, prise depuis la documentation en ligne du projet Meander 6 , présente un programme écrit avec ce langage.

      

Figure 2.2 Un programme visuel avec Meander

      Cantata [Young95] est un langage visuel combinant représentations iconique et diagrammatique. Il fournit un environnement de programmation visuel dans le système Khoros. Dans Cantata, les programmes visuels sont créés en tant que graphes orientés, où chaque noeud du graphe est un élément iconique (appelé glyphs) représentant un programme du système Khoros et chaque arc représente un chemin sur lequel les données circulent.

      Le langage VIPR (Visual Imperative PRogramming) [Citrin93][Citrin95] utilise des figures géométriques. Un programme dans VIPR est représenté comme un ensemble de cercles (ring) emboîtées. Un cercle contient un prédicat (condition) textuel facultatif, qui peut référencer un état, et qui doit être vrai pour que le cercle puisse participer à une combinaison lors de l'exécution du programme. Les procédures et les fonctions sont des ensembles de cercles emboîtés en dehors des cercles de la procédure principale. Les figures géométriques sont aussi utilisées pour les langages de programmation visuelle logique.

      Dans [Agusti98] est présenté un langage de programmation visuelle logique dont la syntaxe visuelle est une personnalisation des higraphs (combinaison de deux formalismes: graphe et diagramme de Venn). Il existe deux types des termes visuels, terme élémentaire et ensemble visuel de termes. Le terme élémentaire peut être représenté par un cercle (une variable), ou une boîte arrondie étiquetée (une constante), ou une boîte arrondie étiquetée et ayant n arcs entrants (une fonction d'arité n, et chaque arc est appliqué à un autre terme élémentaire). L'ensemble visuel de termes représente un ensemble d'éléments de l'univers du discours. Il peut être représenté par:

  • une boîte rectangulaire étiquetée (ensemble correspondant au prédicat unaire du nom spécifié);
  • une boîte rectangulaire étiquetée et ayant (n-1) arcs entrants (prédicat d'arité n);
  • une boîte rectangulaire sans étiquette contenant deux ensembles de termes visuels racines (union de ces ensembles de termes visuels);
  • une boîte rectangulaire non étiquetée partagée par deux ensembles de termes visuels racines qui le contiennent (intersection de ces ensembles de termes visuels);
  • une boîte grise reliée avec un ensemble de termes visuels racine (l'ensemble complémentaire de cet ensemble, négation).

2.1.2.1.c Les langages à base de formulaires

      Les langages à base de formulaires ou de tableurs présentent les programmes visuels sous formes d'un ensemble de formulaires. Comme pour un tableur classique, les données sont représentées dans les cellules et les formulaires expriment les programmes (les calculs). Chaque cellule peut contenir une formule composée de constantes ou des références à d'autres cellules.

      

Figure 2.3 Programme en Forms/3

      Forms/3 [Burnett94a] est un langage déclaratif de programmation visuelle utilisant les métaphores de cellules et de formules des tableurs. Les programmes sont faits par la définition des formules sur une cellule qui peut être référencée par d'autres formules. Les cellules peuvent être organisées en groupe appelé 'formulaire' (form), un mécanisme de base d'abstraction de données. Un formulaire peut utiliser une image (un graphisme). Le programmeur crée un nouveau programme Forms/3 en créant un nouveau formulaire, en lui ajoutant des cellules, et en indiquant les formules. La Figure 2.3, prise dans la documentation en ligne  7  de Forms/3 représente le calcul du carré d'un nombre.

      Spreadsheet 2000 (ou S2K) est un langage de programmation visuel basé sur le tableur. Il a été créé pour la première fois en mai 1996 sous le nom de 'Let's Keep It Simple Spreadsheet.' (LKISS) [Dees96]. La plupart des tableurs donnent une grille pour l'entrée des nombres ou des étiquettes, et des règles définissant une syntaxe pour les formules. Typiquement, la grille affiche les résultats d'équation mais pas les formules. S2K d'autre part, a une zone de travail avec une barre d'outils et plusieurs palettes des graphismes. L'utilisateur crée des calculs en plaçant (traînant) les objets (y compris les colonnes, lignes, cellules, étiquettes, et opérateurs mathématiques) des palettes sur la zone de travail. Il relie après les objets et S2K exécute les calculs.


2.1.2.2 Classification par l'intérieur

      Les langages de programmation visuelle peuvent aussi être classés selon les paradigmes qu'ils utilisent. Ces paradigmes permettent de spécifier les comportements du programme. Le plus utilisé est le paradigme de flots de données (LabView, Hi-Visual, Prograph, ...). Généralement, la représentation visuelle utilisée est le graphe orienté. Dans ce cas, les noeuds du graphe représentent des modules qui reçoivent des données en entrée et produisent d'autres données en sortie, et les arcs représentent la circulation des données.

      Certains langages visuels spécifient le comportement du programme par des contraintes (Constraint-based languages) (exemple Forms/3). Ils utilisent une approche déclarative. Les contraintes précisent les propriétés que doivent satisfaire les solutions d'un problème et non pas l'algorithme avec lequel les solutions doivent être trouvées. D'autres langages visuels utilisent une approche proche de la spécification par contraintes, la spécification par les règles (Rule-based languages) (exemple LegoSheets). Une règle a deux parties: la condition et l'action. Elle exprime l'action à effectuer quand la condition de la règle est remplie. Un programme sera donc représenté par un ensemble des règles visuelles.

      D'autres langages visuels basés sur le paradigme de programmation logique fournissent des notations visuelles, utilisant des diagrammes déclaratifs, pour rendre plus intuitif la structuration des expressions logiques.

      Les autres paradigmes utilisés par les langages de programmation visuelle sont :

  • La programmation par démonstration
  • La programmation fonctionnelle
  • La programmation orientée objet
  • La programmation impérative
  • La programmation parallèle.

      Certains langages combinent plusieurs paradigmes. Par exemple, Prograph combine le paradigme de programmation orientée objet et le paradigme de flot de donnée. De son côté, Forms/3 est aussi un langage de flot de données et qui utilise le paradigme de programmation par contraintes.


2.1.2.3 Classification par les besoins

      Une troisième classification des langages de programmation visuelle est basée sur leurs domaine d'utilisation. Certains langages sont d'utilisation générale, d'autres sont liés à un domaine spécifique tel que le traitement d'images, le traitement de son, les bases de données, la génération d'interface utilisateur, et les applications basées sur le web.


2.1.3 Avantages et inconvénients

      Citons quelques avantages de la programmation visuelle.

  • Elle permet un raisonnement visuel: une partie importante des activités cognitives est accompagnée d'une 'visualisation' mentale; les langages visuels peuvent aider les utilisateurs à penser visuellement, par exemple en voyant des chemins plutôt qu'en les exprimant. Ils peuvent servir de moyen de communication pour le résultat d'un tel raisonnement.
  • Elle offre une ouverture vers des utilisateurs moins spécialisés: les spécialistes d'un domaine applicatif ont rarement des compétences informatiques (ou du moins ce n'est pas leur travail de les acquérir); les techniques visuelles facilitent l'interaction homme-machine et aussi la création de programmes - tache complexe réservée par tradition aux spécialistes informaticiens.
  • Elle améliore la qualité de programmes: la programmation visuelle permet aux programmeurs expérimentés de se concentrer mieux à la résolution du problème qu'à l'écriture de programme.
  • La programmation visuelle enlève aussi la barrière linguistique. Le langage visuel sera utile pour des personnes qui ont des problèmes avec l'anglais en général, puisque la plupart des langages textuels qui existent aujourd'hui tendent à être basés sur l'anglais.

      Rendre la programmation plus accessible à quelques assistances particulières et améliorer l'exactitude et la vitesse avec lesquelles les gens accomplissent des tâches de programmation sont les buts spécifiques les plus communs des recherches dans le domaine de la programmation visuelle [Burnett99].

      Mais il ne faut pas, non plus, ignorer que la programmation visuelle présente quelques inconvénients qui pourraient, néanmoins, être résolus d'une façon ou une autre.

  • Par rapport au langages visuels, les langages textuels restent plus généraux et plus capables d'exprimer des abstractions. On peut 'discuter' de tout, mais on ne peut pas tout visualiser, par contre ce qu'on peut voir est mieux compris.
  • Les langages visuels sont bien adaptés pour la description des objets manipulés mais ils ont plus de difficultés à exprimer le comportement. Ceci devrait être représenter par d'autres objets visuels abstraits.
  • Il y a aussi des représentations graphiques qui dépendent de la culture. Il faut alors se mettre d'accord sur la façon de représenter les choses. La normalisation pourrait remédier à ce problème.
  • La programmation visuelle a besoin d'un large espace sur écran pour créer un programme. Ceci peut être résolu partiellement par l'utilisation de défilement dans une fenêtre et/ou par diffèrent mécanisme d'abstraction comme la structure hiérarchique dans un programme. Mais la compréhension d'un programme peut être affectée par une visualisation partielle, car avec chaque élément invisible on perd aussi ses relations avec le reste des objets. La hiérarchisation couplée avec des représentations iconiques oblige à définir des représentations graphiques pour des objets de plus en plus généraux et abstraits. L'utilisation non seulement des icônes graphiques, mais également du texte, pour les noms des variables, les classes, ... permet aussi de résoudre ce problème. Les recherches visant à trouver de nouveaux moyens d'adresser le problème de l'espace d'écran sont ainsi de plus en plus utiles.

2.2 Paradigmes flot de contrôle et flot de données

      Le paradigme sur lequel se base un langage de programmation, que ce soit textuel ou visuel, définit le comportement du logiciel conçu ou écrit avec ce langage. Pour ce travail, nous nous sommes intéressés sur deux paradigmes précis, le flot de contrôle et le flot de données. Chacun de ces paradigmes met l'accent sur certains aspects du comportement et, de ce fait, néglige d'autres. Cela rend chacun plus approprié à des applications particulières.


2.2.1 Flot de contrôle


2.2.1.1 Principe

      Le flot de contrôle définit le traitement 8  (ou calcul) en termes d'ordre des opérations discrètes. Il était le paradigme utilisé dans les premiers langages de programmation, les langages impératifs, qui ont été basés sur le modèle de von Neumann, c'est à dire le programme est enregistré en mémoire et le CPU 9  comporte un compteur ordinal contenant l'adresse de la prochaine instruction. Le programmeur définit donc l'ordre dans lequel les opérations seront effectuées.


2.2.1.2 Utilisation

      Le paradigme de flot de contrôle met l'accent sur l'ordonnancement des étapes en exigeant qu'une étape finisse avant que des autres débutent. Il ne vérifie pas implicitement la disponibilité des entrées lorsqu'une étape commence. Les entrées sont déterminées pendant les transitions entre les étapes, mais ne sont pas exigées pour commencer une étape. Ceci rend le flot de contrôle plus approprié aux applications dans lesquelles l'ordre exact des étapes est le plus important, comme dans des applications d'affaires 10 .

      Comme l'avons exprimé ci-dessus, le flot de contrôle est la base des langages impératifs tels que Fortran, COBOL, Basic, C, Ada, Java, ...). Pour ces langages textuels, il peut être visualisé à l'aide des organigrammes [Good99][Whitley97] (utilisant des éléments géométriques simples pour représenter le début et la fin d'un programme, les actions, les tests et les entrées/sorties) ou des réseaux de Pétri [Reisig98].

      Les arcs qui relient les différents éléments du graphe de flot de contrôle sont généralement orientés. Ils représentent l'écoulement du contrôle (commande) entre ces éléments. Puisque la commande parvient d'une façon séquentielle, il y a habituellement un seul arc entre deux éléments. Il n'existe pas de représentation visuelle pour l'utilisation des données. Les données sont représentées textuellement, habituellement comme variables dans des noeuds, même s'il s'agit des langages visuels.


2.2.2 Flot de données


2.2.2.1 Principe

      Le flot de données est à la fois un concept de programmation et aussi une technique d'implémentation. Dans la technologie de la programmation, le flot de données laisse entendre l'échange d'information (les données) entre des entités (fonctions) qui manipulent des données et effectuent des calculs sur les données. Par conséquent, dans un programme basé sur le flot de données, une étape est entrée lorsque d'autres étapes lui fournissent ses entrées directement à partir de leurs sorties. Les modules du programme sont alors toujours prêts à effectuer leurs opérations. Une fois que toutes les données nécessaires arrivent au module, l'opération est lancée automatiquement.

      D'une façon générale, dans un modèle d'exécution utilisant le paradigme de flot de données, l'exécution d'un noeud se produit dès que toutes ses entrées seront disponibles. Dans ce cas, on parle d'un modèle d'exécution basé sur l'offre de données  11  [Jagannathan95]. Dans certains cas, l'exécution d'un noeud se produit lorsque toutes ses entrées sont disponibles et il y a au moins une demande de l'une de ses sorties. C'est un modèle d'exécution basé sur la demande  12 .


2.2.2.2 Utilisation

      Le paradigme de flot de données met l'accent sur la détermination des entrées en exigeant que les sorties d'une étape soient explicitement liées aux entrées d'une (ou des) autre(s) étape(s). Il ne tient pas compte de l'ordonnancement des étapes, parce que le moment où toutes les entrées d'une étape sont disponibles est déterminé par les temps dont les diverses étapes mettent pour délivrer leurs sorties. Par conséquent, certaines étapes peuvent obtenir toutes leurs entrées plus tôt que d'autres dans un ordre moins restrictif que le flot de contrôle.

      Ces caractéristiques rendent le flot de données plus convenable aux applications dans lesquelles la détermination appropriée des entrées est la plus importante, comme dans les applications en temps réel. L'analyse du flot de données permet aussi de déterminer les dépendances de données entre étapes ou modules d'un programme. Elle a plusieurs utilités comme l'optimisation, le parallélisme, ...

      Comme langage orienté flot de données textuel, on peut citer le langage Signal [Bournai93] qui est un langage de spécification de système réactifs temps-réels, développé à IRISA (Institut de Recherche en Informatique et Systèmes Aléatoires), Rennes, France, depuis 1982. Comme son nom l'indique, le langage Signal manipule des signaux. Ces signaux sont utilisés comme des variables dans une sorte de système d'équations. Un programme Signal définit un automate à partir de ce système d'équations.

      La représentation graphique la plus utilisée pour un programme basé sur le flot de données est le graphe orienté. Dans un tel graphe, les noeuds représentent des fonctions et les arcs représentent l'écoulement des données entre les fonctions. Les arcs entrant dans un noeud représentent des données d'entrée à une fonction et les arcs sortant représentent les données résultant du traitement. L'exécution d'un noeud se produit quand tous ses opérandes (les données en entrée) sont disponibles, ainsi les fonctions sont exécutées dans un ordre résultant seulement des dépendances de données.


2.2.3 Le besoin de combiner le flot de données et le flot de contrôle

      Nous constatons donc que l'un ou l'autre de ces paradigmes privilège un aspect du comportement du programme au détriment d'un autre. Si nous pouvons les mettre ensemble, nous pourrions créer un système plus riche et plus puissant. Pour cette combinaison, nous sommes intéressés par les langages visuels.

      D'une part, un langage purement de flot de données a besoin des constructions, c'est à dire des éléments tout-faits, de programmation pour traiter des problèmes complexes. Un langage visuel de flot de données est de plus en plus puissant s'il fournit des constructions de programmation supplémentaires et des fonctions prédéfinies. D'autre part, les langages de flot de contrôle ont besoins des nouveaux formalismes visuels pour pouvoir s'adresser directement aux données en représentant la circulation des données entre les noeuds.

      L'objectif de la combinaison est donc de maintenir l'importance des données dans le traitement et, en même temps, d'offrir plus de flexibilité dans les spécifications des constructions de programmation et des structures de contrôle (cheminement sélectif de données, itération, récursion...).

      Fréquemment la combinaison de ces deux paradigmes se fait à partir d'un langage purement de flot de données et auquel sont ajoutées des structures de contrôle complexes, très souvent une forme de construction différente pour chaque structure de contrôle. Plusieurs travaux semblables [Auguston97b][Ghittori98][Hils92] ont été faits dans cette direction, quelques exemples sont présentés dans la section suivante.

      Dans notre cas, nous avons commencé à partir d'un langage visuel simple qui a été, à l'origine, basée sur le paradigme de flot de contrôle. Nous y avons intégré le paradigme de flot de données. Dans le langage ainsi enrichi, nous pouvons considérer les données dans le déroulement des traitements et nous pouvons facilement spécifier, sans constructions additionnelles, les diverses structures de contrôle.


2.2.4 Exemples de combinaison de flot de contrôle et de flot de données

      Plusieurs développements ont été faits dans le domaine de la programmation visuelle pour ajouter de diverses structures de contrôle dans un langage basé sur le paradigme de flot de données. C'est pourquoi la plupart des langages visuels qui combinent les paradigmes flot de données et flot de contrôle sont des langages de flot de données auxquels des constructions des structures de contrôle (itération, exécution conditionnelle, séquencement, ...) ont été ajoutées. Ces extensions sont parfois plus ou moins complexes. Nous allons présenter quelques-uns de ces langages visuels basés sur le paradigme de flot de données mais qui sont enrichis par des constructions de contrôle.


2.2.4.1 Le langage V

      Le langage visuel de flot de données V [Auguston97a][Auguston97b][Auguston97c] est un langage avec une représentation visuelle des dépendances entre les données et les processus. Il a des constructions d'itération attachées à l'utilisation des vecteurs et des matrices comme structures de données, et des opérateurs pour examiner ces structures dans un ordre donné (du premier au dernier ou l'inverse), pour les mettre ensemble dans une simple valeur, ou pour adresser des éléments individuels.

      Le langage V définit également la notion de tampon 13  par lequel on peut accéder à plusieurs éléments consécutifs du flot de données indépendamment de leur inclusion dans une structure de données, aussi bien qu'un mécanisme d'assortiment de modèle 14  pour lier des éléments consécutifs avec des variables séparées.

      Avec ces diverses caractéristiques, le langage V est presque purement basé sur le flot de données. Néanmoins, il inclut une opération qui comporte un ordonnancement procédural: la boîte d'expression conditionnelle qui peut contenir des expressions booléennes multiples avec les valeurs de sortie associées. Chaque expression est évaluée consécutivement, commençant par le haut et passant à celle au-dessous d'elle si l'expression booléenne est évaluée à faux, et ainsi de suite. Le langage V a donc la notion de commutateur conditionnel de flot des données (Figure 2.4) pour le traitement itératif, et une construction itérative spécialisée basée sur l'assortiment de modèle pour les vecteurs et matrices. Le commutateur conditionnel de flot de données est utilisé pour contrôler les boucles dans les diagrammes de flot de données (exemple dans Figure 2.5), et le modèle itératif définit une itération sur un vecteur ou sur une ligne ou une colonne d'une matrice. Etant donné ses structures de données de base, le langage V semble être limité principalement aux applications numériques.

      

Figure 2.4 Commutateur conditionnel de flot de données [Auguston97b]

      

Figure 2.5 Calcul itératif de factorielle [Auguston97a]


2.2.4.2 VIPERS

      Dans le langage VIPERS [Ghittori98], la présence des cycles dans le graphe de programme est admise pour s'attaquer à des itérations séquentielles. VIPERS utilise des formes compactes simulant les comportements de boucle (bloc FOR, bloc FOREACH et bloc WHILE). Selon le modèle de flot de données, les programmes VIPERS sont des graphes dans lesquels des jetons de données circulent le long des arcs entre les noeuds (modules) qui transforment les jetons de données. Pour réaliser une synchronisation correcte, VIPERS utilise des signaux de contrôle reliant les ports des blocs de contrôle. S'il existe un signal entre un port de contrôle de sortie (du côté droit) d'un bloc et le port de contrôle d'entrée (du côté gauche) d'un autre bloc, alors le deuxième bloc ne peut pas être exécuté avant le premier.

      La Figure 2.6, tirée de [Ghittori98], représente l'implémentation du bloc FOREACH dans VIPERS.

      

Figure 2.6 Implémentation du bloc FOREACH de VIPERS


2.2.4.3 Prograph

      

      

Figure 2.7 Calcul récursif de factorielle en Prograph

      Prograph [Steinman95] est un langage iconique basé sur le flot de données avec diverses constructions de contrôle. Il n'y a cependant aucun flot de contrôle visuellement explicite. Le premier mécanisme de contrôle dans Prograph est la possibilité d'avoir des multiples cas pour la même méthode. Les cas sont testés dans l'ordre, s'ils se terminent en échec ou si une annotation 'next case' est rencontrée, jusqu'à ce qu'un cas se termine avec succès. En outre, Prograph inclut deux pseudo contrôles: 'Finish' et 'Terminate' pour stopper les constructions d'itération. Le flot de contrôle existe ainsi dans Prograph, mais il n'est pas visible. Prograph est aussi un environnement de programmation visuelle orienté objet [Cox95].

      Les fenêtres de la Figure 2.7 présente des méthodes écrites en Prograph pour le calcul récursif de factorielle.


2.2.4.4 LabVIEW

      LabVIEW [LabVIEW98] est principalement basé sur le formalisme de flot de données, mais il ajoute des constructions de contrôle pour les itérations (For Loop et While Loop), séquencement explicite (Sequence) et exécution conditionnelle (case). Puisque normalement son formalisme de flot de données n'est pas approprié pour passer des données d'une boucle d'itération à la prochaine, LabVIEW définit la notion de registre à décalage (shift register). Un autre inconvénient des structures de contrôle de LabVIEW est que les diverses étapes d'une séquence ne sont pas visibles en même temps. L'utilisateur peut seulement voir une étape à la fois. Il en est de même pour l'exécution conditionnelle, pour laquelle seulement un cas (figure fonctionnelle correspondant à une valeur des données testées) est visible à un moment. LabVIEW a également la notion de dépendance artificielle de données (artificial data dependency), qui est une condition dans laquelle l'arrivée des données plutôt que leur valeur déclenche l'exécution d'un objet. Ainsi la dépendance artificielle de données peut être vue comme une forme de jeton de contrôle.

      La Figure 2.8 illustre l'utilisation de la boucle While. Ce diagramme spécifie la lecture continue d'une température jusqu'à ce qu'un bouton est activé.

      

Figure 2.8 Mesure de température avec LabView (While loop)


2.2.4.5 La synthèse de Hils

      Un aperçu de 15 langages de programmation visuelle (y compris Prograph [TGS89] et Cantata [Rasure91]) utilisant le paradigme de flot de données est présenté dans [Hils92]. L'itération, y compris les structures de contrôle, est une des alternatives de conception qui peut être utilisée pour enrichir le modèle de flot de données pur. Elle est une des caractéristiques qu'un langage de programmation basé sur le flot de données nécessite pour être puissant. Selon cet aperçu, quelques langages visuels de flot de données fournissent l'itération sous forme de cycles dans le graphique de flot de données, et d'autres utilisent des constructions de flot de contrôle spéciales. Le problème avec l'addition des constructions spéciales est que si d'autres formes de contrôle s'avèrent utiles, des nouvelles constructions devraient être créées. Dans le langage de notre système DIVA-cd, puisque les paradigmes de flot de contrôle et de flot de données sont complémentaires, nous n'avons pas besoin de constructions particulières.


2.3 L'Enseignement assisté par ordinateur (EAO)


2.3.1 Qu'est-ce que l'EAO ?

      L'enseignement assisté par ordinateur désigne l'ensemble des techniques et des méthodes d'utilisation interactive de systèmes informatiques dans un contexte éducatif (d'apprentissage). Les logiciels d'EAO (didacticiels) sont donc utilisés comme outils pédagogiques.

      Un apprenant face à un ordinateur ou un terminal informatique, reçoit par ce moyen une suite de messages contenant des informations et des sollicitations auxquelles il répond en utilisant le matériel offert. L'enseignement assisté par ordinateur donne l'occasion aux élèves d'utiliser un ordinateur afin d'acquérir de nouvelles connaissances ou d'approfondir la matière qu'ils ont déjà étudiée.

      L'EAO est considérée comme ayant de grandes possibilités intéressantes pour augmenter la qualité et l'efficacité de l'éducation. Ainsi plusieurs recherches sont faites dans ce domaine pour les différentes sections d'enseignements. Avec les progrès des recherches dans d'autres domaines de l'informatique tels que l'interaction Home-Machine, l'intelligence artificielle, les réseaux, le multimédia, etc, nous entendons à présent parler de EIAH (Environnement Informatique pour l'Apprentissage Humain), TICE (Technologies de la l'Information et de la Communication pour l'Enseignement), EIAO (Enseignement Intelligemment Assisté par Ordinateur), apprentissage à distance 15 , ...


2.3.2 Classification des logiciels d'EAO

      Les différentes recherches effectuées dans le domaine de l'EAO aboutissent à des développements de logiciels d'apprentissage appelés aussi didacticiels. Dans [DeVries01], une typologie des didacticiels, fondée sur la fonction pédagogique visée lors de leur conception, est proposée. Chaque fonction pédagogique est caractérisée par trois aspects: les tâches proposées aux apprenants, le point de vue théorique associé et la manière de traitement des connaissances.

      Cette étude fait ressortir huit fonctions pédagogiques qui correspond donc chacun à un type de didacticiel. Le tableau ci-dessous, tiré de [DeVries01], donne un récapitulatif de ces huit fonctions et de leurs caractéristiques.

      
Fonction pédagogique Type de logiciel Théorie Tâches Connaissances
Présenter de l'information Tutoriel Cognitiviste Lire Présentation ordonnée
Dispenser des exercices Exercices répétés Behavioriste Faire des exercices Association
Véritablement enseigner Tuteur intelligent Cognitiviste Dialoguer Représentation
Captiver l'attention et la motivation de l'élève Jeu éducatif Principalement Behavioriste Jouer  
Fournir un espace d'exploration Hypermédia Cognitiviste constructiviste Explorer Présentation en accès libre
Fournir un environnement pour la découverte de lois naturelles Simulation Constructiviste cognition située Manipuler, observer Modélisation
Fournir un environnement pour la découverte de domaines abstraits Micro-monde Constructiviste Construire Matérialisation
Fournir un espace d'échange entre élèves Apprentissage collaboratif Cognition située Discuter Construction de l'élève

      Les logiciels d'EAO peuvent aussi être classés en deux groupes selon leur condition d'utilisation, les logiciels 'fermés' et les logiciels 'ouverts'.

      Les logiciels fermés sont immédiatement utilisables sans que l'enseignant ait besoin d'ajouter ou de modifier des lignes de code. Mais leur inconvénient est qu'ils ne correspondent pas forcément aux besoins de l'enseignant, et qu'il est impossible de corriger les éventuelles erreurs.

      Pour les logiciels ouverts, l'enseignant doit lui même créer les exercices et les activités proposés aux apprenants. Il peut donc le faire selon ses besoins. L'inconvénient est que ces logiciels exigent de l'enseignant un apprentissage plus ou moins long et difficile.

      Le but principal de notre système dès le départ est de fournir aux enseignants un outil lui permettant de concevoir facilement leurs leçons. Ce système est polyvalent. Il n'est pas conçu pour une matière ou une fonction pédagogique spécifique. Il peut être utilisé pour concevoir des logiciels auto-éducatifs [Ibrahim95], autrement dit, il peut être utilisé pour les différents niveaux d'apprenants.


2.3.3 Quelques avantages de l'EAO


2.3.3.1 Interactivité et Individualisation

      Un critère le plus souvent considéré comme contribuant à l'efficacité des sessions d'EAO est l'interaction. L'apprenant est constamment invité à répondre aux questions ou à effectuer des opérations. Le programme fournit une rétroaction immédiate, soit comme remarques à propos des réponses de l'étudiant, soit comme des résultats selon les entrées qu'il a choisi.

      La «valeur ajoutée » de l'utilisation des ordinateurs pour les exercices, est leur capacité de dire aux étudiants, juste après chaque question, s'ils ont répondu correctement, et de fournir davantage de rétroaction explicative qui est appropriée à la réponse qu'ils ont donnée. Ce genre de rétroaction individualisée permet aux étudiants de progresser à leur propre rythme et d'effectuer autant de répétitions qu'ils le voudront.


2.3.3.2 La capacité d'enregistrer et d'analyser les données

      Un des avantages principaux de l'EAO est que l'ordinateur peut enregistrer les réponses des étudiants aux questions, qui peuvent rapidement être analysées pour fournir à l'enseignant la rétroaction immédiate du progrès des étudiants et leur compréhension des matières, permettant une intervention appropriée et opportune.


2.3.4 Problèmes

      Les nouvelles technologies rendent le corps enseignant parfois dubitatif, parfois enthousiaste. La manque de temps de disponibilité pour le développement du logiciel, ou même pour la familiarisation avec un logiciel existant, est une source significative de frustration pour beaucoup d'enseignants même s'ils désirent utiliser la technologie dans leur enseignement [Bork01].

      Très souvent pour pouvoir utiliser la nouvelle technologie pour leurs enseignements, les enseignants devront avoir le temps de se renseigner sur l'EAO, sur le logiciel déjà disponible, son exécution, et de savoir comment développer leur propre logiciel. Ce genre de travail devra être donné avec un support technique.

      Pour développer une application d'EAO significative, une préparation significative est aussi nécessaire. Le problème reste donc celui de la maîtrise de l'outil qui nécessite une formation adaptée et une pratique fréquente.

      La plupart des recherches dans le domaine de l'EAO vise à améliorer la qualité du logiciel vis-à-vis de l'apprenant. Très souvent la participation des enseignants dans le développement du matériel de cours se limite à l'établissement du cahier de charge de l'application. Dans notre environnement l'enseignant participe dans l'étape de conception en utilisant le gestionnaire de scénario. L'une des caractéristiques de cet environnement est sa simplicité qui le rend utilisable par des enseignants n'ayant pas de connaissances avancées en informatique.


2.3.5 Quelques projets et/ou outils EAO

      Il existe plusieurs projets dans le domaine de l'EAO. Ils peuvent être des projets de collaboration entre plusieurs entités ou même collaboration internationale. Puisqu'ils font intervenir au moins des enseignants et des informaticiens, ces projets sont en général pluridisciplinaires.

      Plusieurs systèmes ou logiciels résultent de ces projets. Certains ont des grands succès comme Cabri-géomètre 16  (CAhier de BRouillon Interactif) [Charrière96] qui est présent sur des calculatrices Texas-Instruments. Nous présentons quelques système permettant aux enseignants de créer eux-même les activités proposées aux apprenants.


2.3.5.1 WebCT - World Wide Web Course Tools

      WebCT 17  [Ojaniemi00] est un outil qui facilite la création par les utilisateurs non techniciens des environnements éducatifs sophistiqués sur le web [WebCT]. Il peut être utilisé pour créer des cours entièrement en ligne, ou pour éditer simplement des matériaux qui complètent des cours classiques en salle.

      Le logiciel WebCT réside sur un serveur, permettant aux enseignants et étudiants de lui accéder par l'intermédiaire d'un navigateur web tel qu'Internet Explorer ou Netscape. Il permet également aux enseignants de faire des changements à leurs cours facilement, à partir de n'importe quel endroit accessible via le web, et de rendre ces changements disponibles aux étudiants immédiatement.

      WebCT offre plusieurs utilitaires permettant de construire les cours, gérer l'aspect du cours, évaluer les étudiants, contrôler les dossiers contenant les supports du cours, ... En Suisse, l'Université de Berne a mis en place un serveur WebCT 18  qui contient plusieurs enseignements dont le laboratoire de télécommunication de l'Université de Genève.

      Des « Plug-in » de langue permettent à des cours en ligne de WebCT d'être affichés dans une langue différente. Chaque « Plug-in » est construit pour une version spécifique de WebCT et ne fonctionnera pas correctement sur d'autre version. Les « Plug-in » de langue changent la langue de l'interface de cours de WebCT seulement, il ne traduit pas le contenu du cours. Dans notre environnement il est possible de traduire le contenu du cours (les dialogues échangés avec l'apprenant) en plusieurs langues.


2.3.5.2 CASTLE

      CASTLE 19  (Computer ASsisted Teaching and LEarning) [Pownall97] [Pownall98] est un ensemble d'outils en ligne qui permet de créer rapidement des exercices interactifs (quiz) pour usage sur le web.

      Les outils de CASTLE ont été développés pour que les concepteurs des cours puissent créer des outils d'évaluation interactifs en ligne rapidement et facilement sans avoir besoin de connaissance antérieure de HTML, de cgi, ou de langages similaires.

      Les outils CASTLE sont disponibles pour d'autres sites pour être utilisables localement. Les avantages principaux de ceci est que les établissements utilisateurs ne doivent plus se connecter au serveur de Leicester. Tous les outils sont écrits en Java et font partie d'un 'package' qui peut être employé sur n'importe quelle plate-forme. Les outils ont été examinés sur des plates-formes Unix, mais devraient également être compatibles avec des serveurs NT. Il y a actuellement deux versions de CASTLE disponibles pour le téléchargement.


2.3.5.3 Projet ARIADNE

      En Suisse, il existe plusieurs projets sur les applications des nouvelles technologies de l'information et de la communication (NTIC) pour l'enseignement dans les hautes écoles suisses. Le projet ARIADNE 20  (Alliance of Remote Instructional Authoring and Distribution Networks for Europe) fait partie de ceux-ci [Forte99].

      C'est un projet européen qui développe et teste des méthodologies et des outils télématiques/informatiques pour l'enseignement (classique, ouvert ou à distance), favorisant la réutilisation et le partage du matériel pédagogique. Il s'agit de permettre de créer et structurer facilement des cursus, par exemple à distance, pour fournir un soutien temporel aux apprenants.

      ARIADNE offre

  • des outils informatiques de recomposition et de conceptualisation de tout document texte, de création d'hypertextes pédagogiques et de segmentation de vidéo, permettant à l'étudiant d'assimiler le contenu en lisant, en regardant et en écoutant (composante expositive);
  • un générateur de simulations, un outil d'auto-évaluation et un générateur de questions à choix multiples (QCM), incitant l'étudiant à pratiquer des activités, en réponse à des stimuli, sous forme de questions ou de simulations (composante active);
  • des outils de télé-interaction qui stimulent l'étudiant à communiquer en direct ou à distance avec l'enseignant (composante interactive).

      En résumé

      Ce chapitre nous a permis de revoir les deux domaines concernés par ce travail de thèse et surtout de situer notre recherche parmi les autres effectuées dans chacun de ces domaines. Nous avons apporté une sorte de taxonomie des langages de programmation visuelle. Un langage de programmation visuelle est donc caractérisé par

  • le type et le degré de ses expressions visuelles,
  • le paradigme qu'il utilise,
  • son domaine d'application.

      Notre système offre une degré d'abstraction élevé, ce qui lui donne une caractéristique plutôt de langage de spécification au lieu de langage de programmation. Compte tenu de ces différentes classifications des langages visuels nous pouvons affirmer que notre langage est un langage de spécification visuelle semi-formelle, combinant une représentation graphique (graphes orientés) et textuelle, qui au départ est basé sur le paradigme de flot de contrôle, et sera enrichi par ce travail de thèse du paradigme de flot de données. Il était conçu pour des applications d'EAO, mais son extension lui donne la caractéristique d'un langage de programmation d'utilité générale. Son niveau d'abstraction élevé et sa caractéristique semi-formelle rendent facile son utilisation. Il permet ainsi aux enseignants de prendre part active dans la conception de leurs leçons d'EAO.


3. L'Environnement DIVA


3.1 Le projet

      Le projet DIVA (Développement Interactif et Visuel d'Application) dérive d'un ancien projet appelé IDEAL (Interactive Development Environment for Assisted Learning) [Ibrahim89a] [Ibrahim89b] démarré en 1987, suite aux activités d'EAO (Enseignement Assisté par Ordinateur) lancées par le professeur B. Levrat. Le but de ce projet est d'offrir un support de type CASE (Computer-Aided Software Engineering) pour le développement de didacticiels. Il est basé sur une méthodologie de développement [Bork92] créée par l'équipe du professeur A. Bork, de l'Educational Technology Center, à l'Université de Californie à Irvine, en collaboration avec l'équipe du professeur Levrat à l'université de Genève. Cette méthodologie utilise un langage de spécification semi-formel basé sur le flot de contrôle (combinaison de graphe orienté et de langage naturel). Le projet DIVA est lancé pour enrichir le système avec d'autres paradigmes pour les formalismes visuels. Ceci pourrait élargie le champ d'application de cette méthodologie.

      Le système DIVA hérite donc des composants du projet IDEAL. Le noyau du système DIVA (Figure 3.1) est formé par l'éditeur synchrone et le générateur de code (voir section 3.3 jusqu'à la section 3.6). L'éditeur synchrone offre deux éditeurs spécifiques: l'éditeur de script et l'éditeur de programme. La conception visuelle est faite avec l'éditeur de script; l'éditeur de programme permet au codeur de modifier les fichiers de programmes manuels. L'éditeur synchrone offre alors la possibilité de synchroniser le script et les programmes correspondants. Le formalisme utilisé n'est pas basé sur un seul langage de programmation. Le générateur de code permet la traduction (ou compilation) de la représentation visuelle en code source pour différents langages de programmation classiques comme Pascal et Ada. Nous présentons dans ce chapitre le formalisme visuel utilisé pour la création des spécifications visuelles, et le modèle d'exécution correspondant qui est pris en compte par le générateur de code. Nous décrivons les états initiaux des principaux composants de DIVA, c'est-à-dire, leurs caractéristiques avant notre projet d'intégration du flot de données.

      D'autres outils complémentaires existent aussi dans cet environnement pour faciliter les tâches des concepteurs. Il s'agit du gestionnaire de traduction pour avoir des versions des logiciels, créées dans des langues différentes, de l'éditeur de structures et de l'éditeur de constantes permettent au concepteur de définir les types de données et de créer des constantes, du superviseur pour contrôler l'exécution d'un programme d'application, et du logiciel 'lister' qui donne une vue d'ensemble d'un projet créé avec le système DIVA. Nous donnons aussi dans ce chapitre des descriptions de ces outils.

      

Figure 3.1 Le noyau de l'environnement DIVA

      Les étapes de développement d'application (d'EAO par exemple) avec le système DIVA sont les suivantes:


3.2 Formalisme visuel

      Notre méthodologie utilise un langage de spécification semi-formel basé sur le flot de contrôle (combinaison de graphe orienté et de langage naturel) que nous appelons langage Script. Le langage Script est un langage de spécification visuel utilisé pour capturer le comportement dynamique des systèmes logiciels. Les constructions syntaxiques du langage sont données par un diagramme appelé diagramme de script. Le diagramme de script est composé de noeuds interconnectés par des arcs orientés.

      Les noeuds décrivent des actions qui devraient avoir lieu pendant l'exécution ou des indications pour le codeur. Les décorations graphiques de chaque noeud indiquent le type d'action décrite dans le noeud. Les arcs qui représentent le flot de contrôle sont utilisés pour indiquer la séquence d'activation des noeuds. Tous les arcs de flot de contrôle ont précisément un noeud d'origine et un de destination. Nous avons différents types de noeud.


3.2.1 Description et représentation graphique des noeuds

      Nous avons trois façons de représenter les noeuds. La première est d'utiliser des décorations textuelles qui encadrent la partie visuelle des textes des noeuds. C'est ce type de présentation qui est utilisé par défaut. Les deux autres façons utilisent des familles d'icônes que nous présentons dans les Figure 3.2 et Figure 3.3 L'utilisateur peut choisir entre ces trois différentes représentations.


3.2.1.1 Noeud Message

      Un message est un morceau de texte qui serait affiché à l'écran (il peut inclure des directives de disposition à l'écran). Le texte de message sera enregistré séparément du programme dans un autre fichier puisqu'il pourrait être traduit en d'autres langues naturelles. Le programme contient seulement des références aux messages mais pas le texte du dialogue lui-même. Le noeud Message n'a pas de décoration visuelle.

      

Exemple 3.1 Représentation d'un noeud Message


3.2.1.2 Noeud Directive

      Un noeud Directive contient des informations pour celui qui va implanter la spécification, c'est-à-dire des directives aux codeurs. Il est aussi appelé Commande. Il s'agit donc de texte décrivant une action qui doit être faite par le programme. Cette action peut être très simple (par exemple, lire une chaîne de caractères du clavier, laisser clignoter une zone de l'écran, ou une autre action élémentaire très commune aux programmes d'EAO) ou beaucoup plus complexe (par exemple, appeler une simulation de tableur, montrer une image complexe ou une animation...). Généralement, une directive est donnée en langage naturel et sera ensuite remplacée par un fragment de code. Ce noeud est représenté par un texte entre accolades.

      

Exemple 3.2 Un noeud Directive (Commande)


3.2.1.3 Noeud documentation

      Ce noeud est aussi appelé commentaire. Il contient des textes qui servent à documenter le script et le rendent ainsi plus compréhensible (pas d'action). Il explique par exemple qu'est ce qui est fait sur une certaine section du script et pourquoi. Les commentaires sont représentés visuellement par un texte entre parenthèses.

      

Exemple 3.3 Un noeud Documentation


3.2.1.4 Noeud appel à un Sous-graphe

      Ce noeud est utilisé pour invoquer un autre script à l'endroit où la référence se trouve. Il permet une décomposition hiérarchique d'une leçon. Il peut aussi mentionner les informations à échanger avec le script appelé. La référence à un script est représentée par le nom du script entre les caractères > et <.

      

Exemple 3.4 Un noeud appel à un Sous-graphe


3.2.1.5 Noeud étiquette

      Ce noeud contient un mot simple qui peut être considéré comme repère dans le script. Aucun code n'est produit pour ces noeuds étiquette. L'étiquette est représentée visuellement par un mot entre deux tirets.

      

Exemple 3.5 Un noeud Etiquette (Label)


3.2.1.6 Noeud Media

      Le noeud Media contient une indication du type de media et toute autre information nécessaire pour l'utiliser. Il est aussi appelé Audiovisuel. Une procédure externe sera générée, et devra être codée à la main. Ce noeud est représenté par un texte entre deux caractères ~.

      ~ Jouer l'interlude ~

      

Exemple 3.6 Un noeud Audiovisuel

      Note

      Pour ces types de noeuds précédents, un seul noeud successeur est autorisé. Par contre ils peuvent avoir plusieurs prédécesseurs.


3.2.1.7 Noeud Test

      Il est aussi appelé condition. Ce noeud contient un prédicat. Il est généralement basé sur la réponse de l'utilisateur (exemple: les réponses possibles, présence de certains mot-clés, ...) et donné soit en langage naturel soit dans un autre formalisme de comparaison (pattern matching). Le noeud Test est représenté graphiquement par un texte dans une boîte rectangulaire (boîte de test).

      

Exemple 3.7 Un noeud Test

      D'habitude, les noeuds Test sont groupés verticalement sous forme de boîtes adjacentes connectées (cascade de noeuds Test) qui sont évaluées séquentiellement depuis le sommet vers le bas jusqu'à ce qu'un prédicat est évalué vrai, et dans ce cas l'évaluation s'arrête. Un compteur est associé à chaque prédicat et sera incrémenté pendant l'exécution à chaque fois que le prédicat est évalué vrai. Le noeud Test peut avoir plusieurs noeuds successeurs et les arcs qui le relient à ses successeurs sont, dans ce cas, libellés (sauf un) avec un intervalle de nombre entier ou un seul nombre. Chaque nombre doit être unique (pas de chevauchement d'intervalles). L'arc non libellé pointe à son successeur qui devrait être actif si les conditions sont fausses. Pratiquement, c'est un autre noeud Test se trouvant juste après lui dans la même cascade.

      

Figure 3.2 Famille d'icônes n.1

      

Figure 3.3 Famille d'icônes n.2

      Un prédicat nommé 'True' ou 'Otherwise' est aussi défini pour avoir plus de souplesse dans l'expression des comportements du système. Le prédicat d'un noeud 'Otherwise' est censé être toujours vrai. Il doit se trouver à la fin d'une cascade de noeuds Test, mais son utilisation n'est pas obligatoire. C'est au concepteur de créer un noeud 'Otherwise' si nécessaire. Comme nous avons dit précédemment, l'arc non libellé sera utilisé lorsque la condition est fausse. Mais si on veut avoir la possibilité de plusieurs évaluations fausses et que les comportements soient différents, on peut utiliser ce prédicat prédéfini et lui associés un certain nombre d'arcs (voir noeud Test 'Otherwise' dans l'Exemple 3.8).


3.2.2 Les arcs

      Le système utilise des arcs orientés pour relier deux noeuds et exprime ainsi l'ordre d'exécution des noeuds. L'existence d'un arc entre deux noeuds indique alors que l'exécution du noeud de départ de l'arc doit être finie avant que le noeud d'arrivée soit activé. Chaque arc provenant d'un noeud Test peut être étiqueté avec un nombre ou un intervalle de nombre. Lorsque le prédicat du noeud Test est évalué à vrai, la valeur du compteur associé indiquera quel arc partant de ce noeud doit être utilisé pour trouver la prochaine action à entreprendre, basé sur le nombre ou l'intervalle étiquetant l'arc. Pour la cohérence de la structure graphique, un arc implicite et invisible relie un noeud Test avec un autre noeud Test qui est juste au-dessous de lui. Le but de cet étiquetage d'arc est d'éviter les boucles infinies et de changer le comportement du programme si l'étudiant répète la même erreur.

      Dans un script (graphe) l'utilisation des arcs est soumise aux restrictions suivantes:

  • les noeuds de tous les types, excepté les noeuds Test, peuvent seulement avoir un arc sortant (c'est-à-dire un seul successeur);
  • l'origine et la destination d'un arc ne peuvent pas être le même noeud. (c'est-à-dire la reflexivité n'est pas permise);
  • il ne peut pas y avoir plus d'un arc reliant un noeud origine et un noeud destinataire donnés.

      

Exemple 3.8 Un bout de script

      Considérons un petit exemple, une partie de script, qui illustre ces différents types de noeud. Nous voudrons demander à un élève de nous donner le résultat de la multiplication de 5 par 7:

  • si au bout de 20s il ne répond pas, on lui demande de le faire. Une deuxième hésitation, on lui redemande encore d'entrer une valeur, mais s'il y une troisième attente de 20s, on lui donne la réponse, et on continue la leçon;
  • s'il donne la valeur 35 (bonne réponse), on le notifie et continue la leçon;
  • s'il donne 12, on lui dit que c'est le résultat de l'addition qu'il a donné. On lui demande d'entrer le résultat de la multiplication. S'il donne encore 12, on lui dit qu'il confond l'addition et la multiplication. On lui donne la réponse, et on continue la leçon;
  • s'il donne d'autre fausse valeur on lui dit que c'est faux et on l'invite de réessayer. S'il donne encore de mauvaise réponse, on lui dit qu'il a encore quelques problèmes. On lui donne la réponse, et on continue la leçon.

      Pour cet exemple, les noeuds Test jouent un grand rôle pour spécifier le comportement du système suivant les réponses de l'apprenant. L'affichage des réponses se fait par des noeuds de types messages. Le bout de graphe de script correspondant aura donc la forme donnée par la figure de l'Exemple 3.8 (représentation schématique).


3.3 L'éditeur Synchrone

      L'éditeur synchrone (SyncEd) est composé de deux éditeurs: l'éditeur de script et l'éditeur de programme (Figure 3.1). L'éditeur synchrone est un outil qui permet à un codeur de leçon avec le système DIVA de modifier les parties manuelles d'un programme produit par le générateur (section 3.5) et correspondant à un script d'une leçon produit interactivement avec l'éditeur de script (section 3.4). Il peut y avoir en même temps plusieurs paires de fenêtre de script/programme sur l'écran. Le codeur peut aussi ouvrir une fenêtre de script ou de programme 'solitaire'. Il peut ensuite ouvrir une autre fenêtre 'solitaire', et les lier pour former une paire.

      Depuis le menu principal de SyncEd (Figure 3.4), le concepteur peut choisir

      

Figure 3.4 Menu (en français) de l'éditeur synchrone

      

Figure 3.5 Fenêtre de choix de langage

      

Figure 3.6 Fenêtre de sélection de script

      Le menu de l'éditeur synchrone est précédé d'un choix de langage (Figure 3.5). L'utilisateur sera d'abord invité à choisir un langage qu'il souhaite utiliser parmi les langages disponibles (anglais, français, allemand, etc..), à moins qu'il y ait seulement un seul disponible (dans ce cas ce langage est utilisé directement). Ce choix concerne les menus (principal et contextuel) et les différents messages du système.

      L'option 'Ouvrir Editeur de script' du menu principal fait apparaître un panneau de sélection de fichier pour permettre à l'utilisateur de choisir le script à éditer. Les noms des fichiers de message existants sont proposés (Figure 3.6). Dans le cas ou le nom donné n'existe pas encore, l'éditeur considère qu'il s'agit d'une création de nouveau script.

      Note

      La langue des messages du script utilisé dépend du fichier choisi lors du chargement du script.

      Une fenêtre similaire s'affiche pour l'option 'Ouvrir Editeur de Programme' (Figure 3.7) mais les noms de fichier proposés sont des noms de fichier de programme contenant les modules manuels produits par le générateur (section 3.5.3). L'option 'paire' ouvre successivement ces deux types de fenêtres.

      

Figure 3.7 Fenêtre de sélection de programme

      Contrairement aux éditeurs paires, les éditeurs solitaires n'offrent pas la possibilités de synchronisation entre script et programme. Pour avoir cette possibilité, il faut les lier (option 'Lier Editeurs'). Lorsque un des éditeurs paires (ou liés) est fermé, celui qui reste perd la fonctionnalité de synchronisation.

      L'éditeur affiche le script et le programme correspondant simultanément sur l'écran dans deux fenêtres de sorte que le codeur puisse facilement voir le script et son programme correspondant. Dans une des fenêtres, il peut se déplacer à n'importe quelle partie du script (ou du programme) et puis 'synchronise' les deux fenêtres afin de voir la section correspondante du programme (ou du script). Si la synchronisation est faite depuis l'éditeur de programme, le curseur clignote sur le noeud correspondant dans l'éditeur de script. Réciproquement, si la synchronisation est faite depuis l'éditeur de script, le numéro du noeud correspondant est mis en sur brillance dans l'éditeur de programme.

      Les éditeurs de script solitaires sont en mode lecture/écriture tandis que ceux qui sont liés sont en mode lecture seule. Si l'utilisateur lie un éditeur de script solitaire à un éditeur de programme, il devient en mode lecture seule. Si l'utilisateur a fait des modifications dans l'éditeur de script solitaire, il ne peut pas lier cet éditeur jusqu'à ce qu'il sauve les changements. Les éditeurs de script en mode lecture seule passent en mode lecture/écriture si l'utilisateur arrête l'éditeur de programme correspondant, de ce fait l'éditeur de script devient solitaire .

      Un mécanisme de contrôle de version a été établi dans l'éditeur synchrone pour permettre aux codeurs de trouver facilement les endroits où un script a été modifié, afin de contrôler si le code doit être mis à jour en conséquence.


3.4 L'éditeur de script

      L'éditeur de script [Soussan89] est l'un des deux composants formant l'éditeur synchrone. Le but de l'éditeur de script est d'offrir une interface interactive utilisée pour la création et la modification des scripts décrivant le flot d'interactions possibles (flot de contrôle) entre l'étudiant et le système d'EAO.

      Un script est un type spécial de graphe orienté défini pour la description de cette interaction et utilise des noeuds et des arcs selon le formalisme décrit ci-dessus. Les arcs indiquent les déroulements possibles de la leçon. Les noeuds peuvent être des types définis ci-dessus. La plupart des noeuds ont un contenu textuel qui est partiellement visible dans le graphe (Figure 3.11). Pour voir son contenu complet, le concepteur peut double-cliquer sur un noeud, et une fenêtre séparée apparaîtra avec le contenu complet (Figure 3.12).

      L'éditeur de script est appelé depuis le menu de l'éditeur de synchrone (Figure 3.4).


3.4.1 La surface d'édition de l'éditeur de script

      La fenêtre de l'éditeur de script se compose d'une zone de script, d'une barre de défilement vertical, d'une barre de défilement horizontal et d'une zone d'information (Figure 3.8). La zone d'information se trouve au-dessous de la barre de défilement horizontal. Sa première ligne est réservée pour les messages du système et les avertissements possibles. Les trois dernières lignes de cette zone (bas de la fenêtre) montrent en permanence les fonctions courantes des bouton de la souris.

      

Figure 3.8 Fenêtre d'édition de l'éditeur de script

      La présentation graphique du script est organisée sur une grille. La grille se compose d'un certain nombre de mailles et de gouttières alternatives (Figure 3.9). Le côté supérieur de la zone commence toujours par une gouttière horizontale et le côté gauche par une gouttière verticale. Une maille peut contenir un noeud ou, quand aucun noeud ne l'occupe, elle peut contenir un arc vertical et/ou horizontal. Une gouttière peut seulement contenir des arcs, excepté les gouttières horizontales qui sont superposées par des noeuds Test appartenant à la même cascade. La représentation d'un noeud est habituellement limitée à une maille. La seule exception est quand les noeuds Test ont plus de deux arcs sortants.

      

Figure 3.9 Grille de la zone d'affichage de script


3.4.2 Les fonctionnalités offertes

      Les différents menus de l'éditeur sont organisés dans une structure arborescente. Le menu principal est le premier menu jaillissant (pop up menu). Tous les autres menus sont inclus dans la structure arborescente, et sont accessibles par des sous-menus de la racine. Pour certains éléments un sous-menu peut être atteint.

      Certains fonctions dans le menu ont seulement un sens dans des situations bien précises. La mise en place d'un arc, par exemple, peut seulement avoir un sens si le point d'insertion est placé sur un noeud. L'éditeur met hors fonction tous les éléments du menu qui ne peuvent pas s'appliquer à la situation courante, selon la position du point d'insertion.

      Habituellement, les commandes s'appliquent sur la sélection actuelle, chaque fois que cette sélection est un opérande approprié à la commande. S' il n'y a aucune sélection ou la sélection est insatisfaisante pour la commande (par exemple la commande implique un noeud simple et la sélection contient plus d'un noeud), l'utilisateur est incité à faire une sélection sur laquelle la commande s'appliquera.

      Un point d'insertion est toujours présent dans le graphe. Il est représenté par

      

      Il peut être placé:

  • dans une maille vide: le nouveau noeud est créé dans cette maille sans successeur ni prédécesseur;
  • au début d'un arc: le nouveau noeud sera placé entre le noeud d'origine et le noeud de destination de l'arc (accompagné d'une création automatique d'un deuxième arc);
  • à la fin d'un arc: ceci est seulement possible si le noeud de destination de cet arc est un noeud Test, alors le noeud Test nouvellement créé fera partie de la même cascade.
  • sur un noeud, alors un nouveau noeud sera créé comme successeur de ce noeud. Si possible, le nouveau noeud sera placé dans la direction donnée par le point d'insertion. Un arc est créé automatiquement entre les deux noeuds.

      L'éditeur permet donc de créer, de modifier et de valider un script. La modification d'un script affecte les détails existants, comme le changement des points d'extrémités d'un arc, le changement (édition) du contenu d'un noeud, le changement d'étiquette d'un arc, le changement de position d'un noeud, le changement de point de départ d'un script (le point de départ, également appelé point d'entrée, d'un script est le noeud à laquelle son exécution devrait commencer). La validation de script l'examine pour des éventuelles incohérences. Le script est contrôlé pour rechercher:

  • des noeuds inaccessibles (isolés);
  • des noeuds vides;
  • des noeuds Test sans arc de succès;
  • des noeuds Test avec des étiquettes incomplètes ou avec des chevauchements.

      Si une erreur est trouvée, alors le curseur sera placé sur le noeud correspondant. Un avertissement dans la zone d'information indiquera de quel genre d'erreur il s'agissait. S' il y a plus d'une erreur, l'utilisateur doit effectuer la validation plusieurs fois.

      Il a été aussi convenu qu'un script doit commencer par un noeud Documentation donnant le nom du script, suivi d'un deuxième noeud Documentation décrivant le script. La validation de script vérifie donc l'existence de ces deux noeuds au début du script. Cette convention est utile pour l'outil de vue d'ensemble d'un projet créé avec le système DIVA (section 3.7.2).


3.4.3 Les fichiers liés au script

      Dans le système DIVA, un script est intérieurement représenté comme un ensemble d'au moins deux fichiers, un pour la structure du graphe (fichier de graphe appelé aussi fichier de script), et un ou plusieurs fichiers pour le contenu de tous les noeuds qui traitent l'interaction (entrée/sortie) avec l'utilisateur (fichier de message, un pour chaque langage supporté).

      Cette séparation facilite la traduction des dialogues des programmes en différents langages, car le fichier de message contient tout le texte qui apparaîtra sur l'écran de l'utilisateur et tous critères d'analyse de réponse employés pour manipuler l'entrée textuelle de l'utilisateur. Une fois que le fichier initial de message est traduit à d'autres langages, le fichier de script peut être utilisé en combinaison avec n'importe quel fichier de message disponible.

      L'éditeur de script donne automatiquement un nom pour chaque message et le fichier de script utilisera ces noms dans les noeuds de message. En nommant le script et les fichiers de message, la convention suivante devrait être utilisée: Si le nom du fichier de script est 'ScriptExample', alors les fichiers de message correspondants devraient combiner le nom du fichier de script avec une extension indiquant le langage utilisé dans le fichier. Le fichier de message avec le texte en anglais devrait être nommé 'ScriptExample.e'.


3.4.3.1 Le fichier de script

      L'en-tête du fichier de script est une chaîne de caractères spéciale employée pour s'assurer que le fichier a été vraiment produit par l'éditeur de script. La deuxième ligne indique l'identification de noeud la plus élevée utilisée dans le script, l'identification du noeud d'entrée du script et son numéro de version. Le reste du fichier représente les noeuds.

      Les noeuds sont séparés l'un de l'autre par des lignes vides et il doit y avoir une ligne vide à la fin du fichier. Si le texte d'un noeud contient une ligne vide, l'éditeur de script la remplacera par une ligne contenant un simple caractère espace pour le différencier des lignes de séparation.

      Pour chaque noeud il y a d'abord une ligne d'information indiquant les caractéristiques suivantes du noeud:

  • L'identificateur de noeud (un nombre positif).
  • La position du noeud. Cette position n'a aucune signification sémantique. Elle est juste employée pour garder la disposition visuelle des noeuds dans le script. La position est donnée dans un système de coordonnées qui ressemble à celui de la Figure 3.10. Une grille de base est créée sur ce système et la position d'un noeud est donnée dans l'unité de la grille. Le nombre de pixel sur une unité de grille peut être changé afin de rendre le script plus ou moins compact.
  • Le type du noeud. Le type est indiqué par une lettre M, C, T, D, S, L ou A. M signifie Message, C signifie Commande (qui correspond au noeud de type Directive), T pour un Test, D pour la Documentation, S pour l'appel de Sous- graphe (sous-script), L pour un noeud étiquette (Label en anglais, ne pas confondre avec une étiquette d'arc) et A signifie Audiovisuel (ou encore Media).
  • La liste de successeurs et des étiquettes correspondantes. L'identification du successeur est donnée le premier suivi de l'étiquette de l'arc reliant le noeud courant à ce successeur. Si les étiquettes minimum et maximum sont égales, alors les étiquettes sont représentées par juste un nombre entier, autrement les étiquettes minimum et maximum sont séparées par deux points (min..max). Pour un noeud Test, le successeur ayant l'étiquette '0' représente le successeur d'échec.

      

Figure 3.10 Système de coordonnées pour les positions des noeuds

      La ligne d'information est suivie d'un certain nombre de lignes de textes:

  • Si le type du noeud est un message, alors il devrait y avoir une et seulement une ligne de textes et cette ligne contient le nom du message qui peut être trouvé dans un fichier de message.
  • Pour tous les autres types de noeuds, les lignes de textes indiquent le contenu du noeud. Ce contenu peut être vide, dans ce cas il n'y a aucune ligne de textes.

      Voici un exemple de représentation d'un noeud Test, extrait du fichier de script de l' Exemple 3.8:

      

Exemple 3.9 Exemple de représentation d'un noeud Test

  • Ceci représente un noeud avec l'identificateur 5. Le noeud se trouve à la position (2,5) de la grille, et il s'agit d'un noeud Test. Ses successeurs sont les noeuds avec les identificateurs: 6, 10 et 15.
  • Les noeuds 5 et 6 font partie de la même cascade et l'arc qui les relie (de 5 vers 6) est un arc d'échec puisque l'étiquette est 0.
  • Les arcs reliant le noeud 5 avec le noeud 10 et le noeud 15 sont des arcs de succès et sont étiquetés respectivement 3 et 1..2.

      L'exemple de représentation d'un noeud Message suivant est aussi extrait du même fichier de script de l'Exemple 3.8:

      

Exemple 3.10 Exemple de représentation d'un noeud message

      Il s'agit d'un noeud Message avec l'identificateur 10, se trouvant à la position (3,9), et ayant comme successeur le noeud identifié par 16. Puisque ce n'est pas un noeud Test, il n'y a qu'un seul successeur.

      Traitons01 est le nom du message correspondant dans le fichier de message. Ce message commence donc par 'Traitons'. Les noms sont numérotés pour éviter les messages de même nom.

      Note

      Dans le fichier de script, les nombres consécutifs sont séparés par un espace.


3.4.3.2 Les fichiers de message

      Un fichier de message fait la correspondance entre les noms de message, se trouvant dans le fichier de script, et les messages eux-mêmes. Le fichier de message devrait contenir tous les messages pour lesquels un nom est utilisé dans le fichier de script.

      Le fichier de message commence par une en-tête indiquant à quelle version de script ce fichier de message correspond. Cette ligne commence par \\-- et sera considère comme un commentaire. Pour chaque message nous avons l'information suivante:

  • Une ligne avec le nom du message. La ligne commence par la chaîne de caractères '<<', suivie du nom de message composé exactement de dix caractères, et finit par la chaîne de caractères '>>'.
  • Une ligne de commentaire indiquant dans quelle version de script le message a été pour la dernière fois modifié.
  • Le message lui-même. Il peut se composer d'autant de lignes que nécessaires, mais chaque ligne est limitée à 80 caractères. Elle peut être vide.
  • Une ligne indiquant la fin du message. La ligne commence par la chaîne de caractères '<<END', suivie du nom du message, et finit par la chaîne de caractères '>>'.

      Le texte en dehors de la structure donnée ci-dessus devrait commencer par '\\--'. Ce sont des commentaires et ils sont ignorés par l'éditeur de script.

      L'éditeur de script crée les noms des messages en prenant les huit premières lettres du contenu du message et en y ajoutant un nombre à deux chiffres. Le numéro 01 est utilisé la première fois que les huit lettres se produisent au début d'un message et il est incrémenté pour les prochains messages avec ces mêmes huit premières lettres. Le nom d'un message est créé la première fois où un texte est placé dans le noeud. Une fois qu'un nom est donné à un message, ce nom ne peut pas être modifié. Le contenu d'un message peut être radicalement changé de telle sorte que les lettres du nom ne correspondent plus au début du message.

      Dans le fichier de message associé au script de l'Exemple 3.8, le message correspondant au dernier noeud Message a la forme:

      

Exemple 3.11 Représentation d'un message dans un fichier de message

      Note

      Pour notre bout de leçon donnée dans l'Exemple 3.8. Le graphe a été créé 'manuellement' avec un éditeur classique (dessin FrameMaker). Avec l'éditeur de script nous avons le graphe (script) présenté dans la Figure 3.11.

      Comme nous remarquons dans cette figure, les contenus textuels des noeuds sont seulement visibles en partie dans le graphe. Pour voir le contenu complet du noeud, l'utilisateur doit choisir la commande 'Montre Noeud'. Une fenêtre d'édition de texte s'ouvre en mode lecture seule et affiche le contenu du noeud. Par exemple, la Figure 3.12 affiche le contenu du noeud Message donnant l'énoncé de la leçon, qui est partiellement affiché comme la chaîne de caractères 'Combien' dans le graphe de la Figure 3.11. La barre supérieure de la fenêtre contient l'identificateur du noeud en question. La même fenêtre mais ouverte en mode lecture/écriture (Figure 3.13) est utilisée pour l'édition du contenu du noeud lors de la création du noeud. L'utilisateur peut modifier le contenu du noeud en choisissant la commande 'Edite/Change/Contenu' ou en double-cliquant sur le noeud.

      

Figure 3.11 Un simple script créé avec l'éditeur de script

      

Figure 3.12 Affichage du contenu d'un noeud

      

Figure 3.13 Edition du contenu d'un noeud

      Le sauvegarde sur le disque du script de la Figure 3.11 crée le fichier de script (simplescript) et le fichier de message (simplescript.f). Le contenu du fichier de script, qui est généralement caché aux utilisateurs, est le suivant:

      

      

Exemple 3.12 Contenu du fichier de script

      Le contenu du fichier des messages correspondant est:

      

      

Exemple 3.13 Contenu du fichier de message en français

      Pour avoir des messages dans un autre langage, par exemple l'anglais, seuls les textes des messages seraient traduits et seraient mis dans un nouveau fichier de message avec l'extension '.e'. Dans le cas de cet exemple le nom du fichier de message en anglais serait donc simplescript.e. Les noms des messages qui sont créés à leur création reste toujours les mêmes. Un outil de gestion des traductions a été conçu pour aider les concepteurs dans cette tâche (voir section 3.7.1).


3.5 Le générateur de code


3.5.1 Le modèle d'exécution

      Initialement, le déroulement du programme avec le système DIVA dépend seulement du flot de contrôle. Pendant l'exécution d'un graphe, un noeud peut être dans l'un des deux états suivants: dormant et actif. Au début, un noeud se trouve à l'état dormant. Lorsqu' un de ses prédécesseurs lui envoie un jeton de contrôle (c'est-à-dire, a fini de s'exécuter), il devient actif. A la fin de son exécution, il envoie un jeton de contrôle à son successeur et retourne à l'état dormant.

      Le comportement est un peu différent pour un noeud de type test. Le choix de son successeur dépend de la valeur du compteur associé. Les compteurs sont initialisés à 0 au début de l'exécution du script. Un noeud Directive spécial, 'reset counters', peut être utilisé avant une cascade de noeuds Test pour imposer une remise à zéro explicite de tous les compteurs associés à cette cascade. Puisque la plupart des cascades implique une boucle, il est fortement indiqué au concepteur de mettre explicitement un noeud 'reset counters' avant chaque cascade. Ceci mettra en valeur la lisibilité de la spécification.

      Ce modèle d'exécution est pris en compte par le générateur automatique de code.


3.5.2 Les caractéristiques du générateur de code

      Le générateur de code automatique [Aubord88][Aubord91] est un programme qui prend comme entrée un script produit par l'éditeur de script et génère en sortie un ensemble de fichiers contenant des codes sources, dans un certain langage de programmation, pour implanter l'application spécifiée par le script.

      Les détails de la syntaxe du langage de programmation cible sont gardés séparés de la logique du générateur de code. Ceci permet de créer très facilement des différentes versions du générateur qui produisent des codes sources dans différents langages de programmation. Les langages de programmation suivants sont actuellement supportés: Turbo Pascal, Vax Pascal, Sun Pascal, Ada et JavaScript. Pour pouvoir séparer les langages cibles utilisés de la génération du code, le générateur est composé de deux parties: Une partie s'occupant de la génération de code, un autre traitant l'interfaçage avec les différents langages cibles.

      Le formalisme que nous utilisons pour les scripts est semi-formel, c'est-à-dire quelques parties d'un script suivent une syntaxe formelle et d'autres sont en langage naturel. Les parties formelles sont: les types de noeud, la logique de l'exécution (c'est-à-dire, l'ordre dans lequel les noeuds sont exécutés, indiqué par les arcs reliant les noeuds d'un script), les étiquettes sur les arcs provenant d'un noeud Test et la sortie textuelle d'écran (noeuds de message). Les parties non-formelles correspondent aux textes en langage naturel trouvés dans les directives au codeur et aux prédicats dans les boîtes de test. Les noeuds d'appel de sous-graphe peuvent également contenir de l'information non-formelle, par exemple pour indiquer quelle information devrait être passée entre les scripts appelant et appelé.

      L'approche choisie pour la génération automatique est la suivante. Les parties formelles d'un script sont représentées par un automate à états finis. Chaque noeud du graphe correspond alors à un état de l'automate et chaque arc à une transition d'un état vers un autre. A chaque état de l'automate, on exécute le code de l'un des noeuds du script. L'automate à états finis (pour le langage cible Pascal) est de la forme:

      


3.5.3 Les résultats de la génération de code

      Le code pour l'automate à états finis se trouve dans un module séparé et est éclaté en deux fichiers nommés du nom du script correspondant: Xxx.DEF et Xxx.IMP (Xxx étant le nom du script). Le fichier .DEF contient l'interface du module, c'est-à-dire la déclaration de la procédure de l'automate à états finis, et le fichier .IMP contient l'implantation du module, c'est-à-dire le corps de la procédure de l'automate à états finis. Quand un script est mis à jour ou modifié, les deux fichiers contenant l'automate à états finis sont complètement régénérés à partir de zéro. Ces fichiers ne devraient donc jamais être modifiés par un programmeur, autrement, ses changements seront détruits la prochaine fois que le code est régénéré.

      Le générateur de code ne peut pas produire le code nécessaire correspondant aux parties non-formelles du script. Pour cela il génère un deuxième module qui sera modifié à la main par le programmeur (hand-coded module). Ce module est également éclaté en deux fichiers, un pour l'interface (nommé XxxTC.DEF) et un pour l'implantation (nommé XxxTC.IMP). Ce module contient une procédure générale d'initialisation, une procédure par directive au codeur (par noeud Directive), et une fonction booléenne par boîte de test dans le script.

      Le fichier d'interface est automatiquement produit et ne devrait pas être modifié par le(s) programmer(s). Par contre, le fichier d'implantation est initialement généré automatiquement avec un corps factice pour chaque procédure. Les codeurs sont censés remplacer ces corps factices par le code qui fait réellement ce que les créateurs (concepteur) ont demandé dans la directive au codeur ou dans le critère de boîte de test. Quand un tel fichier XxxTC.IMP existe déjà et le générateur de code est exécuté de nouveau, le générateur n'écrase pas le fichier existant, de sorte qu'aucun code manuel ne soit détruit. Au lieu de cela, le générateur fusionne le code existant au code automatiquement produit qui serait nécessaire pour les directives ou boîtes de test nouvellement ajoutées.

      Le fonctionnement du générateur du code peut être résumé comme suit. Pour chaque noeud du script, il analyse son contenu. Il ajoute une entrée (état) correspondant à ce noeud dans l'automate à états fini et fournit le comportement de l'application lorsqu'elle est dans cet état. Ceci pourrait être

  • soit un simple changement d'état si aucune opération n'est nécessaire (cas des noeuds Documentation et Etiquette),
  • soit un appel de la procédure d'affichage de message s'il s'agit d'un noeud message, suivi du changement d'état;
  • soit un appel d'une procédure dans le cas des noeuds Directive, appel Sous-graphe et Audiovisuel. Cette procédure devrait être en même temps déclarée dans le module à coder à la main, suivi aussi du changement d'état;
  • soit un appel d'une fonction booléenne dans le cas de noeud Test. elle devrait aussi être déclarée dans le module à coder à la main. Le changement d'état dépend de l'évaluation de cette fonction. Puisque le noeud Test peut avoir plusieurs successeurs, le changement d'état dépend de la valeur de compteur associé au noeud Test en question.

      Le générateur produit également un cinquième fichier qui est très petit et contient un programme principal qui pourrait exécuter le code implanté du script. Ce fichier, nommé Xxx.PRG, ressemble généralement à ceci, pour le langage Pascal:

      

Exemple 3.14 Contenu d'un fichier de programmes

      Puisque les instructions déclaratives nécessaires au début d'un programme, ou d'un module, pour utiliser (importer) d'autres modules sont non seulement dépendants du langage, mais aussi du système d'exploitation, il a été décidé que ces déclarations de liste d'importation seraient rendues disponibles au générateur de code par des fichiers sources qui seraient baptisés du nom du fichier produit par le générateur auquel elles seraient incluses. C'est-à-dire, pour chacun des cinq fichiers produits par le générateur, un fichier correspondant de déclaration de liste d'importation sera recherché, et son contenu sera copié dans le fichier produit à l'endroit approprié pour les déclarations de liste d'importation (habituellement au début du fichier).

      Voici la convention pour nommer les fichiers de liste d'importation:

  • Pour Xxx.PRG, la liste d'importation sera recherchée dans XxxPrg.DAT;
  • pour Xxx.DEF, la liste d'importation sera recherchée dans XxxDef.DAT;
  • pour Xxx.IMP, la liste d'importation sera recherchée dans XxxImp.DAT;
  • pour XxxTC.DEF, la liste d'importation sera recherchée dans XxxTCDef.DAT;
  • pour XxxTC.IMP, la liste d'importation sera recherchée dans XxxTCImp.DAT.

      Si certains de ces fichiers .DAT ne sont pas trouvés, rien ne sera inséré dans le fichier correspondant produit, et le générateur l'indiquera par des messages. Ces messages ne devraient pas être confondus avec des messages d'erreur. Il n'y aucun problème même si un fichier généré n'a pas de liste d'importation insérée.

      Continuons le développement de notre extrait de leçon de l'Exemple 3.8. Supposons que nous voulons maintenant utiliser un des générateurs existants pour produire les codes, par exemple
générateur pour Turbo Pascal. Puisque notre script s'appelle simplescript, les fichiers générés par ce générateur sont:

  • simplescript.DEF
  • simplescript.IMP
  • simplescript.PRG
  • simplescriptTC.DEF
  • simplescriptTC.IMP

      Le fichier simplescript.PRG utilise la procédure Initsimplescript déclarée dans simplescriptTC.DEF et la procédure Codesimplescript définie dans simplescript.DEF. Ces deux fichiers doivent être mentionnés dans le fichier de données simplescriptPrg.DAT qui donne la liste d'importation pour le fichier simplescript.PRG. De même, des listes d'importation sont aussi nécessaires pour les fichiers simplescript.IMP et simplescriptTC.IMP.

      Note

  • Quelques modules devraient être disponibles lorsque le code produit est compilé et exécuté. Ces modules compléteraient le code produit, comme une bibliothèque d'exécution (run-time library). Deux modules principaux sont systématiquement utilisés dans le code produit: un module pour gérer l'interaction homme-machine et les routines d'affichage, et un autre module pour traiter et utiliser les fichiers de message.

3.6 L'éditeur de programme

      L'éditeur de programme est le second composant de l'éditeur synchrone. Le code manuel dans le fichier XxxTC.IMP devrait de préférence être écrit et/ou modifié avec l'éditeur de programme. L'éditeur de programme est donc un outil qui permet à un codeur de leçon de modifier les parties manuelles du programme produit par le générateur correspondant à un script de leçon produit en mode interactif avec l'éditeur de script.

      

Figure 3.14 Edition fichier simplescriptTC.IMP dans une fenêtre de l'éditeur de programme

      L'éditeur de programme (Figure 3.14), utilisé pour modifier le code produit correspondant à un script, est similaire à l'éditeur utilisé pour le contenu d'un noeud (Figure 3.13) dans l'éditeur de script. Cependant en plus des fonctionnalités de base d'un éditeur de texte, chaque éditeur (programme ou contenu de noeud) a son propre menu. L'éditeur de contenu de noeud offre des commandes permettant de se positionner dans le noeud correspondant ou de le faire clignoter, tandis que l'éditeur de programme offre la synchronisation lorsqu'il est lié à un éditeur de script.

      L'éditeur de programme a une fonction qui 'actualise' le code d'un noeud d'un script, c'est-à-dire, permet au système de savoir que le code factice qui a été initialement produit par le générateur automatique de code a été maintenant remplacé (modifié) manuellement par un code qui fait réellement ce que les concepteurs ont demandé. L'éditeur synchrone insère alors dans le code un commentaire de programme qui contient le texte de la directive au codeur ou du critère de test.

      

Exemple 3.15 Code (en Pascal) factice généré pour un noeud de directive au codeur.

      Et voici la même procédure, après qu'il a été codé manuellement et 'actualisé'.

      

Exemple 3.16 Code (en Pascal) après actualisation.

      Le commentaire de Pascal qui se trouve entre la ligne (* N:#64 *) et la déclaration de la procédure a été automatiquement ajouté par l'éditeur synchrone lorsque le codeur a choisi actualise' dans le menu de l'éditeur de programme.

      Un autre élément du menu ('Divergence') indique au système de trouver le prochain sous-programme dans le code qui n'est pas à jour avec sa spécification, c'est-à-dire, la prochaine procédure qui n'avait jamais été remplacée manuellement, ou pour laquelle la spécification a changé dans le script depuis la dernière fois où le sous-programme 'a été actualisé'. Ceci est fait dans l'éditeur synchrone en comparant le texte des directives au codeur et les boîtes de test avec les commentaires de programme qui ont été inclus dans le code lorsque la commande 'Actualise' a été utilisée.

      Les codeurs ne sont pas obligés à utiliser l'éditeur de programme pour écrire le code manuel. Cependant, s'ils ne l'utilisent pas, ils perdront les avantages du mécanisme de contrôle de version offert par l'éditeur synchrone, et auront des problèmes pour trouver dans le code les endroits à mettre à jour une fois que le script a été modifié.


3.7 Les outils supplémentaires

      

Figure 3.15 Les outils supplémentaires du système DIVA

      En plus du noyau du système DIVA (formé par l'éditeur synchrone et le générateur de code), d'autres outils supplémentaires (Figure 3.15) ont été créés pour aider les concepteurs, les codeurs et les utilisateurs des applications créées avec ce système. Certains de ces outils sont déjà conçus pour être utilisés avec l'extension du système (intégration du flot de donnée).


3.7.1 Gestionnaire de traductions (Translation manager)

      Le gestionnaire de traductions facilite le maintient de la cohérence entre les différentes traductions des leçons multi-langues, en indiquant les messages qui diffèrent d'une traduction à l'autre.

      

Figure 3.16 Interface utilisateur du gestionnaire de traduction

      Si le logiciel doit être employé par des étudiants de diverses origines linguistiques, les dialogues et les critères d'analyse des réponses textuelles doivent être traduits en d'autres langages. Ceci peut être fait par des traducteurs professionnels en utilisant le gestionnaire de traduction. Cet outil multifenêtre 'éditrice' (Figure 3.16) présente au traducteur, le contenu des noeuds de message de la spécification dans une fenêtre, un message à chaque fois. Dans une autre fenêtre, le traducteur peut introduire au clavier la traduction du message.

      Un mécanisme de contrôle de version, similaire à celui de l'éditeur synchrone, est inclus dans l'éditeur de traduction pour rendre facile la localisation des changements dans le texte des dialogues depuis que la dernière traduction a été faite. Les traducteurs indiquent d'abord quel langage est l'original, et à quelle traduction ils veulent travailler. Puis, ils doivent seulement vérifier ce qui a changé sur les messages spécifiques concernés par les changements. Dans différentes fenêtres, le contenu d'un noeud de message est affiché dans le langage original, avant et après le changement. La traduction est aussi montrée aux traducteurs, s'il en existait déjà, et ils peuvent la changer si nécessaire, basé sur les changements faits dans le langage initial, ou ils peuvent créer une nouvelle traduction si aucune n'existait avant. Ils peuvent donc d'un seul coup faire des changements et mettre rapidement la traduction à jour.

      Les fenêtres éditrices sont synchronisées entre-elles et toute requête, formulée dans l'une d'elles pour rechercher le message non valide suivant ou pour revenir sur des messages déjà traités, provoque le même déplacement dans les autres fenêtres. A tout moment, elles affichent le même message mais dans des langues et des versions différentes.


3.7.2 Outil pour la vue d'ensemble de projet (le Lister)

      Le but de ce programme est de donner une vue d'ensemble d'un groupe de scripts qui ont des références entre eux. Il se sert de noeud de type 'appel de sous-graphe'. Il est fondé sur les hypothèses suivantes:

  • une référence à une autre script est faite par un noeud d'appel de sous-graphe qui commence par le nom d'un autre script.
  • le noeud après le point d'entrée dans un script est une documentation qui récapitule le but de ce script. Ceci implique que les concepteurs suivent la convention que le point d'entrée soit un noeud de documentation avec le nom de la 'routine' et le noeud venant après soit un deuxième noeud de documentation qui explique ce que fait le sous-programme .

      

Figure 3.17 Menu de l'outil Lister

      Etant donné un script racine, ce programme trouvera tous les scripts directement ou indirectement référencés depuis cette racine. Le programme peut exécuter deux fonctions, depuis son menu (Figure 3.17):

      1. Enumérer les scripts et leurs références croisées: la sortie du programme est un fichier qui contiendra

  • pour chaque script trouvé:
    • le nom du script,
    • le contenu du premier noeud documentation trouvé après le point d'entrée dans le script (si le script n'existe pas, le programme met une ligne qui l'indique)
    • la liste de scripts qui sont mentionnées dans un noeud d''appel '
    • la liste de scripts qui font référence à ce script racine.
  • Le fichier de sortie de ce programme est créé dans le répertoire courant, sous le nom de MyScript.RES, où Myscript est le script racine. Le programme créera également un autre fichier nommé MyScript.STA qui est utilisé pour exécuter la deuxième fonction.

      2. Enumérer les scripts qui n'ont pas encore été créés: le programme sort sur l'écran la liste de scripts qui ont été référencés, mais n'existent pas (c'est-à-dire les scripts qui doivent encore être créés). Afin d'exécuter la deuxième fonction, l'utilisateur DOIT d'abord exécuter la première fonction.


3.7.3 Outil d'impression de script ou graphe décoré

      Comme nous l'avons remarqué, une partie du contenu du noeud est visible dans le graphe de script affiché par l'éditeur de script. L'utilisateur peut voir le contenu entier en choisissant le menu 'Montre noeud' ou en cliquant deux fois sur le noeud.

      Pour des copies sur papier de ces graphes, il est préférable que le contenu de chaque noeud soit entièrement visible. Ainsi, un outil d'impression spécifique [Dupuis95], baptisé PDG (Printing Decorated Graph), a été développé pour imprimer les graphes de script. Une des spécificités de ces graphes de script est que le contenu de chaque noeud est un texte de taille variable, qui peut aller de zéro au delà d'un millier de caractères. A l'impression, les noeuds ne vont pas garder les même dimensions du fait de cette variabilité de leur tailles.

      La Figure 3.18 présente le script du fameux programme 'bouteilles de bière' (Bottles of beer). Dans cette figure, seuls quelques caractères au début du contenu de chaque noeud sont visibles. L'impression avec PDG nous donne le contenu complet du graphe (Figure 3.19). Dans ce graphe, le contenu de chaque noeud est entièrement affiché.

      Le nom du fichier contenant les messages du graphe (nom du graphe suivi de l'extension de la langue) doit être spécifié sur la ligne de commande, avec le nom du programme PDG, en utilisant l'option '-fi'. Les autres options sont facultatives:

  • -h : liste des options.
  • -fi <fichier> : nom du fichier contenant les textes des noeuds de type ' Message '
  • -fo <A5,....,A0> : format du papier. (par défaut A4)
  • -l <10..50> : longueur des traits de coupe en [pt]. ( 25[pt] correspond à peu près à1[cm] ) (par défaut 15)
  • -o <1,2,3> : orientation du dessin. (1 : libre, 2 : paysage, 3 : portrait) (par défaut 1)
  • -s : espace minimum entre les noeuds en [pt]. (par défaut 20)
  • -j <1,2> : justification du texte dans les noeuds (1: justifié, 2: cadré à gauche, par défaut 1)
  • -a <1..10> : espace minimum entre des arcs n'arrivant pas aux mêmes points en [pt] (par défaut 1)

      

Figure 3.18 Script du programme 'Bottles of beer'

      PDG crée, entre autres, un fichier Postscript qui est le fichier final prêt à être envoyé à l'imprimante. L'utilisateur pourrait ainsi le visualiser d'abord à l'aide d'un logiciel approprié (par exemple Ghostview) et relancer PDG avec des options s'il n'est pas satisfait du précédent résultat. Par exemple si les arcs sont trop rapprochés, il peut spécifier l'espacement de son choix en utilisant l'option '-a'. Dans ce cas il faut aussi augmenter en conséquence l'espace minimum entre les noeuds avec l'option '-s'. Des propositions d'amélioration de cet outils sont suggérées.

      

Figure 3.19 Sortie de PDG pour le script


3.7.4 Superviseur à distance d'exécution (Remote execution supervisor)

      Si les machines des étudiants sont connectées en réseau (local) avec les postes de travail des professeurs, ces derniers peuvent voir directement sur la spécification visuelle (graphe de script) le déroulement des leçons que les étudiants font , en utilisant un outil de surveillance appelé superviseur [Tiar98]. Le superviseur établit alors une connexion entre le programme d'application et sa spécification (graphe de script). L'utilisation du superviseur ajoute une nouvelle option dans le menu de l'éditeur synchrone (Figure 3.20).

      

Figure 3.20 Menu de SyncEd avec option du superviseur

      

Figure 3.21 L'interface du Contrôleur Central du superviseur

      En plus d'un Contrôleur Central (Figure 3.21), le superviseur utilise l'éditeur de script pour afficher la spécification du programme d'application en exécution, et suivre ainsi, noeud à noeud, son déroulement. La Figure 3.22 montre les composants mis en oeuvre par le superviseur.

      

Figure 3.22 Composants du superviseur

      Le programme d'application se charge de l'ouverture de la communication avec le Contrôleur Central, de l'envoi progressif des états atteints par le programme d'application au Contrôleur Central, et de l'arrêt des envois. Actuellement, les procédures qui assurent ces fonctionnalités, c'est-à- dire qui composent l'interface de communication, sont ajoutés à la main dans le module de l'automate à états finis (fichier 'Xxx.IMP'. L'exécution d'un programme d'application se fait par la commande 'nom_prog host port' , où nom_prog désigne le nom du fichier exécutable du programme d'application, host et port désignent où s'exécute le Contrôleur Central et à quel port il faut se connecter. Seules trois fonctions de l'éditeur de script, à savoir, afficher un script, faire clignoter un noeud et, enfin, faire fermer l'affichage d'un script sont utilisées par le superviseur. Ces fonctions sont activées au niveau de l'éditeur de script à partir des ordres provenant du Contrôleur Central.

      Le Contrôleur Central est constitué de trois composants. Le premier composant est le contrôleur dédié qui gère la communication entre le programme d'application correspondant et le contrôleur central. Le deuxième, appelée module statistique, s'occupe du calcul statistique et de la mise à jour des états provenant du programme d'application et le dernier, appelée transport, gère la communication entre le contrôleur central et l'éditeur de script.

      Execution Demo: Lorsque le superviseur est prêt (commande: Supervisor, ou menu: Connect to Supervisor), lancer dans une autre fenêtre l'application à surveiller.

      

Exemple 3.17 Lancement d'une application pour le superviseur


3.7.5 L'éditeur de structures et l'éditeur de constantes.

      Puisque l'extension de DIVA (DIVA-cd) devrait tenir compte des données (structures et valeurs des données), deux éditeurs spéciaux sont conçus pour aider les concepteurs d'applications; l'éditeur de structures et l'éditeur de constantes. L'éditeur de structures permet à l'utilisateur de créer ses propres types de données, tandis que l'éditeur de constantes permet la création des constantes de type prédéfini ou de type créé par l'utilisateur à l'aide de l'éditeur de structure. Ces deux éditeurs utilisent des représentations visuelles des types de données.


3.7.5.1 Les représentations graphiques des types de données.

      Les types de données offerts par le système DIVA peuvent être classés en deux groupes: les types de données statiques et les types de données dynamiques. Les types de données statiques incluent les types de données simples (comme le booléen, le nombre entier, le nombre réel, l'intervalle des nombres entiers, les caractères et les chaînes de caractères), et les types de données structurés (comme des tableaux et des enregistrements). Les types de données dynamiques sont surtout utilisés pour les données qui changent de cardinalité durant l'exécution. Pour cela, deux structures de données prédéfinies sont offertes: l'arbre et la liste.


3.7.5.1.a Représentations graphiques des types de données simples

      Pour les types de base, nous avons essayé de choisir une représentation visuelle qui serait facile à comprendre et à se rappeler (Figure 3.23).

  • Nous avons choisi le point d'interrogation (?) pour le booléen parce que sa nature de vrai/faux peut rappeler une question.
  • Le signe de nombre (#) est choisi pour les nombres entiers puisque ce signe est souvent associé à la notion d'une valeur numérique, même en dehors du monde d'informatique.
  • Les réels sont représentés par deux signes de nombre séparés par un point décimal (#.#) (dans certaines cultures, un autre caractère est utilisé comme séparateur décimal, mais le point décimal est probablement encore très largement compris).
  • Les intervalles des nombres entiers sont représentés avec un signe de nombre suivi d'un indice inférieur et d'un exposant; l'indice inférieur représente la limite inférieure de l'intervalle, et l'exposant représente la limite supérieure.
  • Les caractères sont représentés avec un petit rectangle, évocateur de la forme du curseur souvent affiché pour l'entrée de caractère.
  • En dernier lieu, les chaînes de caractères sont représentées comme rectangle plus large avec une valeur facultative à l'intérieur indiquant une longueur maximum possible.

      

Figure 3.23 Représentation graphique des types simples

      A première vue, la représentation visuelle peut sembler n'apporter aucune amélioration, comparée à une représentation textuelle. Mais la représentation visuelle est indépendante du langage. La représentation textuelle peut sembler très normale et intuitive aux anglophones, mais les non-anglophones n'ont pas la même sensation.


3.7.5.1.b Représentation graphique du type tableau

      Les tableaux sont des types de données structurées homogènes. Pour les représenter, nous avons choisi d'évoquer le concept d'un paquet de cartes (Figure 3.24), avec le type de base des éléments du tableau affiché sur la première carte (ce type de base peut être un type simple comme décrit sur la Figure 3.23, ou le nom ou l'image d'un type de données défini par l'utilisateur). L'intervalle des indices du tableau est indiqué par une valeur près du coin inférieur droit de la première et de la dernière carte. Un nom et/ou une image peut être associé à une structure de tableau, près de son coin supérieur gauche, pour représenter le type de données défini ainsi.

      

Figure 3.24 Représentation graphique du type tableau.


3.7.5.1.c Représentation graphique du type enregistrement

      

Figure 3.25 Représentation graphique du type enregistrement

      Les enregistrements sont aussi des types de données structurées mais qui sont hétérogènes. Ils sont représentés en boîtes rectangulaires subdivisés et chaque partie contient un composant (un champ) de l'enregistrement (Figure 3.25). Chaque subdivision peut, optionnellement, porter un nom à sa gauche, représentant le nom de ce composant de l'enregistrement. A l'intérieur de chaque subdivision est représenté le type du champ correspondant. Comme pour les tableaux, ce type peut être un type simple ou un type structuré autre que le type enregistrement qui est entrain d'être défini. Un nom et/ou une image peut être associé à une structure enregistrement, à coté de son coin supérieur gauche, pour représenter le type de données défini ainsi.


3.7.5.1.d Représentation graphique du type arbre

      Toutes les formes d'arbres sont représentées de la même manière, comme représenté sur la Figure 3.26. En définissant un nouveau type d'arbre, le programmeur doit indiquer le type de données contenues dans chaque noeud, le degré de l'arbre, et le nom ou le graphisme représentant le type nouvellement créé. Si le type du contenu n'est pas donné, un type prédéfini nommé 'notype' sera utilisé. Ceci permet d'avoir des types différents pour les noeuds de l'arbre.

      

Figure 3.26 Représentation graphique du type arbre


3.7.5.1.e Représentation graphique du type liste

      Les listes ont une représentation qui est très semblable aux tableaux, sauf la dernière carte qui est en trait pointillé au lieu de trait plein et les indices qui ont été retirés pour prouver que les éléments ne sont pas limités en nombre (Figure 3.27). Comme pour les arbres, si le type du contenu n'est pas donné, un type prédéfini nommé 'notype' sera utilisé. Ceci permet d'avoir des types différents pour les éléments de la liste. Les listes sont très souvent utilisées pour des tableaux illimités.

      

Figure 3.27 Représentation graphique du type liste


3.7.5.2 Editeur de structures

      L'éditeur de structure est un outil qui pourrait être utilisé dans la nouvelle version du système DIVA utilisant le nouveau formalisme pour l'intégration du flot de données. Il sert à créer de manière visuelle et interactive des structures (types) de données définies par l'utilisateur. Il fournit ainsi un support schématique des structures de données. Ce support schématique des structures de données est surtout censé être utilisé plutôt par les codeurs d'application que par les concepteurs initiaux. Son aspect visuel devrait cependant faciliter la compréhension par les non-programmeurs de ce qui est fait.

      L'ensemble de structures créées par l'éditeur de structure est enregistré dans un fichier (texte) avec l'extension .ds (data structure). La fenêtre principale de l'éditeur (Figure 3.28) donne à l'utilisateur la possibilité de créer un nouveau fichier de structure ou d'ouvrir un fichier existant pour le modifier ou consulter. Ces modifications peuvent être une création ou suppression d'une structure, ou la modification des caractéristiques d'une structure.

      

Figure 3.28 Fenêtre principale de l'éditeur de structure

      Quelques types sont déjà prédéfinis: les types simples (booléen, entier, réel, intervalle d'entier, caractère et chaîne de caractères) et quelques types structurés (tableau, enregistrement, liste et arbre). Pour les types structurés, le type des éléments peut être soit un des types simples prédéfinis soit un type créé par l'utilisateur et qu'on appelle sous-structure (Sub-structure). Le système vérifie si la sous-structure existe. Le cas échéant, un message d'alerte est affiché.

      La Figure 3.29 montre la fenêtre d'édition (création ou modification) d'une structure tableau. L'utilisateur doit fournir le nom de la structure, choisir l'icône représentant la structure (une icône par défaut est définie), modifier les indices minimal et maximal (par défaut <1,1>), choisir le type d'éléments du tableau (qui pourrait aussi être une structure, sous-structure, créée avec l'éditeur).

      

Figure 3.29 Fenêtre d'édition (création ou modification) d'une structure tableau

      Dans le fichier de structures, les structures sont séparées les unes des autres par une ligne composée par des séquences de '='. Le fichier contient le nombre de structures y existant. Pour chaque structure les informations suivantes sont enregistrées:

  • commentaire global sur la structure (optionnel)
  • son nom
  • l'icône (une valeur par défaut existe) qui la représente visuellement
  • son type
  • et s'il s'agit de type structuré, le type de ses éléments de base est aussi donné, les indices min et max pour les tableaux, le nom et le type de chaque champ pour les enregistrements, le degré (nombre maximum de successeurs) pour les arbres,...

      

Figure 3.30 Représentation graphique d'un fichier de structure avec 6 éléments

      La Figure 3.30 présente graphiquement un fichier de structure, appelé aaabb.ds, contenant cinq structures: MaListe qui est une liste de booléen, MaString qui est une chaînes de caractères dont la longueur maximale est 80, MonArbre qui est un arbre de chaînes de caractères de longueur maximale 80, MonEnreg qui est un enregistrement avec deux champs: Field0 de type entier et Field1 de type réel, MonEntier qui est un entier (type simple), et MonTableau qui est un tableau d'entier de trois éléments.

      Le contenu du fichier aaabb.ds correspondant à cet ensemble de six structures est présenté ci- après. Ce fichier ne contient pas de commentaire.

      

Exemple 3.18 Contenu d'un fichier de structure avec 6 éléments


3.7.5.3 Editeur de constantes

      Comme l'éditeur de structure, l'éditeur de constante pourrait aussi être utilisé dans le nouvel état du système DIVA, c'est à dire avec l'intégration du flot de données. Il permet à l'utilisateur de créer une constante qui sera ensuite utilisée par l'Editeur de script en tant que paramètre d'entrée d'un noeud par exemple. La fenêtre principale (Figure 3.31) de l'éditeur de constante ressemble à celle de l'éditeur de structure (Figure 3.28). Elle permet donc à l'utilisateur de créer un nouveau fichier de constantes ou d'ouvrir un fichier existant. La fenêtre d'édition de constante (Figure 3.32) permet de créer une nouvelle constante ou de modifier les caractéristiques d'une constante donnée.

      

Figure 3.31 Fenêtre principale de l'éditeur de constante

      

Figure 3.32 Fenêtre d'édition d'une constante

      Le type d'une constante pourrait être simple (booléen, entier, réel, caractère, chaîne de caractère) ou structuré (tableau, liste, arbre). Il peut aussi être un type défini par l'utilisateur à l'aide de l'éditeur de structure. Le choix du type se fait à partir de la fenêtre d'édition de constante (Figure 3.32). L'utilisateur doit aussi donner un nom et choisir, s'il le veut, une icône pour représenter la constante. L'entrée de (des) valeur(s) de la constante dépend de son type. La Figure 3.33 présente l'entrée de valeur d'une constante nommée age de type entier.

      

Figure 3.33 Entrée de valeur d'une constante de type entier

      L'ensemble de constantes créées par l'éditeur de constantes est enregistré dans un fichier (texte) avec l'extension .dc (data constant). Comme pour les structures, les constantes sont aussi séparées les unes des autres par une ligne composée par des séquences de '='. Le fichier donne le nombre de constantes qu'il contient. Pour chaque constante les informations suivantes sont enregistrées:

  • commentaire global sur la constante (optionnel)
  • le nom de la constante
  • l'icône (une valeur par défaut existe) qui la représente visuellement
  • son type
  • et sa valeur. Si le type de la constante est structuré, le type de base est donné avant les différentes valeurs.

      

Figure 3.34 Fichier de constantes (myconst.dc) avec deux éléments

      

Figure 3.35 Valeur du quatrième élément d'une constante tableau de sept éléments

      La Figure 3.34 présente graphiquement un fichier de constante contenant deux éléments: age qui est une constante de type entier dont la valeur est 25, joursem qui est une constante de type tableau de chaîne de caractères ayant sept éléments qui sont les jours de la semaine. La Figure 3.35 montre que la valeur du quatrième élément de ce tableau est 'mercredi'.

      Le fichier de constantes correspondant est le suivant:

      

Exemple 3.19 Le contenu du fichier de constante myconst.dc

      L'éditeur de structures et l'éditeur de constantes peuvent communiquer entre eux. Durant l'édition (création ou modification) d'une constante, l'utilisateur peut choisir une structure qu'il avait préalablement créée avec l'éditeur de structure en appuyant sur le bouton ' structure prédéfinie' (représenté par un livre ouvert, Figure 3.32). A ce moment-là, si l'éditeur de structures n'est pas actif, il est lancé par l'éditeur constant. Dans l'éditeur de structures, l'utilisateur doit choisir une structure (en cliquant dessus), puis l'envoyer en utilisant la fonction 'Envoie' (Figure 3.28). Dans l'éditeur constant, si l'utilisateur change d'avis et ne veut pas recevoir le type, il devra appuyer sur un bouton représentant un autre type.

      D'autres communications similaires devraient aussi être mises en place d'une part entre l'éditeur de structures et l'éditeur de script pour que ce dernier puisse choisir un type défini par l'utilisateur, et d'autre part entre l'éditeur de constantes et l'éditeur de script pour que ce dernier puisse aussi prendre une constante définie par l'utilisateur. L'éditeur de structures aurait alors deux fonctions d'envoi, l'une vers l'éditeur de script et l'autre vers l'éditeur de constante.

      Note

  • La version actuelle de DIVA-cd ne tient pas encore compte de l'existence de ces deux éditeurs.
  • En se basant sur les représentations visuelles des types données décrites ci-dessus. Notre groupe a aussi conçu des représentations visuelles de certaines manipulations de données [Ibrahim98a]. Les représentations visuelles des types et des manipulations de données ne devront pas apparaître directement sur la représentation statique du graphe pour ne pas trop encombrer l'affichage. Elles apparaîtraient sur demande, dans une fenêtre transitoire, toutes les fois que l'utilisateur clique sur les endroits appropriés. Ces représentations visuelles ne sont pas encore implantées dans la version actuelle de DIVA-cd.

      En résumé

      La représentation interne de la spécification (fichier du graphe de script) est utilisée d'une manière ou d'une autre par la plupart des outils: le générateur de code automatique l'utilise directement pour produire le code sous forme d'automate à états finis, l'éditeur synchrone l'utilise pour afficher des vues synchronisées de la spécification et du code complémentaire que les programmeurs doivent produire, l'outil de surveillance à distance l'utilise pour afficher l'état actuel de l'exécution du programme final fonctionnant sur une machine cible.

      Il faut donc noter que la spécification visuelle est ainsi utilisée

  • en tant qu'entrée formelle au générateur de code,
  • comme une spécification pour les programmeurs qui doivent implémenter les parties qui ne pourraient pas être produites automatiquement,
  • comme documentation humainement lisible pour aider les programmeurs qui font l'entretien, à mieux comprendre le code,
  • comme une carte visuelle du logiciel pour les enseignants qui veulent suivre ce que les étudiants font.

      Tous les outils supplémentaires sont aussi prévus pour des utilisations multi-langues. Ils commencent donc par l'affichage de la fenêtre de choix de langue (Figure 3.5).

      Seuls les deux composants principaux du système DIVA sont directement concernés par l'intégration du flot de données: l'éditeur synchrone, notamment l'éditeur de script, qui devra être enrichi avec des fonctionnalités permettant de dessiner des éléments relatifs au flot de données, et le générateur de code, qui devrait tenir compte de ces données soit dans le module du code correspondant à l'automate à états finis, soit dans le module du code manuel.

      Du point de vue implémentation, le tableau suivant donne un aperçu des langages de programmation utilisés pour les différents composants du système DIVA et ses outils supplémentaires.

      
  Ada Tcl/Tk Java C Autres
Editeur synchrone x x   x  
Générateur de code x        
Gestionnaire de traduction x        
Outil de vue d'ensemble de projet x x   x  
Outil d'impression de script       x latex
Superviseur x   x x  
Editeur de structures   x      
Editeur de constantes   x      


4. Intégration du flot de données: le nouveau formalisme visuel

      Le fait de pouvoir représenter visuellement la 'circulation' des données dans un langage de programmation visuelle permet d'augmenter l'utilité du langage. Comme nous l'avons discuté dans le chapitre 2, la co-existence des flots de données et des flots de contrôle permet de tirer les avantages de chacun d'eux. Nous avons déjà décrit dans le chapitre 3 la représentation du flot de contrôle dans le système DIVA. Ce flot de contrôle reste le même dans le nouveau système intégrant le flot de données. Dans ce chapitre, nous allons étudier comment le système DIVA tient compte des données traitées dans une application [Randriamparany01a] [Randriamparany01b]. Le nouveau langage ainsi défini est baptisé DIVA-cd, c'est-à- dire 'DIVA combinant flots de contrôle et de données'.

      Le système DIVA, avec le flot de contrôle, est utilisable seulement pour spécifier des applications qui n'ont pas des traitements et d'échanges de données. C'est généralement le cas de la plupart des applications d'EAO (leçons). Ce qui domine surtout c'est l'interaction entre le système et l'apprenant. Le système affiche des messages à l'écran, l'apprenant agit en entrant ses réponses (données) directement au clavier. Très souvent, ces données entrées sont traitées tout de suite (localement) et ne seront pas réutilisées dans des étapes ultérieures de la leçon. Ces données sont donc considérées comme des variables locales à chaque étape d'exécution (correspondant à un noeud de la spécification visuelle). Lorsque le traitement de l'étape est fini, la leçon continue selon le flot de contrôle prévu. On ne garde pas des traces des données utilisées. Si la leçon nécessite de spécifier la circulation des données le formalisme utilisant seulement le flot de données ne pourrait donc pas être utilisé.

      Le but principal de l'intégration du flot de données dans le système DIVA est donc de pouvoir considérer dans la spécification visuelle les échanges et les circulations des données dans une application. Ceci enrichit davantage les spécifications d'application d'EAO, et offre aussi une ouverture vers des applications des autres domaines qui pourront être purement de flot de données. Nous avons donc besoin d'un formalisme visuel permettant, d'une part, de localiser les données, et d'autre part, de mettre en place l'échange de données entre les différents noeuds. En plus de ça, nous voulons aussi que les données jouent des rôles significatifs dans les conditions d'activation des noeuds.

      Dans notre formalisme de flot de données, comme dans d'autres formalismes de flot de données [Jagannathan95] [Newton92], les noeuds (d'activité) sont reliés entre eux par les arcs de flot de données. Une particularité de notre formalisme est le fait que ces arcs sont 'accrochés' à des petits terminaux représentant les paramètres d'entrée et de sortie des noeuds d'activité. Le comportement du système change selon le type de terminal utilisé.

      Dans ce chapitre nous allons décrire le formalisme visuel liés à ces terminaux. Ils sont aussi au centre de discussion dans le chapitre traitant le modèle d'exécution. Nous décrirons aussi les nouveaux types de noeuds que nous avons conçus pour pouvoir stocker les données. Nous allons aussi discuter de la sémantique liée aux arcs de flot de données.


4.1 Les terminaux de données

      Les terminaux de données, comme nous l'avons dit, servent de point de départ et de point d'arrivée des arcs de flot de données. Ils représentent aussi les paramètres d'entrée et de sortie des noeuds associés. Nous avons ainsi défini deux catégories de terminaux de données: les terminaux d'entrée et les terminaux de sortie. La Figure 4.1 donne les représentations graphiques de ces terminaux de données.

      Lorsque l'utilisateur clique sur un terminal, le type du paramètre qu'il représente sera affiché dans une fenêtre transitoire. Dans notre flot de données, chaque paramètre doit être représenté individuellement. Il y aura donc autant de terminaux de données entrant (respectivement, sortant) que de paramètres d'entrée (respectivement, de sortie).

      Chaque terminal a donc un type de données qui lui est associé. Puisque le langage DIVA-cd est fortement typé, quand un terminal de sortie d'un noeud de source est relié à un terminal d'entrée d'un noeud destinataire par un arc de flot de données, les types associés aux terminaux de la source et du destinataire doivent coïncider. Mais nous avons aussi défini d'autres façons de pouvoir relier deux types différents (voir section 4.3).

      

Figure 4.1 Représentations graphiques des terminaux de données


4.1.1 Les terminaux de sortie

      Les terminaux de sortie (output terminal) reçoivent les valeurs des paramètres de sorties correspondants. Puisque, en général, notre flot de données est 'piloté par les données' (data-driven), les données qui arrivent sur un terminal de sortie sont tout de suite transmises par l'arc de flot de données sur le (ou les) terminal (terminaux) d'entrée correspondant(s). Exception est faite pour les terminaux de sortie des noeuds de données.


4.1.2 Les terminaux d'entrée

      Les terminaux d'entrée reçoivent les valeurs des paramètres d'entrée correspondants. Nous avons défini deux comportements différents qui nous entraînent à considérer deux terminaux d'entrée différents.

      D'une part, nous voulons que lorsqu'un noeud s'exécute, les données qui sont dans les terminaux d'entrée soient consommées. Des nouvelles valeurs seront donc nécessaires pour que ce noeud puisse de nouveau s'exécuter. De tels terminaux sont dits déclenchants (triggering input terminal). Les paramètres correspondants peuvent avoir des valeurs par défaut qui seront considérées une seule fois (à la première activation du noeud en question). Une autre caractéristiques des terminaux déclenchants est aussi le fait que, sous certaines conditions, les arcs arrivant sur ce type de terminal d'entrée peuvent déclencher l'exécution du noeud correspondant. Cette caractéristique est décrite dans le chapitre traitant le modèle d'exécution.

      D'autre part, nous voulons aussi avoir des terminaux d'entrée qui gardent leur contenu, même après l'exécution du noeud correspondant. Ces terminaux sont dits non-déclenchants (non-triggering input terminal) et les valeurs par défaut sont obligatoires pour les paramètres correspondants. Si des arcs de tels terminaux se trouvent avec d'autres arcs qui sont reliés avec des terminaux déclenchants ou avec des arcs de flot de contrôle, ils ne sont pas 'décisifs' dans l'activation du noeud correspondant.


4.2 Les noeuds de données

      Pour le flot de données, nous avons créé des types de noeuds de données spéciaux pour représenter des récipients de données avec un certain comportement d'exécution spécifique (mémorisation et expédition). Les noeuds de données doivent avoir des noeuds d'activité comme prédécesseurs et successeurs. Ils ne peuvent pas être directement reliés entre eux. Nous avons défini trois types de noeuds de données: le noeud bag, le noeud queue et le noeud datastore.


4.2.1 Noeud Bag

      Un noeud Bag (ou sac) fonctionne comme un récipient homogène de jetons de données. Comme pour les noeuds du flot de contrôle, les noeuds de données ont aussi des représentations visuelles textuelles et graphiques. Un noeud Bag est représenté par un texte entre deux caractères $. Pour un noeud de données en général, ce texte donne une explication de son contenu ou d'autres informations utiles.

      

Exemple 4.1 Un noeud bag

      Un noeud Bag a un paramètre d'entrée simple qui indique le type de données que le sac peut contenir (la cohérence du type est examinée, comme pour tous les autres types de noeuds, chaque fois qu'un nouvel arc est relié à un sac) et deux paramètres de sortie. L'un est de même type que son paramètre d'entrée et l'autre est un nombre entier qui donne le nombre de jetons restant dans le sac.

      N'importe quel jeton qui vient d'un des prédécesseurs d'un noeud Bag est enregistré jusqu'à ce qu'il puisse potentiellement être utilisé par un de ses noeuds successeurs. Un jeton d'un noeud Bag est envoyé seulement à un successeur, offrant ainsi un mécanisme d'exclusion mutuelle. Un noeud Bag peut avoir n'importe quel type de noeuds d'activité comme prédécesseurs ou successeurs. Il est relié avec ces noeuds par un arc de flot de données. Un noeud Bag envoie les jetons seulement à un de ses successeurs qui sont prêts à les consommer ('demand-driven').


4.2.2 Noeud Queue

      Un noeud Queue (ou file d'attente) a un comportement très semblable à un noeud Bag parce qu'il fonctionne aussi comme récipient homogène de jetons de données. La seule différence, comparée aux noeuds Bag, est que les jetons sont enregistrés séquentiellement et recherchés dans l'ordre de leur enregistrement. Le noeud Queue est représenté par un texte entre deux caractères ¦.

      

Exemple 4.2 Un noeud Queue


4.2.3 Noeud Datastore

      Un noeud Datastore est un noeud passif qui représente une variable globale. Ainsi il contient seulement un jeton de données. Il aura un paramètre d'entrée indiquant le type de données qu'il représente. Son unique paramètre de sortie doit avoir le même type que son paramètre d'entrée. Le noeud Datastore est représenté par un texte entre deux caractères #.

      

Exemple 4.3 Un noeud Datastore

      Contrairement aux noeuds Bag et Queue, ce type de noeud a un comportement d'exécution spécifique. Il envoie une copie de sa donnée dans un jeton de données chaque fois qu'un successeur a besoin d'elle, alors que pour les deux premiers types c'est la donnée elle-même qui est envoyée (donc supprimée du sac ou de la file d'attente).

      Note

      Les noeuds de données ont aussi des représentations graphiques dans les deux familles d'icônes que l'utilisateur peut utiliser (Figure 4.2 et Figure 4.3).

      

Figure 4.2 Représentations des noeuds de données dans la famille d'icônes n.1

      

Figure 4.3 Représentations des noeuds de données dans la famille d'icônes n.2


4.3 Les arcs de flot de données

      Les arcs de flot de données sont utilisés pour spécifier la circulation ou l'échange des données dans un script (spécification visuelle). Ils relient un terminal de sortie à un terminal d'entrée. En général, les deux terminaux reliés par un arc de flot de données doivent avoir le même type de paramètres associés. Cependant, nous avons considéré un mécanisme de sélection qui permet d'avoir des types différents sur les deux bouts d'un arc de flot de données [Ibrahim98a].

      Si la sélection se trouve à l'origine de l'arc de flot de donnée, elle consiste à extraire un élément (cas du tableau) ou un champ (cas de l'enregistrement) de la structure. Dans ce cas le type du paramètre associé au terminal de sortie est un type structuré alors que la donnée transmise le long de l'arc de flot de donnée sortant est un élément de type simple. Inversement, si la sélection se trouve à la destination de l'arc, elle correspond à une composition des éléments d'une structure. Dans ce cas le type du paramètre associé au terminal d'entrée est un type structuré alors que la donnée reçue par l'arc de flot de donnée entrant est un élément de type simple.

      Pour que l'utilisateur localise facilement la présence de sélection et/ou de composition de données le long des arcs de flot de données, la tête et la queue de la flèche représentant un arc peuvent avoir des formes différentes, selon qu'une sélection et/ou une composition ont lieu. Comme illustré dans la Figure 4.4, la tête de la flèche est un triangle si une composition a lieu au terminal de la destination, autrement elle est composée de deux segments formant un angle obtus, et la queue de la flèche est composé de trois segments si une sélection a lieu au terminal de la source, autrement c'est un simple trait.

      

Figure 4.4 Représentation, sur les arcs, des manipulations des données.

      Dans la version actuelle du prototype de DIVA-cd, ces représentations spécifiques des arcs de flots de données qui spécifient visuellement la sélection ne sont pas encore implantés. Mais si l'utilisateur clique sur un arc de données, une fenêtre est ouverte et affiche les caractéristiques des arcs, y compris les modes de sélection (P ou W) à l'origine et à la destination de l'arc. P, qui signifie Part, indique l'existence de sélection. Le cas contraire, qui est la situation par défaut, est indiqué par W signifiant Whole. L'équivalence des situations présentées dans la figure 4.4 est donc la suivante:

      

Figure 4.5 Représentation d'un arc

      Pour l'arc représenté par la fenêtre de la Figure 4.5, le code à son origine est P c'est-à-dire que la vraie source de l'arc est une partie du paramètre représenté par le terminal correspondant, ici c'est un paramètre du nom date et de type enregistrement.


4.4 Les vues de flot de contrôle et de flot de données

      L'intégration du flot de données entraîne l'existence de deux types d'arcs, donc deux types de flot. Dans la version actuelle de l'éditeur de script les deux flots ne sont pas visibles simultanément. Il y a deux modes de vues séparés dans le système DIVA-cd: le mode flot de contrôle et le mode flot de données. L'utilisateur peut commuter entre ces deux modes à tout moment. Pendant la commutation, les noeuds demeurent en place et l'affichage des arcs de flot de contrôle est remplacé par l'affichage des arcs de flot de données et vice- versa. Ainsi, tous les arcs sont représentés par des traits pleins. Ce choix est pris dans le but d'avoir une meilleure lisibilité.

      Pour illustrer ce multiparadigme combinant le flot de données et le flot de contrôle et aussi ces deux modes de vue, nous allons présenter la spécification du petit programme très connu 'Bouteilles de bière' (bottles of beer). Il s'agit d'effectuer les affichages suivants:

      

Exemple 4.4 Sortie du programme 'Bouteilles de bière'

      Tout d'abord présentons une version de ce programme dans le langage initial basé uniquement sur le flot de contrôle (Figure 4.6). Les données, le nombre de bouteilles ($nb$) et le caractère final ($fin$), sont représentées textuellement, comme des variables à l'intérieur des noeuds.

      De haut en bas du graphe, nous avons le noeud d'en-tête (ou de début) qui est un noeud Documentation et contient le nom de graphe. Le deuxième noeud est aussi un noeud Documentation donnant la description du programme. Le troisième noeud est un noeud Directive qui initialise les données. Le quatrième est un noeud Message qui contient un texte de trois lignes à afficher. Le cinquième est un noeud Directive qui décrémente le nombre de bouteilles. Et le sixième est un noeud Test, toujours vrai, utilisé pour compter l'itération des affichages.

      Ici, nous exploitons la caractéristique des noeuds Test qui peuvent avoir plusieurs noeuds successeurs et des arcs étiquetés. Pour les 97 premières itérations, le programme suit l'arc étiqueté 1..97 qui aboutit à un autre noeud Message affichant une ligne de texte. Pour la 98ème itération, il suit l'arc étiqueté 98 qui se termine sur un noeud Directive changeant la valeur de la variable $fin$ avant que le message soit affiché. Le programme s'achève avec l'arc étiqueté 99 qui aboutit sur un autre noeud de message affichant un message final. La décoration dans le noeud Test représente le compteur associé.

      

Figure 4.6 Spécification de 'Bouteilles de bière' avec flot de contrôle pur

      Avec le paradigme combiné, deux noeuds Datastore sont utilisés pour représenter les deux variables globales. Le noeud Directive pour l'initialisation de données n'est pas nécessaire parce que les noeuds Datastore peuvent avoir des valeurs par défaut qui seront leurs valeurs initiales (voir Figure 4.7 pour la variable nombre de bouteilles). Les paramètres des noeuds sont représentés soit par des anses de paramètres soit par des terminaux de données selon le mode de vue en cours. La Figure 4.8 présente la vue flot de contrôle et Figure 4.11 la vue flot de données.

      

Figure 4.7 Représentation du paramètre correspondant au nombre de bouteille pour le noeud Datastore, valeur par défaut 99


4.4.1 La vue flot de contrôle

      Dans la vue flot de contrôle, les arcs représentent l'ordre d'exécution et relient deux noeuds directement. Même si les noeuds de données sont utiles seulement dans la vue flot de données, ils restent visibles dans la vue flot de contrôle pour éviter des superpositions de noeud pendant la création de noeud.

      Des petites décorations graphiques sont ajoutées aux noeuds ayant des paramètres d'entrée et/ou de sortie (nous les appelons 'anse' de paramètres). L'anse de paramètre pour la liste de paramètres d'entrée pointe vers le centre du noeud tandis que celle pour la liste de paramètre de sortie pointe vers l'extérieur du noeud. En cliquant sur ces décorations, l'utilisateur pourra voir, dans une fenêtre instantanée, les détails au sujet des types de paramètre (liste de paramètres). Les anses de paramètre sont représentées par la forme

      

      Les arcs de la Figure 4.8 représentent donc des arcs de flot de contrôle. Les deux noeuds qui ne sont pas connectés dans cet exemple sont des noeuds de données. Mais notre formalisme permet aussi aux noeuds d'activité de ne pas avoir de flot de contrôle entrant et/ou sortant.

      

Figure 4.8 Graphe du script 'Bouteilles de bières' avec DIVA-cd: vue flot de contrôle

      L'existence de l'anse de paramètre d'entrée sur le troisième noeud (avec le texte 'nb boute') indique que ce noeud a au moins un paramètre d'entrée. L'activation de celle-ci affiche la liste des paramètres d'entrée de ce noeud (Figure 4.9). Le quatrième noeud qui est un noeud Directive spécifiant la décrémentation du nombre de bouteilles retourne la valeur résultant dans un paramètre de sortie qui est représenté donc par une anse de paramètre. L'activation de cette dernière donne la fenêtre de la Figure 4.10.

      

Figure 4.9 Liste de paramètres d'entrée

      

Figure 4.10 Liste de paramètres de sortie


4.4.2 La vue flot de donnée

      Dans la vue de flot de données, les arcs représentent le flot de données et relient un terminal de sortie d'un noeud à un terminal d'entrée d'un autre noeud. Les anses de paramètre sont remplacées par des terminaux de données. Il doit y avoir une décoration séparée (terminal de données) pour chaque paramètre du noeud (ou de script). Ainsi, un noeud aura autant de terminaux que de paramètres. L'activation d'un terminal de données ouvre une fenêtre instantanée affichant ses caractéristiques: le nom et le type du paramètre qu'il représente, son comportement c'est à dire déclenchant ou non.

      Dans la Figure 4.9 la fenêtre montre que le noeud numéro 3 a deux paramètres d'entrée nommés nb et fin. Ainsi dans la Figure 4.11 nous voyons que ce noeud a deux terminaux d'entrée. Quand l'utilisateur clique sur le deuxième terminal, le système affiche la fenêtre de la Figure 4.12 qui donne ses caractéristiques. De même, l'activation du terminal de sortie du noeud numéro 4 ouvre la fenêtre de la Figure 4.13.

      

Figure 4.11 Graphe du script 'Bouteilles de bières' avec DIVA-cd: vue flot de données

      

Figure 4.12 Caractéristique d'un terminal d'entrée

      

Figure 4.13 Caractéristique d'un terminal de sortie

      Note

      Remarquons que dans les graphes de script (Figure 4.6, Figure 4.8 et Figure 4.11), seulement une partie du contenu des noeuds est visible. Comme nous l'avons expliqué dans la note 3.4 du chapitre présentant le système DIVA (Chapitre 3), si l'utilisateur clique deux fois sur le noeud ou choisit la commande 'Montre noeud' de l'éditeur de script, le contenu du noeud est affiché. Puisque ce n'est pas le cas avec le support papier, voici, dans le fichier de messages correspondant (Exemple 4.5), les contenus des trois noeuds Message du script, version paradigme combiné (Figure 4.8 et Figure 4.11), et dans le fichier du graphe (Exemple 4.6) les contenus des autres noeuds. Les détails sur les formats de ces fichiers sera présentés dans la section 6. du chapitre traitant l'implantation du système (Chapitre 6).

      

Figure 4.5 Contenu du fichier de messages pour le script 'bouteilles de bière' version paradigme combiné

      

      

      

      

Exemple 4.6 Contenu du fichier de graphe pour le script 'bouteilles de bière' version paradigme combiné


4.4.3 Avantages de la représentation visuelle

      Rappelons que pour le développement d'une application avec le système DIVA-cd, nous avons deux acteurs principaux, l'enseignant qui souhaite que ses cours soient mis sur ordinateur et qui participe à la spécification de l'application, et l'informaticien qui effectuera le codage manuel nécessaire.

      Pour l'enseignant, la représentation visuelle du flot de données lui permet de prendre connaissance des données qui sont traités dans l'application et de leur utilisation. Cela lui permet donc de discuter avec l'informaticien et de donner son avis, ses propositions. Du coté de l'informaticien, la représentation visuelle du flot de données lui permet de contrôler facilement les données et leur utilisation.


4.5 Paramètre(s) du script

      Un script (un graphe) peut aussi avoir des paramètres d'entrée et/ou des paramètres de sortie. Les anses de paramètre correspondant à ces paramètres sont attachés au noeud d'en-tête. Ce noeud est donc considéré comme une 'antichambre' où les paramètres du script transitent. Les paramètres d'entrée du script 'sortent' de cette chambre pour être utilisés par les autres noeuds du script tandis que ses paramètres de sortie y 'entrent' pour être 'récupérés' par le script appelant. C'est pourquoi les paramètres d'entrée (réciproquement, de sortie) du script sont représentés comme des paramètres de sortie (réciproquement, d'entrée) du noeud d'entrée du script (Figure 4.14).

      

Figure 4.14 Représentation des paramètres du graphe dans la vue flot de contrôle

      Pour éviter toute ambiguïté entre paramètres du script et paramètres du noeud, le noeud d'en-tête doit être de type Documentation. Par conséquent,

      En résumé

      Dans ce chapitre, nous avons présenté les différents formes graphiques utilisées pour représenter visuellement les données et leurs manipulations. Ces formes graphiques devraient être supportées par l'éditeur de script. Seuls les noeuds de données, les anses de paramètre et les terminaux de données seront directement visibles dans la spécification visuelle d'une application.

      L'intégration du flot de données a des impacts sur la représentation textuelle du graphe (grammaire). Ces conséquences seront discutées dans le chapitre traitant l'implantation du système (chapitre 6)'. Ses impacts sur les sorties du générateur de code seront discutés dans le chapitre parlant des modèles d'exécution et des générateurs de code (chapitre 5).


5. Intégration du flot de données: modèle d'exécution et générateur de code

      L'intégration du flot de données dans notre formalisme et surtout notre choix de vouloir faire intervenir les données dans l'activation des noeuds entraînent un grand changement quant au modèle d'exécution des programmes développés dans notre environnement DIVA-cd [Ibrahim01a][Ibrahim01b]. Nous allons donc, dans ce chapitre, décrire ce modèle d'exécution qui résulte des sémantiques définies dans le chapitre précédent.

      Puisque la concrétisation du modèle d'exécution est faite par le générateur de code, nous allons aussi décrire les caractéristiques et les fonctionnements des générateurs de code. Nous parlons des générateurs de code au lieu d'un générateur de code puisque notre formalisme permet d'avoir plusieurs générateurs de code selon les langages cibles considérés.


5.1 Interaction du flot de données et du flot de contrôle

      Le combinaison des deux paradigmes, flot de données et flot de contrôle, implique un changement considérable dans les comportements des noeuds d'activité. Les changements d'état de noeud tiendront également compte de l'existence des arcs de flot de données et du type des terminaux d'entrée qui leur sont associés.

      Pendant l'exécution d'un script, les noeuds peuvent être dans un des états suivants: dormant, en attente de données, et actif. En général les règles de changement d'état sont les suivantes:

      La figure 5.1 donne un résumé de cette règle de changement d'état des noeuds.

      

Figure 5.1 Changement d'états des noeuds en tenant compte des flots de données


5.2 Modèle d'exécution

      Au début, nous avons commencé par supposer que les concepteurs spécifient d'abord le flot de contrôle de l'application, et que le flot de données serait ajouté ultérieurement. Mais il pourrait y avoir des cas où la spécification est seulement basée sur les données (data-driven) et il n'y a aucune raison d'indiquer explicitement un flot de contrôle.

      Pour faire face à toute une gamme d'applications, du flot de contrôle pur au flot de données pur, nous avons décidé de retirer la contrainte d'avoir un graphe de flot de contrôle complètement relié. Au lieu de cela, là où des arcs de flot de contrôle existent entre deux noeuds, le générateur de code s'assurera que les deux noeuds seront exécutés dans l'ordre, mais si seulement des arcs de flot de données relient deux noeuds ou groupes de noeuds, c'est la disponibilité des données qui guidera l'ordre d'exécution.

      Le modèle d'exécution peut être défini comme suit. S'il y a un ou plusieurs arcs flot de contrôle, alors un nouveau jeton de contrôle est exigé pour commencer l'exécution du noeud. Si le noeud a un ou plusieurs terminaux d'entrée déclenchants, alors un nouveau jeton de données est exigé sur chacun d'eux. Puisque les terminaux d'entrée non-déclenchants ont toujours une valeur disponible, ils ne sont pas impliqués au déclenchement de l'exécution du noeud, à moins que le noeud n'ait aucun prédécesseur de flot de contrôle et n'ait aucun terminal d'entrée déclenchant (c.-à-d. le noeud a seulement des prédécesseurs de flot de données reliés aux terminaux d'entrée non-déclenchants).

      Si un noeud a seulement des terminaux d'entrée non-déclenchants, et n'a aucun prédécesseur de flot de contrôle, son exécution peut commencer lorsque le graphe, dans lequel il est défini, est appelé (ou lancé). Après qu'il soit exécuté une fois, il sera exécuté de nouveau lorsqu'une de ses entrées change, c.-à-d. lorsqu'un nouveau jeton arrive sur un de ses terminaux d'entrées (non-déclenchants). Ce mécanisme permet d'établir un système réactif, c.-à-d. un système pour lequel les sorties sont recalculées à chaque changement de l'une de ses entrées.


5.3 Le générateur de code

      Puisque toute les fonctionnalités du système DIVA sont encore disponibles dans le nouveau DIVA-cd, nous avons gardé les acquis de ce système vis-à-vis du traitement de flot de contrôle. Toutes les caractéristiques principales du générateur sont encore gardées, par exemple la séparation des détails de la syntaxe du langage de programmation cible avec la logique du générateur de code. Le générateur est toujours composé de deux parties: une partie s'occupant de la génération de code, et une autre partie pour l'interfaçage avec les différents langages cibles. Le détail du fonctionnement de base du générateur est donné dans le rapport du mémoire de diplôme de Aubord [Aubord88].

      Mais plusieurs fonctionnalités sont ajoutées à ce générateur pour pouvoir traiter le flot de données. L'ensemble des codes générés doit traduire la spécification du flot de données de l'application représentée par le graphe de script, notamment la localisation des données, paramètres des noeuds ou noeuds de données, et la circulation des données entre les noeuds, c'est-à-dire les arcs de flot de données.


5.3.1 La prise en compte du flot de données

      L'intégration du flot de données dans le graphe de script ajoute des nouveaux éléments formels que le générateur de code traite automatiquement durant la phase de génération de code. Il s'agit:

  • de l'utilisation ou du traitement des données par les noeuds. Elles sont spécifiées dans la liste des paramètres, en entrée ou en sortie, du noeud correspondant;
  • de la considération des données dans l'activation des noeuds. Elle correspond au type de terminal d'entrée, déclenchant ou non, utilisé pour représenter le paramètre;
  • de la circulation des données entre les noeuds. Elle est indiquée par les arcs reliant un terminal de sortie à un ou plusieurs terminaux d'entrée.

      Les deux parties (génération du code et interfaçage avec les différents langages cibles) du générateur de code sont donc modifiées pour tenir compte de ces nouveaux éléments formels. L'automate à états finis est toujours utilisé pour simuler le flot de contrôle. Il y a pourtant quelques modifications si le noeud correspondant à l'état courant contient des paramètres. Dans ce cas, si un appel de fonction ou de procédure est nécessaire, cet appel doit être effectué avec les paramètres actuels correspondants. Le syntaxe de cet appel varie d'un langage cible à une autre, c'est pourquoi il est décrit dans la partie interfaçage avec le langage cible.

      Selon le modèle d'exécution défini dans la section 5.2, il est possible qu'un noeud soit activé parallèlement au déroulement normal du script. Ceci dépend des existences, en entrée, des arcs de flot de contrôle, des arcs de flot de données arrivant sur des terminaux déclenchants et des arcs de flot de données arrivant sur des terminaux non-déclenchants. Le tableau ci-après récapitule ces possibilités. La manière de mettre en place des processus concurrents dépend aussi du langage cible. Pour simuler les arcs de flot de données, il faut mettre en place un mécanisme permettant d'associer un paramètre de sortie à tous les paramètres d'entrée qui lui sont reliés.

      
Tableau 5.1 Conditions d'exécution en parallèle d'un noeud
Arc de flot de contrôle Arc de flot de données sur terminal déclenchant Arc de flot de données sur terminal non déclenchant  
Oui Non Non Pas d'exécution concurrente
Oui Non Oui Pas d'exécution concurrente
Oui/Non Oui Oui/Non Exécution concurrente
Non Non Oui Exécution concurrente

      Pour ne pas trop surcharger l'automate à états finis, nous avons décidé de générer séparément deux modules traitant ces éléments formels. Le premier spécifie tous les paramètres et les noeuds de données existant dans le script et met en place la structure traduisant les arcs de flot de données. Le deuxième module spécifie les processus parallèles correspondant aux noeuds qui en ont besoin, selon les règles de changement d'états des noeuds données dans la Figure 5.1.


5.3.2 Les fichiers générés

      Le code pour l'automate à états finis se trouve toujours dans un module séparé et est éclaté en deux fichiers (l'interface et l'implémentation) nommés du nom du script correspondant: Xxx.DEF et Xxx.IMP (Xxx étant le nom du script). Comme pour la version purement de flot de contrôle, ces fichiers ne devraient jamais être modifiés par un programmeur. Les changements effectués seront détruits la prochaine fois que le code est régénéré.

      Un deuxième module correspond à la spécification de toutes les données (paramètres en entrée, paramètres en sortie, les noeuds de données) et des arcs qui les relient. Il s'agit seulement d'une interface. Donc il se trouve dans un fichier nommé XxxDF.DEF DF signifie 'Data Flow'.

      Le module spécifiant les processus concurrents est éclaté en deux fichiers, l'un pour l'interface et l'autre pour l'implémentation, et sont respectivement nommés XxxCP.DEF et XxxCP.IMPCP signifie 'Concurrent Process'.

      Le module (hand-coded module) qui sera modifié à la main par le programmeur est toujours éclaté en deux fichiers, un pour l'interface (nommé XxxTC.DEF) et l'autre pour l'implémentation (nommé XxxTC.IMP). Les procédures et fonctions dans ce module peuvent avoir des paramètres. Ce sont les paramètres formels qui sont spécifiés dans ce module.

      Le fichier du programme principal, nommé Xxx.PRG, n'a pas subit de modification suite à cette intégration du flot de données.

      Note

  • Dans les cas des noeuds Directive, des noeuds Appel à sous-graphe et des noeuds Test, les paramètres de chaque noeud deviennent des paramètres formels de la procédure ou fonction correspondante générée dans les fichiers nommés XxxTC.DEF et XxxTC.IMP.
  • Pour les noeuds Message, la liste des paramètres est données en paramètre actuels de l'appel de la procédure d'affichage qui se trouve dans le module de l'automate à états fini, Xxx.IMP.
  • Normalement, les noeuds Documentation ne doivent pas avoir de paramètres sauf s'il s'agit du noeud d'entrée de script. Dans ce cas, ce sont des paramètres du script. Ils deviennent alors des paramètres formels du programme principal de l'application qui se trouve dans le fichier nommé Xxx.PRG.

5.3.3 Les modules offerts

      Comme pour la version purement de flot de control, afin de faciliter les tâches des codeurs, quelques modules sont mis à leur disposition pour compléter le code produit. Il y a d'abord le module pour la gestion de l'interaction homme-machine et des routines d'affichage, et le module pour le traitement et l'utilisation des fichiers de message.

      Les autres modules concernent le flot de données. Le premier module offre les procédures nécessaires pour simuler le flot de données c'est-à-dire relier un paramètre de sortie à un ou plusieurs paramètres d'entrée. Trois autres modules donnent des types de données abstraits (ADT: Abstract Data Type) qui correspondent aux trois types de noeuds de données.


5.3.4 Listes d'importation

      Le concept de liste d'importation est toujours utilisé pour fournir au générateur les listes des modules utilisés par les modules qu'il génère. Rappelons que ce concept est utilisé pour éviter les problèmes dus au fait que les instructions déclaratives nécessaires au début d'un programme, ou d'un module, pour importer d'autres modules dépendent à la fois du langage, et aussi du système d'exploitation.

      

Figure 5.2 Dépendance entre modules

      La convention pour nommer les fichiers de liste d'importation reste la même que ce que nous avons déjà utilisée pour le système DIVA. Ainsi, pour les nouveaux modules relatifs au flot données nous avons:

  • XxxDFDef.DAT, pour fournir la liste d'importation correspondant au fichier XxxDF.PRG;
  • XxxCPDef.DAT, pour fournir la liste d'importation correspondant au fichier XxxCP.DEF;
  • XxxCPImp.DAT, pour fournir la liste d'importation correspondant au fichier XxxCP.IMP.

      La figure 5.2 montre la dépendance entre les modules produits par le générateur de code et les modules offerts par le système. Elle permet de savoir et d'établir le contenu minimum de la liste d'importation correspondant à chaque module.


5.3.5 Langage cible

      La première critère du choix du langage cible est la modularité. Il doit permettre la compilation séparée. Ceci était déjà le cas pour l'ancien système. L'intégration du flot de données et la sémantique attribuée aux différents éléments du formalisme visuel ajoute d'autres critères.

      Puisqu'à chaque type de noeud de données est associé un ADT, chaque occurrence des noeuds de données dans un script donne lieu à une instanciation de l'ADT concerné dans le code généré. En plus de ça, la considération des données dans l'activation d'un noeud pourrait faire exécuter la procédure ou fonction correspondante parallèlement au déroulement normal du programme.

      En plus d'être modulaire, le langage cible devrait permettre alors l'instanciation d'un ADT et l'utilisation de processus concurrent. Ainsi, dans ce travail de thèse, nous avons choisi Ada comme langage cible. A la différence de C++, Ada définit un modèle pour la programmation concurrente en tant qu'élément du langage lui-même. Peu d'autres langages (Java par exemple) fournissent l'aspect concurrent au niveau du langage, d'autres langages fournissent un modèle concurrent par l'utilisation des bibliothèques (Parallel-C++ par exemple).

      Note

      Puisque les nouveaux éléments conçus pour intégrer le flot de données font partie des éléments formels de notre formalisme, les codes correspondants sont générés entièrement et ils n'ont donc pas besoin d'être modifiés. Leur seul impact dans le module manuel est l'ajout des paramètres formels dans les déclarations de procédures et des fonctions. L'éditeur de programme ne subit donc pas de changement, il garde son comportement avant l'intégration du flot de données. Celui-ci est décrit dans la section 3.6 du chapitre présentant le système DIVA (chapitre 3).


5.4 Fonctionnalités principales de l'éditeur de script

      Le modèle d'exécution que nous avons décrit ci-dessus (section 5.2) concerne le comportement attendu de l'application qui est développé en utilisant le système DIVA-cd. Il dépend surtout des caractéristiques des nouveaux éléments conçus pour intégrer le flot de données. L'outil qui est utilisé pour associer ces caractéristiques à ces nouveaux éléments étant l'éditeur de script, ainsi nous allons présenter les fonctionnalités principales de cet éditeur.

      Désormais, il a deux groupes de fonctionnalités distingués selon le mode de vue en cours. Nous avons adopté cette séparation d'opérations selon le mode de vue pour ne pas trop surcharger les menus du système et pour éviter des éventuelles confusions qui peuvent être source d'erreur.


5.4.1 Vue flot de contrôle

      En mode flot de contrôle, l'éditeur de script affiche seulement les noeuds et les arcs de flot de contrôle. Les fonctionnalités qu'il offre ne concernent que les opérations sur ces éléments du flot de contrôle. Les fonctionnalités concernant les éléments du flot de données sont désactivées. En bref, l'éditeur de script se comporte comme s'il est encore utilisé dans la version purement de flot de contrôle (voir section 3.4.2, chapitre 3).

      La petite différence est l'affichage des anses de paramètres pour les noeuds ayant des paramètres. On peut dire que ces décoration sont 'importées' depuis le mode flot de données puisqu'ils représentent des éléments créés depuis ce mode.


5.4.2 Vue flot de données

      Toutes les manipulations concernant les éléments du flot de contrôle sont désactivées dans la vue flot de données, à savoir manipulation des noeuds d'activités et des arcs de flots de contrôle. L'opération principale pour attribuer aux éléments du formalisme visuel leurs caractéristiques étant la création, ainsi pour chacun de ces éléments nous allons voir le processus de sa création.


5.4.2.1 Les noeuds de données

      Deux cas sont possibles pour la création de noeud de données:

  • Le point d'insertion est placé sur une zone vide, dans ce cas, le nouveau noeud sera placé sur cette zone vide;
  • Le point d'insertion se trouve sur un noeud. le nouveau noeud sera placé sur une zone vide la plus proche de ce noeud.

      

Figure 5.3 Entrée du nom et du type du contenu d'un noeud de données (Bag ou Queue)

      Cette création se fait en deux étapes.

  • La première étape permet à l'utilisateur de déterminer le nom et le type des données contenus dans le noeud. Pour cela, une fenêtre instantanée est affichée (Figure 5.3).
  • La deuxième étape est similaire à la création de noeud de flot de contrôle. Une fenêtre d'édition de texte est ouverte permettant à l'utilisateur de donner la description du noeud ou d'autre information, comme la structure de données s'il ne s'agit pas de structure simple.

      

Figure 5.4 Entrée du nom et du type du contenu d'un noeud Datastore

      

Figure 5.5 Entrée de la valeur initiale du contenu d'un noeud Datastore.

      Pour les noeuds de type Datastore, l'utilisateur peut donner une valeur par défaut (valeur initiale) au contenu du noeud. Ainsi, la fenêtre d'entrée des nom et type différencie un peut de celle pour les noeuds Bag et Queue (Figure 5.4). Lorsque le bouton 'Valeur par défaut ' est activé, une entrée de valeur par défaut est présentée (Figure 5.5).


5.4.2.2 Les paramètres

      La manipulation de paramètre ne peut être faite qu'en mode flot de données. Les paramètres des noeuds de données sont créés automatiquement lors de leur création, donc la création de paramètres est désactivée pour ces types de noeuds. Certains noeuds d'activités sont censés ne pas utiliser des données, les traitements des paramètres seront donc désactivés pour ces types de noeud (Documentation, Etiquette).

      

Figure 5.6 Cascade de boites de test avec deux paramètres d'entrée

      Les noeuds Test d'une même cascade ont les mêmes paramètres d'entrées. Leur création est seulement activée sur la première noeud de la cascade et le paramètre créé est partagé par tous les noeuds du cascade.

      Par exemple, supposons que dans la cascade de boîtes de test de la Figure 5.6 le premier noeud Test a deux paramètres, le premier nommé nb est de type entier et le deuxième nommé ok est de type booléen. Les deux autres noeuds Test de la cascade ont aussi le même couple de paramètres d'entrée.

      Seuls les noms et les types sont demandés pour la création de paramètres de sortie (voir Figure 5.7), tandis que pour les paramètres d'entrée (Figure 5.8), l'utilisateur doit aussi spécifier si le paramètre à créer est déclenchant ou non et peut fournir les éventuelles valeurs par défaut (Figure 5.9). Ces dernières sont obligatoires si le paramètre est non-déclenchant.

      

Figure 5.7 Création paramètre de sortie

      

Figure 5.8 Création paramètre d'entrée: nom et type

      

Figure 5.9 Création paramètre d'entrée: valeur par défaut (valeur initiale)


5.4.2.3 Les arcs de flot de données

      La vue de flot de données permet à l'utilisateur de créer des chemins de circulation de données entre les différents noeuds d'activité qui avaient été créés dans la vue de flot de contrôle.

      Comme pour le flot de contrôle, la création des arcs de flot de données nécessite l'existence du noeud de départ et du noeud d'arrivée. Pour la version actuelle, cette création peut seulement se faire depuis un noeud ayant au moins un terminal de sortie (c'est-à-dire un paramètre de sortie). Le système demande alors à l'utilisateur de choisir le noeud de destination qui, à son tour, doit aussi avoir au moins un paramètre d'entrée.

      Une fenêtre à double entrée (Figure 5.10) est affichée pour permet à l'utilisateur de choisir les paramètres à relier et de donner aussi les autres caractéristiques de l'arc comme le code à la source et le code à la destination. Dans la partie gauche de la fenêtre est affichée l'identification du noeud de départ de l'arc. Tandis que dans la partie droite est affichée l'identification du noeud d'arrivée. Chaque identification est suivi de la liste des paramètres du noeud en question. Pour le noeud de départ, il s'agit de la liste des paramètres de sortie, et pour le noeud d'arrivée, il s'agit de la liste des paramètres d'entrée.

      

Figure 5.10 Création d'un arc de flot de données

      Si le type du paramètre choisi n'est pas un type simple. Le système propose à l'utilisateur de choisir le code de sélection du paramètre. La valeur par défaut est 'Whole'. Dans la figure le paramètre de sortie choisi est de type enregistrement ce qui entraîne l'affichage du choix de code à la source.

      

Figure 5.11 Création d'un arc de flot de données: choix du code à la source

      Si l'utilisateur choisit le code 'Part', le système lui demande de fournir le type et le nom de l'élément choisi. Ceci pourrait donc concerner les deux parties de la fenêtre de création (Figure 5.12) c'est-à-dire les deux bouts de l'arc à créer.

      

Figure 5.12 Création d'un arc de flot de données: choix du type des données élémentaires

      Les types des données reliées par un arc doivent être les mêmes. Ils sont donc contrôlés lors de la création de l'arc. La création de l'arc sera refusée si les deux types sont différents. La création échoue aussi si l'utilisateur a choisi deux noeud de données comme source et destination de l'arc.

      En résumé

      Dans ce chapitre, nous avons mis en évidence que la sémantique associée aux éléments visuels utilisés dans notre formalisme pour intégrer le flot de données modifie énormément le modèle d'exécution des applications créées avec l'environnement DIVA-cd par rapport à l'ancien système.

      Cela modifie aussi le générateur de code et définit clairement les caractéristiques du langage cible: modulaire, supporte les types de données abstraits et la programmation concurrente. Ce qui a guidé notre choix vers le langage Ada. En plus, notre groupe a des expériences sur ce langage, qui est déjà largement utilisé pour l'implémentation de système DIVA.

      En résumé, l'intégration du flot de données a comme conséquence d'élargir le champ d'application de notre méthodologie. Ceci fournira un plus dans le développement d'application pour l'enseignement assisté par ordinateur, et permettra une ouverture vers d'autres domaines, par exemple les systèmes réactifs qui utilisent surtout les données. Cette intégration fournira donc une flexibilité d'utilisation de la méthodologie.


6. Intégration du flot de données: Implémentation

      L'intégration du flot de données dans le système DIVA touche surtout les composants suivants: éditeur synchrone et générateur automatique de code (voir Figure 3.1 du chapitre 3). Ainsi les tâches d'implémentation sont divisées en deux grandes parties plus ou moins indépendantes.

      Comme nous avons expliqué dans le chapitre 3, l'éditeur synchrone est composé de deux éléments, l'éditeur de script et l'éditeur de programme. L'intégration du flot de données concerne plutôt l'éditeur de script. Tous les nouveaux éléments de notre formalisme doivent être pris en compte par cet éditeur. Puisque ces nouveaux éléments font partie des côtés formels de notre formalisme, leur code d'implémentation est produit entièrement par le générateur et est censé ne pas être modifié manuellement, même s'il se trouve dans le module à coder manuellement (fichier XxxTC.IMP).

      Il y a en fait deux impacts de cette intégration du flot de données dans le module manuel. Le premier est l'ajout des paramètres formels aux déclarations des procédures et fonctions, le deuxième c'est le chargement explicite de données depuis un ADT si nécessaire. A priori ces deux choses ne doivent pas être modifiées. Le fonctionnement de l'éditeur de programme n'est donc pas modifié. En ce qui concerne le générateur du code, tous les modifications et les ajouts nécessaires ont été effectués.

      Nous allons donc décrire les différents modules nécessaires et les structures de données utilisées, surtout pour la représentation des scripts. Nous avons aussi établi un heuristique de dessin du graphe que nous allons décrire dans ce chapitre.


6.1 L'Editeur de script


6.1.1 Architecture globale et communication entre les unités de programme

      Rappelons que l'éditeur de script fait parties de l'éditeur synchrone que nous nommons SyncEd. D'une manière générale, SyncEd se compose de deux parties: les principaux traitements (procédures/fonctions) sont écrits en Ada et la partie interface utilisateur graphique (GUI) est écrite en Tcl/Tk. Quelques utilitaires pour la communication par socket entre les deux sont écrits en C. L'utilisateur communique avec SyncEd par la partie Tcl/Tk et les événements d'utilisateur (clique sur le bouton de la souris) sont transmis de Tcl/Tk à Ada par le socket (Figure 6.1).

      

Figure 6.1 Architecture de l'éditeur synchrone (SyncEd)

      La communication entre Ada et le Tcl/Tk est établie donc par le mécanisme de socket. Les messages envoyés par le socket sont des chaînes de caractères mais la composition du message n'est pas la même selon le sens de l'envoi, de Ada vers Tcl/Tk ou de Tcl/Tk vers Ada. Plus précisément, d'une part, un message venant d'Ada correspond à une procédure Tcl/Tk, et d'autre part un message venant de Tcl/Tk est un événement muni de ses valeurs.


6.1.1.1 Côté Tcl/Tk

      Puisque SyncEd commence par le démarrage d'un programme Tcl/Tk (doSyncEd.tcl), c'est une procédure Tcl/Tk qui ouvre une communication par socket comme serveur (par conséquent Ada est un client). C'est aussi une procédure Tcl/Tk qui ouvre un port pour le serveur et exécute le programme principal Ada (DoSyncEd). Deux autres procédures Tcl/Tk sont utilisés pour envoyer des messages vers Ada, et pour recevoir des messages de Ada.

      Les messages de Tcl/Tk se composent des éléments suivants: nom d'événement, identification de fenêtre, options de menu, valeur nécessaire etc... Ils respectent une syntaxe bien définie pour avoir un mécanisme d'extraction des informations nécessaires à partir d'une chaîne de caractère envoyée depuis Tcl/Tk vers Ada. Le caractère '_' est utilisé pour séparer chaque élément et '-' pour séparer les sous-élément.

      

Exemple 6.1 Un événement envoyé depuis Tcl/Tk vers Ada

      L'événement de l' Exemple 6.1 peut être lu comme un événement de l'éditeur de script (ScriptEditor) dont l'identification de la fenêtre est 117440626. Cet évènement est créé par le sous-menu d'insertion de noeud Documentation (IDocumentation) dans le menu principal (Menu).


6.1.1.2 Côté Ada

      La partie Ada possède un ensemble de modules qui complète la communication par socket. Ces modules permettent, entre autre, l'initialisation de la communication, l'envoi et la réception des messages. Le message envoyé par Ada reflète l'appel d'une procédure TCL/Tk (nom de la procédure et liste des paramètres).

      Les évènements reçus depuis TCL/Tk sont traités par un module d'expédition (de tri) des évènements. Chaque message est filtré et envoyé au module de traitement d'évènements de l'éditeur correspondant (éditeur de script ou éditeur de programme). Apres cela l'action spécifiée est appliquée à l'éditeur correspondant.


6.1.2 Structure de données

      Les structures de données utilisées pour implanter le système pourraient être divisées en trois groupes:

  • les structures de données pour les représentations internes des scripts dans les programmes Ada;
  • les structures de données pour les représentations graphiques des scripts dans les programmes Ada;
  • les structures de données dans les programmes Tcl/Tk.

6.1.2.1 Les représentations internes dans Ada

      Pour éviter de tout refaire, nous avons gardé telles quelles les structures de données qui concernent le flot de contrôle. Nous avons donc simplement ajouté des éléments permettant de traiter le flot de données.

      Les éléments de base d'un script sont les noeuds (ou sommets) et les arcs (arcs de flot de contrôle et arcs de flot de données). Les arcs sont associés à un noeud. Nous avons décidé qu'un noeud doit seulement connaître ses successeurs dans le flot de contrôle tandis que pour le flot de données, un noeud doit savoir quelles sont les destinations de ces résultats pour qu'ils puisse 'envoyer' les données et d'où viennent ses entrées pour qu'il puisse les 'chercher' si nécessaire.

      Lors de la création des noeuds dans un script, un indice lui est attribué. L'indice est unique et est associé à un seul noeud. Si un noeud est supprimé, l'indice qui lui a été attribué ne sera plus utilisable. Il est placé dans un endroit de la grille de l'éditeur de script, référencé par ses coordonnées X et Y.

      Un noeud (ou sommet ) est donc caractérisé par son indice, son type, son contenu textuel, sa position (X et Y) dans la grille de l'éditeur de script, le nombre d'arcs de contrôle sortants de ce noeud, et les listes des paramètres d'entrée et des paramètres de sortie. La structure correspondante est:

      

      Notons que les arcs de flot de données ne sont pas directement liés aux noeuds. Ils sont associés aux paramètres d'entrée ou paramètres de sortie.

      Un arc de flot de contrôle est caractérisé par sa destination et la valeur de son étiquette, sa forme d'intervalle (borne inférieure et borne supérieure). Rappelons qu'à l'exception des noeuds Test le nombre d'arcs de flot de contrôle sortant d'un noeud est au maximum 1. L'étiquette correspondante est 1..1. La représentation interne d'un arc de flot de contrôle est donnée par la structure ControlArcRecord.

      

      Les paramètres d'entrées et les paramètres de sorties ont des attributs communs: l'indice du noeud correspondant (identification du noeud), le nom du paramètre, son type et la liste des arcs qui lui sont attachés. Ces quatre caractéristiques sont suffisantes pour les paramètres de sortie, tandis que pour les paramètres d'entrée il faut ajouter deux attributs supplémentaires: la valeur par défaut et un attribut spécifiant si le paramètre en question est déclenchant ou non. Ainsi nous avons les structures de données suivantes:

      

      Les arcs de flot de données sont caractérisés par les codes de combinaison à la source et à la destination des données, les indices des noeuds source et destination, les noms des paramètres concernés à la source et à la destination, et les types des données à la source et à la destination. Si le code est W, que ce soit à la source ou à la destination, le nom et le type des données sont les même que ceux du paramètre concerné. Il y a aussi d'autres attributs qui sont nécessaires pour le traçage des arcs de flot de données.

      

      Un script est composé d'un ensemble de noeuds qui est représenté sous forme de tableau de pointeur de noeud. Il est aussi caractérisé par l'indice du noeud de début (point d'entrée), la plus grande valeur d'indice utilisé, le nom du fichier de graphe, le nom de fichier de message et le numéro de version.

      La structure de donnée qui représente un script est donc la suivante:

      


6.1.2.2 Les représentations graphiques dans Ada

      L'éditeur de script utilise une grille formée par des mailles, des gouttières verticales, des gouttières horizontales et des intersections des gouttières. Chaque noeud est placé dans une maille et occupe au moins une maille. Les noeuds Test peuvent occuper plus d'une maille. L'algorithme de traçage d'arc considère ces différents endroits de la grille. Des structures sont donc créées pour les classifier.

      

      Chaque gouttière est divisée en canal (numérotés de 1 à 9). Un canal peut être libre ou occupé par un ou deux arcs. Chaque arc occupant un canal doit avoir une direction bien précise. L'information concernant un canal donne donc son numéro et la direction de l'arc qui l'occupe.

      

      L'heuristique de traçage d'arc vérifie la direction vers le noeud de destination par rapport au noeud d'origine. un type de donnée est créé pour donner tous les positions possibles.

      

      Pour les traçages des arcs, il est nécessaire de savoir ses extrémités et des éventuelles points d'intersection. Tandis que la structure qui représente l'extrémité d'un arc contient ses coordonnées, le type de gouttière concernée, le numéro de canal utilisé et les directions (depuis-vers), celle des intersections donne ses coordonnées, le type de l'endroit où il se trouve, des informations sur le canal entrant et sur le canal sortant (formant le coude).

      

      La structure d'un arc sortant d'un noeud contient donc l'indice du noeud destinataire, la direction à la sortie et les deux extrémités (début et fin). Ces attributs sont communs aux arcs des deux flots. Mais pour les arcs de flot de données, il faut aussi spécifier les paramètres concernés au début et à la fin de l'arc.

      

      Une maille peut contenir un noeud ou un arc. La structure d'une maille dépend donc de son contenu. S'il s'agit d'un noeud, il doit contenir l'indice du noeud, ses dimensions (hauteur et largeur) et les listes des arcs (arcs de flot de contrôle et arcs de flot de données). Si le contenu est un arc, sa structure donne les états des canaux vertical et horizontal.

      

      La structure d'une gouttière contient les états des canaux longitudinaux et celui du canal transversal.

      

      La représentation graphique d'un script est donc formée, entre autre, par un tableau de mailles et des tableaux de gouttières horizontales et de gouttières verticales. Elle est donnée par :

      

      Un autre élément important dans la représentation graphique d'un script est le point d'insertion. Il peut se trouver dans une maille vide ou dans un noeud sur l'un de ces quatre cotés. Dans ce dernier cas, il peut être sur un noeud. Ainsi, la structure du point d'insertion est formée de sa position, ses coordonnées, les indices de la source et de la destination de l'arc concerné.

      

      Durant l'édition d'un graphe, l'utilisateur peut sélectionner un ou plusieurs noeuds et/ou arcs. Les ensembles des noeuds et des arcs sélectionnés sont enregistrés dans une structure qui permet de les gérer.

      

      Une autre structure est aussi créée pour contenir des renseignements pour traiter la barre de défilement (dimensions du graphe).

      

      La structure finale contient les différentes informations (graphe, point d'insertion, sélection, barre de défilement) concernant le script, les différentes dimensions (grille, canal, noeud, gouttière, fenêtre, ...), la famille d'icônes utilisée et les autres préférences de l'utilisateur.

      

      


6.1.2.3 Les représentations graphiques dans Tcl/Tk

      Dans les programmes Tcl/Tk, la représentation graphiques d'un script est géré par les étiquettes (tag) des éléments graphiques et par différentes variables globales. Tcl/Tk autorise l'utilisation de plusieurs étiquettes pour un objet graphique donné. Ceci permet le regroupement d'un certain nombre d'objet sous une même étiquette.

      Chaque noeud est contrôlé par son étiquette et les éléments qui le composent ont également leurs propres étiquettes. Ces éléments du noeud sont le fond rectangulaire et le texte à afficher. Pour un noeud d'indice i, son étiquette est node_i, celle de son rectangle est node_i.Rectangle et celle de son texte est node_i.String. Les étiquettes sont attribuées au moment de la création du noeud.

      Nous profitons de l'utilisation d'étiquette multiple pour regrouper les objets graphiques qui sont seulement visibles en mode flot de contrôle et ceux visibles seulement en mode flot de données. En plus de leurs propres étiquettes, les premiers ont aussi l'étiquette controlObj et les deuxièmes l'étiquette dataObj.

      Comme nous l'avons déjà expliqué, pendant le mode de vue flot de contrôle les paramètres d'un noeud sont représentés par une seule décoration graphique, l'anse des paramètres. Sa propre étiquette est composée du mot param, de l'indice du noeud associé et le type des paramètres représentés (in ou out). Elle a aussi l'étiquette controlObj. L'étiquette param_2.out désigne l''anse des paramètres de sortie du deuxième noeud du graphe.

      Par contre, dans le mode de vue flot de données chaque paramètre est représenté individuellement par son terminal de données. L'étiquette caractérisant un terminal de données est composée du mot term, de l'indice du noeud associé, de l'indice du paramètre représenté et son type (in ou out). Il a aussi l'étiquette dataObj. L'étiquette term_2_1.out désigne le terminal de données représentant le premier paramètre de sortie du deuxième noeud du graphe.

      Puisque nous avons deux classes d'arcs, nous avons deux étiquettes d'arcs différentes. Mais elles ont des parties communes. Elles commencent par le mot arc suivi par l'indice du noeud source puis celui du noeud destination. Cette forme d'étiquette est suffisante pour représenter les arcs de flot de contrôle, mais pour les arcs de flot de données il faut aussi mentionner les noms du paramètre source et du paramètre destination. En plus de ça, les arcs de flot de contrôle ont aussi l'étiquette controlObj tandis que ceux de flot de données l'étiquette dataObj.

      L'étiquette arc_4-7 désigne l'arc de flot de contrôle partant du noeud d'indice 4 vers le noeud d'indice 7. Supposons que le noeud 4 a un paramètre de sortie appelé X et le noeud 7 un paramètre d'entrée appelé Nombre, l'arc de flot de données reliant ces deux paramètres doit avoir l'étiquette arc_4-7-X-Nombre.

      Trois groupes principaux de variables globales sont utilisés pour mémorisés les différents caractéristiques d'un script:

  • Le tableau globalInfo contient toutes les informations générales de SyncEd à l'exception des informations pour dessiner le graphe.
  • Le tableau scriptInfo contient toutes les informations concernant les états des noeuds et des arcs. Chaque élément est indexé par l'identification du noeud et du numéro du script. Il contient une liste qui inclut le type du noeud, son état de sélection et des informations sur les arcs.
  • Le tableau drawInfo contient des informations nécessaires pour dessiner le graphe (exemple dimension, couleur, font, ...).

6.1.3 L'organisation des programmes


6.1.3.1 Programmes Ada

      L'ensemble des programmes Ada peut être classé en cinq groupes: les programmes pour assurer la communication, les programmes pour effectuer les opérations graphiques et gérer les objets graphiques, les programmes pour manipuler les événements et les taches correspondantes, les programmes pour lire/écrire un script et gérer sa représentation interne, et d'autres programmes qui sont plus moins communs à ces quatre groupes.

      Le groupe de programmes de communication offre des fonctions d'importation écrites en C et des routines pour la communication entre Ada et Tcl/Tk. Il s'occupe aussi de l'envoi des commandes à Tcl/Tk.

      Le groupe de programmes graphiques offre les structures de données des objets graphiques du script et les principaux traitements graphiques de SyncEd. Il calcule par exemple la prochaine position de point d'insertion, la position de noeud dans la maille, la trajectoire d'un arc dans la maille, la gouttière et le canal, etc. Il envoie la requête d'une commande Tcl/Tk.

      Le groupe de programmes d'événement supervise les différentes opérations. Il traite tous les événements reçus depuis Tcl/Tk, filtre les événements de l'éditeur de script et de l'éditeur de programme, effectue les traitements appropriés aux évènements reçus.

      Le groupe de programmes de traitements internes définit les structures de données du script et offre les routines pour la lecture et l'écriture du fichier de script et du fichier de message. Il donne aussi les différentes routines pour la manipulation des structures de données du script.

      Le dernier groupe plus général donne des définitions de quelques constantes globales et gère les messages de 'debugging'. Il est possible d'utiliser six types de messages différents. Ils permettent d'avoir des informations de 'debugging' plus précis. Si une certaine idée au sujet de la cause de l'erreur est déjà avancée, il vaut mieux choisir un certain détail de messages de 'debugging'. La Figure 6.2 permet à l'utilisateur de faire ce choix.

      

Figure 6.2 Panneau de choix de détail de messages de 'debugging'


6.1.3.2 Programmes Tcl/Tk

      L'ensemble des programmes Tcl/Tk peut être classé en trois groupes: les routines propres à l'utilisation de l'éditeur synchrone, les routines pour l'éditeur de textes, et les routines plus générales. Chacun de ces groupes offre des fichiers de langue qui permettent d'utiliser la langue naturelle choisie.

      Les programmes propres à SyncEd permettent la création, l'activation et la désactivation du menu principal. Ils créent le menu jaillissant et le contrôlent (mode Control ou Données). Ils offrent les différentes routines de manipulation de script (création de fenêtre, de noeuds, d'arcs, ..., édition des étiquettes des arcs des noeuds Test ) et les routines pour la communication par socket. Parmi les tâches principales de ce groupe de programmes sont les opérations de manipulation de lien entre un script et son programme. Ces dernières n'ont pas été traitées dans ce travail de thèse.

      Les routines d'édition de textes permettent d'éditer le contenu d'un noeud ou un programme manuel produit par le générateur. Elles offrent les boîtes de dialogues de l'éditeur de texte et la facilité de faire des copier-coller, de chercher et remplacer, d'effectuer des chargements et des sauvegardes de fichier.

      Les programmes d'usages communs offrent quelques fenêtres de message et des routines pour le 'debugging'. Ils donnent aussi les différentes routines pour la sélection de fichier ou des fontes de caractères, la personnalisation de certaines caractéristiques de l'éditeur (exemple couleur).


6.2 Les formats de fichier de script et de fichier de message

      Les formats de fichier de script et de fichier de message sont très importants d'une part, pour garder dans un fichier externe les caractéristiques du script créé, et d'autre part pour transmettre au générateur les informations indispensables pour bien transcrire le script.


6.2.1 Le fichier de script

      Suite à l''intégration du flot de données, le format du fichier de script a beaucoup changé puisqu'il doit enregistrer toutes les informations nécessaires pour rétablir les structures de données internes concernant les paramètres et les arcs.

      Le format retenu doit traduire au moins les situations suivantes:

  • Un noeud peut avoir plusieurs paramètres d'entrée et/ou de sortie, mais ce n'est pas obligatoire;
  • A chaque paramètre doivent être associés son nom et son type;
  • Un paramètre d'entrée peut avoir une valeur par défaut et peut être déclenchant ou non;
  • Les arcs (entrants ou sortants) sont directement associés aux paramètres qui peuvent en avoir un ou plusieurs, mais ce n'est non plus obligatoire.

      Le format d'un noeud dans le fichier de script est donc de la forme:

      

  • <D> signale que le noeud a des paramètres définis et qu'ils seront décrits à la suite.
  • <O> introduit la description d'un paramètre de sortie:
    • ParamName donne le nom du paramètre, de même pour les paramètres d'entrée
    • ParamStr donne le type du paramètre, de même pour les paramètres d'entrée
  • <A> introduit chaque arc relié au dernier paramètre décrit
    • Code est composé de deux caractères (P ou W) et donne le mode de combinaison des données à la source et à la destination de l'arc (voir ..).
    • SNodeId donne l'identification du noeud source
    • TNodeId donne l'identification du noeud destination
    • SVarName donne le nom du paramètre source
    • SVarStr donne le type du paramètre source
    • TVarName donne le nom du paramètre destination
    • TVarStr donne le type du paramètre destination
  • </A> signale la fin d'une liste de descriptions d'arcs
  • <I> introduit la description d'un paramètre d'entrée
    • Trigger prend la valeur 0 ou 1 et indique si le paramètre d'entrée en question est déclenchant (1) ou non (0)
  • <=> introduit la valeur par défaut (ou initial) du paramètre d'entrée
    • Value donne la valeur par défaut
  • </D> signale la terminaison de la spécification des données. Le texte du noeud viendra à la ligne suivante.

      

Exemple 6.2 Noeud avec arcs entrants et arcs sortants

      Le noeud de l' Exemple 6.2 est un noeud Directive (Commande) au codeur lui indiquant que à cet endroit il faut effectuer deux opérations, addition et multiplication. Les deux opérandes op1 et op2 sont donnés en paramètre d'entrée et les résultats resAdd et resMul correspondent aux deux paramètres de sortie du noeud. Les deux paramètres d'entrée sont reliés avec des paramètres du même nom du noeud 3.

      Le paramètre de sortie resMul est relié avec deux paramètres de même nom que lui et qui appartiennent l'un au noeud 7 et l'autre au noeud 14, tandis que le paramètre de sortie resAdd est relié seulement avec un paramètre du noeud 7.

      Tous les paramètres de cet exemple sont de type entier et sont pris tels quels à la source et utilisés tels quels à la destination. Les deux paramètres d'entrée sont non déclenchant. Par conséquent, ils ont des valeurs par défaut qui sont égales à 0.


6.2.2 Le fichier de message

      L'intégration de flot de données n'a pas de conséquence dans le format du fichier de message. Même si le texte du message à afficher peut contenir des variables (paramètres du noeud Message), ces variables ne sont pas traitées au niveau du message mais c'est l'appel à la routine d'affichage qui tiendra compte de ces variables.

      Mais pour cela, les variables contenues dans le texte du message doivent correspondre exactement aux noms des paramètres du noeud. Ces variables peuvent se trouver à n'importe quel endroit du texte du message et peuvent y figurer plusieurs fois.

      

Exemple 6.3 Noeud Message avec deux paramètres: op1 et op2

      

Exemple 6.4 Contenu du fichier de message correspondant au noeud Message ci-dessus.

      Dans l' Exemple 6.3 nous avons un noeud Message ayant deux paramètres op1 et op2 venant tous les deux du noeud 3. Le message correspondant à ce noeud dans le fichier de message est donné par l' Exemple 6.4. Ceci montre que le texte du message contient les noms des paramètres. Ces noms seront remplacés par les valeurs des paramètres lors de l'affichage du message.


6.3 Représentation graphique

      L'utilisateur ne voit pas la structure des fichiers de travail de DIVA-cd. Dans l'environnement de programmation visuelle, la plupart des actions s'effectuent sur l'écran, ce qui exige une grande qualité de la représentation graphique.

      Pour améliorer la lisibilité du graphe de script, notre groupe a entrepris des recherches dans le domaine de dessin graphique 21  [Ibrahim00a][Ibrahim00b][Ibrahim01d]. La majeure partie des recherches faites dans ce domaine est centrée sur l'impression d'un graphe déjà créé et très peu a été fait au sujet des graphes qui sont interactivement créés et modifiés ([Garg94]). Une autre particularité de notre situation est que les noeuds ont un contenu textuel qui occupe une place considérable, et qui doit être au moins partiellement visible à tout moment pour permettre à l'utilisateur de comprendre l'usage du graphe affiché. La partie de la grille occupée par les noeuds est donc beaucoup plus grande que celle pour les arcs. Toutes ces considérations nous ont menés à séparer clairement les secteurs où les arcs peuvent passer (des gouttières) des secteurs utilisés par les noeuds (mailles). Ainsi nous avons conçu notre propre approche. Dans [Ibrahim00a] nous avons présenté une comparaison de notre approche avec d'autres approches.


6.3.1 Structure de l'espace de dessin

      La présentation graphique du script est organisée sur une grille. La grille se compose de mailles et de gouttières. Une maille peut contenir un noeud ou, quand aucun noeud ne l'occupe, elle peut être traversée par un arc vertical et/ou horizontal. Le contenu de noeud est placé dans une maille qui est entouré des gouttières, excepté celui de noeud Test qui peut regrouper verticalement un nombre fini de mailles, cachant ainsi des gouttières horizontales qui se trouvent juste entre les mailles.

      Une gouttière peut seulement contenir des arcs. Les arcs passent verticalement dans les gouttières verticales, horizontalement dans les gouttières horizontales et peuvent changer de direction aux intersections de gouttières (rotation de 90 ou 270 degrés) (dans la Figure 6.3, il y a deux arcs qui changent de direction). Un arc droit reliant deux noeuds physiquement adjacents peut également passer horizontalement à travers le milieu d'une gouttière verticale ou verticalement à travers le milieu d'une gouttière horizontale (dans la Figure 6.3, un arc droit vertical arrive sur le noeud et un arc droit horizontal part du noeud).

      

Figure 6.3 Des gouttières subdivisées en canaux.

      Plusieurs arcs peuvent passer dans la même gouttière. Pour éviter des chevauchements, les gouttières sont subdivisées en canaux dans lesquels seulement un arc peut passer. Dans la version actuelle, il y a neuf canaux longitudinaux et un canal transversal par gouttière. Les canaux transversaux sont utilisés pour dessiner les arcs droits qui relient deux noeuds physiquement adjacents (voir la Figure 6.3).


6.3.2 L'algorithme de dessin

      Nous avons défini trois types d'arcs:

  • Arcs de maille: Ce sont des arcs qui traversent des mailles et qui ont au plus un coude (Figure 6.4 (a)). Ces arcs utilisent le canal transversal des gouttières qu'ils croisent.
  • Arcs de gouttière: ce sont les arcs qui passent exclusivement par des canaux dans les gouttières et ne traversent aucune maille (Figure 6.4 (b)).
  • Arcs combinés: ce sont des combinaisons d'arc de maille et d'arc de gouttière, où à une extrémité l'arc se comporte comme un arc de maille, et comme un arc de gouttière à l'autre extrémité (Figure 6.4 (c)).

      

Figure 6.4 Les trois type d'arcs

      L'algorithme de dessin est utilisé pour trouver automatiquement une trajectoire pour chaque arc du graphe. Les arcs peuvent changer de direction dans une maille ou dans une gouttière (verticale ou horizontale) ou dans une intersection de gouttière. Nous avons trois situations possible pour le traçage des arcs:

  • Traçage simple: c'est la situation où deux noeuds sont sur la même ligne ou la même colonne et aucun noeud se trouve entre les deux, un arc de maille droit est dessiné.
  • Traçage avec heuristique: une heuristique est appliquée pour les arcs qui peuvent être dessinés d'une certaine manière, dans certaines circonstances expliquées ci-après.
  • Traçage général: le 'backtracking' simple est utilisé pour résoudre tous les autres cas. Tous les chemins possibles sont vérifiés un après l'autre jusqu'à ce que le noeud destination soit atteint sans heurter un obstacle.

6.3.3 Heuristique

      L'heuristique est utilisée pour réduire le nombre de coudes dans les arcs. Il s'agit des règles ad-hoc qui indiquent les chemins possibles à essayer, étant donnée une configuration des positions de noeud (annexe C).

      

Figure 6.5 Configurations typiques de noeuds utilisées dans le LHS des règles*

      *(O=noeud d'origine, D=noeud de destination)

      Typiquement, la partie gauche (left-hand side LHS) de ces règles contient une configuration de noeud indiquant la position relative des noeuds d'origine et de destination d'un arc, impliquant ainsi une direction globale de l'arc les reliant (voir la Figure 6.5). La partie droite énumère une liste de chemins possibles que le système devrait essayer dans l'ordre donné (voir la Figure 6.7). Chaque chemin alternatif est une variation selon l'endroit où l'arc est relié aux noeuds.

      L'heuristique de dessin inclue quatre groupes de règles selon les positions relatives des noeuds d'origine et de destination (voir Figure 6.6 pour déterminer les coordonnées de chaque position).

      

Figure 6.6 Les coordonnées des mailles

      Ces quatre groupes de règles sont:

      Cas 1: 'No intermediate' : Le noeud destination est adjacent avec l'origine, c'est à dire: (|XOrigine - XDestination| est inférieur ou égal à 1) et (|YOrigine - YDestination| est inférieur ou égal à 1)
La Figure 6.7 montre une règle de ce groupe pour la direction 'South-East' (Sud-Est) (Voir section C.1 de l'annexe C, pour l'ensemble des règles).

      

Figure 6.7 Règle type: Direction 'South-East' pour le cas 'No intermediate'.

      Note

      Les mots 'Right,' 'Left,' 'Down' et 'Top' dans les chemins alternatifs de la règle de la figure 6.7 font référence au côté du noeud où l'arc est connecté.

      Cas 2: 'Vertical intermediates' : L'origine et la destination se trouvent dans la même colonne ou dans deux colonnes adjacentes, mais les noeuds ne sont pas adjacents. La condition est:
(|XOrigine - XDestination| est inférieur ou égal à 1) et (|YOrigine - YDestination| est supérieur ou égal à 1)

      Par exemple, si nous considérons la direction 'South-East', seule l'alternative 'Down -> Top' ('Bas->Haut') est différente de ce qui est dans le groupe 'No intermediate '. Cette différence est montré dans la Figure 6.8 (a) (Voir section C.2 de l'annexe C, pour l'ensemble des règles).

      

Figure 6.8 Direction 'South-East', différences de 'vertical intermediate' et de 'horizontal intermediate' avec les alternatives de 'no intermediate'

      Cas 3: 'Horizontal intermediates' : L'origine et la destination se trouvent dans la même ligne ou dans deux lignes adjacentes, mais les noeuds ne sont pas adjacents. La condition est:
(|XOrigine - XDestination| est supérieur ou égal à 1) et (|YOrigine - YDestination| est inférieur ou égal à 1)

      Pour la direction 'South-East', l'alternative qui est différente de celles de cas 1 est 'Right -> Left' ('Droite -> Gauche'), voir Figure 6.8 (b) (Voir section C.2 de l'annexe C, pour l'ensemble des règles).

      Cas 4: 'Vertical-Horizontal intermediates' : ce cas regroupe toutes les autres possibilités en dehors de celles des trois cas ci-dessus. La condition est:
(|XOrigine -XDestination| est supérieur ou égal à 1) et (|YOrigine - YDestination| est supérieur ou égal à 1)

      Les arcs du cas 4 ont deux segments, un vertical et un autre horizontal. Ils peuvent être:

  • des arcs de maille (voir Figure 6.9 (a), pour la direction 'South-East');
  • des arcs combinés: le premier segment peut être un arc de maille et le second de gouttière, et vice versa (voir Figure 6.9 (b) et (c), pour la direction 'South-East');
  • des arcs de gouttière: Dans ce cas, les arcs peuvent avoir trois, quatre ou cinq coudes. Il y a plusieurs chemins possibles (voir Figure 6.9 (d) pour quelques exemples de la direction 'South-East'). L'algorithme commence tester les chemins avec le moins de coudes.

      

Figure 6.9 'Vertical-Horizontal intermediates': chemins alternatifs pour la direction 'South-East'


6.4 Le générateur automatique

      Dans l'implémentation du générateur de code, il faut déjà penser à tous les besoins pour l'implémentation de l'application utilisant les codes générés. Ces réflexions concernent d'une part les modules minimums nécessaires pour l'application et d'autre part les structures de données permettant de retrouver dans le logiciel applicatif le comportement spécifié par le script, notamment le flot de données.

      Il est important de rappeler que le générateur de code est écrit entièrement en Ada, mais le logiciel applicatif sera écrit dans le langage cible du générateur utilisé.


6.4.1 L'organisation des modules


6.4.1.1 Les modules du générateur de code

      L'organisation de base des modules du générateur de code a déjà été expliquée dans le chapitre traitant le modèle d'exécution, à savoir l'existence de deux groupes de modules: un groupe pour la génération de code, et un autre pour l'interfaçage avec les différents langages cibles.

      L'interfaçage avec les langages cibles offre des définitions de constantes et de variables d'état pour l'écriture des codes dans le langage cible (voir Exemple 6.5 et Exemple 6.6). Il fournit aussi des procédures de gestions des modules et des procédures d'écriture de code dans les langages cibles. Ces modules se basent sur les constantes et les variables d'état définies à cette fin.

      

Exemple 6.5 Extrait de la définition de code pour le langage Pascal

      

Exemple 6.6 Le même extrait de la définition de code mais pour le langage Ada

      La constante DefImportAvantEntete est utilisée, par exemple, pour créer l'interface d'un module. Selon la valeur de cette constante, la liste d'importation est ajoutée avant ou après le début de module. Lors de la création d'un commentaire, la valeur de DefLineBasedComment est vérifiée, et DefFinComment est ajoutée si nécessaire.

      Les modules de génération de code font appel au module de lecture de script utilisé par l'éditeur synchrone. Ils permettent de traiter chaque noeud du graphe, selon son type, entraînant ainsi l'insertion du noeud dans l'automate à états finis, la génération de procédure ou de fonction appropriée et le traitement des paramètres du noeud.


6.4.1.2 Les modules du logiciel applicatif

      Le langage d'implémentation de l'application dépend du langage cible du générateur utilisé pour produire les codes. Mais l'organisation des modules doit rester la même. Tout d'abord, il y a les modules produits par le générateur que nous avons déjà expliqué dans le chapitre précédent. Le module de l'automate à états finis est basé sur une boucle qui s'arrête lorsque l'état final est atteint. Le module à la main fournissent les procédures ou fonctions correspondant aux noeuds Test et Directive.

      Ils y a aussi les modules utilitaires qui devront être offerts et utilisés avec les modules générés. Ils s'agissent des modules pour la gestion de l'interaction homme-machine et des routines d'affichage, et des module pour le traitement et l'utilisation des fichiers de message. Des versions dans le langage cible de ces modules doivent être implanté. Les modules qui ont été utilisés pour Pascal sont très complets mais des versions pour Ada n'existent pas encore. Ainsi des modules similaires mais beaucoup plus simple sont utilisés pour notre travail de thèse.

      Un troisième groupe de modules est formé des modules spécifiques en relation avec le flot de données et qui sont aussi offerts. Pour implanter le comportement d'envoi des valeurs de paramètres de sorties à tous les paramètres d'entrée, une procédure ayant comme paramètres la valeur en sortie et la liste de paramètres d'entrée est créée. Elle copie la valeur sortie dans tous les éléments de la liste. Ces modules offrent aussi la possibilité de tester la disponibilité de tous les paramètres d'entrée d'un noeud. Parmi les modules de ce groupe doivent exister aussi les modules des types de données abstraits correspondant aux noeuds de données. Tous les modules de ce groupe doivent aussi être implantés dans le langage cible du générateur. Pour le moment ils sont écrits seulement en Ada.


6.4.2 Les structures de données

      Pour le générateur automatique de code, il faut penser à deux groupes séparés de structures de données. Le premier groupe concerne les structures de données utilisés lors de la génération de code tandis que le second groupe est pour les structures de données requises pour les codes générés.


6.4.2.1 Les structures de données pour le générateur de code

      Avant de créer les fichiers produits par le générateur, le contenu de chaque fichier est mis dans une structure de données formée de ligne chaînées. Cette structure est aussi utilisée par l'éditeur de texte et offre des primitives de manipulation (insertion, copie, concaténation, ...).

      

      Chaque instruction simple est mise dans une structure qui offre aussi en même temps des informations pour son écriture.

      

      Le champs CodeInstruction contient le texte de l'instruction. Si PointVirgule est vrai l'instruction sera suivie d'un point virgule. Si DoitIndenter est vrai l'instruction sera indentée à la position courante. Si New_Line est vrai l'instruction suivante sera sur une nouvelle ligne. Le champ Indentation indique si les instructions qui suivent doivent être indentées par rapport a celle-ci et dans quel sens se fait l'indentation (Nombre de caractères dans un sens ou dans l'autre en fonction du signe).

      Il est parfois aussi nécessaire de passer aux procédures servant à écrire le code plusieurs éléments qui forment un tout dans le langage cible. Pour cela deux listes munies de primitives de manipulation sont créées, la première pour la liste d'instruction et la seconde pour la liste de variable. Pour cette dernière, le type TypeVariable indique s'il s'agit d'un paramètre passé par référence ou par valeur, ou d'une variable à déclarer dans un bloc.

      

      Pour les cascades de noeuds Test, nous avons décidé que les noeuds d'une même cascade partagent les paramètres en entrée cependant seuls les paramètres en entrée du premier noeud de la cascade peuvent être reliés par des arcs. Ce qui signifie que les paramètres des autres arcs ne sont pas reliés et risquent de ne pas recevoir des valeurs actuelles. Lors de la génération de code, nous associons à chaque paramètre de sortie une liste des paramètres d'entrée qui lui sont reliés. Ainsi, si un paramètre d'entrée appartient à un noeud Test, il faut considérer tous les paramètres de même nom appartenant à tous les noeuds de la même cascade. Nous avons donc besoin d'une structure qui rassemble tous les noeuds Test d'une même cascade.

      

      Ces structures de données sont conçues pour la génération de code. Mais pour l'interfaçage avec les langages cibles, les données sont fournies sous formes de constantes de chaînes de caractères ou de constantes booléennes (variables d'états).


6.4.2.2 Les structures de données pour les codes générés

      Les principales structures dont nous avons besoin sont les structures permettant d'établir les paramètres actuels (paramètres d'entrée et de sortie). En plus des valeurs de ces paramètres actuels, les structures utilisées doivent permettre de préserver les informations existant depuis la spécification pour ces paramètres. Nous avons donc les deux structures suivantes pour les paramètres d'entrées et de sortie.

      

      En résumé

      Le but principal de ce chapitre est de présenter et de discuter de l'enjeu principal de l'intégration du flot de données dans l'implémentation du système DIVA-cd. Pour cela nous avons présenté l'organisation des modules principaux. Il y a pourtant d'autres modules que nous n'avons pas parlé ici.

      De même pour les structures de données, ce sont les principales et importantes structures de données que nous avons décrites dans ce chapitre. Les structures complets se trouvent dans les fichiers interfaces des modules concernés.


7. Etudes de cas

      Avant de conclure ce rapport, nous voulons présenter dans ce chapitre quelques exemples significatifs qui nous permettront non seulement d'illustrer les différentes notions introduites pour l'intégration du flot de données mais surtout de discuter de leurs apports par rapport à l'utilisation du système uniquement de flot de contrôle. Ainsi pour chacun des exemples, nous allons d'abord présenter une version avec seulement le flot de contrôle et puis une autre version utilisant les deux paradigmes flot de contrôle et flot de données combinés.

      Nous allons présenter quatre exemples. Le premier reprend le bout de script que nous avons présente dans la figure 3.11. Il s'agit d'un petit exercice pour travailler la multiplication. Le deuxième est aussi un exercice mais pour se familiariser avec la conversion d'un nombre binaire en nombre décimal. Nous allons aussi présenter un exemple qui reprend l'illustration donnée dans [Ibrahim01a]. C'est la fusion de deux fichiers triés. Et nous terminons par la présentation des besoins de flot de données dans l'application messagerie auto-éducative appelée 'Friendly Mailer' [Ibrahim93][Ibrahim95].


7.1 Exercice de multiplication

      Reprenons le petit exemple (exemple 3.8) qui illustre ces différents types de noeud dans la section 3.2. On demande à un élève de donner le résultat de la multiplication de deux nombres:


7.1.1 Version avec flot de contrôle uniquement

      Pour spécifier ce petit exercice avec l'ancien système DIVA, nous avons deux choix:

  1. Fixer les valeurs des deux opérandes
  2. Utiliser des variables locales qui vont représenter les opérandes.

      La version présentée dans la section 3.2 a été établie selon le premier choix. Le script a l'allure présentée dans la figure 3.11. Dans cette version, les valeurs des opérandes sont 5 et 7.

      Considérons ici, une autre version avec l'utilisation des variables. Nous pouvons ainsi changer les valeurs des opérandes par des valeurs que le système génère aléatoirement. Nous avons donc le script de la Figure 7.1.


7.1.2 Points faibles

      Pour la version avec fixation des valeurs des opérandes, il est évident qu'on ne peut pas réutiliser le logiciel pour d'autres valeurs. Il faut changer les valeurs dans les codes et cela nécessite une compilation des programmes.

      L'utilisation des variables remédie à ce problème, un générateur des nombres aléatoires peut être utilisé pour avoir des valeurs différentes à chaque utilisation du logiciel ou pour pouvoir répéter plusieurs fois l'exercice (le mettre dans une boucle).

      Mais en utilisant un langage purement de flot de contrôle, nous ne pouvons pas visualiser la circulation des données. On ne peut pas savoir à quel endroit les valeurs sont générées, ni où elles sont utilisées. Nous allons donc re-spécifier cette petite application en utilisant le nouveau système DIVA-cd.


7.1.3 Version avec flot de contrôle et flot de données combinés

      Le graphe obtenu avec le système mixte ressemble un peu à celui de la Figure 7.1 puisque tous les deux utilisent les mêmes noeuds. La grande différence est la possibilité de 'mettre les mains' sur les données en utilisant le flot de données. La circulation des données est explicitement spécifiée par les arcs de flot de données. Nous avons donc le graphe de la Figure 7.2 pour la vue flot de contrôle et celui de la Figure 7.3 pour la vue flot de données.

      Note

      Il y a deux groupes de fichiers qui sont liés à cette application, les fichiers de script et de messages et les fichiers produits par le générateur.

      Les différences entre les contenus des fichiers de script et ceux des fichiers de messages pour les deux versions sont les informations concernant les données et les arcs de flot de données. Nous les présentons dans l'annexe A.

      Les fichiers produits par le générateur de code (langage cible: Ada) pour les deux versions se trouvent dans l'annexe B.

      

Figure 7.1 Version de l'exercice de multiplication avec flot de contrôle pur (choix 2)

      

Figure 7.2 Version de l'exercice de multiplication avec la combinaison des deux flots: vue flot de contrôle

      

Figure 7.3 Version de l'exercice de multiplication avec la combinaison des deux flots: vue flot de données


7.2 Conversion binaire vers décimal

      Un système devrait permettre aux apprenants de tester leur connaissance sur la conversion de nombres binaires signés (sur 8 bits) en nombre décimal. Pour cela, l'apprenant peut faire autant d'exercices de conversion qu'il veut. Un générateur automatique de nombres binaires est donc utilisé par le système. A la fin de l'exercice le système donne le résultat du test en affichant un message du genre:

      

Exemple 7.1 Message final

      Le concepteur pourrait commencer par une spécification du système en basant seulement sur le flot de contrôle. D'abord, un nombre binaire signé est généré. Le système tient un compteur des tests. Il fait la conversion en décimal. Puis il affiche un message invitant l'apprenant à entrer la valeur décimale qui correspond à la valeur binaire. L'apprenant donne donc une valeur décimale. Le système compare ensuite la valeur entrée par l'utilisateur et celle obtenue par la conversion faite par lui-même.

      Si les deux valeurs sont égales, le système met à jour un compteur de résultats corrects, puis affiche un message qui dit à l'apprenant que sa réponse est juste. Dans le cas contraire, un message disant que la réponse est fausse est tout de suite affiché. Dans les deux cas, après l'affichage des messages, le système demande à l'apprenant s'il veut encore faire une autre conversion.

      Si la réponse est Oui, l'exécution du programme reprend depuis la génération du nombre binaire. Dans le cas contraire, le système affiche le message ci-dessus (Exemple 7.1) qui donne un résumé des résultats. Après cela, le programme s'arrête.


7.2.1 Version avec flot de contrôle uniquement

      La Figure 7.4 représente la spécification de ce programme en utilisant seulement le flot de contrôle. L'ordre entre le noeud qui représente la tâche de conversion du nombre par le système et les noeuds qui invitent l'apprenant à entrer la valeur décimale peut être interverti.


7.2.2 Points faibles

      La nécessité de spécifier la circulation des données est fortement ressentie. D'abord, il faut passer la valeur binaire générée au noeud qui affiche le message invitant l'apprenant à entrer la valeur décimale correspondante. La valeur décimale résultant de la conversion et celle entrée par l'apprenant doivent être aussi passées au noeud qui effectue leur comparaison. Le résumé du résultat donné dans le message final nécessite l'utilisation des compteurs des valeurs positives et celles négatives générées et d'autres compteurs pour les résultats corrects faits par l'apprenant.


7.2.3 Version avec flot de contrôle et flot de données combinés

      Le script pour la version avec le flot de données et flot contrôle combiné sera établi de la manière suivante:

  • Deux 'récipients' de données seront utilisés pour compter d'une part le nombre de valeurs binaires positives générées et le nombre de réponses correspondantes correctes, et d'autre part le nombre de valeurs binaires négatives générées et aussi le nombre de réponses correspondantes correctes. Nous avons donc choisi deux noeuds Datastore, de type enregistrement (record) à deux champs. Le premier champ contient le nombre de valeurs générées et le second le nombre de réponses correctes.
  • Le noeud générateur de binaire envoie le bit de signe au noeud qui incrémente le nombre de valeurs générés et au noeud qui incrémente le nombre de réponses correctes. Puisque la valeur binaire sera représentée sous forme de tableau, ces deux envois nécessitent donc une opération de sélection du premier élément du tableau au début des arcs de flot de données correspondants. Ce noeud envoie aussi en entier la valeur binaire générée au noeud de conversion et au noeud qui affiche le message d'invite à l'apprenant.
  • Le noeud qui incrémente le nombre de valeurs générées reçoit le bit de signe de la valeur générée. Selon la valeur de ce bit, il met à jour le champ correspondant dans le compteur positif ou dans le compteur négatif. C'est pourquoi, en plus du bit de signe, il a comme paramètre d'entrée le nombre de valeurs positives et le nombre de valeurs négatives. Ces deux paramètres sont plutôt des paramètres d'entrée/sortie, c'est pourquoi on les retrouve aussi à la sortie du noeud. Il faut aussi préciser que les entrées ne sont que des parties des compteurs, donc on a, au début des arcs entrants correspondants, une opération de sélection du champ contenant le nombre de valeurs générées. Réciproquement, les résultats de l'incrémentation vont aussi modifier une partie du compteur correspondant, c'est pourquoi à la fin des arcs sortants on a une opération de composition pour le champ contenant le nombre de valeurs générées.
  • Le noeud de conversion a comme paramètre d'entrée la valeur binaire générée et comme paramètre de sortie la valeur décimale correspondante. Cette dernière sera envoyée au noeud de test pour la vérification de la réponse de l'apprenant.
  • Le noeud qui affiche le message invitant l'apprenant à entrer la valeur décimale qui correspond à la valeur binaire générée a seulement cette valeur binaire comme paramètre d'entrée.
  • Le noeud suivant qui reçoit la valeur entrée par l'apprenant a seulement un paramètre de sortie contenant cette valeur. Cette valeur sera aussi envoyée au noeud de test pour être comparée avec le résultat de la conversion.
  • Le noeud de comparaison prend donc deux paramètres d'entrée correspondant au résultat de la conversion et à la valeur entrée par l'apprenant.
  • Comme pour le noeud qui incrémente le nombre de valeurs générés, celui qui incrémente le nombre de réponses correctes reçoit aussi le bit de signe de la valeur générée. Selon la valeur de ce bit, il met aussi à jour le champ correspondant dans le compteur positif ou dans le compteur négatif. Il a donc deux autres paramètres d'entrée/sortie correspondant au nombre de réponses positives correctes et au nombre de réponses négatives correctes. Comme ce sont aussi des parties des compteurs, une opération de sélection du champ contenant le nombre de réponses correctes existe donc au début des arcs entrants correspondants. A la fin des arcs sortants on a aussi une opération de composition pour modifier seulement le champ du compteur correspondant qui contient le nombre de réponses correctes.
  • Le noeud qui reçoit la réponse de l'apprenant s'il veut ou non continuer l'exercice a seulement un paramètre de sortie qui est envoyé au noeud test effectuant l'analyse de cette réponse.
  • Le noeud test qui analyse la réponse de l'apprenant a donc seulement un paramètre d'entrée représentant cette réponse.
  • Le noeud qui affiche le résultat du test a deux paramètres d'entrée correspondant au deux compteurs. Ici les deux données sont transmises et utilisées en entier.

      Dans tous les noeuds d'activités utilisant des données, les arcs entrants sont liés à des terminaux déclenchants. Des nouvelles valeurs sont donc nécessaires pour chacun des paramètres pour pouvoir activer le noeud correspondant. Les deux compteurs doivent être initialisés à zéro.

      Dans la Figure 7.5 nous présentons la vue flot de contrôle du script obtenu, nommé 'bin2dec_cd' et dans la Figure 7.6 nous avons la vue flot de données.

      

Figure 7.4 Script 'bin2dec' purement de flot de contrôle

      

Figure 7.5 'bin2dec_cd': Vue flot de contrôle

      

Figure 7.6 'bin2dec_cd': Vue flot de données


7.3 Fusion de fichier

      Cet exemple a été donné pour illustrer un de nos articles [Ibrahim01a]. Il fait intervenir un noeud Queue pour faire usage de tampon entre la lecture et l'écriture des contenus des fichiers. Il permet de découpler les lectures dans les fichiers d'entrée et l'écriture dans le fichier de sortie. Puisque le script spécifiant cette opération prend beaucoup d'espace d'affichage, nous le représentons ici par des graphes schématiques.

      Note


7.3.1 Version avec flot de contrôle uniquement

      La Figure 7.7 donne la spécification de cette application avec le système de flot de contrôle pure. Cette spécification ne présente pas la circulation des données. Nous allons l'étudier en examinant les différentes parties qui la forment.

      L'exécution du programme commence par la première partie du graphe composée par les noeuds 1 à 7. Le but de cette partie est de vérifier des conditions spéciales, telles que l'un ou les deux fichiers en entrée étant vide(s).

      La deuxième partie du graphe est composé des noeuds 8 à 11'. Un jeton de contrôle arrive sur le noeud 8 si les deux fichiers en entrée ne sont pas vides. Ce noeud prend des données à partir du premier fichier (F1) puis envoie un jeton de contrôle au noeud 9. Quand le noeud 9 reçoit le jeton de contrôle, il commence son exécution et prend des données à partir du deuxième fichier (F2), et puis envoie un jeton de contrôle au noeud 10, noeud Test avec le prédicat 't1 < t2'. Si l'évaluation du prédicat donne vrai, un jeton de contrôle est envoyé par le noeud 10 au noeud 10' qui met t1 dans le fichier de sortie F3. Si le prédicat est évalué à faux, le noeud passera un jeton de contrôle au noeud Test (noeud 11) juste au-dessous de lui. Puisque l'évaluation du prédicat prédéfini 'otherwise' donne toujours vrai. S'il reçoit le jeton de contrôle, le noeud 11 enverra un jeton de contrôle au noeud 11' qui met t2 dans le fichier de sortie F3.

      

Figure 7.7 Fusion de deux fichiers dans un troisième fichier version purement de flot de contrôle

      Après cela, il y a deux possibilité. D'une part, nous avons la troisième partie du graphe qui est formée par les noeuds 12 à 14. Après avoir mis t2 dans F3, le noeud 11' envoie un jeton de contrôle au noeud 12, un noeud Test qui contrôle si nous avons atteint la fin du fichier F2. Si c'est le cas, il envoie un jeton de contrôle au noeud 12' qui enregistre t1 dans F3. Puis les noeuds de la quatrième partie (noeuds 15 à 17') du graphe vide le fichier F1 dans F3. Mais si ce n'est pas le cas, le noeud 13 envoie un jeton de contrôle au noeud 14 qui lit une donnée (t2) depuis F2 et puis envoie un jeton de contrôle au noeud Test (noeud 10) avec le prédicat t1 < t2. Et le cycle reprend.

      D'autre part, nous avons la cinquième partie du graphe formée par les noeuds 18 à 20. Après avoir mis t1 dans F3, le noeud 10' envoie un jeton de contrôle au noeud 18, un noeud Test qui contrôle si nous avons atteint la fin du fichier F1. Si c'est le cas, il envoie un jeton de contrôle au noeud 18' qui enregistre t2 dans F3. Puis les noeuds de la sixième partie (noeuds 21 à 23') du graphe vident le fichier F2 dans F3. Mais si ce n'est pas le cas, le noeud 19 envoie un jeton de contrôle au noeud 20 qui lit une donnée (t1) depuis F1 et puis envoie un jeton de contrôle au noeud Test (noeud 10) avec le prédicat t1 < t2. Et le cycle reprend aussi.

      La dernière partie du graphe formée par les noeuds 28 et 29 procède à la fermeture de tous les fichiers. Le noeud 24 reçoit un jeton de contrôle lorsque les deux fichiers d'entrée sont vides. Comme ce noeud a trois arcs de flot de contrôle entrants, ceci signifie qu'il y a trois possibilité, soit les deux fichiers sont vides dès le début (testé dans la première partie du graphe) , soit F1 (réciproquement F2) est vide puis F2 (réciproquement F1).


7.3.2 Points faibles

      Comme pour les autres exemples, la version avec flot de contrôle pur ne permet pas de suivre les données. Par exemple, le noeud 10, noeud Test avec le prédicat t1 < t2, fait la comparaison des deux données t1 et t2. Le script dans la figure ne spécifie pas les provenances de ces deux données. Il ne spécifie non plus ce que ce noeud fait après la comparaison.


7.3.3 Version avec flot de contrôle et flot de données combinés

      La spécification établie avec le système combinant flot de contrôle et flot de données (Figure 7.8) offre des informations sur la circulation et le traitement des données. Ici le traitement concerne surtout la comparaison des valeurs lues depuis les fichiers.

      Note

  • Dans cette figure nous avons schématisé ensemble les deux flots. Ainsi, pour les distinguer, les arcs de flot de données sont en traits continus tandis que ceux de flot de contrôle sont en traits pointillés. Les textes entre parenthèses sont des commentaires et l'étiquette à côté de chaque terminal de données donne le nom du paramètre associé.
  • La première partie du graphe (noeuds 1 à 7) reste la même. Aucune donnée n'entre en jeu dans cette partie. La deuxième partie du graphe (noeuds 8 à 11) nous montre que le noeud 8 envoie la donnée qu'il a lue au noeud 10 pour être testée, de même pour le noeud 9. Dans cette version, un noeud Queue (noeud 25) est utilisé pour découpler la lecture et l'écriture des données. Les données à écrire dans F3 sont envoyées dans ce noeud. Les noeuds 10', 11', 12', 17', 18' et 23' du graphe de la Figure 7.7 sont donc supprimés dans celui de la Figure 7.8. Il y a seulement un noeud pour l'écriture sur F3, le noeud 26.

      L'arc de flot de contrôle entre le noeud 9 et le noeud 10 assure que le noeud Test ne commencera pas à évaluer son prédicat avant qu'il ait des données fraîches sur tous ses deux terminaux d'entrée. Quand ce noeud Test reçoit le jeton de contrôle, il y aura des données sur chacun de ses terminaux d'entrée venant des fichiers d'entrée respectifs. Si l'évaluation du prédicat donne vrai, le jeton avec la valeur plus petite, marquée t1, sera envoyée à la queue (file d'attente, attendant pour être écrit dans le fichier de sortie, et le jeton marqué t2 sera envoyé à la cinquième partie du graphe (noeud 18 à 20). Si le prédicat est évalué à faux, le noeud passera tous ses jetons (contrôle+données) au noeud Test juste au-dessous de lui. L'évaluation du prédicat prédéfini 'otherwise' donne toujours vrai. S'il reçoit un jeton de contrôle, le noeud 11 enverra son jeton de données marqué t2 à la queue citée précédemment et le jeton marqué t1 à la troisième partie du graphe (noeuds 12 à 14).

      Dans la troisième partie du graphe (noeuds 12 à 14), si nous avons atteint la fin du fichier F2, le noeud Test (noeud 12) envoie t1 à la queue et le reste de F1 est aussi envoyé à la queue par la quatrième partie du graphe (noeuds 15 à 17). Si nous n'avons pas atteint la fin de F2, le noeud 14 lit une nouvelle donnée à partir du fichier F2. Il la passera au terminal t2 du noeud 10 (noeud Test avec le prédicat t1 < t2), et lui envoie aussi en même temps un jeton de contrôle.

      

Figure 7.8 Fusion de deux fichiers dans un troisième fichier version flot de contrôle et flot de données combinés

      Dans la cinquième partie du graphe (noeuds 18 à 20), si nous avons atteint la fin du fichier F1, le noeud Test (noeud 18) envoie t2 à la queue et le reste de F2 est aussi envoyé à la queue par la sixième partie du graphe (noeuds 21 à 23). Si nous n'avons pas atteint la fin de F1, le noeud 20 lit une nouvelle donnée à partir du fichier F1. Il passera cette nouvelle donnée au terminal t1 du noeud 10 (noeud Test avec le prédicat t1 < t2), et en même temps il lui envoie un jeton de contrôle.

      La dernière partie du graphe formée par les noeuds 24 à 29 procèdent à l'écriture dans le fichier de sortie et à la fermeture de tous les fichiers. Le noeud 25 est censé découpler l'arrivée en série des données venant des deux fichiers en entrée par les divers arcs de flot de données, du stockage de ces données dans le fichier de sortie F3. C'est un noeud Queue qui reçoit les jetons de données de diverses parties du graphe par son terminal d'entrée et les garde jusqu'à ce qu'ils puissent être stockés dans le fichier de sortie F3. Le noeud 26 fait l'écriture dans le fichier. Ces deux noeuds ont seulement des prédécesseurs de flot de données et sont ainsi complètement data-driven. Le terminal marqué n du noeud Queue n donne le nombre de jeton restant dans la file d'attente chaque fois qu'un jeton de données est envoyée de la queue. Ce nombre peut être employé pour déterminer si la file d'attente est vide ou pas (notons que la file d'attente peut être vide à un moment donné, et non vide un moment plus tard).

      Le noeud Test avec le prédicat 'n=0' peut recevoir beaucoup de jetons de données sur son terminal avant qu'il reçoive un jeton de contrôle. Chaque nouveau jeton de données recouvrira le précédent. Quand il reçoit un jeton de contrôle, le prédicat est évalué et, si la file d'attente (représentée par le noeud Queue, noeud 25) n'est pas vide, le noeud Test (noeud 28) envoie un jeton de contrôle au noeud 27, l'incitant à refaire la vérification.

      Note

      Dans les quatrième (noeuds 15 à 17) et sixième (noeuds 21 à 23) parties du graphe (Figure 7.8), nous avons des boucles, gérées par un jeton de contrôle, qui envoient des jetons de données à la queue.


7.4 Messagerie auto-éducative: 'Friendly Mailer'


7.4.1 Le projet

      Ce projet d'EAO [Bork92a] suggère une nouvelle approche de développement de logiciel qui met l'accent sur les diverses classes d'utilisateurs. Il combine l'apprentissage et l'utilisation d'un logiciel. Le logiciel est dit auto-éducatif. La conception d'un logiciel auto-éducatif ne correspond pas à une simple intégration d'aides en ligne dans le logiciel, même si beaucoup de logiciels ont des degrés variables d'aide en ligne. Ces aides en ligne sont au mieux utiles aux utilisateurs expérimentés.

      Une personne qui n'a jamais utilisé un système de courrier électronique et commence à le faire a des problèmes tout à fait différents qu'une personne qui est expérimentée dans plusieurs systèmes de courrier électronique, mais qui est en train d'utiliser un autre sur un système différent. Par conséquent, les aspects d'apprentissage doivent dépendre de l'utilisateur: les connaissances de base de l'utilisateur, ses désirs et ses besoins. Le logiciel doit pouvoir recueillir des informations sur l'utilisateur, et doit pouvoir prendre des décisions raisonnables basées sur cette information.


7.4.2 La spécification du logiciel

      Le système DIVA est utilisé pour spécifier cette application. Il y a à peu près une cinquantaine de script. Après quelques routines d'initialisation, le système vérifie si l'utilisateur a déjà un profil enregistré. Si c'est le cas, la suite du traitement dépend du niveau de compétence de l'utilisateur (Novice, Intermédiaire et Avancé). Dans le cas contraire, le logiciel essaye d'obtenir des détails sur les expériences de l'utilisateur et décide sur sa classification dans le niveau de compétence. La Figure 7.9 et la Figure 7.10 présentent deux extraits du script principal de cette application.

      

Figure 7.9 Début du script Main1, script principal de 'Friendly Mailer'

      

Figure 7.10 Un autre extrait du script Main1


7.4.3 Besoin de flot de données

      Rien qu'en lisant la description du projet, nous constatons déjà qu'un tel logiciel doit traiter plusieurs informations. Pour la spécification avec DIVA, les données sont classées en deux catégories: les symboles et les variables globales. Les symboles sont les variables indiquant les profiles des utilisateurs. Ils sont enregistrés dans un fichier de symboles. Les variables globales sont des variables utilisées par plusieurs scripts et correspondent à des variables globales Pascal (Les codes générés sont en Pascal). Les symboles ont des variables globales correspondantes.

      Les tableaux suivants donnent des descriptions de quelques exemples de symboles et des variables globales utilisés. Nous avons sélectionné ici des symboles ou des variables qui sont décrits dans un script et utilisés dans d'autres script. Ces échanges de données pourraient être représentés avec le flot de données.

      
Tableau 7.1 Quelques symboles
Nom Type (valeurs possible) Défini dans Utilisé dans Signification
User_Level Chaine de caractères (novice,intermediate,advanced) Main1 DisplayMsgNovice, HandlePending1, Main1 Indique la compétence de l'utilisateur
User_Name Chaine de caractères InitializeRecord, Main1 InitializeRecord, Main1, HandlePending1, Lesson1 Nom d'accès de l'utilisateur
Nb_Msg_Sent Entier InitializeRecord, Main1 Main1 Nombre de fois que l'utilisateur a envoyé un message

      
Tableau 7.2 Quelques variables globales
Nom Type Défini dans Utilisé dans Signification
CouldRefuseSend Booléen Init, Suggesting1, TypeBody1 SendMsg1 Si l'utilisateur a l'opportunité de refuser l'envoi
NbLesson2 Entier Main1, Lesson2, InitializeRecord Main1, Lesson2 Nombre de fois que l'utilisateur a utilisé Lesson2
NbMsgSentAtAdvance Entier InitializeRecord, Main1 Main1 Garde la valeur de NbMsgSent lorsque l'utilisateur monte un niveau

      En résumé

      Les différents cas que nous avons présentés dans ce chapitre nous montrent que l'intégration du flot de données dans le système DIVA lui donne un champ d'application plus large. Elle permet aussi au concepteur d'être plus précis quant à l'utilisation des données existant dans l'application. Ceci améliore la spécification des applications EAO.


8. Bilan et Perspectives

      Avant de conclure ce rapport nous allons tout d'abord apporter un bilan de notre travail. Le but que nous nous sommes fixé est-il atteint? Quels sont les apports et avantages de notre formalisme? Quels sont aussi ses faiblesses et inconvénients? Quelles sont les améliorations possibles?

      Le nouveau formalisme que nous avons intégré dans notre système offre plusieurs perspectives. Par exemple, l'intégration du flot de données dans notre système ouvre aussi un autre axe de recherche dont notre groupe a déjà proposé une première ébauche. Il s'agit de l'utilisation de notre système dans le développement d'application parallèle [Randriamparany00], c'est à dire l'intégration du parallélisme. Il sera donc aussi question de cette direction dans ce chapitre.


8.1 Bilan

      En essayant d'apporter des réponses aux questions que nous nous sommes posées dans la présentation du but de notre recherche (section 1.2), nous pouvons juger l'effort accompli pour ce travail de thèse. Sur la base des exemples qui ont été traités, nous pouvons savoir ce qui est fait, ce qui reste à améliorer et ce qui serait encore à faire.


8.1.1 Quels sont les éléments nécessaires dans le flot de données?

      Pour pouvoir intégrer le flot de données, nous avons besoin des concepts permettant de considérer les données utilisées individuellement par les noeuds du script, les données partagées par l'ensemble des noeuds et les échanges des données entre les noeuds.

      Est-ce que ces concepts sont donc présents dans notre formalisme? La réponse est trois fois OUI. Il s'agit des paramètres des noeuds pour les données individuelles, des noeuds de données pour les données partagées et les arcs de flots de données pour les échanges de données.


8.1.2 Comment ces éléments sont-ils représentés dans notre formalisme visuel?

      La réponse à cette question est développée dans le chapitre 4 mais nous pouvons la résumer comme suit.

      Les paramètres sont représentés visuellement par des décorations ajoutées aux noeuds concernés. Puisque nous avons deux modes de vues, nous avons deux types de décorations: les terminaux de données dans la vue flot de données et les anses de paramètres dans la vue flot de contrôle.

      Les noeuds de données ont trois formes de représentation. La première est une représentation plutôt textuelle qui est affichée avec le contenu du noeud. Les deux autres sont des représentions iconiques.

      Et finalement, l'échange de données est représenté par des arcs orientés, l'origine de l'arc correspond au noeud 'expéditeur' des données et sa destination correspond au noeud 'destinataire' des données.


8.1.3 Quelle est l'utilité de ces éléments?

      Le fait de pouvoir représenter visuellement les paramètres des noeuds permet aux utilisateurs de prendre connaissance facilement de l'existence des données manipulées par ces noeuds. Si cette représentation fait défaut, l'utilisateur doit consulter le contenu du noeud et pourrait être obligé à déchiffrer ce contenu. Ce qui n'est pas forcement facile.

      La présentation visuelle des échanges permet de suivre les circulations des données, et d'en déduire les éventuelles dépendances entre les différents noeuds. Les autres sémantiques que nous avons ajoutées aux arcs de flot de données enrichissent davantage les informations fournies par leurs représentations.

      L'utilisation des noeuds de données permet de spécifier les stockages des données qui pourront être traitées ultérieurement ou qui pourront être partagées par plusieurs noeuds. Le fait de donner une représentation visuelle de ces noeuds permet de spécifier explicitement la volonté de stocker les données.

      L'ensemble de tous ces éléments permet aux concepteurs de penser en terme de données durant la spécification de leur application.


8.1.4 Quels sont les différents comportements que l'intégration du flot de données rend possibles?

      Le premier comportement évident est l'échange de données entre les noeuds. Si un arc de flot de données relie deux noeuds d'activités, lorsque le noeud source finit son exécution, il envoie le long de cet arc les données correspondantes qui seront donc reçues tout de suite par le noeud destinataire. Si la source est un noeud de données, les données sont transférées lorsque le destinataire en a besoin.

      D'autres comportements ont été définis au niveau du noeud destinataire. Celui-ci peut 'consommer' les données qu'il reçoit et aura donc besoin d'une nouvelle arrivée de données pour sa prochaine activation. Ou bien, la dernière valeur des données reçue par le destinataire reste toujours valable et il peut l'utiliser plusieurs fois si aucune nouvelle valeur n'est arrivée.


8.1.5 Comment ces comportements sont-ils spécifiés visuellement?

      Le comportement correspondant aux envois de données est simplement spécifié visuellement par les arcs de flot de données. Mais le comportement correspondant à la 'consommation' des données par les noeuds destinataire est spécifié visuellement par les terminaux de données. C'est pour cela que nous avons défini deux sortes de terminaux d'entrée: terminaux déclenchants et terminaux non déclenchants.


8.1.6 Comment tenir compte des données dans le générateur de code?

      Le générateur de code doit respecter la même règle qu'en chimie qui disait 'rien ne se perd et rien ne se crée mais tout se transforme'. C'est à dire que dans les modules produits par le générateur, les éléments visuels et les comportements spécifiés par le script doivent être 'transformés' ou 'décodés' pour que l'application ainsi développée ait les comportements attendus.

      Pour cela, les paramètres de chaque noeud deviennent des paramètres formels de la procédure ou fonction correspondante. L'envoi des données le long des arcs est codé par des copies de chaque paramètre de sortie à tous les paramètres d'entrées qui lui sont attachés. Ces valeurs deviennent ensuite des paramètres actuels pour l'appel des procédure ou fonction correspondante. Une structure de données spéciale est créée pour chaque paramètre d'entrée afin qu'on puisse vérifier l'arrivée d'une nouvelle instance si ce paramètre correspond à un terminal déclenchant.


8.1.7 Un peu de chiffres

      Pour l'implémentation de notre formalisme, nous avons repris les codes qui existent déjà pour la version purement de flot de contrôle et nous y avons ajouté les codes nécessaires pour l'intégration du flot de données. La raison de ce choix est notre décision de garder tel quel le comportement de l'ancien système pour qu'on puisse utiliser toujours les scripts créés avec celui-ci.

      Pour cela, il a fallu comprendre les milliers lignes de code pour savoir 'où mettre la main'. Ceci est une tâche assez difficile puisque ces codes ne sont pas toujours bien documentés. Rappelons que pour l'éditeur de script l'interface utilisateur graphique est écrit en Tcl/Tk tandis que les manipulations internes sont écrites en Ada. La communication entre ces deux composantes est écrite en C. Quant au générateur, il est écrit entièrement en Ada. Le petit tableau suivant recense les nombres de lignes de code existant avant (c'est-à-dire, les codes à comprendre) et les nombres de lignes de code après l'intégration.

      
Composante Nombre de lignes de code Ada Nombre de lignes de code Tcl/Tk
Avant Après ajout Avant Après ajout
Editeur de script 66.274 71.713 5.439 15.837 17.627 1.790
Générateur de code 4.712 6.615 1.903  


8.2 Quelques comparaisons

      Dans la section 2.3.4, nous avons déjà présenté comment certains langages mettent ensemble les paradigmes de flot de contrôle et de flot de données. Maintenant, que nous avons présenté notre formalisme, nous allons dans cette section, comparer notre langage avec quelques langages qui incluent aussi ensemble le flot de données et des constructions de structures de contrôle.

      Un exemple d'un langage visuel qui était principalement basé sur un formalisme de flot de contrôle, mais évolué vers l'intégration de flot des données, est les réseaux de Pétri Coloré (RPC) [Jensen97]. Dans les RPC, le jeton stocké dans les places peut contenir des données (appelées couleur) et ces données peuvent être modifiées par des noeuds de transition lorsqu'un jeton va d'une place à une autre. Chaque place a un ensemble de couleurs qui lui est associé et seulement le jeton avec une couleur appartenant à cet ensemble peut être stocké dans cet endroit. C'est un mécanisme de typage trouvé dans la plupart des langages de programmation. Les RPC ont eu une forte influence sur la conception de DIVA-cd et il y a une forte ressemblance entre les places et les transitions dans les RPC et, respectivement, les terminaux de données et les noeuds d'activité dans DIVA-cd. Cependant, la similitude s'arrête là, puisque la sémantique comportementale pour les places des RPC est tout à fait différente de celle de nos terminaux de données. En effet, les places des RPC peuvent contenir un nombre indéfini de jetons, alors que les terminaux de données contiennent seulement une seule donnée. En outre, une transition de RPC peut utiliser n'importe quel jeton contenu dans ses places prédécesseurs, alors qu'un noeud d'activité dans DIVA-cd utilise toujours la dernière donnée qui est arrivée sur chacun de ses terminaux de données. Le comportement des places de RPC est malgré tout trouvé dans les noeuds Bag de DIVA-cd, qui a également les noeuds Queue pouvant accomplir un but semblable mais néanmoins différent. En résumé, le langage de DIVA-cd inclut un composant de flot de données qui a le même comportement que les places des RPC (multi-ensembles), mais inclut également d'autres composants inexistants dans les RPC, noeuds Queue et les noeuds Datastore.

      VIPERS [ Ghittori98a][Ghittori98b ] inclut explicitement des arcs de flot de contrôle et de flot de données et permet les cycles. A cet égard, VIPERS a une ressemblance marquée à DIVA-cd, sauf que les terminaux des données de VIPERS ont seulement des sémantiques de 'déclenchement'. Une autre différence est que les terminaux des données de VIPERS ne peuvent pas avoir plus d'un arc de flot de données entrant, exigeant l'utilisation des noeuds de MERGE pour réaliser le même effet que le multiple arc de flot de données arrivant sur le même terminal dans DIVA-cd (c'est cependant juste une simplification visuelle qui n'ajoute aucune puissance expressive). VIPERS n'inclut pas des caractéristiques semblables aux noeuds de type Bag et Queue de DIVA-cd.

      Avec HP-VEE [Helsel94], en plus des terminaux de flot de données, un noeud peut avoir un pin 'sequence-out' et un autre 'sequence-in' qui peuvent être utilisés pour envoyer des signaux de contrôle entre les noeuds. Ceci ressemble légèrement aux capacités du flot de contrôle de DIVA-cd, sauf que VEE ne permet pas à plus d'un arc de flot de contrôle d'arriver sur un pin de séquence. En outre, les signaux de flot de contrôle ont la priorité sur le flot de données parce que la réception d'un signal de contrôle terminera immédiatement l'exécution d'un bloc indépendamment du flot de données courant. le HP-VEE inclut également des constructions d'itération 'For-count' et 'Until-break' et un commutateur conditionnel 'If/Then/Else'. Le VEE n'inclut pas des caractéristiques semblables aux noeuds de type Bag et Queue de DIVA-cd.


8.3 Perspectives

      Le formalisme que nous avons défini dans ce travail de thèse offre plusieurs nouvelles potentialités d'extension. Il pourrait s'agir des améliorations liées directement au prototype actuel de DIVA-cd, ou des nouvelles extensions qui apporteront de nouveaux concepts fourniront ainsi d'autres caractéristiques du système. Parmi ces nouvelles extensions, nous pouvons parler d'intégration d'analyse du comportement des apprenants qui sera très utile dans les applications EAO, ou bien de l'utilisation des jetons de contrôle dans les noeuds de données ou encore l'intégration du parallélisme. Mais avant de présenter ces extensions, nous allons parler des améliorations possibles de DIVA-cd. Ces améliorations utiliseront les concepts ou notions déjà définis dans ce travail.


8.3.1Améliorations de DIVA-cd

      Parmi les concepts que nous avons présentés dans ce travail, certains ne sont pas encore pris en compte par DIVA-cd, ou bien sont représentés autrement.

      Pour les représentations visuelles graphiques des structures de données (voir section 3.7.5.1), elles ne doivent pas surcharger le script mais devraient être affichées dans des fenêtres séparées. Actuellement, les fenêtres donnent des représentations visuelles textuelles.

      Les apparences des arcs de flot de données présentées dans la section 4.4 ne sont pas encore implémenté dans DIVA-cd. Elles sont aussi remplacées pour le moment par des descriptions textuelles affichées dans des fenêtres séparées.

      Pour les manipulations (sélections) des données aux extrémités des arcs de données, des représentations visuelles graphiques ont été décrites dans [Ibrahim98]. Elles ne sont pas encore prises en compte dans DIVA-cd.

      Dans la section 3.7.5, nous avons parlé de deux éditeurs conçus pour être utilisés avec l'éditeur de script: l'éditeur de structures et l'éditeur de constantes. Des communications d'une part, entre l'éditeur de script et l'éditeur de structure devront être mises en place pour que l'éditeur de script puisse utiliser un type de données créé avec l'éditeur de structures, et d'autre part, entre l'éditeur de script et l'éditeur de constantes pour que l'éditeur de script puisse utiliser une constante créée avec l'éditeur de constantes. Mais cela suppose que les représentations visuelles graphiques des structures de données soient déjà implémentées.


8.3.2 Analyse du comportement des apprenants

      L'existence des structures permettant de stocker des données est déjà un élément indispensable dans le suivi du comportement des apprenants. Mais pour avoir une analyse plus complète de leurs comportements, il est nécessaire d'étendre le formalisme actuel en ajoutant par exemple des concepts permettant de définir des comportements types. Le comportement de chaque apprenant serait alors évalué par rapport à ces comportements types.

      L'existence d'une analyse de comportement des apprenants permet, d'une part, d'avoir une meilleure qualité des séquences d'aides offertes par le système aux apprenants, et d'autre part, de classifier les apprenants afin de pouvoir donner des aides de différents niveaux.


8.3.3 Stockage de jetons de flot de contrôle

      La création de types de noeud permettant de stocker des informations dans notre formalisme (noeud Bag et noeud Queue) nous permettra de stocker d'autres types d'information selon le besoin, par exemple de stocker des jetons de contrôle. Dans ce cas, ces noeuds peuvent avoir des arcs de flot de contrôle entrant et sortant.

      Normalement l'activation d'un noeud consomme un seul jeton de contrôle depuis l'arc concerné. Mais il sera aussi possible que le noeud nécessite plus d'un jeton de contrôle pour être activé, c'est-à-dire qu'il a besoin que son prédécesseur ait été exécuté plus d'une fois. Nous avons donc besoin de stocker les jetons de contrôle produits par le prédécesseurs. Pour cela nous mettons un noeud de données de types bag ou queue, contenant de jetons de contrôle, entre les deux noeuds. L'arc de flot de contrôle reliant la sortie du noeud de données et du noeud en question portera une étiquette donnant le nombre de jetons de contrôle nécessaires pour son activation. Dans ce cas, le noeud reste dans l'état dormant jusqu'à ce que tous les jetons nécessaires soient disponibles.


8.3.4 Intégration du parallélisme

      Plusieurs langages ou systèmes utilisés pour le développement d'application parallèle sont basés sur le paradigme de flot de données, par exemple CODE [Newton92], VPE [Newton94]. Puisque DIVA-cd intègre le flot de données, nous avons effectué une première ébauche de l'intégration du parallélisme dans ce système [Randriamparany00]. Elle permettra d'utiliser DIVA-cd pour spécifier des applications parallèles. Cette intégration devrait garder les caractéristiques originale du système DIVA-cd qui sont la simplicité d'utilisation, le haut niveau d'abstraction, le multiparadigme, la multilinguisme, etc.

      Deux formes de parallélisme seraient possibles avec ce système: le parallélisme de données qui sera déduit surtout du flot de données qui est intégré dans DIVA-cd, et le parallélisme de contrôle qui sera obtenu par l'enrichissement du modèle de flot de contrôle. Comme pour l'intégration du flot de données, l'extension du système pour supporter le parallélisme affecte deux niveaux, le formalisme visuel et le générateur de code.

      Une grande partie du formalisme visuel de DIVA-cd pour le flot de données est utilisée pour le parallélisme de données. Le parallélisme de contrôle nécessite la définition des nouveaux types de noeud d'activité. Nous en avons prévus deux:

  • Le noeud Garde qui contient une expression booléenne. Son activation provoque l'évaluation de son expression. Si cette évaluation retourne la valeur booléenne 'vrai', tous ses successeurs dans le flot de contrôle sont activés en parallèle.
  • Le noeud Spawn qui est semblable au noeud Appel de sous-graphe. Il est ainsi associé à un sous-script. Mais la différence principale est que, avec le noeud Spawn, le sous-script appelé est exécuté en parallèle avec le script appelant.

      Pour la génération automatique de code, deux options se présentent,

  • soit avoir seulement un modèle d'exécution c'est-à-dire choisir une plate-forme d'exécution cible et créer un générateur de code spécifique pour cette plate-forme,
  • soit avoir plusieurs modèles d'exécution, donc plusieurs plates-formes, et créer un générateur de code le plus générique possible ou plusieurs générateurs indépendants selon les modèles d'exécution choisis.

      Pour le premier cas, il y aura une limitation des applications du système mais l'optimisation du code produit sera plus haute. Pour le deuxième cas, le système aura une large utilisation mais avec une optimisation moins avancée.

      Ce qui était présenté dans [Randriamparany00] n'est qu'une première ébauche qui nécessite encore des études et recherches plus approfondies. Et pour cet axe de recherche un travail collaboratif avec des spécialistes du parallélisme est souhaitable.

      En résumé

      Dans ce chapitre nous avons apporté des réponses aux questions que nous nous sommes posées au début de ce travail. Nous pouvons affirmer que nous avons pu répondre de façon positive à ces différentes questions.

      Nous avons aussi présenté les différentes perspectives qui peuvent être de simples améliorations du système DIVA-cd, ou de la prise en compte de nouveaux concepts tels que le comportement des étudiants, ou une toute autre direction de recherche, l'intégration du parallélisme, partant du formalisme actuellement utilisé dans DIVA-cd.


9. Conclusion

      Notre défi au départ est de trouver un moyen simple mais efficace de mettre ensemble les deux paradigmes flot de données et flot de contrôle dans un langage de spécification visuelle. Cette intégration nous permet d'attribuer de l'importance aux données en gardant toujours les avantages du flot de contrôle. Elle donne alors une souplesse d'utilisation de notre système puisque le concepteur peut raisonner en terme de flot de données et/ou en terme de flot de contrôle sans avoir besoin de changer de système.

      Mais le système est incomplet si le formalisme visuel n'est pas accompagné d'un générateur de code qui peut traduire toutes les caractéristiques de la spécification. Dès le début (avec DIVA), la conception du générateur de code prévoit déjà la possibilité d'avoir plusieurs langages cibles en séparant l'interfaçage avec ces langages. Cette caractéristique est sauvegardée dans l'intégration du flot de données. Ceci rend flexible la création d'un nouveau générateur de code pour un langage cible donné.

      Nous n'oublions pas non plus que notre domaine applicatif de base est l'EAO. En utilisant notre système pour la spécification de son cours, l'enseignant est libre de choisir s'il veut explicitement spécifier l'utilisation des données ou non. Soulignons que d'après les études de cas présentés dans la chapitre 7, l'intégration du flot de données permet d'avoir des applications plus performantes et réutilisables.

      Nous constatons que cette intégration ajoute un degré de complexité à DIVA-cd par rapport à DIVA. Mais cette situation n'affecte pas l'utilisation de notre système par des utilisateurs non-informaticiens puisque les deux flots sont traités séparément. Avec DIVA les données sont prises en compte lors du codage manuel effectué par un informaticien, l'utilisateur (notamment l'enseignant) pourrait donc avoir du mal à les comprendre, tandis qu'avec DIVA-cd les données peuvent être considérées dès la spécification, l'enseignant peut alors les visualiser et donner son avis.

      Mais pour le codeur, cette intégration du flot de données a un grand avantage. Puisque le flot de données font partie des éléments formels de notre formalisme, il est entièrement traduit par le générateur de code. Ceci allège considérablement la tâche de codage manuel.

      Une des grandes utilisations des données dans les applications d'EAO est la saisie ou la prise en compte des informations sur les progrès des étudiants. Puisque notre système offre un langage visuel, à granularité fine, intégrant le paradigme de flot de données, il propose diverses structures de données statiques et dynamiques [Ibrahim98]. Ceci donne plus de choix dans la mise en place des structures de données nécessaires pour le suivi des progrès des étudiants.

      On peut juger que notre approche privilégie plutôt les enseignants par rapport aux apprenants. Nous sommes convaincus que les premiers à être motivés pour vulgariser l'utilisation de l'EAO sont d'abord les enseignants. Mais cela n'empêche pas d'utiliser des méthodes permettant de développer l'interactivité pour fournir un environnement attrayant aux apprenants.

      Un autre point que nous voulons aussi souligner est la souplesse d'utilisation de notre système. Etant un gestionnaire de scénario, il peut être utilisé dans n'importe quel type d'application EAO. Il peut être utilisé utiliser aussi bien pour développer une application EAO basée sur Internet [Bork01b] que pour développer une application utilisant des hautes technologies multimédia [Bork99].


[Précédent] [Suivant]