Vue d’ensemble de Xcas pour le programmeur

# Chapitre 1 Vue d’ensemble de Xcas pour le programmeur

## 1.1 Installation de Xcas

Le programme `Xcas` est un logiciel libre écrit en C++, (disponible sous licence GPL). La version à jour se récupère sur :
http://www-fourier.ujf-grenoble.fr/ parisse/giac_fr.html ou
ftp://fourier.ujf-grenoble.fr/xcas
où l’on trouve le code source (`giac.tgz`) ou des versions précompilées pour Linux (PC ou ARM), Windows, Mac OS.

## 1.2 Les différents modes

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.

## 1.3 Éditer, sauver, exécuter un programme avec la syntaxe Xcas

On édite un programme ou un script (i.e. une suite de commandes séparées par des ;) avec son éditeur préféré : on peut écrire, dans un même fichier, la définition de plusieurs fonctions séparées par des points virgules (;) (que l’on sauve par exemple sous le nom de bidon), puis dans Xcas on tape :read("bidon"); et cela a pour effet, de compiler les différentes fonctions de bidon, de les mettre comme réponse (avec Success.. dans la zone des résultats intermédiaires pour indiquer les fonctions valides).
En reéditant le programme, ou le script, avec son éditeur préféré, on peut le corriger, le sauver sous un autre nom etc..., mais il est préférable de le recopier dans un niveau éditeur de programmes (que l’on ouvre avec Alt+p) pour cela on peut :

- soit écrire directement le programme (ou le script), dans un niveau éditeur de programmes,
- soit utiliser le menu Fich sous-menu Charger de l’éditeur de programmes, si le programme est dans un fichier,
- soit le recopier avec la souris, si le programme est dans la ligne de commande (par exemple après avoir fait Charger du menu Fich de la session) ou si le programme est dans son éditeur préféré,

En effet, depuis un niveau éditeur de programmes, on peut :

- avoir de l’aide sur les commandes de Xcas : il suffit d’écrire la commande et d’appuyer sur la touche F1 de vôtre ordinateur,
- indenter facilement : il suffit d’appuyer sur la touche de tabulation de vôtre ordinateur,
- tester facilement si le programme est syntaxiquement correct : il suffit d’appuyer sur le bouton OK de la barre des menus ou sur la touche F9 de vôtre ordinateur: la ligne où se trouve la faute de syntaxe est indiquée en bleu dans la zone intermédiaire.

On corrige les fautes si il y en a...

- Quand le script est syntaxiquement correct, en appuyant sur le bouton OK ou la touche F9 le script s’exécute et on obtient le résultat de l’exécution si on n’a pas terminé son écriture par :; ou Done si on a terminé l’écriture du programme par :;
  Exemple On tape dans l’éditeur :
  S:=0;for (j:=1;j<5;j++) {print(S);S:=S+1/j;} On obtient dans la zone intermédiaire :
  S:0
  S:1
  S:3/2
  S:11/6
  et en réponse : (0,25/12)
- Quand le programme est syntaxiquement correct, en appuyant sur le bouton OK ou la touche F9 il y a Success compilling ... dans la zone intermédiaire et on a le programme en réponse ou Done si on a terminé l’écriture du programme par :;. On peut alors exécuter le programme dans une ligne de commande.

Vous sauvez le programme (ou le script) avec le bouton Save du niveau éditeur de programmes sous le nom que vous voulez lui donner en le terminant par le suffixe .cxx (ce nom s’inscrit alors à côté du bouton Save du niveau éditeur de programmes). Si ensuite, vous voulez lui donner un autre nom il faut le faire avec le menu Prog sous-menu Sauver comme de l’éditeur de programmes.

## 1.4 Débugger un programme avec la syntaxe Xcas

Pour utiliser le débuggeur, il faut que ce programme soit syntaxiquement correct : vous avez par exemple un programme syntaxiquement correct, mais qui ne fait pas ce qu’il devrait faire, il faut donc le corriger.

