• Aucun résultat trouvé

2.Syntaxed’appel 1.Introduction I.Procéduresetfonctions

N/A
N/A
Protected

Academic year: 2022

Partager "2.Syntaxed’appel 1.Introduction I.Procéduresetfonctions"

Copied!
6
0
0

Texte intégral

(1)

I. Procédures et fonctions

Fichiers Maple à télécharger : Pproc.mw ou Pproc.mws

1. Introduction

Une procédure est une donnée Maple constituée d’une suite d’instructions ser- vant à effectuer une tâche spécifique. Comme tous les objets Maple, une procédure peut être désignée par un nom.

Une fonction est une procédure particulière (plus simple). Attention à ne pas confondre le terme fonction au sens de Maple et au sens mathématique. Une "fonc- tion Maple" par exemple n’a pas d’espace de départ. Je déconseille l’utilisation des

"fonctions Maple" pour représenter des fonctions mathématiques. Utiliser simple- ment des expressions.

Il faut bien distiguer la définition et les appels d’une procédure.

La définition est une assignation à un nom (le nom choisi pour la procédure) des instructions qui la constituent.

Un appel est une instruction servant à faire exécuter à la procédure la tâche pour laquelle elle a été écrite et à lui indiquer les valeurs des paramètres qu’elle utilise.

À côté des noms réservés par Maple pour désigner des objets mathématiques usuels ( Pi 1 2 3 ... ) figurent des noms de procédures ( subs solve irem evalf ...) Par exemple, la commande

> cos(Pi);

est un appel de la procédure cos.

À chaque appel, une procédure fonctionne de manière autonome. Cette autonomie se traduit par un domaine spécifique pour la validité des noms (on dira local).

Autrement dit, elle dispose de son propre système d’état-civil, le même nom (par exemple i) peut désigner des objets differents dans des procédures et dans le pro- gramme qui les appelle (comme un même prénom désigne des personnes différentes dans des familles différentes). À l’inverse, on peut déclarer dans la définition d’une procédure un nom de variable comme global pour qu’il désigne le même objet que dans l’instruction qui l’appelle.

Une procédure doit pouvoir échanger des informations avec le système qui l’a ap- pelée ainsi qu’avec l’extérieur.

Pour faire entrer les données dans la procédure, on peut utiliser les paramètres ou les variables globales. Pour faire sortir les données on peut utiliser le retour (ce que renvoie la fonction), les variables globales ou une interface vers un dispositif exté- rieur (le plus souvent l’écran mais éventuellement une imprimante ou un fichier).

Toutes les procédures que nous écrirons passent les valeurs des paramètres et non les références

1

. La syntaxe Maple pour le passage des paramètres par référence n’entre pas dans le cadre de ce cours.

Pour Maple, le retour est le résultat de la dernière instruction de la procédure. On peut aussi utiliser return pour renvoyer un résultat et c’est une bonne pratique de le faire systématiquement.

2. Syntaxe d’appel

Le nom de la procédure est suivie par des parenthèses contenant une séquence de paramètres. Par exemple pour appeler la procédure machin avec le paramètre bidule :

> machin(bidule);

Ici Maple ne connait ni l’un ni l’autre et affiche seulement l’appel sans rien faire.

Les nom subs solve irem evalf sont connus de Maple et désignent des pro- cédures. Pour d’autres procédures plus spécifiques les noms ne sont pas chargés automatiquement en mémoire. Elles sont stockées dans des bibliothèques qu’il est nécessaire d’appeler à l’aide de with.

> plot(cos,-Pi..Pi);

plot([[0,0],[1,0],[1,1],[0,0]],axes=none, color=blue);

desscos:=plot(cos,-Pi..Pi,scaling=constrained):

desstri:=plot([[0,0],[1,0],[1,1],[0,0]]

,axes=none, color=blue,scaling=constrained):

display([desscos,desstri]);

with(plots);

display([desscos,desstri]);

with(geometry);

point(pA,[0,0]):point(pB,[0,1]):point(pC,[1,0]):

draw([pA,pB,pC],axes=none);

triangle(tri,[pA,pB,pC]):

circumcircle(circ,tri):

draw([pA,pB,pC,circ(color=blue)],axes=none);

Les instructions précédentes utilisent la bibliothèque plots et fournissent aussi des exemples de retour.

1Il est possible de faire passer les références de paramètres. Par exemple les procédures de la bibliothèque de géométrie le font assez systématiquement.

(2)

3. Syntaxe de définition

1. Pour une procédure

> nomchoisi := proc(para1,para2,...) local varloc1,varloc2,...;

global varglob1,varglob2,...;

instruction1;

...

derninstruction;

end proc;

Exemples de définitions :

> factorielle:= proc(n) local i,resultat;

resultat :=1;

for i from 1 to n do resultat := resultat*i;

od;

resultat; # ou return resultat;

end proc;

factoriellebis:= proc(n) local i,resultat;

resultat :=1;

for i from 1 to n do resultat := resultat*i;

od;

print(resultat);

end proc;

#appels

factorielle(5);factoriellebis(5);

f:=factorielle(5): ff:=factoriellebis(5);

