Indications pour la programmation de l'éditeur sonore editmath

Je décris ici, les choix qui ont été faits pour la réalisation de l'environnement editmath, en langage c++

L'objectif que je me suis fixé, est de construire une application pour WINDOWS, qui permette de saisir des formules de mathématiques, de les traiter, puis de les insérer, ainsi que les résultats des calculs, dans un document texte. Des logiciels comme word ou excel peuvent accomplir ce type de travail, mais ils ne sont pas très faciles d'utilisation pour les aveugles, même quand il possèdent un logiciel de revue d'écran comme JAWS

L'idée m'est venu d'utiliser la synthèse vocale de studyvox, pour permettre la lecture sonore des formules de mathématiques, en l'ajoutant dans un éditeur de texte.

La programmation d'un éditeur sdi (simple document interface) pour WINDOWS, avec sa barre de menu et ses raccourcis, est quelque chose de classique, que l'on peut faire à partir d'un modèle standard, que l'on personnalise.

J'ai choisi l'exemple apxsdi de bc5 de borland, écrit en c++

Une fois modifié, on compile apxsdi.exe avec la procédure compapxs.bat, et on renomme apxsdi.exe avec le nom editmath.exe

Si vous êtes interéssé par cet aspect de la programmation, vous pouvez consulter la rubrique winweb dans la page index du site studyvox. Vous y trouverez des projets, comme dynakit, gramdyna, mididyna... construits sur le modèle apxsdi de bc5

Tous les projets sont téléchargeables avec leur source complète, et les procédures .bat qui permettent de les compiler en ligne de commande (vous devez posséder pour cela, les versions bcc et bcc32 de Borland BC5, avec leurs exemples)

Je me contente ici de commenter la programmation des outils du calcul formel.

Les formules de mathématiques, peuvent contenir des symboles grecs ou latins, des opérateurs et des fonctions, des nombres, des vecteurs...

La saisie et le traitement des chaînes de caractères qui contiennent des formules, peut se faire avec les caractères ASCII ou ISO Le plus simple est d'utiliser les caractères ASCII, mais alors, la saisie sous WINDOWS nécessite un codage-décodage.

J'ai opté pour une saisie par les fonctions gets et fgets, qui permettent des entrées avec le flux standard STDIN ou à partir de fichiers en mémoire morte. Les chaînes saisies sont écrites dans des fichiers du répertoire où se trouve l'exécutable editmath.exe, en utilisant la fonction fputs, dans des fichiers de noms phrmath.prv, phrresu.prv, phrvar.prv, phrsubst.prv et phrtexte.prv

La chaîne phrmath.prv contient la formule saisie en entrée, la chaîne phrresu.prv contient le résultat d'un calcul que l'on peut faire avec un item du menu "outils"...

Les items des menus "saisir" activent, par l'intermédiaire de la fonction WinExec, les .exe obtenus en compilant les sources phrmath.cpp, phrresu.cpp, phrvar.cpp, phrsubst.cpp et phrtexte.c

Les .exe sont des applications pour DOS, dont les noms sont ceux des sources correspondantes.

phrtexte.c doit être compilé en c et non en c++, car il contient des appels à la fonction strstr avec des arguments unsigned char *, qui ne sont pas portables en c++

phrtexte.c permet de saisir un texte écrit en français, pour le lire oralement avec la synthèse vocale de studyvox. Il utilise le moteur grammatical grampoh.exe, qui transforme le texte saisi, en une suite de phonèmes.

Le texte et les formules qu'il contient éventuellement, sont lus, en utilisant les sources .wav, situées dans le répertoire c:\sv3.