Avec le débuggeur, on a la possibilité d’exécuter le programme au pas à pas (sst), ou d’aller directement (cont) à une ligne précise marquée par un point d’arrêt (break), de voir (voir ou watch) les variables que l’on désire surveiller, d’exécuter au pas à pas les instructions d’une fonction utilisateur utilisée dans le programme (dans ou sst_in), ou de sortir brutalement du débuggeur (tuer ou kill).
On tape : debug(nom _du_programme(valeur_des_ arguments)).
Il faut bien sûr que le programme soit validé :

- si le programme est dans un niveau éditeur de programme, on appuie sur OK pour le compiler, on corrige les fautes de syntaxe éventuelles et on appuie sur OK jusqu’à obtenir Success compiling...
- si le programme qui est syntaxiquement correct se trouve dans un fichier, on tape : read("toto") si toto est le nom du fichier où se trouve ce programme.

Par exemple, si pgcd a été validé, on tape :
debug(pgcd(15,25))
L’écran du débugger s’ouvre : il est formé par trois écrans séparés par une ligne eval et une barre de boutons sst,dans,cont... :

1. dans l’écran du haut, le programme source est écrit et la ligne en surbrillance sera exécutée grâce au bouton sst.
2. dans la ligne eval, Xcas marque automatiquement l’action en cours par exemple sst. Cette ligne permet aussi de faire des calculs dans l’environnement du programme ou de modifier une variable, par exemple on peut y écrire a:=25 pour modifier la valeur de a en cours de programme,
3. dans l’écran du milieu, on trouve, le programme, les points d’arrêts, le numéro de la ligne du curseur.
4. une barre de boutons sst,dans,cont...
   - sst exécute la ligne courante (celle qui est en surbrillance) sans entrer dans les fonctions et met en surbrillance l’instruction suivante,
   - dans ou sst_in exécute la ligne courante (celle qui est en surbrillance) en entrant dans les fonctions utilisées dans le programme et qui ont été définies précédemment par l’utilisateur, puis met en surbrillance l’instruction suivante du programme en incluant les instructions de la fonction. Cela permet ainsi d’exécuter pas à pas les instructions de cette fonction.
   - cont exécute les instructions du programme situées entre la ligne courante et la ligne d’un point d’arrêt et met en surbrillance cette ligne,
   - tuer ou kill ferme brutalement l’écran du débuggeur.
     Attention il faut fermer l’écran du débuggeur pour pouvoir utiliser Xcas.
   - break ajoute un point d’arrêt. Les points d’arrêts permettent d’aller directement à un point précis avec le bouton cont. On marque les points d’arrêts grâce au bouton break ou à la commande breakpoint d’arguments le nom du programme et le numéro de la ligne où l’on veut un point d’arrêt : par exemple breakpoint(pgcd,3). Pour faciliter son utilisation, il suffit de cliquer dans l’écran du haut sur la ligne où l’on veut le point d’arrêt pour avoir : breakpoint dans la ligne eval, avec le nom du programme et le bon numéro de ligne, puis de valider la commande. Il suffit donc de cliquer et de valider !
   - rmbrk enlève un point d’arrêt. On doit, pour réutiliser d’autres points d’arrêts, d’effacer les points d’arrêts utilisés précédemment avec la commande rmbreakpoint qui a les mêmes arguments que breakpoint. Là encore, pour faciliter son utilisation, il suffit de cliquer sur la ligne où l’on veut enlever le point d’arrêt pour avoir : rmbreakpoint dans la ligne de commande, avec le nom du programme et le bon numéro de ligne. Attention si il n’y a pas de point d’arrêt à cet endroit Xcas en mettra un !
   - voir ou watch ajoute la variable que l’on veut voir évoluer. Si on ne se sert pas de voir ou watch toutes les variables locales et tous les arguments du programme sont montrées. Si on se sert de voir ou watch seules les variables designées seront montrées : on appuie sur le bouton voir ou watch et la commande watch s’écrit dans la ligne d’évaluation eval. On tape alors, les arguments de watch qui sont les noms des variables que l’on veut surveiller, par exemple : watch(b,r) et on valide la commande.
   - rmwtch efface les variables désignées précédemment avec watch et que l’on ne veut plus voir, par exemple : rmwatch(r).
