Les instructions copy et =< dans un programme

### 9.4.16 Les instructions copy et =< dans un programme

=< est surtout utile quand on fait beaucoup de modifications dans une liste ou matrice de grande taille, par exemple dans un programme. Mais attention, il faudra utiliser copy lors de l’initialisation des variables listes ou matrices qui seront modifiées avec =< pour que les modifications se fassent sur la copie.
Voir aussi 2.5.3 et 9.4.15.
Attention
Dans un programme si on met :

    local a;
    a:=[0,1,2,3,4];
    ...
    a[3] =< 33;

Cela modifie le programme lui-même et la ligne a:=[0,1,2,3,4]; est remplacée par a:=[0,1,2,33,4]; dans le programme compilé.
Donc dans un programme il faut écrire :

    local a;
    a:=copy([0,1,2,3,4]);
    ...
    a[3] =< 33;

ou

    local a,c;
    c:=[0,1,2,3,4];
    a:=copy(c);
    ...
    a[3] =< 33;

pour que ce soit la copie de [0,1,2,3,4] qui soit modifiée et non la liste [0,1,2,3,4] elle-même.

Remarque
On peut aussi utiliser les commandes makelist, seq, range ou $, par exemple :
a:=makelist(n,n,0,4); ou
a:=[n$(n=0..4)]; ou
a:=range(5); puis
a[3] =< 33; car makelist(n,n,0,4) ou [n$(n=0..4)] est une liste qui va se créer à chaque exécution du programme.

Exemple
On veut écrire un programme qui renvoie les nombres entiers inférieurs ou égaux à n et dont la somme des chiffres (en base 10) vaut 5. On tape :

    somme5(n):={
    local L,j,k;
    L:=seq(0,0);
    k:=0;
    for(j:=0;j<=n;j++){
    if (sum(convert(j,base,10))==5){
    L[k]=<j;
    k:=k+1;
    }
    }
    return L;
    }:;

On tape :

somme5(50)

On obtient :

5,14,23,32,41,50

Dans cet exemple, il faut bien comprendre et faire l’initialisation de L correctement.
Dans ce programme, on a choisit d’avoir le résultat sous la forme d’une séquence, et on a initialisé L avec L:=seq(0,0). Si on avait mis L:=NULL, le programme n’aurait pas fonctionné correctement ! En effet, si on tape :

    fauxsom5(n):={
    local L,j,k;
    L:=NULL;
    k:=0;
    for(j:=0;j<=n;j++){
    if (sum(convert(j,base,10))==5){
    L[k]=<j;
    k:=k+1;
    }
    }
    return L;
    }:;

puis :

fauxsom5(30)

on obtient :

5,14,23,32,41,50

Cela semble juste..... Mais, lors de l’exécution de fauxsom5(50), au départ L pointe sur la séquence NULL, puis cette séquence NULL est modifiée et devient à la fin du programme 5,14,23,32,41,50 et le programme, si on ne le recompile pas, a lui aussi été modifié est est devenu

    fauxsom5(n):={
    local L,j,k;
    L:=5,14,23,32,41,50;
    k:=0;
    for(j:=0;j<=n;j++){
    if (sum(convert(j,base,10))==5){
    L[k]=<j;
    k:=k+1;
    }
    }
    return L;
    }:;

Si on tape maintenant :

fauxsom5(30)

On obtient une séquence trop longue :

5,14,23,32,41,50

alors que si on tape :

somme5(30)

On obtient :

5,14,23

Régle
Dans un programme, si on veut utiliser =< pour modifier une liste L ou une séquence LL, il faut faire attention à l’initialisation.
Par exemple, pour initialiser

- L à la liste vide, on tape :
  L:=[seq(0,0)] ou L:=[0$0] ou L:=copy([]) car [seq(0,0)] ou [0$0] désigne une liste qui va se créer à chaque exécution du programme.
- LL à la séquence NULL, on tape :
  LL:=seq(0,0)] ou LL:=0$0 ou LL:=copy(NULL) car seq(0,0) ou 0$0 désigne une séquence qui va se créer à chaque exécution du programme.

Il faut donc utiliser =< avec précautions car tous les objets pointant sur cette matrice seront modifiés.