Pour saisir des caractères ASCII étentus (de code entre 128 et 226) on garde la touche ALT (située à gauche de la barre d'espace) enfoncée, pendant que l'on tape le code ASCII sur le pavé numérique.

La lecture sonore de Studyvox lit correctement des textes et des formules, qui contiennent des caractères étendus.

On peut ainsi saisir des caractères grecs, des signes spéciaux...

Les items "donnée", "résultat", "variable" du menu "parole", permettent la lecture sonore des chaînes correspondantes, avec la lecture par mot de studyvox, qui ne nécessite pas l'utilisation du moteur grampho. Par contre, l'item "texte" du menu "parole", utilise phrtexte.exe

Les sources .wav ne sont pas indispensables, si vous n'utilisez pas le menu "parole"

Les items du menu "outils" activent par l'intermédiaire de WinExec, les applications winmath.exe, mathcom.exe, copierpp.exe, copppdon.exe...

Toutes les sources pour la compilation du projet editmath sont disponibles, et vous les trouverez en téléchargeant la rubrique mathweb, en utilisant le lien de téléchargement situé dans la page sommaire de cette rubrique.

Grandes lignes du fonctionnement de winmath.exe et de mathcom.exe

Je décris maintenant les grandes lignes du fonctionnement de winmat.exeh et mathcom.exe

Une fois une expression saisie, il faut pouvoir trouver dans la chaîne de la formule, les constantes, les fonctions, les nombres et les opérateurs.

Cette recherche se fait en utilisant un pointeur sur la chaîne, puis en analysant successivement les symboles rencontrés, en incrémentant ce pointeur.

On place dans une liste de séparateurs, les symboles comme les opérateurs + - * / ( ) [ ] { }...

Quand on rencontre un symbole autre qu'un séparateur, on continue jusqu'au séparateur suivant.

Les expressions ainsi séparées sont de 3 type :

Des chiffres ou des nombres entiers ou décimaux

des noms de constantes réduits à un seul symbole (autre qu'un chiffre ou qu'un opérateur)

un nom qui contient au moins 2 symbole, qui est un nom de fonction, nécessairement suivi par une parenthèse ouvrante.

Il est possible, avec ces quelques conventions, de traiter beaucoup d'expressions mathématiques.

Les choix qui suivent, sont plus ou moins pratiques pour le traitement des expressions, et dépend des applications que l'on veut envisager. Par exemple, l'écriture d'une fraction fait intervenir2 nombres, séparés par l'opérateur slash. Si l'on désire faire des calculs dans l'ensemble des rationnels, il faut savoir reconnaître les fractions, avec leur numérateur et leur dénominateur. De même, si l'on veut calculer avec des puissances, il faut choisir une convention pour écrire la puissance d'une expression. On peut par exemple, convenir qu'un seul symbole, suivi par un entier, représente une grandeur élevée à cette puissance entière. Ce choix ne permet pas d'élever n'importe quelle expression à une puissance quelconque.

Il est plus général de définir une fonction puissance, qui possède 2 arguments, l'expression et sa puissance.

Les difficultés pour la simplification des calculs formels

Quand on a choisi toutes les conventions d'écriture, on doit construire les subroutines qui permettront d'effectuer les calculs numériques ou formels. Il faut remarquer que les calculs nécessitent de retrouver les parenthèses imbriquées, les fonctions et les opérateurs qui opèrent sur ces parenthèses, trouver les résultats partiels et les imbriquer pour trouver le résultat final.

Ces opérations sont délicates, car elles nécessitent de simplifier les résultats partiels et de les normaliser, pour que l'écriture soit à chaque étape, conformes aux conventions adoptées.

C'est cette simplification qui nécessite le plus grand travail de programmation.

Je prends comme exemple, la simplification d'une somme de monômes littéraux. Les symboles peuvent être écrits sous des formes très différentes, et il faut les classer pour pouvoir les comparer.

On classera les symboles minuscules d'un monôme, en utilisant l'ordre lexicographique, et l'on placera tous les nombres avec les opérateurs qui les concernent, en tête du monôme. Par contre, on ne touchera pas à l'ordre des symboles majuscules, car l'opérateur * n'est en général pas commutatif quand il opère avec des vecteurs ou des tenseurs.

On calculera le coefficient des monômes et l'on ajoutera les monômes identiques, pour simplifier au maximum une expression polynômiale formelle.

La simplification d'expressions qui contiennent des fonctions est plus délicate, quand ces fonctions ont des arguments littéraux.

Je décris comment j'ai programmé la commande mathcom.exe, qui effectue ces calculs.

On définit la notion de monôme généralisé, qui s'écrit sous sa forme normaliséé :

coef*num/den

où coef est un coefficient numérique, num une suite de produit de symboles, et den une suite de division de symboles.

Ainsi, un monôme généralisé est une fraction formelle, quotient de 2 monômes formels.

Pour travailler avec des monômes généralisés, on peut convenir que les puissances entières sont indiquées à la suite des symboles.

Voici un exemple d'un tel monôme :

-2*5.3/12*a*b2/x5/y2*W/V

On remarque que, sous sa forme normalisée, les nombres du coefficient numérique sont classés , ainsi que les symboles littéraux minuscules, tandis que les symboles majuscules sont laissés dans l'ordre de leur saisie.

L'idée principale pour le calcul formel, est de se débarasser de toutes les parenthèses qui figurent dans une formule, en la transformant en un polynôme généralisé, sur lequel on fera toutes les simplifications possibles, puis on substituera les résultats des calculs partiels, pour obtenir le résultat final sous une forme réutilisable pour un calcul ultérieur.

On peut écrire toutes les expressions formelles sous la forme d'un polynôme généralisé, en procédant de la manière suivante :

On associe un nouveau symbole à toute expression entre parenthèse, et l'on place l'ensemble de ces symboles les uns à la suite des autres, dans une chaîne appelée listevar.

On fait de même avec les nomdes fonctions, dont les noms des arguments sont dans listevar, et on les place dans une chaîne appelée listefon.

Il faut bien sûr s'assurer que les nouveaux symboles sont significatifs, et ne correspondent à aucun des symboles qui figurent dans la formule.

D'un point de vue technique, il suffit de réserver des caractères ASCII à cet effet, en les choisissant parmi des symboles peu utilisés. Je les ai choisis parmi les caractères graphiques, dont le code est entre 179 et 223

On réécrit alors la formule, qui fait intervenir uniquement ces symboles, les opérateurs sans les parenthèses et des nombres.

La formule apparaît alors sous la forme d'un polynôme généralisé.

Pour faciliter la simplification d'un polynôme généralisé, on simplifie chaque parenthèse avant de lui donner un nom, et on la compare à celles déja placées dans la chaîne listevar.

On lui donne un nouveau nom uniquement quand elle est différente d'une variable précédemment retenue.

On recherche les parenthèses les plus imbriquées en premier.

Quand un nom de fonction et son argument sont identiques à ceux déja écri tdans la chaîne listefon, on ne définit pas de nouveau symbole de fonction.

On simplifie alors le polynôme généralisé, et on peut ensuite envisager la partie de calcul proprement dite.

Il faut reconnaître si un argument est numérique ou littéral, pour décider si l'on peut calculer la valeur d'une expression, ou s'il faut simplement la simplifier.

On donne la possibilité de substituer des expressions par d'autres expressions, pour permettre d'effectuer des calculs numériques, des changements de variables...

On commence donc par faire toutes les substitutions demandées, puis on recommence la recherche des nouveaux symboles et des nouvelles parenthèses, pour constituer les chaînes listevar et listefon, que l'on traite comme précédemment.

Quand on obtient des valeurs numériques, celles-ci sont transformées en chaîne de caractère, en utilisant la fonction sprintf.

On réinsère ces chaînes dans la formule, ce qui nécessite de réintroduire, en général, des parenthèses.

On continue le processus, jusqu'à ce que le résultat ne puisse plus être davantage simplifié.

On comprend que la mise en oeuvre du programme est assez laborieuse. Ceci provient de ce que l'on désire traiter les formules écrites comme le fait un professeur dans son cours.

Toutes ces difficultés tombent, quand on procède autrement, en utilisant par exemple un tableur. Dans ce cas, on saisit chaque opération élémentaire dans une cellule, et l'on écrit son résultat dans une autre cellule, en utilisant excel par exemple.

Traitement des erreurs

Comme il est impossible d'envisager tous les cas qui peuvent se présenter dans l'écriture d'une formule, les exceptions sont nombreuses, et leur traitement systèmatique alourdirait le fonctionnement.

Il vaut mieux développer plusieurs projets, qui traitent séparément différents calculs, avec des conventions légérement différentes les mieux adaptées possibles aux traitements envisagés.

Ainsi, dans le projet mathcom pour DOS, j'ai choisi d'écrire les puissances en plaçant l'exposant après un symbole ou après une parenthèse fermante, tandis que dans le projet winmath pour WINDOWs, les cette écriture n'est pas permise.

Quand on ajoute aux difficultés de programmation, celles qui sont liées à la portabilité sur toutes les plateformes (qui sont nombreuses depuis les versions 16 et 32 bits de WINDOWS !) on comprend pourquoi il reste encore beaucoup de cas non traités.

J'espère que ces commentaires vous donneront des idées, pour aborder ce domaine du calcul formel, et je serais heureux de profiter de vos réfléxions personnelles.

Ceci termine la rubrique mathweb de studyvox.

Retour dans le sommaire de la rubrique mathweb du site studyvox webups

Retour dans la page index du site studyvox webups