Xcas propose un mode de compatibilité avec Maple, MuPAD et
la TI89/92 :
pour cela, il suffit de le spécifier dans Prog style du menu de
configuration du cas (bouton Config ou menu
Cfg->Configuration du CAS) ou avec le menu
Cfg->Mode (syntax). On peut choisir, en
cliquant sur la flèche située à coté de Prog style : Xcas
ou Maple ou MuPAD ou TI89/92.
On a aussi la possibilité d’importer une session Maple
ou une archive TI89/92 en choisissant
Importer du menu Fich, ou importer dans
un niveau éditeur de programmes un fichier écrit
en syntaxe Maple, Mupad ou TI89/92
par le menu Prog->Inserer.
On présente ici le mode Xcas qui est proche de la syntaxe C. On a aussi la possibilité d’avoir toutes les instructions en français de façon à être proche du langage Algorithmique.
Il faut prendre l’habitude de commenter les programmes.
En algorithmique un commentaire commence par
// et se termine par un passage à la ligne.
Exemple :
//ceci est un commentaire
Avec Xcas un commentaire commence par
// et se termine par un passage à la ligne.
Exemple :
//ceci est un commentaire
Un commentaire commence par # et se termine par un passage à la
ligne.
Exemple :
# ceci est un commentaire
Un commentaire est entouré de deux # ou
commence par /* et se termine par */.
Exemple :
# ceci est un commentaire #
/* ceci est un commentaire */
Le commentaire commence par
© (F2 9) et se termine par un passage à la ligne.
Exemple :
© ceci est un commentaire
Voir aussi 1.5.3
Ce sont les endroits où l’on peut stocker des valeurs, des nombres, des
expressions.
Avec Xcas les noms des variables ou des fonctions commencent par une
lettre et sont formés par des lettres ou des chiffres.
Par exemple :
azertyuiop:=2 met la valeur 2 dans la variable azertyuiop
azertyuio?:=1 renvoie un message d’erreur car azertyuio? contient
? qui n’est pas une lettre.
Étant donné que Xcas fait du calcul formel il faut quelquefois purger
une variable var pour qu’elle redevienne formelle avec la commande
purge(var) ou encore utiliser la commande assume(var,symbol) pour
que var redevienne formelle.
On tape :
x:=2;
x contient 2 et n’est pas formelle.
On tape :
purge(x) : cela renvoie la valeur x si x est
affecté et x redevient une variable formelle, et, si x n’est
pas affecté purge(x) renvoie "x not assigned".
ou bien, on tape :
assume(x,symbol)
et cela renvoie dans tous les cas DOM_SYMBOLIC.
Avec MapleV et MuPAD, un nom doit commencer par une lettre, ne pas contenir d’espace, de symbole
opératoire (+, -, ...) et ne pas être un mot réservé comme D, I, ... pour MapleV.
On peut utiliser des noms ayant plus de 8 caractères.
Pour TI89/92 un nom doit commencer par une lettre, ne pas contenir
d’espace, de symbole opératoire (+, -, ...), ne pas être un mot
réservé et ne doit pas avoir plus de 8 caractères.
Pour Xcas il faut définir les variables locales en début de programme
en écrivant :
local a,b,c;
Attention
Dans un programme toutes les variables sont des variables qui sont initialisées par défaut à 0.
Mais ces variables peuvent être initialisées au moment de leur
déclaration avec local, par exemple :
local a,(b:=1),c;
Remarque
Xcas accepte qu’il y ait plusieurs local dans un programme, par
exemple :
essailoc(n):={ local s:=0; local j; for (j:=1;j<=n;j++){ s:=s+1/j; } return s; }
Pour MapleV, il faut définir les variables locales en début
de programme en écrivant :
local a,b
Pour MuPAD, il faut définir les variables locales en début de programme en écrivant :
local a,b
Pour la TI89/92 il faut définir les variables locales en début de programme en écrivant :
:local a,b
Quand on écrit une fonction il est possible d’utiliser des paramètres.
Par exemple si A et B sont les paramètres de la fonction PGCD on écrit :
PGCD(A,B)
Ces paramètres se comportent comme des variables locales, la seule
différence est qu’ils sont initialisés lors de l’appel de la fonction.
L’exécution se fait en demandant par exemple :
PGCD(15,75)
Avec Xcas on peut définir une fonction :
^
2+1,1..3) ou ^
2+1,1..9,2).Autre exemple :
pgcd(a,b):={ local r; while (b!=0){ r:=irem(a,b); a:=b; b:=r; } return(a); };
ou encore :
pgcd:=(a,b)-> { local r; while (b!=0){ r:=irem(a,b); a:=b; b:=r; } return(a); };
L’exécution se fera alors en tapant : pgcd(15,75).
PGCD:=proc(A,B)
....
....
end:
Attention
Ces paramètres NE se comportent PAS comme des variables locales : ils sont
initialisés lors de l’appel de la fonction mais ne peuvent pas être
changés au cours de la procédure.
L’exécution se fait en demandant par exemple :
PGCD(15,75)
PGCD:=proc(A,B)
begin
....
end_proc:
Ces paramètres se comportent comme des variables locales, la seule différence
est qu’ils sont initialisés lors de l’appel de la fonction.
L’exécution se fait en demandant par exemple :
PGCD(15,75)
Pour les TI 89/92 on met le nom des paramètres dans le nom de la
fonction par exemple :
:addition(a,b)
:pgcd(a,b)
Pour que l’utilisateur puisse entrer une valeur dans la variable A au
cours de l’exécution d’un programme, on écrira, en algorithmique :
saisir A
Et pour entrer des valeurs dans A et B on écrira :
saisir A,B
On écrit :
input(A);
ou
saisir(A);
On peut utiliser :
A := readline() ; ou
A:=readstat(’A=?’);
input("A=",A)
input("A=",A,"B=",B )
:Prompt A
:Prompt A,B
ou encore :
:Input ‘‘A=’’,A
En algorithmique on écrit :
afficher A
ou si on veut connaitre le nom de la variable qui est affichée
afficher "A=",A
On écrit :
A:=2;B:=3;
print(A);
ou
afficher(A);
On obtient, en bleu dans la zone intermédaire 2,3
print(A,B);
ou
afficher(A,B);
On obtient, en bleu dans la zone intermédaire 2,3
ou encore
print("A=",A);
ou
afficher("A=",A);
On obtient, en bleu dans la zone intermédaire "A=",2
ou encore
print("A="+A);
ou
afficher("A="+A);
On obtient, en bleu dans la zone intermédaire A=2
print("A=",A,"B=",B);
ou
afficher("A=",A,"B=",B);
On obtient, en bleu dans la zone intermédaire "A=",2,"B=",3
print ou afficher permet de réaliser des affichages en cours de
programmme.
Ces affichages s’écriront alors en bleu dans la zone intermédaire .
On tape par exemple dans un niveau éditeur de programmes (que l’on ouvre avec
Alt+p) :
carres(n):={ local j; for (j:=1;j<n+1;j++) { print(j^2); } return n^2; }
Puis on complile ce programme en cliquant sur OK.
On tape ensuite dans une ligne de commandes :
carres(5)
On obtient :
1
4
9
16
25
écrit en bleu dans la zone intermédaire
et
25
le résultat écrit en noir dans la zone des réponses.
print(‘A=‘.A):
On préférera ‘ (accent grave) à " (guillemet), comme délimiteur de chaîne, car le premier n’est pas affiché, alors que le deuxième l’est.
print("A=",A)
Il fait savoir que lorsqu’une procèdure est appelée, la suite d’instructions entre
begin et end_proc est exécutée, et le résultat est égal au
résultat de la dernière évaluation.
:Disp "A=",A
:ClrIO efface l’écran.
:ClrHome efface l’écran pour la TI 83+.
:Pause arrête le programme (on appuie sur ENTER pour reprendre l’exécution).
Une action ou bloc est une séquence d’une ou plusieurs
instructions.
En langage algorithmique, on utilisera l’espace ou le passage à la ligne
pour terminer une instruction.
Avec Xcas la séquence d’instructions est parenthèsées par
{ }. La séquence d’instructions est appelée un bloc ou une
action et ; termine chaque instruction.
Seule la dernière instruction d’un programme génére la réponse. Si on
veut des sorties intermédiaires il faudra le faire à l’aide de la commade
print ou afficher et ces sorties se feront alors avant
la réponse, dans la zone intermédaire en écriture bleue.
Par exemple si on écrit dans un niveau éditeur de programmes
(que l’on ouvre avec Alt+p) :
pgcd(a,b):={ local r; while (b!=0){ r:=irem(a,b); print(r); a:=b; b:=r; } return(a); };
On compile en appuyant sur OK et on tape :
pgcd(15,25)
On obtient :
5 comme réponse et :
r:15
r:10
r:5
r:0
s’écrivent en bleu dans un écran appelé zone intermédaire qui se met
avant la réponse.
Si la dernière instruction est géométrique, elle
génère une sortie dans unécran géométrique. Les instructions
print ou afficher se feront alors en bleu dans la zone
intermédaire située avant l’écran géométrique où se trouve la
réponse. Mais les instructions géométriques intermédiaires se feront
dans l’écran DispG qui est un écran géométrique que l’on obtient
avec la commande DispG() ou avec le menu Cfg->Montrer->DispG.
Par exemple si on écrit dans un niveau éditeur de programmes (que l’on ouvre avec Alt+p) :
pgcdg(a,b):={ local r; while (b!=0){ r:=irem(a,b); print(r); point(a+i*b); segment(a+i*b,b+i*r); a:=b; b:=r; } return(point(a+i*b)); };
On compile en appuyant sur OK et on tape :
A:=pgcdg(15,25)
On obtient :
Un écran de graphique s’ouvre avec le point A de coordonnées (0;5)
et :
r:15
r:10
r:5
r:0
s’écrivent en bleu dans un écran appelé zone intermédaire qui se met
avant l’écran de géométrie.
On ouvre l’écran géométrique DispG (avec la commande DispG()
ou avec le menu Cfg->Montrer->DispG)
Sur l’écran DispG il y a les différents segments et les points (sans
la lettre A)
Pour tout voir, vous devez soit appuyer sur le bouton auto de l’écran
DispG, soit changer la configuration avec le bouton cfg de
l’écran DispG.
: ou ; indique la fin d’une instruction.
Une instruction terminée par point-virgule ( ; ) génére une sortie et celle
terminée par deux points ( : ) n’en génére pas.
Le : ou ; est un séparateur d’ instructions.
Le ; génére une sortie alors que le : n’en génére
pas.
: indique la fin d’une instruction. Il faut noter qu’à chaque passage à la ligne le : est mis automatiquement.
L’affectation est utilisée pour stocker une valeur ou une expression dans une variable.
En algorithmique on écrira par exemple :
3=>A
2*A=>B
pour stocker 3 dans A, 2*A (c’est à dire 6) dans B
Avec Xcas on écrira :
a:=3;
b:=2*a;
ou encore
3=>a;
2*a=>b;
pour stocker 3 dans a, 2*a (c’est à dire 6) dans b
En tapant le nom d’une variable dans Xcas on peut voir le contenu de
cette variable. Si on tape le nom d’une fonction, on verra la définition de
la fonction.
Attention
On peut écrire :
(a,b):=(1,2) ou (a,b):=[1,2] ou [a,b]:=[1,2]
ou [a,b]:=(1,2) qui est équivalent à a:=1;b:=2
c’est à dire ici à a:=1;b:=2 mais
a:=1;b:=2; (a,b):=(a+b,a-b) est équivalent à
c:=a;a:=a+b;b:=c-b donc ici à a:=3;b:=-1
Donc si on tape :
(a,b):=(1,2);(a,b):=(a+b,a-b)
On obtient :
3 dans a et -1 dans b
Donc si on tape :
a:=1;(a,b):=(2,a)
On obtient :
2 dans a et 1 dans b
mais purge(a);(a,b):=(2,a)
On obtient :
2 dans a et 2 dans b
Donc méfiance ....et utiliser (a,b):=(b,a) qu’avec prudence !
Avec Maple on écrit :
b:=2*a pour stocker 2*a dans b.
Avec MuPAD on écrit :
b:=2*a pour stocker 2*a dans b.
On écrit 2*A=>B pour stocker 2*A dans B.
L’affectation := est utilisée pour stocker une valeur ou une
expression dans une variable. Mais lorsque Xcas réalise cette
affectation il effectue une recopie de la valeur dans la variable ce qui peut
être long lorsqu’il s’agit d’une liste de grande taille. C’est pourquoi
quand la variable contient une liste, avec Xcas, il faut utiliser
l’opérateur infixé =< qui stocke par référence le deuxième
argument dans la variable donnée en premier argument.
On tape par exemple :
L=<makelist(x->x^
2,0,10000):;
puis, par exemple :
for(j:=0;j<=1000;j++) L[10*j]=<0
L’instruction assume ou supposons permet de faire une hypothèse sur une variable formelle par exemple d’attribuer une valeur à une variable pour faire une figure, tout en laissant cette variable reste formelle lorsqu’on l’utilise pour faire des calculs ou encore de supposer que n est une v ariable entère ce qui permet de simplifier certaines expressions comme cos(n*pi)....
En algorithmique on écrira par exemple :
supposons(n,entier)
supposons(a>2)
supposons(a=2)
Avec Xcas on écrira :
assume(n,integer); ou supposons(n,integer);
puis par exemple cos(n*pi) et on obtient (-1)^
n
assume(a>2);
On peut faire plusieurs hypothèses sur une variable avec assume et
additionally par exemple, pour dire que n est un entier plus grand
que 3, on tape :
assume(n,integer);additionally(n>3);
Il faut noter que si on écrit dans l’écran de géométrie:
assume(a=2); ou supposons(a=2);
ou encore
assume(a:=2); ou supposons(a:=2);
cela a pour effet de mettre en haut et à droite un curseur noté a.
En effet, cela veut dire que l’on va faire
une figure de géométrie en donnant à a la valeur 2, mais que
les différents calculs se feront avec a formelle. Bien sur la valeur
donnée à a pourra être modifièe à l’aide du curseur et ainsi
modifier la figure selon les valeurs de a.
Avec Maple on écrit :
assume(n,integer);
assume(a>2);
Avec MuPAD on écrit :
assume(n,integer);
assume(a>2);
Il n’y a pas d’hypothèse en mode TI.
En algorithmique on écrira par exemple :
domaine(A)
Avec Xcas on écrira :
about(a) ou domaine(a)
assume(a) ou supposons(a)
Avec Maple on écrit :
about(a) ou domaine(a)
assume(a)
Avec MuPAD on écrit :
getprop(a)
Il n’y a pas d’hypothèse en mode TI.
si condition alors
action
fsi
si condition alors
action1 sinon
action2
fsi
Exemple :
si A = 10 ou A < B alors B-A=>B sinon A-B=>A fsi
if (condition) {action;}
ou encore
if (condition) then action; end
ou encore
si (condition) alors action; fsi
et
if (condition) {
action1;
} else {
action2;
}
ou encore
if (condition) then
action1;
else
action2;
end
ou encore
si (condition) alors
action1;
sinon
action2;
fsi
Exemples
if ((a==10) or (a<b)) {b:=b-a;} else {a:=a-b;}
essaiif(a,b):={ if ((a==10) or (a<b)) { b:=b-a; } else { a:=a-b; } return([a,b]); }; essaisi(a,b):={ si ((a==10) or (a<b)) alors b:=b-a; sinon a:=a-b; fsi; return([a,b]); }; idivsi(a,b):={ local (q:=0),(r:=a); if (b!=0){ q:=iquo(a,b); r:=irem(a,b); } return([q,r]); }; idivsi(a,b):={ local (q:=0),(r:=a); si (b!=0) alors q:=iquo(a,b); r:=irem(a,b); fsi return([q,r]); };
Avec Xcas, lorsqu’il y a plusieurs if...else if... à la suite
on peut aussi utiliser un elif qui est une écriture
condensée de else if et se traduit par :
if (condition1) then
action1;
elif (condition2) then
action2;
elif (condition3) then
action3;
end
ou bien
if (condition) then
action1;
elif (condition) then
action2;
elif (condition) then
action3;
else
action4;
end
Exemples
s(a):={ local r; if a>=10 then r:=5; elif a>=8 then r:=4; elif a>=6 then r:=3; elif a>=4 then r:=2 else r:=1; end; return r; }
Avec Xcas, on peut aussi utiliser un "case" lorsque les différentes
instructions à effectuer correspondantes à la valeur d’une expression qui
doit être une valeur entière et qui se traduit par :
switch (<nom_de_variable>){ case val_de_la_variable : { ..... break; } case val_de_la_variable : { ..... break; } default : { ... } }
Exemple :
s(a):={ local r; switch(a) { case 1 :{ r:=1; break; } case 2 :{ r:=-1; break; } default :{ r:=0; } } return r; }
si ... alors
if <condition>
then <action>
fi;
si ... alors ... sinon ...
if <condition>
then <action1>
else <action2>
fi;
Le schéma général à n cas :
if <condition_1> then <action_1>
elif <condition_2> then <action_2>
... elif <condition_n-1> then <action_n-1> else <action_n> fi ;
if <condition>
then
<action>
end_if
if <condition> then
<action1> else
<action2>
end_if
Exemple :
if a = 10 or A < B then b:=b-a else a:=a-b end_if
Lorsque il y a plusiuers if else à la suite on écrit elif au
lieu de else if.
Si ..alors
:If condition Then :
action :
EndIf
Si..alors sinon
:If condition Then :
action1 : Else :
action2:
EndIf
Exemple :
:If A = 10 or A < B Then : B-A=>B : Else : A-B=>A : EndIf
On utilise l’instruction "pour" lorsqu’on connait le nombre de fois que l’on doit effectuer les instructions ("pour" peut aussi servir à faire des boucles complètement génériques).
pour I de A jusque B faire action fpour
pour I de A jusque B (pas P) faire action fpour
Attention si vous avez coché pas de test de i dans la
configuration generale, on ne doit pas employer la variable i
car i represente le nombre complexe de module 1 et d’argument π/2.
for (j:=1;j<=b;j:=j+1) {action;} ou encore
for (j:=1;j<=b;j:=j++) {action;}
ou encore
pour j de 1 jusque b faire action; fpour
et
for (j:=1;j<=b;j:=j+p) {action;}
ou encore
pour j de 1 jusque b pas p faire action; fpour
Exemples
essaifor(a,b):={ local s:=0; for (j:=a;j<b+1;j++){ s:=s+1/j^2; } return(s); }; essaiford(a,b):={ local s:=0; for (j:=b;j>a-1;j--){ s:=s+1/j^2; } return(s); };
Voici la syntaxe exacte :
for <nom> from <expr> by <expr> to <expr>
do <action> od ;
Par exemple
for i from 1 to n do
<action:>
od
for i from 1 by p to n do
<action:>
od
for i from a to b do <action> end_for
for i from b downto a do <action> end_for
for i from a to b step p do <action> end_for
Vous pouvez aussi ouvrir le menu MuPAD sous menu Shapes et
séléctionner for.
:For I,A,B : action : EndFor
:For I,A,B,P : action : EndFor
On effectue les instructions tant que la condition est vraie :
on teste la condition si elle est fausse on s’arrête (arret=
(condition =fausse)) sinon on effectue les instructions etc ...
On arrête la boucle quand la condition devient fausse c’est à dire :
tantque (non arret) on effectue les instructions.
tantque condition faire
action
ftantque
while (condition) {
action;
}
ou encore
tantque (condition) faire
action;
ftantque
Exemple
essaiwhile(a,b):={ while ((a==10) or (a<b)) { b:=b-a; } return([a,b]); };
while <condition> do <action> od:
while <condition> do
<action>
end_while
Vous pouvez aussi ouvrir le menu MuPAD sous menu Shapes et
séléctionner while.
:While condition :action :EndWhile
On répéte les instructions jusqu’à ce que la condition devienne vraie. On fait les instructions (les instructions se font donc au moins une fois) puis on teste la condition si elle est vraie on s’arrête (arret= (condition=vraie)) sinon on effectue les instructions etc ...On arrête la boucle quand la condition devient vraie.
repeter
action
jusqua condition
repeat
action
until (condition)
ou encore
repeter
action
jusqua (condition)
L’instruction "repeter" est traduite en :
while (true){
action;
if (condition) break;
}
cette traduction reste invisible à l’utilisateur (tant qu’il n’exécute pas
son programme au débugueur).
Pas de schéma "repeter" en MapleV, on utilise une
boucle infinie et un break
do action if condition then break; fi; od;
repeat
action
until condition
end_repeat
Pas de schéma "repeter" chez TI, on utilise une
boucle infinie et un Exit
:Loop :action :If (condition) :Exit :Endloop
Une condition est une fonction qui a comme valeur un booléen, à savoir elle est soit vraie soit fausse.
Pour exprimer une condition simple on utilise en algorithmique
les opérateurs :
= > < ≤ ≥ ≠
Ces opérateurs se traduisent pour Xcas par :
== > < <= >= !=
Attention pour Xcas l’égalité se traduit comme en langage C par : ==
Ces opérateurs se traduisent pour MapleV, MuPAD et TI89/92 par :
= > < <= >= <>
Pour traduire des conditions complexes, on utilise en algorithmique,
les opérateurs logiques :
ou et non
Pour Xcas, ces opérateurs se traduisent par :
or and not ou encore par ∥ && !
Pour MapleV, MuPAD et TI89/92, ces opérateurs se
traduisent par :
or and not
Dans une fonction on ne fait pas de saisie de données :
on utilise des paramètres qui seront initialisés lors de l’appel.
Les entrées se font donc par passage de paramètres.
Dans une fonction on veut pouvoir réutiliser le résultat :
en algorithmique, c’est la commande retourne qui renvoie la valeur de la
fonction.
Si la fonction est utilisée seule, sa valeur sera affichée et si la
fonction est utilisée dans une expression sa valeur sera utilisée pour calculer cette expression.
On écrit par exemple en algorithmique :
fonction addition(A,B) retourne A+B ffonction
Cela signifie que :
- Si on fait exécuter la fonction, ce qui se trouve juste après
retourne sera la valeur de la fonction, mais les instructions qui
suivent retourne seront ignorées (retourne fait sortir
immédiatement de la fonction).
- On peut utiliser la fonction dans une expression ou directement dans la
ligne de commande et, dans ce cas, sa valeur sera affichée.
Xcas utilise return ou retourne.
addition(a,b):={ return(a+b); }
Remarques :
addition(a,b):=a+b;
mini1(a,b):={ si(a>b) alors return b sinon return a; fsi }soit avec 2 instructions
mini2(a,b):={ si(a>b) alors return b; fsi return a; }
retourne se traduit par RETURN
addition:= proc(a,b) RETURN(a+b); end:
Remarque
RETURN fait sortir immédiatement de la fonction.
retourne se traduit MuPAD par return :
addition:=proc(a,b) begin return(a+b) end_proc;
Remarque
return fait sortir immédiatement de la fonction.
:addition(a,b) :Func :Return a+b :EndFunc
Remarque
Return fait sortir immédiatement de la fonction.
On utilise les { } pour délimiter une liste.
Attention!!!
En algorithmique, on a choisi cette notation car c’est celle qui est employée
par les calculatrices...à ne pas confondre avec la notion d’ensemble en
mathématiques : dans un ensemble l’ordre des éléments n’a pas
d’importance mais dans une liste l’ordre est important...
Par exemple {} désigne la liste vide et {1, 2, 3} est une liste de 3 éléments.
concat sera utilisé pour concaténer 2 listes ou une liste et un
élément ou un élément et une liste :
{1, 2, 3}=>TAB
concat(TAB,4)=>TAB (maintenant TAB désigne {1, 2, 3, 4}
TAB[2] désigne le deuxième élément de TAB ici 2.
Avec Xcas il existe différentes notions : la liste ou le vecteur, la séquence et l’ensemble.
La liste vide est désignée par [ ] et la séquence vide par NULL.
La commande makelist permet de fabriquer une liste à
partir d’une fonction f. Les paramètres sont : la fonction, l’intervalle de variation de l’argument de f et le pas de son incrémentation.
On tape :
f(x):=x2
l:=makelist(f,2,10,3) ou encore
l:=makelist(x->x2,2,10,3) ou encore
l:=makelist(x->x2,2..10,3) ou encore
l:=makelist(sq,2,10,3)
On obtient l= [4,25,64]
Pour avoir une liste constante on peut taper par exemple :
l:=makelist(3,1..5) on obtient l= [3,3,3,3,3]]
On peut écrire l:=[1,2,3].
Attention Les éléments sont indicés à partir de zéro (contrairement
à Maple ou MuPAD qui commencent les indices à 1):
dans l’exemple l[0] vaut 1.
Si on tape ensuite :
l[0]:=4 : après cette instruction l sera la liste [4,2,3].
La commande append(l,elem) permet de mettre à la fin
d’une liste l,
un élément (ou une liste) elem.
La commande prepend(l,elem) permet de mettre au début d’une liste l,
un élément (ou une liste) elem.
La commande tail(l) renvoie la liste l privée de son premier élément et,
la commande head(l) renvoie le premier élément de la liste.
La commande concat permet de concaténer deux listes ou une liste et un élément.
La commande augment permet de concaténer deux listes.
La commande size ou nops renvoie la longueur d’une liste ou d’une séquence.
La commande op transforme une liste en une séquence.
On a la relation :
si l est une liste op(l) est une séquence.
Exemple
l:=[1,2,3]
s:=op(l) (s est la séquence 1,2,3),
a:=[s] (a est la liste l égale à [1,2,3]),
Pour concaténer deux séquences il suffit d’écrire :
s1:=(1,2,3)
s:=(s1,4,5)
ou encore
s:=s1,4,5 car la virgule (,) est prioritaire par rapport
à l’affectation (:=).
La commande seq permet de fabriquer une séquence à
partir d’une expression. Les paramètres sont : l’expression,
la variable=l’intervalle de variation (le pas d’incrémentation de la
variable est toujours 1).
On tape :
seq(j^
2,j=1..4)
On obtient ;
(1,4,9,16)
On peut aussi utiliser $
qui est une fonction infixée.
On tape :
(j^
2) $ (j=1..4)
On obtient ;
(1,4,9,16)
Soit A:=set[1,2,3,4]; B:=set[3,4,4,6];
union(A,B) désigne l’union de A et B,
intersect(A,B) désigne l’intersection de A et B,
minus(A,B) désigne la différence de A et B.
On a :
union(A,B)=set[1,2,3,4,5,6]
intersect(A,B)=set[3,4]
minus(A,B)=set[1,2]
En Maple on utilise { }, comme en mathématiques, pour représenter un ensemble.
Exemple : De := {1, 2, 3, 4, 5, 6}
Dans un ensemble, l’ordre n’a pas d’importance. La répétition est
interdite.
Pour délimiter une liste, on utilise [ ].
L’ordre est pris en compte, la répétition est possible.
Exemple : [Pile, Face, Pile]
Une séquence est une suite d’objets, séparés par une virgule.
Si C est un ensemble ou une liste, op(C) est la séquence des
objets de C.
nops(C) est le nombre d’éléments de C.
Ainsi, si L est une liste, {op(L)} est l’ensemble des objets
(non répétés) de L.
Exemples
On écrit :
S:=NULL: (pour la séquence vide)
S:=S,A: (pour ajouter un élément à S)
Une liste est une séquence entourée de crochets :
L:=[S]:
L[i] est le iéme élément de la liste L.
On peut aussi revenir à la séquence :
S:=op(L):
Une liste est une suite d’expressions entre un crochet ouvrant [ et un crochet
fermant ].
[ ] désigne la liste vide.
Exemple :
l:=[1,2,2,3]
nops(l) renvoie le nombre d’éléments de la liste l.
l[1] ou op(l,1) renvoie le premier élément de la liste l : les
éléments sont numérotés de 1 à nops(l).
op(l) renvoie 1,2,2,3
append(l,4) ajoute l’élément 4 à la fin de la liste l.
De plus, les listes peuvent être concaténées avec le signe .
(un point), par exemple [1,2].[2,3]=[1,2,2,3].
Attention une suite d’expressions entre une accolade ouvrante { et une
accolade fermante } désigne un ensemble.
Exemple d’ensembles et de fonctions agissant sur les ensembles :
A:={a,b,c}; B:={a,d}
A union B désigne {a,b,c,d}
A intersect B désigne {a}
A minus B désigne {b,c}
augment permet de concaténer deux listes.
{} désigne la liste vide.
Pour travailler avec des listes, on peut initialiser une liste de
n éléments avec la commande newlist, par exemple :
newlist(10)=>L (L est alors une liste de 10 éléments nuls).
On peut utiliser les commandes suivantes :
seq(i*i, i, 1, 10) qui désigne la liste des carrés des 10 premiers entiers, ou seq(i*i, i, 0, 10, 2) qui désigne la liste des carrés des 5 premiers entiers pairs (le pas est ici égal à 2).
Exemple :
seq(i*i, i, 0, 10, 2) =>L va par exemple créer la liste :
{0, 4, 16, 36, 64, 100} c’est à dire la liste des carrés de 0 à 10
avec un pas de 2 que l’on stocke dans L.
L[j] qui désigne le jème élément de la liste L.
On peut aussi écrire :
2=>L[2]
La liste L est alors {0, 2, 16, 36, 64, 100}
ou si L est de longueur n on peut rajouter un élément (par
exemple 121) à L en écrivant :
121 => L[n+1]
Dans l’exemple précédent n=6 on peut donc écrire :
121 => L[7] (L est alors égale à {0, 2, 16, 36, 64, 100, 121}).
left (L, 5) désigne les 5 premiers éléments de la liste L.
Pour trouver les nombres premiers inférieurs ou égaux à N :
Fonction crible(N) local TAB PREM I P // TAB et PREM sont des listes {} =>TAB {} =>PREM //on suppose que les indices d'une liste debutent par 0 //si ils commencent par 1, mettre pour I de 1 a N pour I de 0 a N faire concat(TAB, I) => TAB fpour //On met 0 dans TAB[1] car 1 n'est pas premier //barrer 1 a ete realise en le remplacant par 0 0 => TAB[1] //TAB est la liste 0 0 2 3 4 ...N 2 => P // On a fait les points 1 et 2 tantque P*P <= N faire pour I de P a E(N/P) faire //E(N/P) designe la partie entiere de N/P 0 => TAB[I*P] fpour // On a barre tous les multiples de P a partir de P*P P+1 => P //On cherche le plus petit nombre <= N non barre (non nul) // entre P et N tantque (P*P <= N) et (TAB[P]=0) faire P+1 => P ftantque ftantque //on ecrit le resultat dans une liste PREM pour I de 2 a N faire si TAB[I]!= 0 alors concat(PREM, I) => PREM fsi fpour retourne PREM
//renvoie la liste des nombres premiers<=n selon eratosthene crible(n):={ local tab,prem,p,j; tab:=[0,0]; prem:=[]; for (j:=2;j<=n;j++){ tab:=append(tab,j); } p:=2; while (p*p<=n) { for (j:=p;j*p<=n;j++){ tab[eval(j*p)]:=0; } p:=p+1; while ((p*p<=n) and (tab[p]==0)) { p:=p+1; } } for (j:=2;j<=n;j++) { if (tab[j]!=0) { prem:=append(prem,j); } } return(prem); };
ou avec les instructions françaises
//renvoie la liste des nombres premiers<=n selon eratosthene crible(n):={ local tab,prem,p,j; [0,0]=>tab; []=>prem; pour j de 2 jusque n faire append(tab,j)=>tab; fpour; 2=>p; tantque (p*p<=n) faire pour j de p jusque n/p faire 0=>tab[eval(j*p)]; fpour p+1=>p; tantque ((p*p<=n) et (tab[p]==0)) faire p+1=>p; ftantque; ftantque; pour j de 2 jusque n faire si (tab[j]!=0) alors append(prem,j)=>prem; fsi fpour retourne(prem); };
Voici la fonction crible :
- n est le paramètre de cette fonction.
- crible(n) est égal à la liste des nombres premiers inférieurs ou
égaux à n.
:crible(n) :Func :local tab,prem,i,p :newList(n)=>tab :newList(n)=>prem :seq(i,i,1,n) =>tab :0 => tab[1] :2 => p :While p*p <= n :For i,p,floor(n/p) :0 => tab[i*p] :EndFor :p+1 => p :While p*p<= n and tab[p]=0 :p+1 => p :EndWhile :EndWhile :0 => p :For i,2,n :If tab[i]!= 0 Then :p+1 =>p :i =>prem[p] :EndIf :EndFor :Return left(prem,p) :EndFunc
Voici la définition de la fonction a dite fonction de ackermann
qui est une fonction de
ℕ×ℕ dans ℕ :
a(0,y)=y+1, a(x,0)=a(x-1,1) si x>0, a(x,y)=a(x-1,a(x,y-1) si x>0 et si y>0.
Ainsi on a :
a(0,0)=1
a(1,0)=a(0,1)=2
a(1,1)=a(0,a(1,0))=a(0,2)=3
a(1,2)=a(0,a(1,1))=4
a(1,n)=a(0,a(1,n-1))=1+a(1,n-1)=...=n+2
a(2,0)=a(1,1)=3
a(2,1)=a(1,a(2,0))=a(1,3)=5
a(2,2)=a(1,a(2,1))=2+a(2,1)=7
a(2,n)=a(1,a(2,n-1))=2+a(2,n-1)=2n+3
a(3,0)=a(2,1)=5
a(3,1)=a(2,a(3,0))=2*a(3,0)+3=13
a(3,2)=a(2,a(3,1))=2*a(3,1)+3=29
a(3,n)=a(2,a(3,n-1))=2*a(3,n-1)+3
=2^
(n+1)+3*(2^
n+2^
(n-1)...+1)
=2^
(n+1)+3*(2^
(n+1)-1)=
2^
(n+3)-3
On a donc par exemple : a(3,5)=2^
8-3=253
Les calculs sont vite gigantesques on a par exemple :
a(4,1)=a(3,a(4,0))=a(3,a(3,1))=a(3,13)=65533
a(4,2)=a(3,a(4,1))=a(3,65533)=2^
65536-3
a(4,3)=a(3,a(4,2))=a(3,2^
65533-3)=2^
(2^
65536-3)-3
On a donc :
a(4,y)=a(3,a(4,y-1))=2^
(a(4,y-1)+3)-3
=2^
(2^
(a(4,y-2)+3)-3+3)-3=2^
(2^
(a(4,y-2)+3))-3
et donc
a(4,y)=2^
(2^
..(2^
(a(4,0)+3))..)-3=
2^
(2^
..(2^
16)..)-3,
avec 2^
qui se répète y fois, et comme
16=2^
(2^
2) on a,
a(4,y)=2^
(2^
..(2^
2)..)-3,
avec 2 qui se répète y+3 fois.
Voici un premier programme :
akc(x,y):={ if (x==0) return y+1; if (y==0) return akc(x-1,1); return ack(x-1,ack(x,y-1)); }
ou bien en utilisant ifte :
ack(x,y):=ifte(x==0,y+1, ifte(y==0,ack(x-1,1),ack(x-1,ack(x,y-1))));
On remarque que le temps pour calculer la valeur pour a(3,5) est de 5.06s
ce qui est tres long, mais on peut donc améliorer le programme en arrêtant
la récursivité lorsque x==3.
On écrit :
a(x,y):={ if (x==0) return y+1; if (x==1) return y+2; if (x==2) return 2*y+1; if (x==3) return 2^(y+3)-3; if (y==0) return a(x-1,1); return a(x-1,a(x,y-1)); }
On peut aussi améliorer le programme en arrêtant
la récursivité lorsque x==4.
On écrit :
a(x,y):={ if (x==0) return y+1; if (x==1) return y+2; if (x==2) return 2*y+1; if (x==3) return 2^(y+3)-3; if (x==4) { local p:=1; for (j:=1;j<=y+3;j++) p:=2^p; return p-3; } if (y==0) return a(x-1,1); return a(x-1,a(x,y-1)); }
Essayez a(4,1)=65533, a(4,2)....