5. dans l’écran du bas, on voit soit l’évolution de toutes les variables locales et de tous les arguments du programme, soit l’évolution des variables désignées par watch.

## 1.5 Présentation générale des instructions avec la syntaxe Xcas

### 1.5.1 Les commentaires

Les commentaires sont des chaînes de caractères, ils sont précédés de `//` ou sont parenthésés par /* */

### 1.5.2 Le bloc

Une action ou bloc est une séquence d’une ou plusieurs instructions.
Quand il y a plusieurs instructions il faut les parenthéser avec { } et séparer les instructions par un point virgule (;)
Un bloc est donc parenthésé par { } et commence éventuellement par la déclaration des variables locales (local...).

### 1.5.3 Les variables globales et les variables locales

Voir aussi 2.2 Les variables sont les endroits où l’on peut stocker des valeurs, des nombres, des expressions, des objets.
Le nom des variables est formé par une suite de caractères et commence par une lettre : attention on n’a pas droit aux mots réservés ...ne pas utiliser par exemple la variable i dans un for si vous avez coché pas de test de i dans la configuration generale car i représente le nombre complexe de module 1 et d’argument π/2.
L’affectation se fait avec := (par exemple a:=2; b:=a;) ou avec => (par exemple 2=>a; a=>b;) .

#### Les variables locales non symboliques

Une variable utilisée uniquement à l’intérieur d’une fonction (resp d’un bloc) pour contenir des résultats intermédiaires est une variable locale à la fonction (resp au bloc). Les variables locales doivent être déclarées au début de la fonction (resp au début d’un bloc) par le mot réservé local puis on met les noms des variables séparés par des virgules (,).
Attention
Cette déclaration n’initialise pas ces variables locales à 0.

Les variables locales peuvent être initialisées lors de leur déclaration à une valeur en mettant les affectations entre parenthèses et separées par des virgules. Mais attention l’initialisation des variables locales faites dans la ligne de local se fait en utilisant le contexte global d’évaluation , par exemple :

    n:=5;
    f():={
      local (n:=1),(d:=n+1);
      return d;
    }

f() renvoie 6 et non 2 : c’est la valeur de n+1 ou n est global. Il faut initialiser d après la déclaration locale pour utiliser le contexte local en tapant :

    f():={
      local (n:=1),d;
      d:=n+1;
      return d;
    }

et alors f() renvoie 2.

#### Les variables locales symboliques

Attention Les variables locales ne sont pas affectèes lors de leur déclaration MAIS ce ne sont pas des variables formelles : il faut les obligatoirement les initialiser dans le corps du programme.
Si on veut utiliser dans un programme des variables formelles, on a 2 solutions :

- On considère les variables formelles du programme comme globales, MAIS alors il faut s’assurer que ces variables sont purgées avant l’exécution du programme...ce qui contraignant !
- On déclare les variables formelles du programme avec local (par exemple local x;), PUIS on utilise assume(x,symbol); pour spécifier que la variable x devient symmbolique ou on utilise purge(x) pour purger la variable x qui devient symmbolique. Ainsi au cours du programme, x pourra devenir non symbolique si on l’affecte, puis, redevenir symbolique après l’instruction assume(x,symbol); ou l’instruction purge(x).

Il est donc préférable de définir la variable formelle var, avec local var; suivi de assume(var,symbol); ou de purge(var).
Exemple
Voici le programme qui donne la valeur de la suite de Fibonnacci u définie par u0=u0,u1=u1,un+2=un+1+un.
On sait que si a et b sont les racines de x2−x−1, les suites vérifiant la relation de récurrence un+2=un+1+un sont des combinaisons linéaires des suites géométriques an et bn, c’est-à-dire que l’on a :

un=Aan+Bbn

pour A et B solutions du système [u0=A+B, u1=Aa+Bb].

Voici les deux façons de faire :

