Projet Croap

previous up next contents
Précédent : Présentation générale et objectifs Remonter : Projet CROAP, Conception et réalisation Suivant : Grands domaines d'application



Fondements scientifiques

 

Outils pour la manipulation de données structurées

Un des objectifs de notre groupe est de développer des outils génériques qui facilitent la construction d'applications interactives d'aide à la programmation. Les langages de programmation sont fortement structurés, par conséquent il est très souvent avantageux de pouvoir manipuler les programmes comme des structures de données arborescentes respectant une certaine syntaxe abstraite. Notre composant générique central est donc constitué par un noyau de manipulation d'arbres. Autour de ce noyau, gravitent plusieurs types d'outils : des outils d'analyse syntaxique, des outils d'affichage et des outils de manipulation sémantique. L'interactivité et la composante sémantique constituent les aspects les plus originaux de cette recherche.

Moteur d'affichage et outils interactifs de manipulation



Participants : Thierry Despeyroux , Valérie Pascual , Laurence Rideau , Laurent Théry


Dans des applications interactives, l'outil d'affichage est un acteur central. Il se doit de visualiser des données comme des formules mathématiques qui suivent des règles de typographie importantes. Il permet aussi de conserver une correspondance entre la visualisation d'un objet et sa structure pour permettre d'utiliser la visualisation comme un interacteur. Enfin cet outil se doit d'être programmable afin de permettre d'encoder facilement des réactions diverses aux interactions provoquées par l'utilisateur.

Par exemple, il est intéressant d'associer deux fenêtres pour que le contenu de l'une change en fonction de la position sélectionnée dans l'autre. Ce type d'association permet aisément de construire des outils qui guident l'utilisateur dans l'édition des programmes, afin de ne proposer que des modifications valides en fonction de la sélection courante.

L'outil d'affichage peut également être utilisé comme frontal pour un programme avec qui il communique soit en transmettant des données structurées, soit en communiquant des événements. Pour construire ce type d'applications complexes, il importe de disposer d'interfaces précises et de protocoles pour faciliter la communication entre les différents programmes. Notre étude de ces interfaces et protocoles a mené à la mise au point d'un cadre général pour l'organisation d'applications distribuées [7].

Spécifications sémantiques



Participants : Isabelle Attali , Yves Bertot , Joëlle Despeyroux , Thierry Despeyroux , Mikael Pettersson


Pour fournir des outils qui aident à programmer correctement, il est nécessaire de maîtriser le sens des programmes et des langages de programmation. C'est l'objectif de la sémantique des langages de programmation. Plusieurs styles de sémantique existent, chacun étant adapté à une classe d'applications : la sémantique axiomatique, basée sur la possibilité d'annoter les programmes avec des formules logiques décrivant l'état des variables du programme, est bien adaptée pour exprimer les propriétés de programmes impératifs dans un langage fixé. La sémantique dénotationnelle, basée sur la définition d'une fonction de l'ensemble des programmes vers le domaine des fonctions que ces programmes calculent, est bien adaptée pour comparer le pouvoir expressif de plusieurs langages de programmation. Dans notre projet, nous avons développé un style issu de la Sémantique Opérationnelle Structurelle, baptisé sémantique naturelle, qui est bien adapté pour décrire formellement des outils sur un langage donné.

Le nom «sémantique naturelle» fait référence à la déduction naturelle, un style de description du raisonnement logique, auquel il emprunte la notion de règle d'inférence. Chaque règle d'inférence contient un certain nombre de prémisses et une conclusion, avec le sens intuitif que l'on aura prouvé une instance de la conclusion dès que l'on aura prouvé les instances correspondantes des prémisses. Le contenu de chaque prémisse ou conclusion est ce que l'on appelle un jugement. La forme des jugements peut varier, mais ils contiennent typiquement un contexte, représentant des informations connues, un sujet, et des propriétés établies sur ce sujet.