f;ff;

Il ne faut pas confondre renvoyer et afficher. Lorsque la définition se termine par un print, la procédure ne renvoie rien et affiche quelque chose. Par défaut, une procédure renvoie le résultat de l’évaluation de la dernière commande. Si cette commande est un print, il n’y a pas d’évaluation, il y a affichage sur l’écran.

Je conseille d’utiliser systématiquement return expr;. Cette commande termine l’appel de la procédure et renvoie l’évaluation de expr.

Si on veut que la procédure renvoie plusieurs objets, il faut en faire une séquence puis l’ empaqueter dans un seul objet comme une liste ou un tableau.

2. Pour une fonction

nomchoisi := (para1,para2,...) -> expr des paramètres;

la fonction renvoie l’évaluation de l’expression

> cbin:= (m,n)->mul(m-i,i=0..n-1)/n!;

cbin(4,2);

4. Exemples

Définir une procédure cle telle que l’appel cle(x,A) (où A est le nom d’un tableau de dimension 2) renvoie

– la liste [0,0] si l’évaluation de x ne figure pas parmi les valeurs de A – une liste [i,j] (n’importe laquelle) telle que la valeur du tableau associée

soit égale à l’évaluation de x.

Modifier la procédure précédente pour définir cle1 utilisant une variable globale bonnecle. Un appel cle1(x,A) ne renvoie rien, affiche "trouvé" ou "pas trouvé"

et assigne à bonnecle la liste [i,j] comme pour la procédure précédente.

Définir une procédure qui "retourne" un tableau A à une dimension.

Si A désigne un tableau de valeurs [1,2,3,truc,4] , l’appel retourne(A) doit modifier le tableau désigné par A. Ses valeurs doivent être [4,truc,3,2,1] après l’appel.

Dans cette définition, vous devez utiliser

– des variables globales A et n pour le tableau array(1..n).

– une variable locale i qui prendra des valeurs entières.

– une variable locale "à tout faire" faitout et rien d’autre.

II. Exemple : corrigé du TP injectivité et surjec- tivité

Fichiers Maple à télécharger : Csurjinc.mw ou Csurjinc.mws

(3)

1. est_image(x). Renvoyer vrai si x est une image de la fonction f et faux sinon.

Syntaxe sans utiliser de fonction.

> n:=4;p:=5;

A:= array(1..n,[4,4,2,1]);

x:= 3;

## x est-il une valeur du tableau ? res := false:

for i from 1 to n do if A[i]=x then

res := true;

i := n+1; # pour sortir de la boucle fi;

od:

res;

Syntaxe avec une fonction

> # définition de la fonction est_image := proc(x)

local i, res;

global n,p,A;

res := false:

for i from 1 to n do if A[i]=x then

res := true;

i := n+1; # pour sortir de la boucle fi;

od:

return(res);

end proc:

# définition des données n:=4;p:=5;

A:= array(1..n,[4,4,2,1]);

# appel de la fonction est_image(3);

2. nbantecedent(x) Renvoyer le nombre d’antécédents de x pour la fonction f

lorsque x est une image et renvoyer 0 si x n’est pas une image.

Syntaxe sans fonction

> n:=4;p:=5;

A:= array(1..n,[4,4,2,1]);

x:= 4;

## Nombre d’antécédents de x?

res := 0:

for i from 1 to n do if A[i]=x then

res := res +1;

fi;

od:

res;

Syntaxe avec une fonction

> #définition de la fonction nbantecedent := proc(x)

local i, res;

global n,p,A;

res := 0:

for i from 1 to n do if A[i]=x then

res := res +1;

fi;

od:

return(res);

end proc:

#définition des données n:=4;p:=5;

A:= array(1..n,[4,4,2,1]);

#appel de la fonction nbantecedent(4);

3. est_surjective() Renvoyer vrai si f est surjective et faux sinon.

Syntaxe sans fonction. On initialise la réponse à true puis on boucle sur

les éléments de l’espace d’arrivée. On s’arrête en renvoyant false lorsqu’un

élément n’est pas une image.

(4)

> n:=5;p:=4;

A:= array(1..n,[4,4,2,1,3]);

# la fonction est-elle surjective ? res:= true:

for x from 1 to p do est_pas_im := true;

for i from 1 to n do if A[i] = x then

est_pas_im:= false;

i:= n+1;

fi;

od;

if est_pas_im then res := false;

x := p+1;

fi;

od:

res;

Avec des fonctions, l’idée est la même mais on peut réutiliser est_image.

> # définition de la fonction est_surjective := proc()

local x, res;

global n,p,A;

x:= 1;

while est_image(x) and x<=p do x := x+1;

od;

res := evalb(x=p+1);# évalue en booléen return(res)

end proc:

# définition des données n:=5;p:=5;

A:= array(1..n,[4,4,2,1,3]);

#appel de la fonction est_surjective();

4. est_injective() Renvoyer vrai si f est injective et faux sinon.

L’idée est de chercher un couple d’éléments distincts dans l’ensemble de dé- part qui ont la même image. Si on en trouve un, la fonction n’est pas injective.