- les variables formelles sont globales,
  Dans le programme qui suit, on utilise les variables formelles x,A,B qui doivent être purgées et qui seront des variables globales.
  On tape :

      u(n,uo,u1):={
      local L,a,b;
      //verifier que A,B,x ne sont pas affect\'ees
      [a,b]:=solve(x^2-x-1,x);
      L:=linsolve([A+B=uo,A*a+B*b=u1],[A,B]);
      return normal(L[0]*a^n+L[1]*b^n);
      };

  Lors de la compliation, Xcas dit :
  //Warning: x A B declared as global variable(s)
  compiling u
  On tape :
  u(3,0,1)
  On obtient :
  2
- les variables formelles sont declarées locales,
  Dans le programme qui suit, on utilise les variables formelles A,B,x qui seront symboliques ou formelles grâce aux commandes :

      assume(A,symbol);
      assume(B,symbol);
      assume(x,symbol);

  ou à la commande purge(A,B,x).

  Remarque : pour retrouver des variables non formelles il suffira de les affecter.
  On tape :

      u(n,uo,u1):={
      local L,a,b,A,B,x;
      assume(A,symbol);
      assume(B,symbol);
      assume(x,symbol);
      [a,b]:=solve(x^2-x-1,x);
      L:=linsolve([A+B=uo,A*a+B*b=u1],[A,B]);
      return normal(L[0]*a^n+L[1]*b^n);
      };

  Ou on tape :

      u(n,uo,u1):={
      local L,a,b,A,B,x;
      purge(A,B,x);
      [a,b]:=solve(x^2-x-1,x);
      L:=linsolve([A+B=uo,A*a+B*b=u1],[A,B]);
      return normal(L[0]*a^n+L[1]*b^n);
      };

  Lors de la compliation, Xcas dit :
  // Success compiling u
  On tape :
  u(3,0,1)
  On obtient :
  2
  Pour bien comprendre ce qui se passe, on rajoute des print :

      u(n,uo,u1):={
      local L,a,b,A,B,x;
      print(A);
      assume(A,symbol);
      print(A);
      assume(B,symbol);
      assume(x,symbol);
      [a,b]:=solve(x^2-x-1,x);
      L:=linsolve([A+B=uo,A*a+B*b=u1],[A,B]);
      A:=5;
      print(A);
      return normal(L[0]*a^n+L[1]*b^n);
      };

  On tape :
  A:=30
  u(3,0,1)
  On obtient écrit en bleu :
  A:0 (A est locale et n’est pas symbolique et vaut 0)
  A:A (A est locale et symbolique)
  A:5 (A est locale etn’est pas symbolique et vaut 5)
  puis la réponse :
  2
  On tape :
  A
  On obtient :
  30 (la variable globale A n’est pas symbolique et vaut 30)

#### Variables locales internes à un bloc

Voici comme exemple le programme de la fonction qui donne le quotient et le reste de la division euclidienne de 2 entiers (c’est la fonction iquorem de Xcas) :

      idiv2(a,b):={
        local (q:=0),(r:=a);
        if (b!=0) {
          q:=iquo(a,b);
          r:=irem(a,b);
        }
        return [q,r];
      };

Voici le programme de la même fonction mais avec les variables locales internes au bloc du if :

      idiv2(a,b):={
        if (b==0) {return [b,a];}
        if (b!=0) {
          local q,r;
          q:=iquo(a,b);
          r:=irem(a,b);
          return [q,r];
        }
      };

ou encore avec les variables locales internes au bloc du else :

      idiv2(a,b):={
        if (b==0) {return [b,a];}
        else {
          local q,r;
          q:=iquo(a,b);
          r:=irem(a,b);
          return [q,r];
        }
      };

### 1.5.4 Les programmes et les fonctions

Les paramètres sont mis après le nom du programme ou de la fonction entre parenthèses (par exemple f(a,b):=...).
Ces paramètres sont initialisés lors de l’appel du programme ou de la fonction et se comportent comme des variables locales.

L’affectation se fait avec := (par exemple a:=2; b:=a;) ou se fait avec => (par exemple 2=>a; a=>b;).