Si l'on dispose de la description formelle d'un outil pour un langage de programmation, il est possible de simuler automatiquement le comportement de cet outil sur un programme du langage en construisant l'arbre de preuve dont la conclusion a ce programme pour sujet. En fait, la recherche de l'arbre de preuve peut être confiée à un interprète PROLOG. C'est l'un des résultats initiaux du projet CROAP d'avoir développé un langage de spécification appelé TYPOL permettant d'écrire des spécifications de sémantique naturelle et un compilateur vers PROLOG, permettant d'exécuter ces spécifications sur des programmes objets.

L'exécution en PROLOG a le défaut principal d'être gourmande en mémoire et, somme toute, plutôt lente. Pour cette raison, nous avons également cherché à découvrir d'autres stratégies d'exécution de spécification TYPOL. De telles stratégies efficaces peuvent souvent être trouvées si on se restreint à une certaine classe de spécifications TYPOL. Par exemple, une compilation à base de grammaires attribuées permet l'exécution sans unification de la classe de spécifications TYPOL restreintes aux aspects statiques des langages [3]. D'autre part, un évaluateur fonctionnel incrémental permet de mettre en oeuvre une classe plus large de spécifications permettant la description des aspects dynamiques. Enfin, Mikael Pettersson (Univ. Linköping) a obtenu des résultats très intéressants en termes de performances avec le développement de RML comme langage d'implantation de la sémantique naturelle.

Étude de langages de programmation



Participants : Isabelle Attali , Denis Caromel (SLOOP) , Sidi Ould Ehmety , Romain Guider


Une fois que l'on dispose d'une panoplie d'outils interactifs et d'une technique de description sémantique, il est intéressant d'aborder l'étude des grandes classes de langages de programmation. Ainsi, nous avons étudié tour à tour les langages impératifs, les langages procéduraux, les langages fonctionnels, les langages parallèles, les langages à flux de données et les langages à objets.

Le langage Sisal



Participants : Isabelle Attali , Denis Caromel (SLOOP) , Romain Guider


Le langage SISAL (Streams and Iteration in a Single Assignment Language), fortement typé, applicatif et à affectation unique, est particulièrement utilisé sur des architectures multiprocesseurs ou data-flow. La version SISAL 2.0 inclut des caractéristiques telles que les fonctions d'ordre supérieur, le polymorphisme, la surcharge et l'inférence de type (dans une forme limitée). Il n'existe pas de compilateur pour cette version du langage.

Nous avons décrit la sémantique dynamique de SISAL puis le format intermédiaire IF1(le format IF1 est une description textuelle de graphes data-flows qui permet les optimisations de code classiques), ainsi que la traduction de SISAL vers IF1. Enfin, nous avons spécifié des optimisations classiques sur ce format.

Le langage Eiffel



Participants : Isabelle Attali , Denis Caromel (SLOOP) , Sidi Ould Ehmety


Pour les langages à objets, nous avons tenu à effectuer l'étude d'un langage pratiquement complet : le langage EIFFEL. Nous avons formalisé les principaux concepts de la programmation à objets en général (objet, envoi de message, polymorphisme, héritage et liaison dynamique) et d'EIFFEL en particulier (combinaison du renommage et de la redéfinition). À partir de cette définition [2], nous dérivons un algorithme fondé sur la hiérarchie des classes et non pas sur une quelconque structure intermédiaire. Cet algorithme permet aux programmeurs EIFFEL d'aborder de manière pratique l'héritage, le renommage et la redéfinition, et ainsi de savoir déterminer quelle version d'une routine s'applique effectivement à un objet donné. Ces travaux servent actuellement de base à l'étude de la sémantique de l'héritage en JAVA.

Le langage Eiffel//



Participants : Isabelle Attali , Denis Caromel (SLOOP) , Sidi Ould Ehmety


Nous avons modifié la sémantique d'EIFFEL pour obtenir la sémantique d'EIFFEL// (extension parallèle du langage EIFFEL). Les deux langages partagent la même syntaxe, seules leurs sémantiques diffèrent : les instances de classes héritant d'une classe prédéfinie « Process » deviennent des objets actifs (processus) et tout appel de routine sur un processus devient systématiquement un appel asynchrone.

Nous avons décrit formellement en sémantique opérationnelle des notions liées au parallélisme telles que : objet actif, asynchronisme, attente par nécessité et continuation automatique.