Comme les éléments sont distincts, on en prend un strictement plus petit que l’autre.

> n:=5;p:=7;

A:= array(1..n,[4,6,2,1,3]);

# la fonction est-elle injective ? res:= true:

for i from 1 to n do for j from 1 to i-1 do

if A[i] = A[j] then res := false;

j:= n+1;

i:= n+1; # pour sortir des boucles fi;

od:

od:

res;

> # définition de la fonction est_injective := proc()

local i,j,res;

global n,p,A;

res:= true:

for i from 1 to n do for j from 1 to i-1 do

if A[i] = A[j] then res := false;

j:= n+1;

i:= n+1; # pour sortir des boucles fi;

od:

od:

return(res);

end proc:

# définition des données

n:=5;p:=7;

(5)

A:= array(1..n,[4,6,2,1,3]);

# appel

est_injective();

5. reciproque() Renvoyer un tableau B qui, lorsque f est bijective, modélise la bijection réciproque f

−1

.

On suppose ici que la fonction est bijective. On ne le vérfiera donc pas. On remplit les clés du tableau B avec les valeurs du tableau A.

> n:=5;p:=5;

A:= array(1..n,[4,5,2,1,3]);

# former un tableau "réciproque"

B:= array(1..p):

for i from 1 to n do B[A[i]] := i;

od:

eval(B);

Syntaxe avec une fonction :

# définition de la fonction reciproque := proc()

local i,B;

global n,p,A;

B:= array(1..p):

for i from 1 to n do B[A[i]] := i;

od:

return(eval(B));

end proc:

# définition des données n:=5;p:=5;

A:= array(1..n,[4,5,2,1,3]);

# appel

C := reciproque():

eval(C);

Noter l’utilisation du eval() avant le renvoi pour forcer l’évaluation. En effet les tableaux dérogent à la règle de l’évaluation maximale. Quand une variable

désigne un tableau, elle est évaluée à son nom seul. Il me semble préférable d’éviter le renvoi d’un nom local à la fonction.

III. Introduction à la récursivité

La récursivité est un concept qui généralise la notion de suite définie par récur- rence.

Une procédure (ou fonction au sens informatique) est récursive lorsqu’elle s’appelle elle même.

Certains langages (dont Maple) autorisent cette manière de mettre en oeuvre un algorithme. Il est particulièrement important de prouver que l’algorithme va s’ar- rêter. En général on introduit pour cela un nombre entier qui doit strictement décroitre d’un appel à l’autre. Un exemple simple est donné par la définition (du cours) des coefficients du binôme.

cbin:=proc(n,p) if p=0 or p=n then

1 else

cbin(n-1,p-1) + cbin(n-1,p);

fi;

end:

cbin(5,2);

Dans cet exemple le nombre qui diminue strictement à chaque appel est n+p. On peut former une procédure qui rend mieux compte de ce qu’elle fait.

nbappel:=0;

cbinbavard:=proc(n,p) global nbappel;

local texte;

nbappel:=nbappel+1;

texte:= "appel numero" || nbappel || " , n=" || n || " , p=" || p;

print(texte);

if p=0 or p=n then 1

else

cbinbavard(n-1,p-1) + cbinbavard(n-1,p);

fi;

(6)

end:

cbinbavard(3,2);

Remarquer qu’il est indispensable d’utiliser une variable globale pour compter le nombre d’appels de la procedure. Remarquer l’opérateur de concaténation k qui permet d’envoyer vers l’écran un joli texte.

Bien noter qu’une procédure récursive doit contenir dès le début une structure de contrôle if comprenant une branche qui se termine sans s’appeler. Cette branche correspond à l’initialisation de la récursivité. Sans cela la boucle infinie est assurée.

Enregistrez avant d’exécuter.

Références

Documents relatifs

Les deux catégories principales de cas prévues à l’article 29 exigent à la fois le maintien de l’instance principale et un effet réel sur son sort

Dans cette nouvelle mission, l’architecte de parcours aura pour mission de faire une mesure d’écart entre le profil du candidat et l’objectif de certification qu’il poursuit dans

 Moins de 18 ans : après le délai d’observation de 24 heures, lorsque le dépistage n’est pas recommandé, (voir critères page 2), l’enfant peut retourner dans son milieu

 Après le délai d’observation de 24 heures, lorsque le dépistage n’est pas recommandé, (voir critères de la page 2), la personne peut retourner dans son milieu. Retour dans

Voici les nouvelles catégories de dépistage recommandées par la directrice de la santé publique pour la population de la région Chaudière-Appalaches, excluant les usagers dans

G3 :RI-RTF-RPA-CHSLD : les usagers et le personnel dans des milieux d’hébergement tels que les centres d’hébergement et de soins de longue durée (CHSLD), les résidences privées

G3 :RI-RTF-RPA-CHSLD : les usagers et le personnel dans des milieux d’hébergement tels que les centres d’hébergement et de soins de longue durée (CHSLD), les résidences privées

Si on fait l’opération inverse, on constate qu’en français pince est utilisé dans les mots pince à glace, pince à riveter, pince à sucre, pince monseigneur, pince à feu, pince