Les entrées se font par passage de paramètres ou avec input.
Les sorties se font en mettant le nom de la variable à afficher (ou la séquence des variables à afficher ou entre crochets les variables à afficher séparées par une virgule) précedé du mot réservé print.
Il n’y a pas de distinction entre programme et fonction : la valeur d’une fonction est précedée du mot réservé return.
Remarque return n’est pas obligatoire car Xcas renvoie toujours la valeur de la dernière instruction, mais return est très utile car il fait sortir de la fonction : les instructions situèes après return ne sont jamais effectuées.

### 1.5.5 Les tests

Avec le langage Xcas les tests ont soit une syntaxe similaire au langage C++ soit une version française proche du langage algorithmique.
Pour les tests, les syntaxes admises sont :

- if (condition) instruction;
  on met {..} lorsqu’il faut faire plusieurs instructions :
  if (condition) {instructions}
  ou
  si condition alors instructions fsi
  on teste la condition : si elle est vraie, on fait les instructions et si elle est fausse on ne fait rien c’est à dire on passe aux instructions qui suivent le if ou le si.
  Par exemple :

      testif1(a,b):={
      if  (a<b)
          b:=b-a;
      return [a,b];
      };

  ou

      testsi1(a,b):={
      si a<b alors
          b:=b-a;
      fsi;
      return [a,b];
      };

  et on a :
  testif1(3,13)=testsi1(3,13)=[3,10]
  testif1(13,3)=testsi1(13,3)=[13,3]
- if (condition) instruction1; else instruction2;
  on met {..} lorsqu’il faut faire plusieurs instructions :
  if (condition) {instructions1} else {instructions2}
  ou
  si condition alors instructions1 sinon instructions2 fsi
  on teste la condition : si elle est vraie, on fait les instructions1 et si elle est fausse on fait les instructions2.
  Par exemple :

      testif(a,b):={
      if (a==10 or a<b)
          b:=b-a;
      else
          a:=a-b;
      return [a,b];
      };

  ou

      testsi(a,b):={
      si a==10 or a<b alors
          b:=b-a;
      sinon
          a:=a-b;
      fsi;
      return [a,b];
      };

  et on a :
  testif(3,13)=testsi(3,13)=[3,10]
  testif(13,3)=testsi(13,3)=[10,3]
  testif(10,3)=testsi(10,3)=[10,-7]

### 1.5.6 Les boucles

Avec le langage Xcas les boucles ont soit une syntaxe similaire au langage C++ soit une version française proche du langage algorithmique.
La commande break permet de sortir d’une boucle.
Si vous avez fait une boucle infinie, il faut appuyer sur STOP pour arrêter votre programme (ou sur Shift+STOP si plusieurs sessions travaillent en parallèle).
Pour les boucles, les syntaxes admises sont :

