{\rtf1\mac\deff2 {\fonttbl{\f0\fswiss Chicago;}{\f2\froman New York;}{\f3\fswiss Geneva;}{\f4\fmodern Monaco;}{\f6\fdecor London;}{\f8\fdecor San Francisco;}{\f11\fnil Cairo;}{\f12\fnil Los Angeles;}{\f13\fnil Zapf Dingbats;}{\f14\fnil Bookman;} {\f16\fnil Palatino;}{\f18\fnil Zapf Chancery;}{\f20\froman Times;}{\f21\fswiss Helvetica;}{\f22\fmodern Courier;}{\f23\ftech Symbol;}{\f24\fnil Mobile;}{\f33\fnil Avant Garde;}{\f34\fnil New Century Schlbk;}{\f101\fnil Wartburg;}{\f118\fnil Warwick S;} {\f128\fnil Moscow;}{\f129\fnil Russian;}{\f135\fnil MATH-BES;}{\f140\fnil Lovell;}{\f149\fnil Detroit;}{\f171\fnil XB Futura ExtraBold;}{\f176\fnil H Futura Heavy;}{\f201\fnil ¡Math;}{\f512\fnil Alexandrie;}{\f2500\fnil Konstanz;}} {\colortbl\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;}{\stylesheet{\s243\qj\tqc\tx4320\tqr\tx8640 \f20 \sbasedon0\snext243 footer;}{\s245\qj \f20\fs18\up6 \sbasedon0\snext0 footnote reference;}{\s246\qj \f20\fs20 \sbasedon0\snext246 footnote text;}{\s247\qj\li720 \i\f20\fs20 \sbasedon0\snext0 heading 9;}{\s248\qj\li720 \i\f20\fs20 \sbasedon0\snext0 heading 8;}{\s249\qj\li720 \i\f20\fs20 \sbasedon0\snext0 heading 7;}{\s250\qj\li720 \f20\fs20\ul \sbasedon0\snext0 heading 6;}{\s251\qj\li720 \b\f20\fs20 \sbasedon0\snext0 heading 5;}{\s252\qj\li354\sb40\sa40 \f20\ul \sbasedon0\snext0 heading 4;}{ \s253\qj\li354\sb120\sa80 \b\f20 \sbasedon0\snext0 heading 3;}{\s254\qj\sb200\sa140 \b\f20\fs36\ul \sbasedon0\snext0 heading 2;}{\s255\qc\sb240 \b\f20\fs48 \sbasedon0\snext0 heading 1;}{\qj \f20 \sbasedon222\snext0 Normal;}{\s2\sb120\keep\keepn \b\f22 \sbasedon0\snext2 input;}{\s3 \f22\fs20 \sbasedon0\snext3 output;}{\s4\qj\li1120 \f20\fs20 \sbasedon0\snext4 commentaire;}}{\info{\title chap5.doc}{\author EBM}} \paperw11880\paperh16800\margl1701\margr1701\margt1417\margb1417\deftab709\widowctrl\ftnbj\pgnstart51 {\*\nextfile Macintosh HD:Seance 5 (Maple)}\sectd \sbknone\linemod0\linex0\headery1077\footery1077\cols1\colsx709\endnhere {\footer \pard\plain \s243\qj\tqc\tx4320\tqr\tx8640 \f20 \par \pard \s243\qc\tqc\tx4320\tqr\tx8640 {\fs20 Calcul formel avec Maple page }{\fs20 \chpgn }\par \pard \s243\qj\tqc\tx4320\tqr\tx8640 \par }\pard\plain \s255\qc\sb240 \b\f20\fs48 Programmer Maple\par \pard\plain \qj \f20 {\fs14 \par }\pard \qj Avertissement:\par \pard \qj \bullet Maple est un langage de programmation de type imp\'8eratif proc\'8edural. Il inclut aussi un certain nombre de fonctionnalit\'8es de la programmation fonctionnelle.\par \pard \qj \bullet Maple n'est pas fortement typ\'8e comme Pascal ou C, aucune d\'8eclaration n'est n\'8ecessaire. Mais les types existent. Le contr\'99le de type se fait \'88 l'ex\'8ecution et doit \'90tre programm\'8e explicitement.\par \bullet Le langage de Maple est interpr\'8et\'8e, si bien que Maple n'est pas adapt\'8e \'88 de gros programmes num\'8eriques. Les temps de calcul sont consid\'8erablement sup\'8erieurs \'88 ce qu'ils seraient en C ou en Pascal.\par \pard\plain \s254\qj\sb200\sa140 \b\f20\fs36\ul I. Les structures de contr\'99le\par \pard\plain \s253\qj\li354\sb120\sa80 \b\f20 1. Structures conditionnelles\par \pard\plain \qj \f20 La structure conditionnelle en Maple a la syntaxe suivante (les expressions entre crochets sont facultatives).\par \pard \qj \tab {\b if} {\i expr_1} {\b then} {\i suite_d'instructions\par \tab \tab }[ {\b elif} {\i expr_i} {\b then} {\i suite_d'instructions }] ( 0, 1 ou plusieurs fois)\par \tab \tab [ {\b else} {\i suite_d'instructions }]\par \tab {\b fi\par }\pard \qj Les expressions {\i expr_1} et {\i expr_i} (si les parties {\b elif} existent) sont \'8evalu\'8ees tout \'88 tour en tant qu'expressions bool\'8eennes. Si l'une d'entre elles s'\'8evalue en {\b true}, alors la {\i suite_d'expressions} correspondante est ex\'8ecut\'8ee et l'expression conditionnelle renvoie {\b NULL} (c'est \'88 dire rien). Si aucune d'entre elles ne s'\'8evalue en {\b true}, la {\i suite_d'instructions} qui suit le {\b else} est ex\'8ecut\'8e e si elle existe. Dans les autres cas, aucune suite d'instructions n'est ex\'8ecut\'8ee. Dans tous les cas, l'expression conditionnelle renvoie {\b NULL}. On voit donc que le mot cl\'8e {\b elif} correspond en gros \'88 une contraction de {\b else if} (mais un tel {\b else if} n\'8ecessiterait un {\b fi} pour le terminer contrairement \'88 {\b elif}).\par \pard \qj Exemple d'expression conditionnelle:\par \pard\plain \s2\sb120\keep\keepn \b\f22 if x>0 then 1 elif x=0 then 0 else 1 fi\par \pard\plain \qj \f20 {\fs14 \par }\pard \qj {\i Remarque} : le fait que la structure conditionnelle renvoie NULL fait qu'une structure conditionnelle n'est pas une expression alg\'8ebrique et ne peut donc \'90tre utilis\'8ee pour une affectation. C'est ainsi qu'on ne peut pas \'8ecrire \par \pard\plain \s2\sb120\keep\keepn \b\f22 y:=if x>0 then 1 elif x=0 then 0 else 1 fi\par \pard\plain \qj \f20 {\fs14 \par }\pard \qj (ce qui est bien dommage). Par contre rien n'emp\'90che une ou plusieurs instructions du corps de la structure de d\'8eposer des expressions sur la pile d'\'8evaluation qui pourront \'90tre r\'8ecup\'8er\'8e s par les habituels ", "" et """. On peut par exemple \'8ecrire\par \pard\plain \s2\sb120\keep\keepn \b\f22 if x>0 then 1 elif x=0 then 0 else 1 fi;\par y:=";\par \pard\plain \s253\qj\li354\sb120\sa80 \b\f20 2. Structure r\'8ep\'8etitive\par \pard\plain \qj \f20 Maple poss\'8fde une unique structure r\'8ep\'8etitive, mais particuli\'8frement riche puisqu'elle regroupe \'88 la fois la structure {\b for} et la structure {\b while} de Pascal. Elle se pr\'8esente sous la forme (l\'88 encore les parties entre crochets sont facultatives)\par \pard \qj \tab [ {\b for} {\i nom }] [ {\b from} {\i debut} ] [{\b to} {\i fin} ] [ {\b by} {\i pas} ] [ {\b while} {\i condition} ]\par \tab \tab {\b do }{\i suite_d'instructions} {\b od\par }o\'9d\par \tab - {\i nom} doit d\'8esigner un nom (variable non affect\'8ee)\par \tab - {\i debut, fin }et {\i pas} doivent s'\'8evaluer en des nombres entiers ou r\'8eels\par \tab - {\i condition} est une expression bool\'8eenne\par \pard \qj Dans le cas o\'9d l'une des sous-structures est manquante, Maple utilise pour cette sous structure une valeur par d\'8efaut\par \pard \qj \tab - {\i nom} d\'8esigne par d\'8efaut une variable interne \'88 Maple\par \tab - {\i debut} vaut par d\'8efaut 1\par \tab - {\i fin} vaut par d\'8efaut l'infini\par \tab - {\i pas} vaut par d\'8efaut 1\par \tab - {\i condition }vaut par d\'8efaut {\b true}.\par \pard \qj La boucle est ex\'8ecut\'8ee tant que {\i name \'b2 fin }{\ul et que} {\i condition} s'\'8evalue en {\b true}, en donnant initialement \'88 {\i name} la valeur {\i debut} puis en l'incr\'8ementant de {\i pas} \'88 chaque nouvelle ex\'8e cution de la boucle. Le test intervient toujours avant ex\'8ecution du corps de la boucle (celui ci peut donc ne jamais \'90tre effectu\'8e si {\i debut > fin} ou si {\i condition} ne s'\'8evalue pas initialement en {\b true}). L'expression it\'8e rative renvoie toujours {\b NULL }(cf le paragraphe sur la s\'8emantique du langage), mais les \'8evaluations qui interviennent au cours de l'ex\'8ecution de la boucle contribuent \'88 remplir la pile d'\'8e valuation. Les expressions ainsi obtenues peuvent \'90tre retrouv\'8ees pour les trois derni\'8fres gr\'89ce aux ","" et """ habituels.\par \pard \qj Exemple: recherche du plus petit nombre premier sup\'8erieur \'88 10{\fs20\up6 8}\par \pard\plain \s2\sb120\keep\keepn \b\f22 for i from 10^8+1 by 2 while not isprime(i) do od;print(i);\par \pard\plain \qj \f20 L'exemple pr\'8ec\'8edent montre d'ailleurs que la valeur de l'indice de boucle est accessible apr\'8fs la fin de l'ex\'8ecution de la boucle. Comme en C, Maple dispose d'instructions permettant de modifier l'ex\'8ecution de la boucle \par \pard \qj {\b \tab break} sort imm\'8ediatement de la boucle\par {\b \tab continue} passe imm\'8ediatement \'88 l'it\'8eration suivante (en commen\'8dant par le test).\par \pard \qj {\fs14 \par }\pard \qj Maple dispose d'une variante de {\b for} qui permet d'utiliser successivement les diff\'8erents op\'8erandes d'une expression sous la forme\par \pard \qc {\b for} {\i name} {\b in} {\i expr} {\b while} {\i condition} {\b do} {\i suite_d'instructions} {\b od\par }\pard \qj qui est \'8equivalente \'88\par {\b for }i {\b from} 1 {\b to} {\b nops(}{\i expr }{\b ) while }{\i condition} {\b do \par \tab }{\i name }:={\b op(}i,{\i expr} {\b )}; {\i suite_d'instructions; }{\b od;\par }\pard \qj en se souvenant que la fonction {\b nops} renvoie le nombre d'op\'8erandes d'une expression et que {\b op(i,\'c9) }renvoie son i-i\'8fme op\'8erande. Cette variante est particuli\'8frement utile pour utiliser tour \'88 tour les diff\'8erents \'8el\'8ements d'une liste ou d'une s\'8equence, mais ce n'est pas son seul usage.\par \pard \qj Exemple: impression des carr\'8es d'une liste d'expressions\par \pard\plain \s2\sb120\keep\keepn \b\f22 for x in maListe do print(x^2);\par \pard\plain \qj \f20 {\fs14 \par }\pard \qj {\i Remarque} : au moment o\'9d vous \'90tes tent\'8es d'utiliser une structure r\'8ep\'8etitive en Maple, n'oubliez pas que Maple dispose \'8egalement de fonctions r\'8ep\'8e titives qui sont souvent plus commodes et plus efficaces, les principales \'8etant {\b seq}, {\b sum}, {\b prod} et {\b $.\par }\pard\plain \s254\qj\sb200\sa140 \b\f20\fs36\ul II. Les proc\'8edures\par \pard\plain \s253\qj\li354\sb120\sa80 \b\f20 1. Les objets proc\'8edures\par \pard\plain \qj \f20 Contrairement \'88 d'autres langages de programmation comme Pascal (mais comme en C), les proc\'8edures sont en Maple des objets comme les autres et elles peuvent donc faire l'objet d'affectations. L'objet procedure a la syntaxe suivante (les parties entre crochets sont facultatives comme d'habitude)\par \pard \qj {\fs14 \par }\pard \qj \tab {\b proc(}{\i sequence_de_parametres} {\b )\par \tab \tab }[ {\b local} {\i sequence_de_noms} {\b ; }]\par \tab \tab [ {\b options} {\i sequence _de_noms }{\b ; }]\par \tab \tab {\i suite_d'instructions }\par \tab {\b end\par \par }\pard \qj Les parametres forment une sequence (\'8eventuellement vide), le corps de la proc\'8edure est une suite d'instructions s\'8epar\'8es par des points-virgules. Les noms des variables locales sont list\'8es apr\'8fs le mot cl\'8e {\b local} . Ils forment aussi une s\'8equence, c'est \'88 dire qu'ils sont s\'8epar\'8es par des virgules. Comme les noms Maple, ces variables locales ne sont pas typ\'8ees. Nous reviendrons plus tard sur les options et leur utilit\'8e.\par \pard \qj \tab Les proc\'8edures Maple sont plus des fonctions au sens de C (qui peuvent \'8eventuellement renvoyer NULL) que des proc\'8edures au sens de PASCAL. Une proc\'8edure Maple renvoie en fait la derni\'8fre valeur d\'8epos\'8ee sur la pile d' \'8evaluation interne de la proc\'8edure (cf le paragraphe sur la s\'8emantique du langage) au cours de l'ex\'8ecution de la proc\'8edure, \'88 moins que l'ex\'8ecutions de la proc\'8edure n'ait exig\'8e explicitement de retourner une expression \'88 l'aide de la fonction {\b RETURN}.\par \pard \qj Exemple : une proc\'8edure simple qui, \'8etant donn\'8es x et y, calcule x^2+y^2\par \pard\plain \s2\sb120\keep\keepn \b\f22 proc(x,y) x^2+y^2 end\par \pard\plain \qj \f20 {\b\f22\fs14 \par }\pard \qj L'ex\'8ecution de la proc\'8edure entrainera la d\'8epose sur la pile d'\'8evaluation de la proc\'8edure de l'expression x^2+y^2, qui sera la valeur retourn\'8ee par la proc\'8e dure (qui est donc une fonction au sens habituel des langages de programmation). Ainsi vous pouvez \'8ecrire\par \pard\plain \s2\sb120\keep\keepn \b\f22 z:=proc(x,y) x^2+y^2 end (2,3);\par \pard \s2\sb120\keep\keepn {\fs14 \par }\pard\plain \qj \f20 et \'88 la variable z sera affect\'8ee la valeur 2{\fs20\up6 2}+3{\fs20\up6 2}, qui est la valeur d\'8epos\'8ee sur le sommet de la pile d'\'8evaluation au cours de l'ex\'8ecution de la proc\'8edure.\par \tab Par contre une ex\'8ecution de l'instruction {\b RETURN(}{\i expr} {\b ) }entra\'94ne une interruption imm\'8ediate de la proc\'8edure qui renvoie alors comme valeur {\ul l'\'8evaluation} de l'expression {\i expr}. \par \pard\plain \s4\qj\li1120 \f20\fs20 FUNCTION: RETURN - explicit return from a procedure\par CALLING SEQUENCE:\par RETURN(expr_1, expr_2, ...)\par PARAMETERS:\par expr_1, ... - expression sequence (possibly null)\par SYNOPSIS: \par - A call to the RETURN function causes an immediate return to the point where the current procedure was invoked.\par - If return is via the RETURN function then the value of the procedure invocation is the expression sequence specified in the call to RETURN.\par \par \pard\plain \qj \f20 Exemple de retour explicite: une fonction qui teste la pr\'8esence d'un \'8el\'8ement dans une liste peut avoir la forme suivante\par \pard\plain \s2\sb120\keep\keepn \b\f22 MEMBER:= proc(x,L) local v;\line \tab for v in L do \line \tab \tab if v=x then RETURN(true) fi\line \tab od;\line \tab false\line end;\par \pard\plain \qj \f20 \par Si l'\'8el\'8ement x est dans la liste L, au moment o\'9d v=x deviendra vrai, l'ex\'8ecution de l'instruction RETURN(true) entra\'94nera l'interruption de la proc\'8e dure qui renverra la valeur true. Si par contre x n'est pas dans la liste, la boucle s'ach\'8fvera normalement puis l'ex\'8ecution de la derni\'8fre ligne de la proc\'8edure entra\'94nera la d\'8epose de false sur le sommet de la pile d'\'8e valuation, et ce sera donc cette valeur qui sera retourn\'8ee.\par {\b Attention}: vous devez veiller \'88 ne pas renvoyer comme r\'8esultat un objet local \'88 la proc\'8edure. C'est en principe impossible puisque vous pouvez retourner soit le sommet de la pile d'\'8evaluation (qui est \'8evalu\'8e et qui est donc en g \'8en\'8eral une valeur et non un objet), soit la valeur de l'objet pass\'8e \'88 RETURN. En fait la situation est un peu plus compliqu\'8ee \'88 cause des r\'8fgles d'\'8evaluation propres \'88 Maple concernant l'\'8e valuation standard des tables (donc par exemple des vecteurs ou matrices) et des proc\'8edures. En effet l'\'8evaluation standard de ces objets se fait en le dernier nom rencontr\'8e. Pour peu que ce nom soit local \'88 la proc\'8e dure, on risque de gros ennuis. Un moyen simple de forcer un retour de la valeur de l'objet (et nom de son nom) est de forcer une \'8evaluation compl\'90te \'88 l'aide de la fonction {\b eval}. Autrement dit, si {\i objet } est l'objet que vous voulez renvoyer comme valeur de la proc\'8edure et qu'il est de type {\i table} ou {\i proc} , il faut d\'8eposer sur le sommet de la pile non pas {\i objet} , mais {\b eval}({\i objet} ) ou utiliser un retour explicite {\b RETURN}({\b eval}({\i objet} )).\par \tab Une possibilit\'8e de sortie est donn\'8ee par l'instruction ERROR({\i message} ), qui entra\'94ne non seulement une interruption de la proc\'8edure, mais \'8egalement de toute l'ex\'8ecution normale de Maple et l'\'8emission d'un message d'erreur { \i message} (une cha\'94ne de caract\'8fres entre ` (backquote ou accent grave). Si ce message n'est pas intercept\'8e par une instruction {\b traperror}, il entra\'94ne une interruption de l'ex\'8ecution de Maple.\par \pard\plain \s4\qj\li1120 \f20\fs20 FUNCTION: ERROR - error return from a procedure\par CALLING SEQUENCE:\par ERROR(expr_1, expr_2, ...)\par PARAMETERS:\par expr_1, ... - expression sequence (possibly null)\par SYNOPSIS: \par - A call to the ERROR function causes an immediate return to the point where the current procedure was invoked.\par - If the procedure was not invoked within the context of traperror then control returns to the top level of the Maple system and the following message is printed: ``Error, '' followed by the evaluated expression sequence specified in the cal l to ERROR. (Here, procname will be the name with which the procedure was invoked).\par - If the procedure was invoked within the context of traperror then the value of the global name lasterror is assigned the evaluated expression sequence specified in the call to ERROR. In this case, the value of the traperror call is also this same expre ssion sequence.\par \pard\plain \qj \f20 \par Bien entendu, si, comme c'est le cas le plus ouvent, vous voulez utiliser plusieurs fois une proc\'8edure, vous commencerez par affecter l'objet proc\'8edure \'88 une variable Maple. C'est ainsi que vous pourrez \'8ecrire\par \pard\plain \s2\sb120\keep\keepn \b\f22 sommeCarres:=proc(x,y) x^2+y^2 end;\par \pard\plain \qj \f20 \par et que vous diposerez ainsi d'une nouvelle fonction Maple que vous pourrez utiliser \'88 votre gr\'8e comme toute autre fonction.\par \pard\plain \s2\sb120\keep\keepn \b\f22 z:=sommeCarres(2,3);\par P:=sommeCarres(sin(u),cos(u));\par xyz:=sommeCarres((1+x+y)^2,x*y);\par \pard\plain \s253\qj\li354\sb120\sa80 \b\f20 2. Param\'8ftres et variables locales\par \pard\plain \qj \f20 Une erreur commune en Maple est de traiter les param\'8ftres des proc\'8edures comme des variables locales comme on peut le faire en Pascal ou en C. Ce n'est pas du tout le cas: ces param\'8f tres ne sont pas des variables locales. En fait ce ne sont pas des variables du tout mais uniquement des containers destin\'8es \'88 recevoir les valeurs des param\'8ftres qui seront pass\'8es \'88 la proc\'8edure. \par \tab Lors de l'appel d'une proc\'8edure f qui d\'8epend des param\'8ftres x1,\'c9,xn, avec des param\'8ftres effectifs p1,\'c9,pn (c'est \'88 dire lors de l'ex\'8ecution de {\b f(p1,\'c9,pn)} o\'9d f est d\'8efinie par {\b f:=proc(x1,\'c9,xn) \'c9 end}), Maple commence par \'8evaluer tous les param\'8ftres p1,\'c9,pn, puis il prend l'objet proc\'8edure f et dans cet objet, il commence par remplacer toutes les occurrences de x1,\'c9,xn par les valeurs de p1,\'c9 ,pn. C'est seulement ensuite qu'il ex\'8ecute la suite d'instructions. On voit donc que lors de l'ex\'8ecution du corps de la proc\'8edure, les "variables" x1,\'c9,xn ont disparu.\par Exemple d'une proc\'8edure erron\'8ee: \par \pard\plain \s2\sb120\keep\keepn \b\f22 f:=proc(x) x:=x-1; RETURN(x^2) end\par \pard\plain \qj \f20 (le RETURN n'est pas n\'8ecessaire, il est l\'88 pour la clart\'8e). \par \tab Lors de l'ex\'8ecution de {\b t:=3; f(t)}, Maple commence par \'8evaluer le param\'8ftre effectif t (valeur 3), puis il prend l'objet f et substitue tout au long de f la valeur 3 au param\'8ftre x. Le corps de la proc\'8edure devient alors {\b 3:=3-1; RETURN(3^2)} et comme la premi\'8fre affectation n'a pas de sens, son ex\'8ecution provoquera une erreur.\par \tab Si l'on souhaite donc utiliser, comme on le fait couramment en Pascal ou en C, des param\'8ftres comme variables locales, il faut donc commencer par recopier ces param\'8ftres dans des variables locales. La proc\'8edure pr\'8ec\'8e dente deviendrait (b\'90tement)\par \pard\plain \s2\sb120\keep\keepn \b\f22 f:=proc(x) local xloc;\line \tab xloc:=x; xloc:=xloc-1; RETURN(xloc^2) \line end\par \pard\plain \s253\qj\li354\sb120\sa80 \b\f20 3. Nombre de param\'8ftres\par \pard\plain \qj \f20 Toute proc\'8edure Maple peut en fait recevoir un nombre variable de param\'8ftres, c'est \'88 dire qu'aucune v\'8erification n'est faite au moment de l'ex\'8ecution d'une proc\'8edure que le nombre de param\'8ftres pass\'8es \'88 la proc\'8edure est le m\'90me que celui d\'8eclar\'8e lors de la d\'8efinition de la proc\'8edure. Simplement, si on d\'8eclare f:=proc(x1,\'c9,xn) \'c9 end et si on appelle f(y1,\'c9 ,yp), le processus de substitution de xi par la valeur de yi va se poursuivre de la gauche vers la droite jusqu'\'88 \'8epuisement de l'une des deux s\'8equences, et il va alors s'interrompre. Ensuite a lieu l'ex\'8ecution du corps de la proc\'8e dure. Si n et p sont diff\'8erents, deux cas peuvent alors se produire:\par - si le nombre p de param\'8ftres effectifs est inf\'8erieur au nombre n de param\'8ftres d\'8eclar\'8es, tout se passera bien si lors de l'ex\'8ecution du corps de la proc\'8edure aucun des param\'8ftres formels xi surnum\'8eraire n'est utilis\'8e ; sinon on aura une erreur \'88 l'ex\'8ecution\par - si le nombre p de param\'8ftres effectifs est sup\'8erieur au nombre n de param\'8ftres d\'8eclar\'8es, il n'y aura pas d'erreur, mais les param\'8ftres yi surnum\'8eraires ne seront pas accessibles \'88 travers les param\'8ftres formels xi.\par \tab Bien entendu, cette derni\'8fre possibilit\'8e serait sans int\'8er\'90t si la proc\'8edure n'avait pas un autre moyen de r\'8ecup\'8erer les param\'8ftres effectifs yi surnum\'8eraires. Or ce moyen existe \'88 l'aide de deux fonctions Maple. La premi\'8fre {\b nargs} renvoie dans une proc\'8edure le nombre de param\'8ftres effectifs lors de l'appel de la proc\'8edure, la seconde {\b args} renvoie la s\'8equence des param\'8ftres effectifs transmis \'88 la proc\'8edure. C'est ainsi que lors d'un appel f(y1,y2,y3,y4), au cours de l'ex\'8ecution du corps de la proc\'8edure, nargs renverra 4 et args[i] renverra la valeur de yi.\par \pard\plain \s4\qj\li1120 \f20\fs20 HELP FOR: args --- the sequence of actual arguments passed to a procedure\par HELP FOR: nargs --- the number of arguments passed to a procedure\par CALLING SEQUENCE:\par args or args[i] or args[i..j] and nargs\par SYNOPSIS: \par - Within a procedure, the special name args has as its value the expression sequence of actual arguments with which the procedure was called.\par - Using the selection operation on this expression sequence, it follows that args[i] is the i'th actual argument, and args[i..j] is the sequence of the i'th through j'th arguments.\par - Within a procedure, the special name nargs has as its value the number of elements in the expression sequence args.\par \pard\plain \qj \f20 Exemple: une proc\'8edure de calcul du plus grand \'8el\'8ement parmi un nombre quelconque pourrait \'90tre\par \pard\plain \s2\sb120\keep\keepn \b\f22 MAX:= proc()\line local r,i;\line r := args[1];\line for i from 2 to nargs do \line \tab \tab \tab if r < args[i] then r := args[i] fi \line \tab \tab od;\line r\line end \par \pard\plain \qj \f20 \par Cette proc\'8edure a 0 param\'8ftres formels mais peut calculer le maximum de n'importe quel nombre de param\'8ftres effectifs.\par \pard\plain \s253\qj\li354\sb120\sa80 \b\f20 4. Le passage des param\'8ftres\par \pard\plain \qj \f20 Comme on l'a vu, la passage des param\'8ftres est toujours effectu\'8e par valeur (comme c'est toujours le cas en C, et comme c'est le cas par d\'8efaut en Pascal). Autrement dit les param\'8ftres effectifs sont d'abord \'8evalu\'8e s, et c'est ensuite leur valeur qui est utilis\'8ee par la proc\'8edure. Cependant, rappelons nous que nous travaillons en calcul formel et que donc le r\'8esultat d'une \'8evaluation peut \'90tre lui m\'90me une variable (c'est \'88 dire un nom), qui est donc susceptible de recevoir une affectation au cours de l'ex\'8ecution de la proc\'8edure, et on obtient un analogue du passage par variable de Pascal (ou du passage par r\'8ef\'8erence de C++). C'est ainsi qu'il est tout \'88 fait possible d'\'8ecrire une proc\'8edure\par \pard\plain \s2\sb120\keep\keepn \b\f22 miseAUn:=proc(x) x:=1 end\par \par \pard\plain \qj \f20 Tout se passera bien tant que l'on passera \'88 la proc\'8edure un param\'8ftre effectif dont l'\'8evaluation est une lvalue (par exemple une variable non affect\'8ee). Par contre, on aura une erreur d'ex\'8e cution si on fait des appels \'88 {\b miseAUn(2)} ou \'88 {\b miseAUn(y+3)}. Un bon moyen de garantir la s\'8ecurit\'8e d'un passage par r\'8ef\'8erence est de bloquer l'\'8evaluation de la variable que l'on passe comme param\'8f tre en la mettant entre apostrophes (l'\'8evaluation d'une expression entre apostrophes consiste \'88 enlever un niveau d'apostrophes) ou de provoquer une \'8evaluation en un nom \'88 l'aide de la fonction {\b evaln} (eval to a na me). C'est ainsi que vous ne devriez jamais faire {\b MiseAUn(t)} mais plut\'99t {\b MiseAUn('t')} ou {\b MiseAUn(evaln(t)). }\par \pard\plain \s4\qj\li1120 \f20\fs20 FUNCTION: evaln - evaluate to a name\par CALLING SEQUENCE:\par evaln(expr)\par PARAMETERS:\par expr - an expression\par SYNOPSIS: \par - The evaln function is used to ``evaluate to a name'' or, more generally, to form an assignable object. The name (assignable object) will not itself be evaluated.\par - A typical example of its use would be divide(a,b,evaln(t[i])) where i is the index of a for loop.\par - If the expression is a simple name (i.e., a string) then the same effect can be achieved by using single quotes on the name.\par - Evaln can be used on names, subscripts, function calls, and concatenations.\par \par \pard\plain \qj \f20 Attention: les r\'8fgles de substitution d\'8ecrites dans un paragraphe pr\'8ec\'8edent font qu'il est tout \'88 fait pr\'8ef\'8erable qu'un param\'8ftre pass\'8e par r\'8ef\'8erence (ou plut\'99t par nom) ne re\'8doive qu'une {\ul unique} affectation au cours de {\ul l'ex\'8ecution} du corps de la proc\'8edure. N'hesitez donc pas \'88 utiliser des variables locales tout au long de la proc\'8edure et n'affectez les param\'8ftres pass\'8es par nom que juste avant le retour de la proc \'8edure.\par \tab {\i Remarque: }\'88 titre personnel, l'auteur de ces lignes recommande de ne pas faire usage de la possibilit\'8e de renvoyer des r\'8esultats \'88 travers des param\'8ftres pass\'8e s par nom et au contraire de faire le plus possible usage d'un style de programmation fonctionnel. Alors qu'en Pascal le passage de variable par r\'8ef\'8erence s'impose \'88 cause du type tr\'8fs limit\'8e des types de retour possible pour une fonction et qu'en C il s'impose par suite de l'impossibilit\'8e pratique de retourner plusieurs r\'8esultats \'88 la fois, en Maple ce renvoi de r\'8esultats \'88 travers des param\'8f tres est presque toujours inutile puisqu'une fonction Maple peut renvoyer plusieurs r\'8esultats \'88 la fois par l'interm\'8ediaire d'une s\'8equence de r\'8esultats. Le seul cas o\'9d il peut sembler utile d'utiliser un passage de param\'8f tre par nom est celui de fonctions math\'8ematiques qui calculent deux ou plusieurs objets mais n'en renvoient qu'un seul, l'autre \'8etant le plus souvent sans int\'8er\'90 t. C'est ainsi que dans une division euclidienne, le reste est le plus souvent l'objet int\'8eressant mais qu'on est amen\'8e au passage \'88 calculer le quotient. Il peut \'90tre int\'8eressant dans ce cas de r\'8ecup\'8erer le quotient par l'interm\'8e diaire d'un param\'8ftre pass\'8e par nom pour "le cas o\'9d \'c9 ". C'est ce que font quelques fonctions de la biblioth\'8fque de Maple.\par \pard\plain \s253\qj\li354\sb120\sa80 \b\f20 \page 5. Type des param\'8ftres\par \pard\plain \qj \f20 Comme toutes les variables Maple, les param\'8ftres ne sont pas typ\'8es. Il y a n\'8eanmoins dans la derni\'8fre version de Maple une possibilit\'8e de faire une v\'8erification automatique de type \'88 l'ex\'8ecution de la proc\'8e dure par une syntaxe "\'88 la Pascal" {\b x: type_x}. C'est ainsi que si l'on \'8ecrit\par \pard\plain \s2\sb120\keep\keepn \b\f22 succ:=proc(x:integer) x+1 end\par \pard\plain \qj \f20 \par l'ex\'8ecution de la proc\'8edure avec tout param\'8ftre qui ne serait pas de type integer provoquera une erreur. On peut par contre construire des proc\'8edures polymorphes (c'est \'88 dire pouvant recevoir des param\'8ftres de types diff\'8e rents tout en s'adaptant au type de ces param\'8ftres) en testant \'88 l'aide de la fonction {\b type} \'88 l'int\'8erieur de la proc\'8edure le type des param\'8ftres et en s'adaptant \'88 ce type.\par Exemple:\par \pard\plain \s2\sb120\keep\keepn \b\f22 PLUS:=proc(x,y)\line if type(x,numeric) and type(y,numeric) then\line \tab \tab RETURN(x+y)\line elif type(x,complex) and type(y, complex) then\line \tab \tab RETURN(evalc(x+y))\line elif type(x,matrix) and type(y,matrix) then\line \tab \tab RETURN(evalm(x+y))\line else ERROR(`erreur de type`)\line end;\par \pard\plain \s254\qj\sb200\sa140 \b\f20\fs36\ul II. Les fonctions op\'8erateurs\par \pard\plain \s253\qj\li354\sb120\sa80 \b\f20 1. Fonctions fl\'8fches et fonctions angles\par \pard\plain \qj \f20 A c\'99t\'8e du mode proc\'8edural pr\'8ec\'8edemment d\'8efini, Maple dispose d'un moyen d'associer simplement un r\'8esultat \'88 des param\'8ftres \'88 l'aide de deux modes \'8equivalents \'88 la notation math\'8ematique\par \tab \tab (x{\fs20\dn4 1},\'c9,x{\fs20\dn4 n}) {\f23 \'ae} expression(x{\fs20\dn4 1},\'c9,x{\fs20\dn4 n}).\par Ces deux modes sont le mode "fl\'8fche" (arrow en anglais)\par \tab (x1,\'c9,xn) -> expression(x1,\'c9,xn)\par ou le mode "angle"\par \tab < expression(x1,\'c9,xn) | x1,\'c9,xn >.\par Ces deux expressions renvoient une application de l'ensemble des n-uplets d'expressions Maple dans l'ensemble des expressions Maple, c'est \'88 dire que les lettres x1,\'c9,xn sont des lettres muettes. Comme en math\'8ematique lorsqu'on d\'8e finit l'application \par \tab \tab f: x {\f23\fs28 \'ae }sin(x{\fs20\up6 2})\par on pourra poser en Maple\par \pard\plain \s2\sb120\keep\keepn \b\f22 f:=x->sin(x^2)\par \pard\plain \qj \f20 ou encore\par \pard\plain \s2\sb120\keep\keepn \b\f22 f:= < sin(x^2) | x >.\par \par \pard\plain \qj \f20 \tab Maple permet \'8egalement de construire une fonction \'88 partir d'une expression alg\'8ebrique en rendant un certain nombre de param\'8ftres abstraits (m\'8ethode tir\'8ee du {\f23 l}-calcul) \'88 l'aide de la fonction {\b unapply\par }\pard\plain \s4\qj\li1120 \f20\fs20 FUNCTION: unapply - returns an operator from an expression and arguments\par CALLING SEQUENCE:\par unapply(expr,x,y,..)\par PARAMETERS:\par expr - any expression\par x,y,.. - variable names\par SYNOPSIS: \par - The result of unapply(expr,x) is a functional operator. If we apply this operator to x we get our original expression.\par unapply(expr,x)(x) ==> expr\par - In particular, for a function f(x),\par unapply(f(x),x) ==> f\par - Whenever it is desired to construct an operator using contents of variables or evaluated expressions, unapply should be used.\par \pard\plain \qj \f20 Exemple:\par \pard\plain \s2\sb120\keep\keepn \b\f22 \bullet f:=unapply(sin(x^2),x);\par \pard\plain \s3 \f22\fs20 2\par f := x -> sin(x )\par \pard\plain \qj \f20 \par \pard\plain \s2\sb120\keep\keepn \b\f22 \bullet f(y+1);\par \pard\plain \s3 \f22\fs20 2\par sin((y + 1) )\par \par \pard\plain \qj \f20 \tab On prendra soin (comme on devrait toujours le faire en Math\'8ematiques) de bien \'8etablir une distinction entre le nom de la fonction, la fonction elle-m\'90 me et la valeur de la fonction en un point (ne confondez pas la fonction x {\f23 \'ae }sin x avec la valeur de la fonction sinus au point x).\par \tab Maple dispose d'un certain nombre d'op\'8erations sur ces fonctions, la principale d'entre elle \'8etant bien entendu la composition d\'8enot\'8ee par l'op\'8erateur @ (qui remplace donc dans Maple l'op\'8erateur {\f23 \'b7} des Math\'8e matiques) et son op\'8erateur it\'8er\'8e @@ (correspondant \'88 la puissance des Math\'8ematiques, f{\fs20\up6 n} = f {\f23 \'b7 }\'c9 {\f23 \'b7} f n fois)\par \pard\plain \s4\qj\li1120 \f20\fs20 FUNCTION: @ - the composition operator\par FUNCTION: @@ - the repeated composition operator\par CALLING SEQUENCE:\par f @ g \par f @@ n \par PARAMETERS:\par f, g - any functions\par n - an integer\par SYNOPSIS: \par - @ is the function composition operator.\par - @@ is the repeated function composition operator.\par - If n is negative, the invfunc table is checked to see if it has an entry for f. That is, if invfunc[f] = g, then f@@n --> g@@(-n).\par \pard\plain \qj \f20 Exemple:\par \pard\plain \s2\sb120\keep\keepn \b\f22 \bullet f:=x->sin(x^2): g:=x->cos(x^3): h:=g@f;\par \pard\plain \s3 \f22\fs20 h := g@f\par \pard\plain \s2\sb120\keep\keepn \b\f22 \bullet h(t);\par \pard\plain \s3 \f22\fs20 2 3\par cos(sin(t ) )\par \pard\plain \qj \f20 Maple peut faire un certain nombre d'op\'8erations sur les fonctions comme les d\'8eriver \'88 l'aide de l'op\'8erateur D (le r\'8esultat n'est pas toujours tr\'8fs lisible, \'88 moins de l'appliquer \'88 une variable)\par \pard\plain \s2\sb120\keep\keepn \b\f22 \bullet D(h);\par \pard\plain \s3 \f22\fs20 3 2 2\par (x -> - 3 sin(x ) x )@f (x -> 2 cos(x ) x)\par \pard\plain \s2\sb120\keep\keepn \b\f22 \bullet "(t);\par \pard\plain \s3 \f22\fs20 2 3 2 2 2\par - 6 sin(sin(t ) ) sin(t ) cos(t ) t\par \pard\plain \qj \f20 \par ou en faire des trac\'8es graphiques (les diff\'8erents plot, plot3d, implicitplot, \'c9 acceptent, et m\'90me dans un certain sens pr\'8ef\'8frent, des fonctions en entr\'8ee).\par \pard\plain \s2\sb120\keep\keepn \b\f22 \bullet plot(h,-Pi..Pi);\par \pard\plain \qc \f20 {{\pict\macpict\picw320\pich208 04ca0000000000d00140001102ff0c00ffffffff00000000000000000140000000d00000000000000001000a0000000000d0014000220019002002ff0023010000230200002300000023010200230105002300070023021d002300150023011700230118002300150023011000230109002301fc002301f4002301ee002301 d5002301ec002300ee002302e6002300f8002301fc002301fc002301000023000000230300002301000023010000230100002301040023010300230006002302150023000e002301110023012500230111002301100023000c002301080023010400230000002302f2002300f4002301f1002302de002300ef002301f00023 01e7002301f8002301f9002301f9002301fd002301ff00230200002302000023030000230200002300000023010100230101002300020023020600230005002301050023010800230008002302150023000b0023010c0023011400230214002301100023010d00230105002300040023010100230100002301ff002300fc00 2301fc002301fa002300f9002301fa002301f0002302f0002301ef002301f8002300f8002301f8002301f9002300fa002301f9002301fb002300fb002302f8002301fa002301fc002301fc002302fe002301fe002303fe00230200002303000023060000230500002305000023060000230500002305000023050000230600 002302000023030000230101002302010023010200230203002301030023010200230003002301030023010300230108002301050023000500230106002301070023010e0023010800230008002301110023021100230008002301070023010e00230105002301050023010400230101002301fe002300fd002301fb002301 fb002300f9002301f7002300f7002302ec002301ea002301f4002300f5002302ec002300f8002301f9002301fa002300fc002301fc002301fe002300fe002301ff002301ff002302000023020000230300002302000023000000230101002301010023000300230208002300070023010a002301180023010f002301100023 01210023010f0023000c002301090023010500230000002301fc002301f7002300f3002302e1002301df002301e2002301eb002301f8002301fb002301fb002301000023010000230100002301000023020000230000002301000023010400230104002300080023010b0023010e0023001300230114002301160023001400 2301110023010d0023000700230100002301f9002300f2002302d9002300e7002301e9002301de002301f7002301fb002301fe002300ff002302000023010000230301002200bc00a000fd002200bc011a00fd002200bc00f100fd002200bc00c800fd002200bc00a000fd002200bc007700fd002200bc004e00fd002200bc 002500fd002000bb002000bb012000220018009d05000022003a009d05000022005d009d050000220080009d0500002200a3009d0500002000bb00a0001400a0002c00090004064d6f6e61636f0000030004000d00090006fffe0000002e000400000000002b9dc7013000297a013300002800c700ee0132002800c700c501 31002800c7009d0130002800c70071022d3100002800c70048022d3200002800c7001f022d33000028001e0097013100280040008b03302e39002a2303302e3800002a2303302e3700002a2303302e360000ff}}\par \pard \qj \par Remarque : la d\'8efinition de fonctions op\'8erateurs peut avoir besoin de faire appel \'88 des variables locales comme dans la fonction math\'8ematique\par \tab \tab \tab (x,n) -> \|i\|su({\fs20\dn4 i=1};{\fs20\up6 n}; x{\fs20\up6 i}) \par Aussi Maple autorise-t-il l'introduction de variables locales gr\'89ce \'88 la notation en mode fl\'8fche\par \tab \tab {\i parametres }{\b ->} {\b local }{\i variables_locales} ; {\i r\'8esultat\par }et en mode angle\par \tab \tab {\b < }{\i r\'8esultat }| {\i parametres} | {\i variables locales }{\b >.\par }On pourra ainsi poser indiff\'8eremment\par \pard\plain \s2\sb120\keep\keepn \b\f22 f:=(x,n) -> local i; sum(x^i,i=1..n);\par \pard\plain \qj \f20 ou\par \pard\plain \s2\sb120\keep\keepn \b\f22 f:= < sum(x^i,i=1..n) | x,n | i >.\par \pard\plain \s253\qj\li354\sb120\sa80 \b\f20 2. Un peu de programmation fonctionnelle\par \pard\plain \qj \f20 Un certain nombre de fonctions Maple attendent de fa\'8don essentielle des fonctions comme param\'8ftre. Il en est ainsi par exemple de la fonction {\b map} qui applique une fonction donn\'8ee \'88 tous les op\'8e randes du premier niveau d'une expression alg\'8ebrique (et en particulier \'88 tous les \'8el\'8ements d'une liste, d'un ensemble ou d'une table)\par \pard\plain \s2\sb120\keep\keepn \b\f22 \bullet f:=x->sin(x^2): map(f,[2,y+1,cos(t)]); \tab map(f,2+cos(t));\par \pard\plain \s3 \f22\fs20 2 2\par [sin(4), sin((y + 1) ), sin(cos(t) )]\par \par 2\par sin(4) + sin(cos(t) )\par \pard\plain \s2\sb120\keep\keepn \b\f22 \bullet maTable:=table([(1)=y+1,(2)=3]): map(f,maTable);\par \pard\plain \s3 \f22\fs20 table([\par 2\par 1 = sin((y + 1) )\par 2 = sin(9)\par ])\par \pard\plain \qj \f20 \tab Bien entendu, il n'est nullement n\'8ecessaire de nommer la fonction pour l'utiliser et vous pouvez tr\'8fs bien utiliser {\b map} sous la forme\par \pard\plain \s2\sb120\keep\keepn \b\f22 \bullet map(x->sin(x^2),[2,y+1,cos(t)]);\par \par \pard\plain \qj \f20 La fonction {\b map} admet une syntaxe un peu plus g\'8en\'8erale pour les fonctions \'88 plusieurs param\'8ftres en donnant une valeur par d\'8efaut aux param\'8ftres \'88 partir du second.\par \pard\plain \s4\qj\li1120 \f20\fs20 FUNCTION: map - apply a procedure to each operand of an expression\par CALLING SEQUENCE:\par map(fcn, expr, arg_2, ..., arg_n)\par PARAMETERS:\par fcn - a procedure or a name\par expr - any expression\par arg_i - (optional) further arguments to fcn\par SYNOPSIS: \par - The map function applies fcn to the operands of expr.\par - The i-th operand of expr is replaced by the result of applying fcn to the i-th operand. This is done for all the operands of expr.\par - For a table or array, fcn is applied to each element of the table or array.\par - If fcn takes more than one argument, they are to be specified as additional arguments, arg_2, arg_3,..., arg_n, which are simply passed through as the second, third ,..., n-th arguments to fcn.\par \pard\plain \qj \f20 Vous pourrez \'8egalement avoir besoin de la fonction {\b select }qui s\'8electionne des op\'8erandes suivant un cri\'8fre entr\'8e sous forme fonctionnelle\par \pard\plain \s4\qj\li1120 \f20\fs20 FUNCTION: select - selection from a list, set, sum, or product\par CALLING SEQUENCE:\par select(f, expr)\par select(f, expr, b_1, ..., b_n)\par PARAMETERS:\par f - a Boolean-valued procedure\par expr - a list, set, sum, or product\par b_1, ..., b_n - optional extra arguments\par SYNOPSIS: \par - The function select keeps the operands of expr which satisfy the Boolean-\par valued procedure f, creating a new object of the same type as expr. Those\par operands for which f does not return true are discarded.\par - Additional arguments b_1, ..., b_n are passed to f.\par \pard\plain \qj \f20 \par Exemple: pour s\'8electionner tous les nombres premiers compris entre 100 et 200 on fera\par \pard\plain \s2\sb120\keep\keepn \b\f22 \bullet select(isprime,[$100..200]);\par \pard\plain \s3 \f22\fs20 [101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199]\par \par \pard\plain \s253\qj\li354\sb120\sa80 \b\f20 3. La d\'8efinition d'op\'8erateurs infixes\par \pard\plain \qj \f20 On appelle op\'8erateurs infixes des op\'8erateurs unaires tels que +, - qui se mettent devant leur op\'8erande, ou binaires tels que +, - , *, / , ^ , =, union, \'c9 qui se mettent entre leurs op\'8e randes. Maple ne permet pas facilement de red\'8efinir ces op\'8erateurs infixes initiaux, mais permet par contre d'en d\'8efinir de nouveaux tout \'88 loisir. Une seule r\'8fgle est \'88 respecter: ces op\'8e rateurs infixes doivent commencer par le symbole & et \'90tre suivis soit d'un unique symbole non alphanum\'8erique, soit d'un nom Maple valide. On les d\'8efinit alors ces op\'8erateurs de mani\'8fre pr\'8efixe sous la forme\par \tab \tab `&{\i nom} ` := {\i proc\'8edure ou fonction\par }et on les utilise sous la forme &{\i nom} {\i parametre} pour un op\'8erateur unaire et sous la forme {\i parametre1} &{\i nom} {\i parametre2} pour un op\'8erateur binaire. C'est ainsi que pour d\'8e finir le produit scalaire de deux listes vous pourrez poser\par \pard\plain \s2\sb120\keep\keepn \b\f22 \bullet `&scal`:=(l1,l2)->local i; \tab \tab \tab \tab \tab \tab sum(l1[i]*l2[i],i=1..nops(l1)):\par \bullet [x1,y1,z1] &scal [x2,y2,z2];\par \pard\plain \qj \f20 \par \pard\plain \s3 \f22\fs20 x1 x2 + y1 y2 + z1 z2\par \pard\plain \qj \f20 \par Vous pouvez m\'90me d\'8efinir des propri\'8et\'8es de ces nouveaux op\'8erateurs \'88 l'aide de l'instruction {\b define} comme par exemple\par \pard\plain \s2\sb120\keep\keepn \b\f22 \bullet define(`&+`, associative, commutative, identity=0);\par \bullet define(Ls, unary, type=[algebraic], Ls(0)=0, forall(x, Ls(exp(x))=Ls(x)+1, Ls(ln(x))=Ls(x)-1));\par \pard\plain \qj \f20 \par la premi\'8fre propri\'8et\'8e garantissant que l'op\'8erateur binaire &+ est associatif, commutatif et poss\'8fde 0 comme \'8el\'8ement neutre (Maple proc\'8edera automatiquement aux simplifications n\'8ecessaires) et la deuxi\'8fme que l'op\'8e rateur Ls est une fonction unaire qui ne s'applique qu'aux expressions alg\'8ebriques et qui v\'8erifie Ls(0)=0 et \par \pard \qc {\f23 "}x , Ls(e{\fs20\up6 x}) = Ls(x)+1 et Ls(log(x))=Ls(x)-1.\par \pard\plain \s253\qj\li354\sb120\sa80 \b\f20 4. Exercices\par \pard\plain \qj \f20 Maple est un peu chiche de fonctions sur les listes. Pouvez vous d\'8efinir en Maple les fonctions suivantes (qui font partie de la biblioth\'8fque de base de Mathematica) d'une mani\'8fre aussi fonctionnelle que possible\par {\b flatten }: doit transformer une liste de listes de listes \'c9 en une unique liste en mettant tout \'88 plat au premier niveau\par {\b nestlist }: nestlist(f,x,n) doit engendrer une liste [x, f(x), f(f(x)), \'c9 ]\par {\b foldlist} : foldlist(f,x,[a,b,\'c9]) doit retourner la liste [x, f(x,a), f(f(x,a),b),\'c9 ]\par {\b mapindexed}: mapindexed(f,[a,b,\'c9]) doit retourner la liste [f(a,1), f(a,2),\'c9]\par {\b mapthread}: mapthread(f,[[a1,a2,\'c9],[b1,b2,\'c9]) doit retourner la liste [f(a1,b1),f(a2,b2),\'c9] ; essayez de la g\'8en\'8eraliser \'88 un nombre quelconque de listes\par {\b outer} : outer(f,[a1,a2,\'c9],[b1,b2,\'c9]) doit retourner la "matrice" (liste de listes) des f(a{\fs20\dn4 i},b{\fs20\dn4 j}); essayez de la g\'8en\'8eraliser \'88 un nombre quelconque de listes\par {\b inner} : inner(f,[a1,a2,\'c9],[b1,b2,\'c9],g) doit retourner g(f(a1,b1),f(a2,b2),\'c9) (quand f=* et g=+, on trouve le produit scalaire)\par \par \pard\plain \s254\qj\sb200\sa140 \b\f20\fs36\ul V. La r\'8ecursivit\'8e et les options\par \pard\plain \qj \f20 Toute fonction Maple peut-\'90tre r\'8ecursive. Des fonctions peuvent \'90tre mutuellement r\'8ecursives sans qu'il soit n\'8ecessaire de se livrer \'88 des gymnastiques de {\b forward} \'88 la Pascal puisque les noms ne sont pas v \'8erifi\'8es au moment o\'9d l'on d\'8efinit la fonction, mais au moment o\'9d on l'utilise. On pourra donc d\'8efinir\par \pard\plain \s2\sb120\keep\keepn \b\f22 \bullet f:=proc(x)\line \tab \tab if x=0 then 1 else x*g(x-1);\line end;\par g:=proc(x)\line if x=0 then 1 else f(x-1)/x;\line end;\par \par \pard\plain \qj \f20 Maple dispose \'88 cet \'8egard d'une possibilit\'8e pr\'8ecieuse, c'est l'option {\b remember}. Lorsqu'une fonction est d\'8e finie avec cette option, Maple lui associe une table de souvenance qui contient tous les appels de la fonction et les r\'8esultats trouv\'8es. Si la fonction est de nouveau appel\'8ee avec les m\'90mes valeurs des param\'8ftres, le r\'8e sultat est directement retourn\'8e \'88 partir de la table de souvenance sans que le corps de la fonction soit r\'8eex\'8ecut\'8e. Cela peut entra\'94ner des gains consid\'8erables en temps. C'est ainsi que les deux exemplai res suivants de la fonction de calcul des nombres de Fibonacci ont des complexit\'8es respectives (et donc des temps d'ex\'8ecution respectifs) en 2{\fs20\up6 n} et n:\par \pard\plain \s2\sb120\keep\keepn \b\f22 \bullet fib1(n):= proc(n) if n<=1 then 1 else \line fib1(n-1)+fib1(n-2); end;\par fib2(n):= proc(n) option remember; \line \tab if n<=1 then 1 else \line \tab \tab fib2(n-1)+fib2(n-2); end;\par \pard\plain \qj \f20 \par En effet la premi\'8fre proc\'8edure passe son temps \'88 recalculer les m\'90mes valeurs alors que la deuxi\'8fme ne les recalcule pas puisqu'elle les retrouve directement dans une table. Sur un mac Powerbook, la premi\'8fre proc\'8e dure met 32 secondes pour calculer fib1(18) et la seconde 0,26 secondes pour calculer fib2(18) (les deux fournissant bien entendu le m\'90me r\'8esultat). La premi\'8fre utilise 70 kilooctets de m\'8emoire et la seconde 675 octets.\par \tab Bien entendu, m\'8efiez vous des effets de bord sur le comportement des fonctions ayant des tables de souvenance. D'une part, il est d\'8elicat de savoir si le corps de la fonction sera ex\'8ecut\'8e ou non, et donc si un effet de bord souhait\'8e aura lieu ou non. D'autre part, la table de souvenance ne tient pas compte de la modification \'8eventuelle de variables globales entre deux appels. En particulier si vous appelez une premi\'8fre fois une telle fonction alors que la pr\'8ecision g\'8en \'8erale est fix\'8ee \'88 10 chiffres significatifs, que vous changez cette pr\'8ecision g\'8en\'8erale \'88 l'aide de la variable Digits=30, puis que vous r\'8eappelez la fonction avec le m\'90me param\'8ftre, le r\'8esultat ne sera pas recalcul\'8e et vous n'aurez toujours que vos 10 chiffres significatifs.\par \pard\plain \s254\qj\sb200\sa140 \b\f20\fs36\ul VI. R\'8esum\'8e de la syntaxe et de la s\'8emantique du langage\par \pard\plain \qj \f20 \tab Nous pr\'8esentons ici un r\'8esum\'8e de la syntaxe et de la s\'8emantique du langage. Pour simplifier nous avons convenu de confondre les notations infixes et pr\'8efixes des diff\'8erents op\'8erateurs\par \tab a {\i op }b {\i op} \'c9 {\i op} c \tab \tab est remplac\'8e par \tab {\i op} (a,b,\'c9,c)\par que {\i op} soit +,-,*, / , ^, $ , @ , @@, .. ({\i range }) ou un op\'8erateur neutre &\'c9 .\par \tab De m\'90me nous avons convenu de confondre les diff\'8erentes formes des proc\'8edures ou fonctions\par \tab \|b\|rc\|\}(\|a((x1,\'c9,xN)->\'c9; ;< \'c9 | x1,\'c9xN>)) sont remplac\'8es par {\i proc(x1,\'c9,xN) option operator; \'c9 end\par \par }Comme d'habitude l'op\'8erateur "grammatical" d'affectation ::= doit \'90tre lu comme un "est un" , le symbole | d\'8esigne une alternative et les cochets encadrent des parties facultatives. Les expressions qui contr\'99lent l'ex\'8ecution sans interv enir dans la valeur de retour n'ont pas \'8et\'8e explicit\'8ees et remplac\'8ees par \'c9 .\par \tab La premi\'8fre colonne d\'8ecrit la syntaxe associ\'8ee aux diff\'8erents types d'expressions\par \pard \qj\tx1380\tx3960 \tab * g\'8en\'8erales \tab {\i expr}\par \pard \qj\tx1400\tx3960 \tab * \'8el\'8ementaires \tab {\i elemexpr\par \tab }* index\'8ees\tab {\i indexexpr\par \tab }* compos\'8ees\tab {\i seqexpr}\par \tab * non \'8evalu\'8ees\tab {\i quotexpr\par \tab }* affectations\tab {\i affexpr\par }\tab * conditionnelles\tab {\i condexpr\par \tab }* r\'8ep\'8etitives\tab {\i repexpr\par }\tab * proc\'8edurales\tab {\i procexpr}\par \pard \qj {\i \tab }La deuxi\'8fme colonne d\'8ecrit la valeur de retour de l'\'8evaluation de l'expression (que nous avons indiqu\'8ee par une fonction fictive EV). Ne pas confondre cette valeur de retour de l'\'8e valuation standard avec la valeur de retour de {\b eval}({\i elemexpr }) qui elle est la valeur de retour de l'\'8evaluation compl\'90te (d'une expression \'8el\'8ementaire).\par {\i \par }\trowd \trgaph80\trleft-80 \clbrdrt\brdrs \clbrdrl\brdrhair \clbrdrb\brdrhair \clbrdrr\brdrhair \clshdng0\cellx3124\clbrdrt\brdrs \clbrdrl\brdrhair \clbrdrb\brdrhair \clbrdrr\brdrhair \clshdng0\cellx6328\clbrdrt\brdrs \clbrdrl\brdrhair \clbrdrb\brdrhair \clbrdrr\brdrs \clshdng0\cellx9532\pard \qj\pvpg\phmrg\posxc\posy2117\absw9612\dxfrtext180\intbl {\b Syntaxe\cell valeur de retour de l'\'8evaluation }(d\'8esign\'8ee ici par EV(\'c9)){\b \cell effets de bord \cell }\pard \intbl {\b \row }\trowd \trgaph80\trleft-80 \clbrdrt\brdrhair \clbrdrl\brdrhair \clbrdrb\brdrhair \clbrdrr\brdrhair \clshdng0\cellx3124\clbrdrt\brdrhair \clbrdrl\brdrhair \clbrdrb\brdrhair \clbrdrr\brdrhair \clshdng0\cellx6328\clbrdrt\brdrhair \clbrdrl\brdrhair \clbrdrb \brdrhair \clbrdrr\brdrs \clshdng0\cellx9532\pard \qj\pvpg\phmrg\posxc\posy2117\absw9612\dxfrtext180\intbl {\i expr::=} elemexpr | affexpr | seqexpr | condexpr | repexpr | procexpr {\i \cell }\cell \cell \pard \intbl \row \pard \qj\pvpg\phmrg\posxc\posy2117\absw9612\dxfrtext180\intbl {\i elemexpr::= }nombre | symbole | indexexpr | quotexpr | \par elemexpr{\b (}elemexpr1{\b ,}\'c9{\b ,\par }\tab \tab elemexprN{\b )}\cell le nombre, la valeur du symbole{\fs18\up6 \chftn {\footnote \pard\plain \s246\qj \f20\fs20 {\fs18\up6 \chftn } Rappelons que la valeur d'un symbole est \par \tab - le symbole lui m\'90me s'il n'est pas affect\'8e (il pointe sur lui m\'90me)\par \tab - la valeur de l'expression sur laquelle il pointe (i.e. qui lui a \'8et\'8e affect\'8ee) si cette expression n'est ni une table ni une proc\'8edure\par \tab - le symbole lui m\'90me si le symbole pointe sur une table ou une proc\'8edure (\'8evaluation au dernier nom)}}, la valeur de quotexpr ou de l'expression\par \pard \qj\pvpg\phmrg\posxc\posy2117\absw9612\dxfrtext180\tx700\intbl EV(elemexpr)(EV(elemexpr1),\'c9, EV(elemexprN))\cell \pard \qj\pvpg\phmrg\posxc\posy2117\absw9612\dxfrtext180\intbl empilement de la valeur si \'ad NULL\cell \pard \intbl \row \pard \qj\pvpg\phmrg\posxc\posy2117\absw9612\dxfrtext180\intbl {\i indexexpr::=} elemexpr{\b [}elemexpr1{\b ,}\'c9{\b ,\par }\tab \tab elemexprN{\b ]}{\i \cell }EV(elemexpr)[EV(elemexpr1),\'c9, EV(elemexprN)]\cell empilement de la valeur si \'ad NULL\cell \pard \intbl \row \pard \qj\pvpg\phmrg\posxc\posy2117\absw9612\dxfrtext180\intbl {\i quotexpr::=} 'expr'{\i \cell } l'expression {\i expr} elle m\'90me, non \'8evalu\'8ee\cell l'expression {\i expr} non \'8evalu\'8ee est empil\'8ee\cell \pard \intbl \row \pard \qj\pvpg\phmrg\posxc\posy2117\absw9612\dxfrtext180\intbl {\i affexpr::=} symbole{\b :=} elemexpr | indexexpr:=elemexpr{\i \cell }NULL\cell la valeur{\fs18\up6 2{\footnote \pard\plain \s246\qj \f20\fs20 {\fs18\up6 2} Lorsque {\i expr} est une expression proc\'8edurale, {\i expr }n'est pas \'8evalu\'8ee mais affect\'8ee directement}} de { \i elemexpr} n'est pas empil\'8ee mais affect\'8ee \'88 {\i symbol }ou \'88 {\i indexexpr }(au besoin en cr\'8eant la table correspondante)\cell \pard \intbl \row \pard \qj\pvpg\phmrg\posxc\posy2117\absw9612\dxfrtext180\intbl {\i seqexpr::= } expr1{\b ;}\'c9{\b ;}exprN\cell NULL\cell empilement des valeurs \'adNULL dans la pile d'\'8evaluation \'88 trois places (FIFO)\cell \pard \intbl \row \pard \qj\pvpg\phmrg\posxc\posy2117\absw9612\dxfrtext180\intbl {\i cond_expr::= }{\b if} \'c9 {\b then} seqexpr1 [{\b elif} \'c9 {\b then} seqexpr2] \'c9 [{\b else} seqexprN] {\b fi}\cell NULL\cell celui de la {\i seqexpr} qui est \'8evalu\'8ee\cell \pard \intbl \row \pard \qj\pvpg\phmrg\posxc\posy2117\absw9612\dxfrtext180\intbl {\i rep_expr::=} [{\b for } \'c9] [{\b from} \'c9] [{\b to}\~\'c9] [{\b by} \'c9] [{\b while }\'c9] \par {\b do} seqexpr {\b od}\cell NULL\cell celui de la suite de {\i seqexpr} qui est ex\'8ecut\'8ee\cell \pard \intbl \row \trowd \trgaph80\trleft-80 \clbrdrt\brdrhair \clbrdrl\brdrhair \clbrdrb\brdrhair \clbrdrr\brdrhair \clshdng0\cellx3124\clbrdrt \brdrhair \clbrdrl\brdrhair \clbrdrb\brdrhair \clbrdrr\brdrhair \clshdng0\cellx6328\clbrdrt\brdrhair \clbrdrl\brdrhair \clbrdrb\brdrhair \clbrdrr\brdrs \clshdng0\cellx9532\pard \qj\pvpg\phmrg\posxc\posy2117\absw9612\dxfrtext180\intbl {\i proc_expr::= } { \b proc(}\'c9{\b ) }[{\b options }\'c9{\b ;}]{\b \par }[{\b local }\'c9{\b ;}]{\b \par } seqexpr\par {\b end}\cell le sommet de la pile d'\'8evaluation{\fs18\up6 3} de {\i procexpr}\cell \'88 la sortie, la pile d'\'8evaluation de {\i procexpr }est d\'8etruite; la valeur de retour est empil\'8ee si \'ad NULL\cell \pard \intbl \row \pard \qj \par }