À partir de ces spécifications, un environnement interactif pour le langage EIFFEL// a été produit et permet la visualisation graphique des systèmes d'acteurs générés par EIFFEL// [1] ; on peut notamment visualiser les références entre les différents objets (actifs et passifs), les valeurs des attributs, les requêtes en attente de service, l'activité de chaque objet, l'exécution concurrente des objets, et enfin l'attente par nécessité.

Ces travaux servent actuellement de base à la sémantique des activités concurrentes en JAVA.

Preuve interactive

Les techniques de preuve assistée par ordinateur interviennent dans nos recherches de trois manières différentes. D'abord, le développement d'une interface homme-machine pour un système de preuve interactif est un champ d'application pour nos outils de manipulation interactive d'arbres. Deuxièmement, il existe maintenant plusieurs techniques pour développer en même temps des programmes et la preuve que ces programmes respectent une spécification : il est naturel pour nous d'étudier aussi ce style de programmation, où l'on manipule simultanément les programmes et leurs spécifications. Enfin, la preuve est un prolongement naturel de notre étude de la sémantique des langages de programmation : une fois que l'on a défini formellement un langage de programmation, il est normal d'utiliser cette définition formelle pour raisonner sur le langage.

Interfaces pour la preuve interactive



Participants : Yves Bertot , Yann Coscoy , Olivier Pons , Laurence Rideau , Laurent Théry


Les formules mathématiques et les commandes manipulées dans les systèmes interactifs de preuve sont des objets structurés comme des programmes. Il est donc possible de construire un environnement d'aide à la preuve en utilisant naturellement l'ensemble des outils déjà développés pour les environnements de programmation. Les systèmes de preuves présentent tout de même quelques caractéristiques spécifiques :

Au centre de plusieurs outils développés dans ce contexte se trouve la notion de position ou d'occurrence. En effet, lorsque l'on utilise la souris sur la représentation structurée des formules mathématiques, il est nécessaire de donner un sens à la position sélectionnée dans la structure affichée. On est alors amené à construire des outils proches de compilateurs, mais dont la donnée en entrée est non seulement une donnée structurée mais aussi une ou plusieurs positions valides dans cette donnée. L'exemple le mieux connu est l'outil de preuve par sélection.

Un autre thème important pour notre travail est le calcul des dépendances entre les différentes données présentes à l'écran. Ce calcul permet d'améliorer les commandes de retour en arrière et de faciliter la mise au point de spécifications. Enfin, le dernier grand thème de ce travail a trait à l'explication en langue naturelle des objets du système de preuve qui représentent les raisonnements mathématiques. C'est le propre de la théorie des types de représenter la construction d'une preuve par la construction d'un terme dans un lambda-calcul typé particulier que l'on peut interpréter. Dans ce travail, il est important de savoir abstraire les détails inutiles, en laissant le lecteur se concentrer sur les étapes significatives.

Preuves en sémantique



Participants : Yves Bertot , Joëlle Despeyroux , Ranan Fraer , Guillaume Gillard


Mots-clés : fiabilité du logiciel, sémantique, sémantique naturelle, Coq


Le formalisme de description sémantique que nous utilisons, la sémantique naturelle, se représente très facilement dans les systèmes de preuve, surtout dans les systèmes de théorie des types avec types inductifs, comme le système COQ. Les preuves en COQ qui font intervenir des programmes et des spécifications sémantiques font donc partie de nos champs d'investigation.

Nous disposons d'un outil pour compiler la description de syntaxe abstraite d'un langage de programmation et une spécification de sémantique naturelle en des fichiers de définitions pour le système COQ.

La sémantique naturelle est mieux adaptée pour prouver des propriétés des langages de programmation ou d'outils sur ces langages que pour prouver des propriétés de programmes particuliers. Ainsi, on pourra spécifier en sémantique naturelle l'interprète du langage et un outil de vérification des types. Dans ce cas, on prouvera le théorème de conservation des types : le type d'une expression est le même que le type de sa valeur après évaluation. En quelque sorte, ce théorème exprime que les deux spécifications sémantiques sont cohérentes. De cette manière, nous avons validé des compilateurs, des vérificateurs de type ou des évaluateurs partiels pour de petits langages académiques. Une direction de recherche ouverte est de comprendre comment les techniques utilisées pourront s'adapter aussi à des langages réels.