- la boucle for ou pour qui permet de faire des instructions un nombre de fois qui est connu :
  for (init;condition;increment) instruction;
  on met {..} lorsqu’il faut faire plusieurs instructions :
  for (init;condition;increment) {instructions}
  Le plus souvent (init;condition;increment) s’écrit en utilisant une variable (par exemple j ou k...mais pas i qui désigne un nombre complexe, si vous avez coché pas de test de i dans la configuration generale). Cette variable sera initialisée dans init, utilisée dans condition et incrementée dans increment, on écrit par exemple :
  (j:=1;j<=10;j++) (l’increment ou le pas est de 1) ou
  (j:=10;j>=1;j–) (l’increment ou le pas est de -1) ou
  (j:=1;j<=10;j:=j+2) (l’increment ou le pas est de 2)
  ou
  pour j de 1 jusque 10 faire instructions fpour;
  ou
  pour j de 10 jusque 1 pas -1 faire instructions fpour;
  ou
  pour j de 1 jusque 10 pas 2 faire instructions fpour;
  On initialise j puis on teste la condition :
  - si elle est vraie, on fait les instructions puis on incrémente j, puis, on teste la condition : si elle est vraie, on fait les instructions etc...
  - si elle est fausse on ne fait rien c’est à dire on passe aux instructions qui suivent le for ou le pour.
  Par exemple :

      testfor1(a,b):={
      local j,s:=0;
      for (j:=a;j<=b;j++)
         s:=s+1/j^2;
      return s;
      };

  ou

      testpour1(a,b):={
      local j,s:=0;
      pour j de a jusque b faire
         s:=s+1/j^2;
      fpour;
      return s;
      };

  Si a>b, l’instruction ou le bloc d’instructions du for ou du pour ne se fera pas et la fonction retournera 0,
  Si a<=b la variable j va prendre successivement les valeurs a, a+1,...b (on dit que le pas est de 1) et pour chacune de ces valeurs l’instruction ou le bloc d’instructions qui suit sera exécuté. Par exemple testfor1(1,2) renverra 1+1/4=5/4.

      testfor2(a,b):={
      local j,s:=0;
      for (j:=b;j>=a;j--)
          s:=s+1/j^2;
      return s;
      };

  ou

      testpour2(a,b):={
      local j,s:=0;
      pour j de b jusque a pas -1 faire
         s:=s+1/j^2;
      fpour;
      return s;
      };

  Dans ce cas, si a<=b la variable j va prendre successivement les valeurs b, b-1,...a (on dit que le pas est de -1) et pour chacune de ces valeurs l’instruction ou le bloc d’instructions qui suit sera exécuté. Par exemple testfor2(1,2) renverra 1/4+1=5/4.

      testfor3(a,b):={
      local j,s:=0;
      for (j:=a;j<=b;j:=j+3)
          s:=s+1/j^2;
      return s;
      };

  ou

      testpour3(a,b):={
      local j,s:=0;
      pour j de a jusque b pas 3 faire
         s:=s+1/j^2;
      fpour;
      return s;
      };

  Dans ce cas, si a<=b la variable j va prendre successivement les valeurs a, a+3,...a+3k avec k le quotient de b-a par 3 (3k<=b-a<3(k+1)) (on dit que le pas est de 3) et pour chacune de ces valeurs l’instruction ou le bloc d’instructions qui suit sera exécuté. Par exemple testfor3(1,5) renverra 1+1/16=17/16.
  Attention
  Le pas doit être numérique et non une expression car il faut que le compilateur puisse transformer le pour en for avec le bon test.
  Par exemple:

      testpour4(a,b,p):={
      local j,s:=0;
      pour j de a jusque b pas p faire
         afficher(j);
         s:=s+j;
      fpour;
      return s;
      };

  Selon le signe de p le pour peut se traduire :
  - si p>0 en

        testpour41(a,b,p):={
        local j,s:=0;
        for (j:=a;j<=b;j:=j+p){
           afficher(j);
           s:=s+j;
        };
        return s;
        };

  - si p<0 en

        testpour42(a,b,p):={
        local j,s:=0;
        for (j:=a;j>=b;j:=j+p){
           afficher(j);
           s:=s+j;
        };
        return s;
        };

  - lorsque le compilateur ne connait pas le signe du pas, il suppose alors le pas positif et il le remplace par sa valeur absolue.

        testpour43(a,b,p):={
        local j,s:=0;
        for (j:=a;j<=b;j:=j+abs(p)){
           afficher(j);
           s:=s+j;
        };
        return s;
        };

- la boucle while ou tantque permet de faire plusieurs fois des instructions avec une condition d’arrêt au début de la boucle : while (condition) instruction;
  on met {..} lorsqu’il faut faire plusieurs instructions :
  while (condition) {instructions}
  ou
  tantque condition faire instructions ftantque;
  On teste la condition :
  - si elle est vraie, on fait les instructions puis, on teste la condition : si elle est vraie, on fait les instructions etc...
  - si elle est fausse on ne fait rien c’est à dire on passe aux instructions qui suivent le while ou le tantque.
  Par exemple :

      testwhile(a,b):={
      while (a==10 or a<b)
         b:=b-a;
      return [a,b];
      };

  ou

      testtantque(a,b):={
      tantque a==10 or a<b faire
         b:=b-a;
      ftantque;
      return [a,b];
      };

  Un exemple : le PGCD d’entiers
  - Version itérative

      pgcd(a,b):={
       local r;
       while (b!=0) {
          r:=irem(a,b);
          a:=b;
          b:=r;
       }
       return a;
      };

  ou

      pgcd(a,b):={
       local r;
       tantque b!=0 faire
          r:=irem(a,b);
          a:=b;
          b:=r;
       ftantque;
       return a;
      };

  -Version récursive

      pgcdr(a,b):={
       if (b==0) return a;
       return pgcdr(b,irem(a,b));
      };

  ou

      pgcdr(a,b):=if (b==0)
                     return a;
                   else
                     return pgcdr(b,irem(a,b));

