LOGO
c'est pas que
pour les enfants !!!


Alain BOIS
Collège des quatre-Vents
72800 LE LUDE
in.bois
@
wanadoo.fr

Jean-Louis Guillot
Collège François Grudé
72160 CONNERRÉ
jlguillot72
@
wanadoo.fr

IREM des PAYS de la LOIRE


LOGO
Géométrie Tortue, Arithmétique, Fractales et autres algorithmes ...

Formation de Formateurs IREM - 12/2002 et colloque EMF de Tozeur - 12/2003



Les premiers pas

Souvenirs ...
Les micro-mondes
Comment communiquer ?
Des mots et des phrases pour le faire
Un peu de grammaire LOGO
Entrer les données et contrôler les procédures

Simulation du comportement animal

Comment simuler l'odorat d'un prédateur
Courbes de poursuite

Fractales

Flocon de Koch
Courbe C
Arbres

Arithmétique et suites

Calcul du PGCD et du PPCM
Recherche des nombres premiers
Les nombres parfaits
Les congruences: Calcul de la clé RIB d'un compte chèque
Calcul des éléments de la suite de Fibonacci
Egalité de Bezout et récursivité non terminale

Barycentre et théorème de Guldin




Les premiers pas


Souvenirs ...


Il n'y a pas si longtemps, la tortue se promenait sur le sol de la classe ...
Puis elle est venue dans l'ordinateur, petit triangle bleu dans son aquarium ...
C'est bien facile de la faire se déplacer ... elle parle presque le même langage que nous.
Elle parle en LOGO. Elle connaît les mots avancer, reculer, tourner à droite, à gauche, lever le crayon, baisser le crayon, vider l'écran ... Elle sait où elle est, où elle va, elle mémorise ce qu'on lui demande de garder, elle peut nous donner les renseignements qu'elle connaît.
Elle se comporte presque comme nous :