Preuves de programmes



Participants : Ranan Fraer , Loïc Pottier , Laurent Théry


En théorie, la spécification de la sémantique dynamique d'un langage de programmation suffit pour effectuer des preuves sur les programmes écrits dans ce langage. Ce type d'effort n'est, en fait, pas praticable. Pour prouver directement la validité d'un programme fixé par rapport à une spécification, il vaut mieux utiliser une sémantique orientée vers la preuve de programme, comme la logique de Hoare, où l'on peut annoter des programmes impératifs avec leurs propriétés, exprimées soit en logique du premier ordre, soit avec le calcul des constructions. Dans ce dernier cas le type des fonctions peut représenter la spécification de ces fonctions, exprimée dans une logique d'ordre supérieure.

Nous étudions le développement de programmes validés vis-à-vis d'une spécification en utilisant, d'une part, directement la méthode B (une méthode basée sur la logique de Hoare), d'autre part, le calcul des constructions. En particulier, nous nous intéressons aux algorithmes utilisés en calcul formel. Ces algorithmes sont particulièrement intéressants à étudier car leur validité repose sur des propriétés mathématiques non triviales. Dans notre principale expérience, l'effort pour prouver les propriétés mathématiques est en fait plus important que l'effort pour prouver l'algorithme lui-même, avec un rapport de 1 à 4.

Vers un nouveau système de spécification : théorie et pratique



Participants : Joëlle Despeyroux , Thierry Despeyroux , André Hirschowitz , Pierre Leleu


Mots-clés : sémantique, sémantique naturelle, induction, lambda-calcul, théorie des types, COQ


Nos langages de spécification, aussi bien syntaxiques que sémantiques, peuvent être améliorés sur de nombreux points, afin d'augmenter leur pouvoir d'expression et le confort de l'utilisateur. Nous développons un nouveau langage de descriptions syntaxiques, qui permettra de définir l'analyse concrète, abstraite et le « pretty-print » d'un langage dans une seule spécification. D'autre part, nous étudions l'extension de notre système pour permettre l'utilisation de la syntaxe abstraite fonctionnelle.

La syntaxe abstraite d'ordre supérieur, que nous préférons appeler syntaxe abstraite fonctionnelle est une technique de représentation des langages de programmation qui permet de formaliser les notions de variables liées et de substitution d'un langage, en représentant les variables du langage spécifié (le langage objet) par les variables du langage utilisé pour spécifier (le langage méta). Cette technique permet également de formaliser les side conditions (variable libre dans une hypothèse) et les changements de contexte (déchargement d'une hypothèse en Déduction Naturelle) dans les règles d'inférence. Elle augmente donc nettement le niveau d'abstraction, et par là le confort, à la fois de la description des langages de programmation, et des preuves sur ces langages.

Par ailleurs, la définition d'un type inductif fournit des schémas de récurrence et des principes d'induction qui permettent de faire des preuves générales sur des données de ce type. En particulier, si l'on représente la syntaxe d'un langage par un type inductif, on peut utiliser les principes associés pour faire des preuves sur la sémantique de ce langage.

Le problème est qu'une syntaxe abstraite fonctionnelle, définie de manière naïve, ne forme pas un type inductif. Les solutions en cours d'étude comprennent toutes une utilisation de la logique modale pour distinguer entre les structures fonctionnelles de la syntaxe et l'espace général des fonctions.

Nous espérons pouvoir ainsi participer à l'élaboration d'une nouvelle théorie des types permettant l'utilisation des syntaxes abstraites fonctionnelles dans un calcul comme le Calcul des Constructions Inductives, et à terme dans un système comme le système COQ. Ces travaux s'inscrivent dans une action à long terme, dont le but est d'élargir le champ d'application du système CENTAUR aux langages de programmation décrits à l'ordre supérieur.



previous up next contents Précédent : Présentation générale et objectifs Remonter : Projet CROAP, Conception et réalisation Suivant : Grands domaines d'application