- La boucle repeat ou repeter permet de faire plusieurs fois des instructions avec une condition d’arrêt à la fin de la boucle :
  repeat instructions until condition;
  ou
  repeter instructions jusqua condition;
  ou
  repeter instructions jusqu_a condition;
  On fait les instructions, puis on teste la condition :
  - si elle est vraie, on fait les instructions puis, on teste la condition etc...
  - si elle est fausse on passe aux instructions qui suivent le repeat ou le repeter.
  Par exemple :

      f():={
        local a;
        repeat
           saisir("entrez un reel entre 1 et 10",a);
         until a>=1 && a<=10;
        return a;
      }:;

  ou

      f():={
        local a;
        repeter
          saisir("entrez un reel entre 1 et 10",a);
        jusqua a>=1 et a<=10;
        return a;
      }:;

  Voici la fonction qui renvoie un point fixe de f en utilisant repeat. Cette fonction donne la solution à eps près de f(x)=x en utilisant au plus n itérations et x0 comme début de l’itération donné par le théorème du point fixe.

      point_fixe(f,n,x0,eps):={
       local j,x1,x00;
       j:=0;
       repeat
         x1:=evalf(f(x0));
         j:=j+1;
         x00:=x0;
         x0:=x1;
       until (abs(x00-x0)<eps) or (j>=n);
       return j,x0;
      }:;

  ou

      point_fixe(f,n,x0,eps):={
       local j,x1,x00;
       j:=0;
       repeter
         x1:=evalf(f(x0));
         j:=j+1;
         x00:=x0;
         x0:=x1;
       jusqua (abs(x00-x0)<eps) or (j>=n);
       return j,x0;
      }:;

- La boucle do instructions od ou faire instructions ffaire est une boucle infinie il faut donc mettre une condition d’arrêt avec un break ou un return dans le corps de la boucle.
  Par exemple la fonction précédente en utilisant do :

      point_fixe(f,n,x0,eps):={
       local j,x1;
       j:=0;
       do
         x1:=evalf(f(x0));
         if (abs(x1-x0)<eps) return x1;
         x0:=x1;
         j:=j+1;
         if (j>=n) break;
       od;
       return "non trouve au bout de ", n," iterations";
      }:;

  ou en utilisant faire

      point_fixe(f,n,x0,eps):={
       local j,x1;
       j:=0;
       faire
         x1:=evalf(f(x0));
         if (abs(x1-x0)<eps) return x1;
         x0:=x1;
         j:=j+1;
         if (j>=n) break;
       ffaire;
       return "non trouve au bout de ", n," iterations";
      }:;

  On peut aussi écrire cela avec un for

      point_fixe(f,n,x0,eps):={
       local j,x1;
       for (j:=0;j<n;j++){
         x1:=evalf(f(x0));
         if (abs(x1-x0)<eps) return x1;
         x0:=x1;
       }
       return "non trouve au bout de ", n," iteration";
      }:;

  point_fixe(x->cos(x),100,1.0,1e-12)=0.739085133215
  On vérifie : cos(0.739085133215)=0.739085133215
  Remarque
  Le for permet de faire tous les types de boucle à condition de mettre, soit for (;test_arrêt;)... soit et for (;;)... et une instruction break dans le corps du for, par exemple :

      pgcd(a,b):={
      local r;
      for (;b!=0;) {
      r:=irem(a,b);
      a:=b;
      b:=r;
      }
      return a;
      }
      :;

  ou

      pgcd(a,b):={
      local r;
      for (;;) {
      if (b==0) break;
      r:=irem(a,b);
      a:=b;
      b:=r;
      }
      return a;
      }
      :;