AV (avance) le nombre de pas,
RE (recule),
TG (tourne à gauche) le nombre de degrés,
TD (tourne à droite),
LC (lève crayon),
BC (baisse crayon),
VE (vide écran),
MT (montre tortue),
CT (cache tortue),
POUR (apprends ... jusqu'au mot FIN)
ME (mixte écran) fixe le nombres de lignes de texte, sous l'espace tortue.
...


Les micro-mondes


La tortue et sa géométrie n'est pas seule dans le monde LOGO.
Elle peut vivre avec d'autres robots différents (autres tortues, chariots élévateurs, bras articulé, tables traçantes, tours, ... ).
Il y a aussi le monde des nombres, le monde des mots et des listes, celui de la musique, ... et bien d'autres mondes aussi.
En bref, tous ceux que vous aurez envie d'inventer, des micro-mondes, à l'intérieur et à l'extérieur de l'ordinateur. En parlant LOGO.


Comment communiquer ?


Vous avez deux possibilités, lorsque vous travaillez avec l'ordinateur et la console jLogo (on retrouve ces principes dans la plupart des environnements LOGO) :


Si vous avez réussi, vous devez obtenir le dessin suivant :



Des mots et des phrases pour le faire


Au chargement LOGO connaît un certain nombre de mots. Ce sont les procédures primitives. En raccourci, les primitives.


EC CONTENU permet d'obtenir la liste des primitives disponibles.


EC COMPTE CONTENU donne le nombre des primitives.


Programmer en LOGO, c'est construire de nouveaux mots, les procédures, qui viennent s'ajouter aux primitives, et vous organisez tous ces mots ensemble selon votre projet. Vous apprenez des mots nouveaux au système.
Si vous avez gardé dans l'éditeur la phrase - la liste d'instruction - qui permet d'obtenir le dessin précédent, il vous suffit de la compléter sous la forme du paragraphe suivant pour construire une nouvelle procédure nommée TRUC


POUR TRUC <- le titre de la procédure seul en ligne 1
AV 100 TD 90 AV 100 TD 90 AV 50 TD 90 AV 50 TD 90 AV 100 TD 90 AV 25 TD 90 AV 25 TD 90 AV 50
FIN
<- seul en dernière ligne (fin d'apprentissage)


Sortez de l'éditeur un validant et vous obtenez un nouveau mot qui fonctionne exactement comme les autres. Tapez successivement en mode direct :


VE
TRUC
VE TRUC TG 90 AV 125 TD 90 AV 25 TD 90
VE REPETE 4 [TRUC]
VE REPETE 20 [TRUC TD 10 AV 50]
VE REPETE 20 [TRUC TG 45 AV 100]


Avec jLogo, vous pourrez utiliser les onglets :



La partie graphique peut être diminuée en relevant la barre qui la sépare du texte du "journal" en utilisant la souris.
Vous pouvez également utiliser la procédure ME.


ME 5
réservera 5 lignes de texte afficher le "journal" des commandes et des réponses.


CARRE et TRIANGLE (équilatéral) ne figurent pas parmi les primitives ... vous devrez donc les apprendre à LOGO, comme vous avez fait pour TRUC.


Un peu de grammaire LOGO


Nous décrivons ici seulement les éléments qui vont nous servir dans la suite. De nombreux objets LOGO sont disponibles ou peuvent être créés.

Les objets LOGO pour lire et écrire sont les mots et les listes. Les mots sont écrits avec les caractères usuels et séparés par les espaces. Les nombres sont des mots particuliers ne comportant que des chiffres et s'il y a lieu la virgule ou le point pour séparer la partie décimale.
Les noms des primitives et des procédures (les "exécutables") sont des mots comme AV, REPETE, TRUC ....
Si un mot doit être pris comme une constante non exécutable, comme une donnée ou un identificateur (nom de variable) on le fait précéder d'un guillemet double sauf si c'est un nombre et sauf s'il est un élément d'une liste.

"CANARD
125
1357,89
[CANARD 125 1357,89]
[maison "5" CANARD "125 [1 a 3]]
<- un mot
<- un mot qui est un nombre entier
<- un mot qui est un nombre décimal
<- la liste des trois mots ci-dessus
<- une liste de trois éléments



Une liste est une suite de mots ou de listes.
Vous devrez l'écrire entre crochets, mais LOGO vous la reproduira en supprimant les crochets de début et de fin.

 

EC [maison "5" CANARD "125 [1 a 3]]
maison "5" CANARD "125 [ 1 a 3 ]
EC "CANARD
CANARD

<- vous demandez à LOGO d'écrire
<- voici la réponse de LOGO
<- vous demandez à LOGO d'écrire
<- voici la réponse de LOGO

 


Les opérations (ou fonctions) produisent un résultat (un objet utilisable) et les commandes réalisent une action sur l'environnement.

EC 2 + 3
EC SOMME 2 3
<- opération addition "infixée"
<- opération addition "préfixée"


Les deux instructions produisent 5 comme résultat. La commande EC écrit le nombre 5. Si vous oubliez de taper EC, LOGO dira :


Que faire de 5 ?

C'est comme ça que vous ferez des phrases compliquées.


AV SOMME PROD 2 10 RESTE 24 5
AV SOMME PROD RESTE 24 5 2 10       c'est différent !


Vous pouvez construire des procédures qui sont des commandes, d'autres qui sont des opérations (ou fonctions), d'autres qui sont les deux à la fois.


Certaines fonctions n'ont aucune entrée (argument, paramètre):


POSITION rend la liste des coordonnées de la tortue
CAP rend le cap de la tortue


Certaines fonctions ont une seule entrée :


PREM liste rend le premier élément de la liste ou le premier caractère du mot
RC nombre rend la racine carrée de nombre


Certaines fonctions ont deux entrées :


MOT "car "table rend le mot "cartable


Si on dispose de plusieurs objets en entrées, on peut s'organiser (ne tapez pas le point d'interrogation):


? EC PH PH PH PH MOT MOT "4 "+ "3 [est la somme de] "4 "et "3
4+3 est la somme de 4 et 3


En plus des fonctions mathématiques, et de celles qui opèrent avec les mots et les listes et qui rendent des nombres, des mots ou des listes, LOGO fournit des prédicats.
Un prédicat est une fonction comme celles que nous venons de décrire, mais elle rend comme résultat le mot "VRAI ou le mot "FAUX. Les opérations booléennes sont des prédicats qui ont aussi comme entrée les valeurs booléennes "VRAI ou "FAUX.
C'est très commode à utiliser pour écrire les conditions des tests.


EC ET PLG? RC 2 1,41 PLP? RC 2 1,42
VRAI


Il est bien vrai que racine de 2 est plus grand que 1,41 et plus petit que 1,42
ET est une opération booléenne préfixée ayant deux entrées booléennes.
PLG? et PLP? sont deux prédicats ayant chacun deux nombres comme entrée.


C'est facile à comprendre lorsque vous n'avez pas d'entrée (pas de paramètres) à entrer par exemple, si vous voulez obtenir l'abscisse de la position de la tortue vous définirez la fonction XCOR. Le mot magique est RENDS qui produit un objet directement utilisable dans vos phrases comme EC SOMME 15 XCOR.


POUR XCOR
RENDS PREMIER POSITION
FIN


L'entrée des données sera détaillée au paragraphe suivant. Vous pourrez alors créer avec le mot magique RENDS la procédure DIFFERENCE inconnue en LOGO pour l'utiliser comme SOMME, PROD, RESTE ... avec ses deux entrées.


Entrer les données et contrôler les procédures


Étudions maintenant l'affectation des variables, les tests, la répétition, la récursivité et la récursivité non terminale.


Il y a bien des primitives comme LISCAR (qui prend le caractère tapé au clavier) ou LISLISTE (qui prend toute la phrase tapée au clavier jusqu'au retour de chariot), qui ressemblent un peu au get ou à l'input ou bien au readln ou read que certains connaissent. De toute façon, il faut bien ranger quelque part une donnée qui vient du clavier, ou l'utiliser tout de suite dans une fonction ou une commande pour en faire quelque chose.
La plupart du temps, en LOGO, vous êtes directement dans l'espace de travail, aux commandes de tout l'environnement. Vous allez tout de suite agir avec les primitives ou les procédures qui vous sont nécessaires, et vous leur donnez directement les données (arguments?) dont elles ont besoin. Admettons par exemple que vous ayez besoin de faire des carrés de différentes tailles. Vous écrirez la procédure :


POUR CARRE :COTE
REPETE 4 [AV :COTE TD 90]
FIN


Puis une fois qu'elle sera validée, vous commanderez en mode direct, suivant ce qu'il vous plaira :


CARRE 10
CARRE 50

etc...


Tout se passe comme vous procédiez chaque fois à une affectation de variable, mais c'est fait directement à l'appel de la procédure (sans "input", "read" ...).
En fait, vous avez créé la variable dont le nom est le mot "COTE et dont le contenu est désigné par :COTE (valant successivement 10, puis 50, puis ...). Cette variable a été crée dans le titre de la procédure; c'est une entrée de la procédure CARRE.
Vous pouvez l'utiliser dans le corps de la procédure comme bon vous semble. Par exemple, insérez l'instruction suivante, puis testez la nouvelle procédure.


EC PH PH [Je viens de faire le carré de] :COTE [pas de côté.]


Une variable peut également être définie dans le corps d'une procédure ou directement au niveau supérieur, sans avoir lancé de procédures.
On utilise les commandes DONNE ou SOIT. Tapez en mode direct les deux commandes et vous retrouvez dans votre tirelire ce que vous y aurez mis.


? DONNE "tirelire "20€
? EC :tirelire
20€


De façon analogue essayez :


? SOIT "X 12,5
? EC :X
12,5


Le contenu de la tirelire est le mot 20€ et celui de X est le nombre 12,5
Contrairement à l'apparence, ces deux affectations de variables fonctionnent différemment.
La commande "DONNE produit une variable globale, c'est-à-dire connue de toutes les procédures qui l'appelleront ou de vous-même, au niveau supérieur.
Par contre, la commande "SOIT produit une variable locale, qui n'est connue que par les niveaux d'appels inférieurs à celui où elle a été créée.
Comme vous avez fait "X au niveau supérieur, tout le monde verra son contenu, comme si c'était une variable globale. Par contre la variable "COTE créée par la procédure CARRE n'est pas accessible au niveau supérieur, c'est une variable locale. Tout se passe comme si vous l'aviez définie en utilisant la commande SOIT à l'intérieur de la procédure CARRE.


? EC :COTE
Pas de chose donnée à COTE



Comme structure itérative, LOGO utilise le mot REPETE et la récursivité.


Répétition :


REPETE le nombre de fois indiqué la liste d'instructions qui est écrite.


Récusivité :


Une procédure récursive est une procédure qui s'appelle elle même. Pensez plutôt que des procédures "clones" s'appellent successivement :
La première appelle la deuxième qui appelle la troisième qui appelle ...
en espérant qu'un évènement arrêtera cette chaîne infernale.


POUR CARRE :COTE
REPETE 4 [AV :COTE TD 90]
CARRE :COTE + 10
FIN


Plutôt que d'attendre que la tortue se cogne contre les murs, ou que l'ordinateur fonde, vous préfèrerez prévoir un test d'arrêt lorsque vous entreprendrez une récursivité.


Condition simple si ... alors :


si condition
   alors action
suite

POUR CARRE :COTE
REPETE 4 [AV :COTE TD 90]
SI PLP? :COTE 100 [CARRE :COTE + 10]
FIN

N'oubliez pas de mettre sur la même ligne d'instructions le SI, la condition (prédicat) et la liste d'instructions (entre crochets). Lorsque la condition n'est pas réalisée, on passe à la suite, (ligne du dessous) qui peut être le mot FIN
Dans l'exemple ci-dessus vous avez en fait reconstitué une structure du type


faire action
   jusqu'à condition
suite


En changeant la place du test, il est facile de réaliser la structure


tant que condition
   faire action
suite


Vous reconstituez de la sorte les structures itératives élémentaires des autres langages de programmation avec récursivité et condition simple.


Condition alternative si ... alors .. sinon :


si condition
   alors action 1
   sinon action 2
suite


POUR CARRE :COTE
REPETE 4 [AV :COTE TD 90]
SI PLP? :COTE 100 [CARRE :COTE + 10][AV :COTE TD 30 REPETE 3 [AV :COTE TD 120]]
FIN

Comme précédemment, n'oubliez pas de mettre sur la même ligne d'instructions le SI, la condition (prédicat), et la liste d'instructions (entre crochets) à faire lorsque la condition est vraie, puis la liste d'instructions (entre crochets) à faire lorsque la condition est fausse. Après l'exécution de l'une de ces deux listes, on passe à la suite.

Si vous tapez CARRE 60 vous obtiendrez la figure suivante :


Imaginez bien les procédures qui s'appellent successivement (ce sont les acteurs, les ouvriers qui s'activent dès que vous avez passé votre commande):


CARRE 60

action 1 (dessin du carré de 60)
test VRAI


CARRE 50

action 1 (dessin du carré de 60)
test VRAI
....


CARRE 100

action 1 (dessin du carré de 60)
test FAUX


action 2 (déplacement puis triangle)
FIN


Le travail est fini. Le travail semble fini ...
Regardons d'un peu plus près.


Récursivité non terminale :


Modifiez la procédure précédente pour obtenir :


POUR CARRE :COTE
REPETE 4 [AV :COTE TD 90]
SI PLP? :COTE 100 [CARRE :COTE + 10][AV :COTE TD 30]
REPETE 3 [AV :COTE TD 120]
FIN


Essayez votre nouvelle procédure :


CARRE 60


Vous obtenez ceci :

 



Étonnant, non ? ... et ce n'est pas une erreur de LOGO !


En effet, lorsque les appels successifs sont terminés, le dernier ouvrier qui intervient, CARRE 100 exécute dans son test AV 100 TD 30, puis passe à la ligne suivante pour faire son triangle de 100.


Mais il n'a pas fini contrairement à ce que vous auriez pu croire ...


Par contre, il dit à CARRE 90 qui lui avait passé la commande que son travail est fini. Mais CARRE 90 remarque qu'il n'avait pas fini sa propre liste de commandes: il avait encore une instruction à faire après avoir fait travaillé son collègue. Il fait donc son triangle de 90 ... ensuite, il doit "rendre la main" à celui qui l'avait commandé, lui aussi a des comptes à rendre ! Et ils se repassent la main... Jusqu'à ce que CARRE 60 termine sa liste et vous rende la main à vous le véritable chef : tous les travailleurs ont terminé votre commande.


Pensez aussi à tous ces documents que vous empilez; pour revenir au premier, il faut bien refaire tout le chemin à l'envers, tout dépiler. Ici on dit souvent descendre la récursivité, puis la remonter.


Sommez une liste et faites la moyenne d'une liste de nombres :


POUR TOTAL :L
SI VIDE? :L [RENDS 0] [RENDS SOMME PREM :L TOTAL SP :L]
FIN


Faites la moyenne d'une liste de nombres :


POUR MOYENNE :L
RENDS DIV TOTAL :L COMPTE :L
FIN

Attention : DIV donne le quotient alors que QUOT donne le quotient entier.


? EC MOYENNE [12 16 18 14,5 13]
14,7


Mettez les mots à l'envers :


POUR ENVERS :M
SI VIDE? :M [RENDS "][RENDS MOT DER :M ENVERS SD :M]
FIN


DER pour dernier, et SD pour sauf dernier, agissent ici sur mots et caractères.


? ENVERS "LAPIN
Que faire de NIPAL ?


Simulation du comportement animal


Comment simuler l'odorat d'un prédateur


Nous allons situer sur l'écran une proie dont la position va être définie par l'utilisateur et l'emplacement initial du prédateur (dans notre cas la tortue écran). Pour cela nous écrivons une procédure d'initialisation comme suit:


POUR INITIALISATION
EC [TAPEZ LA POSITION EN X ET Y DU PREDATEUR]
DONNE "POSPREDATEUR LL
EC [TAPEZ LA POSITION EN X ET Y DE LA NOURRITURE]
DONNE "POSNOURRITURE LL
LC FPOS :POSNOURRITURE
BC CROIX
LC FPOS :POSPREDATEUR
DONNE "ANGLE_ALEATOIRE HASARD 60
FIN
POUR CROIX
AV 2 RE 4 AV 2 TD 90 AV 2 RE 4
FIN

Ça va c'est pas trop dur !!!

Maintenant venons à la simulation simple de l'odorat, on considère que la tortue est sur le bon chemin lorsque la distance à la proie se raccourcit - dans ce cas elle continue à avancer - sinon on décide aléatoirement de la faire tourner de 1 degré vers la droite.
On va écrire une procédure-prédicat qui va signaler à la tortue que son odorat faiblit:

POUR SENTE_MOINS_BONNE?
RENDS PLG? DISTANCE POS :POS_NOURRITURE :DERNIERE_DISTANCE
FIN

Il nous faut initialiser la variable :DERNIERE_DISTANCE dans la procédure qui va lancer la recherche de nourriture.

POUR CHERCHER_NOURRITURE
DONNE "DERNIERE_DISTANCE DISTANCE POS :POS_NOURRITURE
AV 1
SI SENTE_MOINS_BONNE? [TD :ANGLE_ALEATOIRE]
TROUVER_NOURRITURE
FIN

Il nous reste à tester cette procédure pour voir l'effet produit :



Voici deux copies d'écran avec un angle de 10 degrés pour la première et un angle de 20 degrés pour la deuxième.
Il est possible de prévoir de l'aléatoire dans les marches de la tortue quand elle se rapproche de la proie ou jouer sur de l'aléatoire dans les angles de rotation.


Courbes de poursuite


Supposons que nous ayons deux animaux dont on veut modéliser le comportement, l'un part du centre de l'écran (le lièvre), l'autre part d'un point fixé à l'avance et peut se promener sur une droite ou un cercle fixé à l'avance (la tortue). C'est là que la possibilité d'avoir plusieurs tortues à l'écran est intéressante.
Vous allez commencer par initialiser la situation.

POUR INIT
VE
FTORTUE 1
vous allez donner les ordres qui suivent à la tortue 1, la tortue
LC FPOS [100 100]
DONNE "A 1
FTORTUE 0
CT
FTORTUE 2
vous allez donner les ordres qui suivent à la tortue 2, le lièvre
ORIGINE
FIN

POUR TOUT_VOIR
FTORTUE 1
FPOS PH DIFF PREM POS :A DER POS
DONNE "POS_TORTUE POS
FTORTUE 2
FCAP VERS : POS_TORTUE AV 1
SI PLP ? DISTANCE POS :POS_TORTUE 2 [STOP]
TOUT_VOIR
FIN

TAPEZ INIT puis TOUT_VOIR
Et vous allez en voir de toutes les couleurs, votre stratégie va changer si vous décidez de donner à la tortue une trajectoire sur un cercle. Voici quelques courbes obtenues :



Fractales


Flocon de Koch


C'est quoi au juste un flocon de Koch. Ça dépend du niveau de récursivité !! Au niveau 0, c'est juste un triangle équilatéral dont les côtés comme tous les côtés sont des simples traits.

Puis les traits se divisent eux-mêmes en 4 traits comme ceci:


Et ainsi de suite:


Et donc un flocon devient l'assemblage de ces nouveaux traits :



Voici comment on programme en Logo tout cela:


POUR COTE :TAILLE :NIVEAU
SI EGAL? :NIVEAU 0 [AV :TAILLE STOP]
COTE :TAILLE / 3 DIFF :NIVEAU 1
TG 60
COTE :TAILLE / 3 DIFF :NIVEAU 1
TD 120
COTE :TAILLE / 3 DIFF :NIVEAU 1
TG 60
COTE :TAILLE / 3 DIFF :NIVEAU 1
FIN


Expliquons un peu: si le niveau de récursivité est 0, la procédure va s'arrêter grâce au STOP après avoir tracé un trait simple "AV :TAILLE" mais si le niveau de récursivité est seulement 1, ça se complique: on croit naïvement quand on ne s'est pas encore attaqué à une récursivité non terminale que la procédure retourne sur elle-même et qu'elle va donc faire dessiner à l'objet "Tortue" un trait 3 fois plus petit "COTE :TAILLE / 3" et que la procédure va s'arrêter. Et non!!! elle va continuer sur TG 60 et COTE :TAILLE / 3 DIFF :NIVEAU 1 donc faire le deuxième côté mais TAILLE et NIVEAU sont les variables de la procédure appelante donc ne changent pas de valeurs et ainsi de suite jusqu'à ce que le mot FIN de la procédure appelante soit détecté. Oh les belles cascades !!!

Pour le plaisir des yeux voici ce qu'on obtient si on tape tout bêtement:
REPETE 6 [FLOCON 100 3 TD 60]


Avouez que c'est pas mal !!!!

L'IREM de Nantes a publié une brochure en 1990: "Les courbes de Von Koch et de Sierpinski comme paradigmes de fractals" par A. Robert, professeur à l'université de Neufchâtel. Il y a des exercices sur les centres de gravité ou autres qui peuvent être traîtés élégamment avec l'aide de Logo.


Courbe C


Sans commentaires mais avec les procédures et les images-écrans, voici la courbe appelée C.

POUR C :TAILLE :NIVEAU
SI :NIVEAU = 0 [AV :TAILLE STOP]
C :TAILLE DIFF :NIVEAU 1
TD 90
C :TAILLE :NIVEAU - 1
TG 90
FIN

Vous voyez pourquoi on l'appelle courbe "C". Selon le niveau de la récursivité il y a des études intéressantes à mener sur l'emplacement de l'axe de symétrie.
Nous terminerons cette étude par la modélisation d'un arbre sur lequel on n'a pas placé des fruits, mais ça pourrait être un bon exercice à faire à la maison !!!


Arbres


Et le bonzaï

BRANCHEG 10 10 10 0.8

Rien ne vous empêche de dessiner une forêt ou des arbres couchés par le vent etc...
Allez, on vous donne les procédures, à vous de les tester, de les modifier.

POUR BRANCHEG :LON :ANG :NIVEAU :COEF
AV :LON * :COEF
NOEUD :LON :ANG :NIVEAU :COEF
RE :LON * :COEF
FIN

POUR NOEUD :LON :ANG :NIVEAU :COEF
SI EGAL? :NIVEAU 0 [STOP]
TG :ANG
BRANCHEG :LON :ANG DIFF :NIVEAU 1 :COEF
TD 2 * :ANG
BRANCHED :LON :ANG + 2 DIFF :NIVEAU 1 :COEF
TG :ANG
FIN

POUR BRANCHED :LON :ANG :NIVEAU :COEF
AV :LON
NOEUD :LON :ANG :NIVEAU :COEF
RE :LON
FIN

Vous commencez par BRANCHEG ou BRANCHED ça fera la même chose.



Arithmétique et suites


Calcul du PGCD et du PPCM


Nous allons utiliser l'algorithme d'Euclide :

Tant que a <> b

faire

si a > b

a <-- a - b
b <-- a

sinon

a <-- b - a
b <-- a

fin si

fin Tant que

Ce qui donne en Logo:

POUR PGCD :A :B
SI EGAL? :A :B [RENDS :A ]
SI PLG? :A :B [RENDS PGCD :B :A - :B]
RENDS PGCD :B - :A :A
FIN

Si vous voulez obtenir le PGCD par la méthode des divisions successives, vous pourrez vous contenter d'écrire :

POUR PGCD :A :B
SI EGAL? 0 RESTE :A :B [RENDS :B ][RENDS PGCD :B RESTE :A :B]
FIN

... ce qui dit exactement : pour avoir le PGCD de A et de B, si B divise A, c'est B, sinon, ce sera le PGCD de B et du reste de la division précédente. Vous êtes en train de faire les fameuses divisions en cascade ... élégant? non ?

Vous pouvez tester ces procédures et naturellement écrire des "choses" comme cela :

EC PGCD 24 36 mais aussi AV PGCD 360 144
et comme nous le verrons plus loin rien ne nous empêche à condition d'avoir défini FIBO d'écrire
PGCD FIBO 15 FIB 30 ou FIBO PGCD 15 30

Il est donc possible d'écrire une procédure pour calculer le PPCM de 2 nombres de la façon suivante :

POUR PPCM :A :B
RENDS QUOT PROD :A :B PGCD :A :B
FIN

Pendant qu'on y est pourquoi s'arrêter au PPCM de deux nombres, on peut écrire le PPCM de n nombres pris dans une liste de la façon suivante :

POUR PPCMS :LISTE
SI EGAL? COMPTE :LISTE 2 [RENDS PPCM PREM :LISTE DER :LISTE]
RENDS PPCMS PH PPCM ITEM 1 :LISTE ITEM 2 LISTE SP SP :LISTE
FIN

Essayez PPCMS [24 36 48] par exemple ou encore PPCMS [15 25 36 42].

Autre idée bien commode, (utilisée parfois pour trouver un dénominateur commun à deux fractions) : vous prenez le plus grand des deux nombres, vous regardez si c'est un multiple du petit, sinon vous prenez son double, vous regardez ... puis les multiples successifs jusqu'à ce que vous ayez un multiple commun.
Ce qui donne en LOGO
Tant que vous n'avez pas ce multiple, vous faites tourner la moulinette PPMC1 :

POUR PPMC :A :B
SOIT "N 1
RENDS PPMC1 :A :B :N
FIN

POUR PPMC1 :A :B :N
SI EGAL? 0 RESTE :N * :A :B [RENDS :N * :A]
RENDS PPMC1 :A :B :N + 1
FIN



Recherche des nombres premiers


POUR LISTE_DIVISEURS :NOMBRE
SI EGAL? :NOMBRE 1 [RENDS 1]
RENDS DIVISEURS :NOMBRE 1
FIN

POUR DIVISEURS :NOMBRE :DEBUT
SI EGAL? :DEBUT RC :NOMBRE [RENDS :DEBUT]
SI PLG? :DEBUT RC :NOMBRE [RENDS "]
SI EGAL? RESTE :NOMBRE :DEBUT 0 [RENDS PH :DEBUT PH DIVISEURS :NOMBRE :DEBUT + 1 :NOMBRE / :DEBUT]
RENDS DIVISEURS :NOMBRE :DEBUT + 1
FIN

Deux remarques :

Il faut s'habituer à l'écriture préfixée des prédicats SI EGAL? ou SI PLG?
l'écriture de la récursivité est originale :

RENDS PH :DEBUT PH DIVISEURS :NOMBRE :DEBUT + 1 :NOMBRE / :DEBUT

On remplit la procédure-objet par les deux bouts : au début le diviseur trouvé, à la fin le nombre divisé par ce diviseur et au milieu la suite des autres diviseurs.
Et donc pour savoir si un nombre est premier, il suffit d'écrire la procédure suivante.

POUR PREMIER? :A
RENDS EGAL? COMPTE LISTE_DIVISEURS :A 2
FIN

Ça marche, mais c'est un peu lourd. Voyons quelque chose de plus élégant.

En calquant notre démarche sur le crible d'Ératosthène, voici ce que nous pourrions écrire en LOGO :

Commençons par le plus simple, savoir si un nombre est premier en donnant comme liste de début [2 3]. Cette procédure ne marche que pour les nombres supérieurs à 3.

Comme vous avez pu déjà le voir, il y a aussi en Logo des procédures-objets -prédicats qui rendent une valeur de vérité.

POUR PREMIER? :A :B
SI VIDE? :B [RENDS "VRAI]
SI EGAL? RESTE :A PREM :B 0 [RENDS "FAUX]
RENDS PREMIER? :A SP :B
FIN

Je vous dois quelques explications :

- la procédure va tester si A est premier en se servant de la liste B qui va être initialisée à [2 3 5 7 ] par exemple,
- si le reste de A par le premier élément de B est nul c'est pas la peine d'aller plus loin, on a trouvé un diviseur donc on peut rendre Faux, sinon on recommence mais avec une liste de diviseurs moins longue, c'est le principe du crible. Essayez PREMIER? 20 [2 3 5] ça marche mais si vous essayez PREMIER? 49 [2 3 5], l'ordinateur vous répond VRAI, CE QUI EST FAUX!!!

Il faut donc agrandir le crible, ce que l'on va faire dans cette deuxième mouture :

POUR LISTE_PREMIERS :A :B
SI PLG? DER :A :B [RENDS "]
DONNE "NBRE SOMME DER :A 2
SI PREMIER? :NBRE :A [RENDS PH :NBRE LISTE_PREMIERS PH :A :NBRE :B]
RENDS LISTE_PREMIERS PH :A :NBRE :B
FIN

Dès que l'on trouve un nombre premier on l'ajoute à la variable B, alors on ne divise plus par 2 et 3 seulement mais par la liste des nombres premiers qui s'allonge au fur et à mesure que l'on en trouve un.
L'inconvénient c'est que 2 et 3 sont oubliés, je n'ai pas trouvé de solution plus élégante que de les rajouter dans la procédure suivante qui va donner sous forme de liste les nombres premiers jusqu'à 200.

POUR CRIBLE_ERATOSTHENE
RENDS PH [2 3] LISTE_PREMIERS [2 3] 200
FIN

POUR PREM? :N
SI OU EGAL? :N 0 EGAL? :N 1 [RENDS "FAUX]
SI OU EGAL? :N 2 EGAL? :N 3 [RENDS "VRAI]
SI EGAL? 0 RESTE :N 2 [RENDS "FAUX]
RENDS NON DIV? 3
FIN

POUR DIV? :D
SI EGAL? :D * :D :N [RENDS "VRAI]
SI PLG? :D * :D :N [RENDS "FAUX]
SI EGAL? RESTE :N :D 0 [RENDS "VRAI]
RENDS DIV? :D + 2
FIN

La procédure PREM? est un prédicat (elle dit si le nombre est premier) qui utilise le prédicat DIV? (est-il divisible par ... ?) qui tourne éventuellement jusqu'à la racine carrée.

Comme précédemment, on retrouve facilement la liste des nombres premiers jusqu'à un nombre donné, en utilisant un compteur qu'on fait tourner à partir de 1, jusqu'à ce nombre final (la "moulinette LISTPREM1) et en rangeant les nombres premiers trouvés au fur et à mesure.

POUR LISTEPREM :F
DONNE "LP []
SOIT "K 1
SI OU EGAL? :F 0 EGAL? :F 1 [RENDS :LP] [RENDS LISTEPREM1 :K]
FIN

POUR LISTEPREM1 :K
SI PLG? :K :F [RENDS :LP]
SI PREM? :K [DONNE "LP PH :LP :K]
RENDS LISTEPREM1 :K + 1
FIN



Les nombres parfaits


En utilisant la procédure LISTE_DIVISEURS, on peut savoir si un nombre est parfait, il suffit d'écrire une procédure qui va donner la somme des éléments d'une liste :

POUR SOMME_LISTE :LISTE
SI VIDE? :LISTE [RENDS 0]
RENDS SOMME PREM :LISTE SOMME_LISTE SP :LISTE
FIN

Je pense qu'elle se comprend sans explication supplémentaire, voir le lexique pour les primitives.
Et donc pour savoir si un nombre est parfait:

POUR PARFAIT? :NOMBRE
RENDS EGAL? SOMME_LISTE SD LISTE_DIVISEURS :NOMBRE :NOMBRE
FIN

Cette procédure est loin d'être parfaite ( sic) pour trouver les nombres parfaits, elle est très lente et je n'ai pu trouver par cette technique que les 4 premiers.



Les congruences: Calcul de la clé RIB d'un compte chèque


On trouve sur le Net, la méthode pour vérifier la clé Rib d'un compte chèque. Le travail est intéressant parce que si on se tourne vers un bon vieux tableur, il reste en rade parce que le numéro de CC dépasse les limites de calcul et vous renvoie donc un nombre en écriture avec exposant. D'où l'intérêt d'utiliser les congruences. Je m'aperçois que je ne vous ai pas donné la méthode, oh elle est simple (?!), il suffit de multiplier votre numéro de CC par 100, de diviser ce nombre par 97, de vous occuper seulement du reste et de chercher son complément à 97. Il fallait y penser. Donc si on applique cela dans un tableur, ça peut donner cela :


Mais bon, je ne suis pas là pour faire de la pub à Bilou, donc voyons comment avec Logo on peut résoudre cela:
Tout d'abord il faut écrire une procédure qui va nous donner la congruence modulo 97 d'une centaine, d'un millier etc... ça c'est facile :

POUR CONGRU :A
SI EGAL? :A 1 [RENDS 1]
RENDS RESTE PROD 10 CONGRU DIFF :A 1 97
FIN

Essayez CONGRU 3, ça donne 3, bien !!! CONGRU 4 ça donne 30 parfait. Vous avez les congruences dans le tableau Excel.

Bon, maintenant il suffit de mettre en face l'un de l'autre, une liste constituée de votre numéro de compte chèque (séparez les chiffres par un espace et n'oubliez pas les deux zéros à la fin) et de faire un produit terme à terme puis d'additionner. Pour que cela se fasse tout seul il suffit de créer la procédure SOM_PROD.

POUR SOM_PROD :A :B
SI VIDE? :A [ RENDS 0 ]
RENDS SOMME PROD PREM :A PREM :B SOM_PROD SPREM :A SPREM :B
FIN

Mais il nous faut aussi une procédure qui fabrique la liste des congruences à l'envers.

POUR LISTE_CONG :B :C
SI PLG? :B :C [RENDS "]
RENDS PH LISTE_CONG :B + 1 :C CONGRU :B
FIN

Regardez encore comment est écrite cette procédure, elle renvoie la liste des congruences en partant de la plus haute vers la plus basse.
On a presque tout pour travailler. Il suffit de ranger cela dans des variables:

DONNE "B [ 1 6 7 0 7 0 0 0 6 5 1 6 5 1 9 0 3 2 3 4 3 0 0]
DONNE "A LISTE_CONG 1 COMPTE :B
EC 97 - RESTE SOMPROD :A :B 97

Et ça devrait vous afficher 32 comme sur la feuille d'Excel.



Calcul des éléments de la suite de Fibonacci


On peut reprendre la définition de la suite et écrire une procédure brutale:

POUR FIBO1 :A
SI MEMBRE? :A [1 2] [RENDS 1]
RENDS SOMME FIBO1 :A - 1 FIBO1 :A - 2
FIN

Tapez FIBO1 10 et laborieusement Logo vous affiche 55. Les récursivités sont longues à remonter et les calculs sont très lents, c'est pourquoi je vous conseille cette solution dont l'explication est donnée en annexe.

POUR FIB :I :A :B
SI :I = 1 [RENDS :B]
RENDS FIB :I - 1 :B :A + :B
FIN

POUR FIBO :I
RENDS FIB :I 0 1
FIN

Vous pouvez vous permettre d'afficher FIBO 30, c'est pas mal. Et si vous voulez la liste des nombres de Fibo, il suffit d'écrire cette récursivité non terminale:

POUR LISTE_FIBO :N
SI EGAL? :N 0 [STOP]
LISTE_FIBO :N - 1
EC FIBO :N
FIN

Maintenant que nous avons la procédure FIBO efficace, il nous est possible de vérifier la convergence de un+1 /un.

POUR CONV :D :F
SI EGAL? :D :F [STOP]
EC DIV FIBO :D +1 FIBO :D
CONV :D + 1 :F
FIN

Tapez CONV 1 25 et vous voyez que ça converge vers f .

De même vous pouvez vérifier que un+3 x un - un+2 x un+1. Essayez pour différents nombres. Il serait facile de transformer FIBO en LUCAS.

Et enfin pour terminer ce chapitre sur l'arithmétique et Logo, une propriété que j'ai trouvée dans "Turtle Geometry" , puis au paragraphe suivant une idée pour trouver ces fameux nombres de Bezout (ou résoudre des équations diophantiennes).

FIBO PGCD :A :B = PGCD FIBO :A FIBO :B. Vous pouvez la vérifier sur quelques nombres. La démonstration est parait-il "hard".



Egalité de Bezout et récursivité non terminale


Reprenons l'algorithme d'Euclide vu au début de ce chapitre d'arithmétique en le suivant sur un exemple avec les nombres 64 et 36.

"Descendons" l'algorithme à partir de 64 et 36 pour trouver leur PGCD 4 (par soustractions successives), puis essayons de "le remonter" pour trouver deux nombres p et q tels que :

p*64+q*36= 4.

Nous aurons ainsi trouvé une «égalité » de Bezout.
Vous verrez qu'il n'y a pas unicité du couple trouvé (p,q) à partir des deux nombres 64 et 36 (nommés R et N ci dessous).

R N p
q
pR+qN=d
64 36 -5 9 -5*54 + 9*36 = 4
I
64 - 36 36
28 36 -5 4 -5*28 + 4*36 = 4
I
28 36 - 28
28 8 -1 4 -1*28 + 4*8 = 4
I
28-8 8
20 8 -1 3 -1*120 + 3*8 = 4
I
20-8 8
12 8 -1 2 -1*12 + 2*8 = 4
I
12 - 8 8
4 8 -1 1 -1*4 + 1*8 = 4
I
4 8 - 4
4 4 0 1 0*4 + 1*4 = 4


Quand vous avez fini de "descendre l'algorithme", vous obtenez deux valeurs égales pour R et N. Elles sont le PGCD de tous les couples (R;N) rencontrés.

Pour "faire la première égalité de Bezout", à la dernière ligne de la descente, vous pourrez affecter par exemple p et q à 0 et 1.

0 * 4 + 1 *4 = 4

Vous pourriez faire d'autres choix que le couple (0;1) pour (p;q).

Puis vous "remontez l'algorithme" ligne à ligne, en vous souvenant des changements effectués dans la descente. Par exemple, si en descendant du niveau n au niveau n+1, vous avez remplacé R par R - N en gardant N, en remontant du niveau n + 1 au niveau n, vous garderez p et changerez q en q - p.

R N p q - p pR + (q-p)N = d <- niveau n
R - N N p q p(R - N) + qN = d <- niveau n + 1

Par contre, pour le changement de N en N-R en descente avec R conservé, en remontant,vous garderez q et vous changerez p en p - q .

R N p - q q (p - q)R + qN = d <- niveau n
R N - R p q pR + q(N - R) = d <- niveau n + 1

Pour faire tout ça, il vous suffira de modifier EUCLIDE de la sorte :

POUR EUCLIDE :N :R
SI EGAL? :R :N [DONNE "P 0 DONNE "Q 1 DONNE "PGCD :N STOP]
SI PLG? :N :R [ EUCLIDE :N - :R :R DONNE "Q :Q - :P] [EUCLIDE :N :R - :N DONNE "P :P - :Q]
EC PH PH PH PH PH PH PH PH :P "* :N "+ :Q "* :R "= :PGCD
FIN

Avec la magie de la récursivité non terminale, c'est le dernier "clône" EUCLIDE (vous pouvez le nommer "EUCLIDE 4 4") qui se charge de dire que P vaut O, que Q vaut 1, et que le PGCD est le nombre N, de valeur 4, que lui a passé son collègue précédent (nommé "EUCLIDE 4 8").

EUCLIDE 4 4 écrit les trois nombres dans trois variables globales.

Quand EUCLIDE 4 8 reçoit le message qui remonte, il regarde ce qu'il lui restait à faire lorsqu'il avait appelé EUCLIDE 4 4, juste après qu'il ait fait son test.

Il s'était dit :
"4 est-il plus grand que 8 ? non donc j'appelle EUCLIDE 4 4"

Maintenant qu'EUCLIDE 4 4 lui a rendu le résultat de son travail, il reste à faire à EUCLIDE 4 8 la fin du test (le "sinon"). Il met dans "P le résultat de :P - :Q soit 0 - 1 (ce qui fait -1). Il ne modifie pas la variable "Q, qui vaut donc toujours 1, ni "PGCD qui est 4.
Puis il écrit, en utilisant ses variables locales "N et "R qui valent 4 et 8 :

-1*4+1*8 = 4

Cette fois EUCLIDE 4 8 a bien fini ... au tour de EUCLIDE 12 8 de faire son travail ... Regardez, ils ont tout fait !

? EUCLIDE 64 36

-1 * 4 + 1 * 8 = 4
-1 * 12 + 2 * 8 = 4
-1 * 20 + 3 * 8 = 4
-1 * 28 + 4 * 8 = 4
-5 * 28 + 4 * 36 = 4
-5 * 64 + 9 * 36 = 4

Fabuleux ? non ?

Vous pourrez améliorer votre équipe de travailleurs en leur apprenant à utiliser les divisions successives à la place des soustractions successives. Vous pouvez également souhaiter qu'ils vous rendent la liste [:P :Q] sans écrire ... Proposer un démarrage du premier couple (p,q) avec un choix aléatoire de l'un des deux ...



Barycentre et théorème de Guldin


Petit rappel: pour une surface de révolution, son aire est égale à la longueur de la ligne qui engendre la surface par la longueur du cercle engendré par le centre de gravité de la ligne. C'est le théorème de Guldin2 . Ce qui donne pour la sphère ci-dessous:
Aire = demi-périmètre du cercle x périmètre du cercle décrit par le centre de gravité du demi-cercle.


Voyons comment la tortue peut vérifier ce théorème.
Nous allons tout d'abord faire décrire à la tortue un demi-cercle. Rien de plus facile:

POUR CERCL
DONNE "C [[0 0]]
TD 1
REPETE 90 [AV 5 TD 2 DONNE "C PH :C LISTE POS "]
FIN

Lancez la procédure CERCL, Logo s'occupe de dessiner et va placer dans une liste de listes (variable C) les coordonnées des différents points sur lesquels elle passe. Si vous demandez l'écriture de C, ça devrait vous donner à peu près cela:

[0 0] [0,08726203218640194 4,999238475781965] [0,34894181340109753 9,992386149554818] [0,7847205271393705 14,973359640013541] ...

Une liste de 91 listes.

Il nous faut maintenant écrire les procédures pour trouver le centre de gravité de cette ligne, c'est à peu près l'isobarycentre de ces 91 points.

POUR ISOBARYCENTRE :A
RENDS PH DIV SOM X :A COMPTE :A DIV SOM Y :A COMPTE :A
FIN

Pour obtenir l'abscisse du centre de gravité, il suffit de sommer les abscisses des différents points rencontrés par la tortue, il nous faut donc écrire deux procédures, l'une qui récupère la liste des abscisses, l'autre qui somme les nombres d'une liste
La liste des abscisses sera écrite de la façon suivante:

POUR X :A
SI VIDE? :A [RENDS "]
RENDS PH PREM PREM :A X SP :A
FIN

Idem pour la liste des y mais on prend dans chaque élément de la liste le dernier.

POUR Y :A
SI VIDE? :A [RENDS "]
RENDS PH DER PREM :A Y SP :A
FIN

Il suffit décrire une procédure qui additionne les nombres d'une liste:

POUR SOM :A
SI VIDE? :A [RENDS 0]
RENDS SOMME PREM :A SOM SP :A
FIN

Comme nous voulons seulement vérifier la validité du théorème de Guldin, nous allons procéder de la façon suivante. Comme on sait déjà que l'aire est égale à 4&Mac185;R2. Le quotient du diamètre du cercle par le rayon du cercle engendré par le centre de gravité doit être égal à P . Il nous suffit donc de demander à Logo de faire ce calcul en tapant:

VE
CERCL
EC DIV PREM POS DER ISOBARYCENTRE :C

Allez-y et vous verrez c'est pas si mal.
Naturellement, cette pratique sera plus intéressante à utiliser lorsque la figure engendrée sera plus complexe.
Il est aussi possible d'étudier la procédure BARYCENTRE dans un cadre plus géométrique, dans ce cas on écrirait la procédure barycentre de la façon suivante:

POUR BARYCENTRE :A :B
SI EGAL? COMPTE :A 2 [RENDS BARY :A :B]
DONNE "BARY_PROVISOIRE
BARYCENTRE LISTE PREM :A PREM SP :A LISTE PREM :B PREM SP :B
RENDS BARYCENTRE MP :BARY SP SP :A MP SOMME PREM :B PREM SP :B SP SP :B
FIN

MP item1 item2 est une primitive Logo qui place en première place item1 d'une liste item2. Donc si je lis bien du Logo, ça signifie qu'on recommence la procédure BARYCENTRE avec une nouvelle liste dans laquelle les coordonnées du barycentre des deux premiers points remplacent celles des deux premiers points (les deux premiers points sont supprimés SP SP :A) et dans la liste des coefficients, les deux premiers coefficients sont remplacés par leur somme.
Il suffit d'écrire la procédure BARY :A :B qui va rendre les coordonnées du barycentre de deux points affectés des coefficients placés dans la liste B.
L'intérêt de travailler de cette façon-là c'est qu'on généralise la procédure BARYCENTRE mais aussi que l'on peut visualiser le chemin engendré par les différents centres de gravité transitoires. Voir à cet effet la brochure IREM : LOGO et géométrie - Alain Bois et Jacques Delgoulet 1986.




Accueil m@ThICE