08. Contrat plus ou moins implicite

Commentaires


Mise à jour 2023-11-17 par Mathilde Ohm
12. D’une idée, l’autre
Page suivante

Novembre (semaine 47)

Après un peu d’hésitation, j’ai fini par comprendre la différence entre suite arithmétique et suite géométrique. Pour calculer le successeur d’un terme au sein d’une suite arithmétique l’opération consiste à ajouter le nombre constant r. En revanche, pour calculer le successeur d’un terme au sein d’une suite géométrique  il faut  multiplier par  le nombre constant q. r pour raison et q comme quotient, parce qu’il est fréquent de multiplier par un nombre fractionnaire et notamment dans les emprunts (ou les prêts) qui sont des suites géométriques.

Pour expérimenter les suites géométriques, notre professeur nous soumet un programme Python de calcul de q^n.

Dans le numéro 7 de mai 1979 (page 56), de l’ordinateur individuel, est paru ce programme de calcul de q puissance n, pour calculer les termes d’une suite géométrique de raison q de rang n et de terme initial U_0=1.

Je peux essayer le programme dans le cadre de droite. Pour cela je  réponds aux questions  sur le panneau noir, et, pour essayer un autre exemple, je clique sur la petite flèche verte juste au-dessus.

J’essaye  ce programme avec 5 \times 5 \times 5 = 5^3,  réponse  125
J’essaye encore avec x = 4 et n = 2 ; réponse 16.
6 \times 6 = 6^2= 36
7^3 = \ldots
Je pourrai être satisfaite  et m’arrêter là.
Pourtant, un dernier essai avec  x = 10   et n = 1  s’avère poser problème.

Suivons un exemple pas à pas, il s’agit de calculer 5^2.
Si j’examiner le programme avec l’intention de le corriger, je peux le suivre à la trace en inscrivant dans un tableau le résultat des actions ligne par ligne.

J’ai noté quelques embuches stupides à dépasser :

  • Le caractère « \# » signifie « commentaire », c’est-à-dire que la ligne commençant par « \# » ne fait rien d’autre que renseigner le lecteur humain ex :« 2 # Ordinateur individuel, numéro 7 de mai 1979 (page 56) » ;
  • Il convient de distinguer le caractère « = » du caractère « == ». La valeur d’une variable est conservée dans une zone mémoire. Si SOMME vaut 10, la notation SOMME = SOMME + 5 affecte à la zone SOMME la valeur précédente de SOMME + 5 (soit 15) . Autre exemple : SOMME = SOMME + SOMME fait passer la zone valeur SOMME de 10 à 20. En revanche, le caractère « == » signifie que égalité (au sens de pareil)
  • J’ai observé que le prof qualifie de variables « a » et « i »  qui évoluent au cours de l’éxécution, alors que «  n  », qui reste inchangé,  est désigné aussi comme variables  bien que gardant une valeur constante. Je vais essayer de suivre les états successifs de « a » et de « i.

 

Excellent, semble-t-il : 5 \textrm{ puissance } 2 = 25
Et je remarque que la première ligne de la boucle « while »  a = a \times x  montre bien que l’on calcule x^n  par multiplications successives. Suivons un autre exemple, cette fois calculons 5^1 ; mais là, surprise, le programme affiche  : 5 \textrm{ puissance } 1 = 25  aussi.Quelle conclusion tirer de ces essais ?  La première conclusion c’est qu’essayer un programme ne prouve pas qu’il soit correct, au mieux, est-il possible de constater qu’il se trompe.

Bien que je ne puisse pas consulter l’auteur de ce programme, je peux admettre son intention explicitement indiquée par la première ligne : le commentaire (1) # Calculer x^n.  Ai-je ma lu ? Ai-je mal utilisé le programme ? Le texte publié,  il y a une quarantaine d’années ne semble pas correspondre à ce que je lis. Y aurait-il deux lectures différentes du même programme ? Cela m’évoque l’écoute de la toccata de Jean-Sébastien Bach l’une interprétée par Michel Chapuis et l’autre par Jacques Loussier.

Cependant, si je peux comprendre qu’une  partition d’œuvre musicales puisse  être interprétée de façons  différentes par deux musiciens, je ne pense pas qu’un programme puisse se comporter différemment dans deux usages aussi proches. La recherche de ce qui distingue les deux exécutions (5^2 et 5^1)  m’a demandé un peu de patience et mobilisé mon désir d’élucider le problème.

Pour cela j’ai ajouté une utilisé une instruction particulière : assert, une sorte de commentaire, une espèce  d’hypothèse,  que j’ai insérée dans le programme.

Il y a toutes sortes de commentaires ! Mais, notre prof nous conseille d’utiliser l’instruction assert pour s’assurer de la justesse de la proposition.  (C’est du globish, ie global-english),  en français on peut dire assertion, affirmation croyance…). On peut,  essentiellement l’utiliser pour comprendre le sens de ce qui est écrit dans le programme.

 Inutile, dit le prof, de l’employer à la place d’une condition comme if then else   :

assert note \leq 20
\overbrace{\hspace*{4cm}}

Si l’expression est vraie,
le programme continue.

Si l’expression est fausse,
le programme s’arrête.
En revanche, c’est fort utile pour s’assurer des relations entre les variables par exemple :

    \[ $a = x^{i} \left\{\begin{array}{rl} ... \\ (9)   & \textrm{assert }  a == x^{i} \\ (10) & a = a\times x \\ (11)  & \textrm{ assert}  a = x^{i+1}\\ (12)  & i =  i+1 \\ (13)  &\textrm{assert }   a=x^{i} \end{array}\right.$ \]

Bon, c’est vrai que cela réclame quelques minutes  pour comprendre, mais, franchement c’est utile. !

 

Il me faut entrer dans les détails.
La ligne (9)  opère par multiplications répétées par x. Oui. Le programme fonctionne correctement pour les puissances n supérieures ou égales à 2, mais, hélas, pour les puissances égales à 0  ou 1, le résultat est catastrophique ;
le programme affiche : \pmb{5} puissance \pmb{1} = \pmb{5^1 = 25} ! 
et \pmb{6} puissance \pmb{0} = \pmb{6^0 = 6 } !
Pour voir loin, il faut regarder de près !

Examinons la boucle (7-12) : La ligne (7)  attribue à la variable a la première valeur de la suite x, x^2, x^3....x^n
La ligne (10)  opère par multiplications répétées par x. Puisque la variable a  représente le terme U_i, je peux exprimer a en fonction de i.
J’arrive la 1^{\grave ere} fois en (7) en venant de (5) avec  a = x^1 \textrm { et } i = 0. Je peux donc écrire l’exposant sous la forme i+1 :

    \[ a = x^{i + 1} \left\{\begin{array}{rl} ... \\ (9)   & \textrm{assert }  a == x^{i + 1} \\ (10) & a = a\times x \\ & \textrm{ assert }  a == x^{i+2}\\ (11)  & i = i+1 \\ &\textrm{assert }   a=x^{i+1} \end{array}\right. \]

Je remarque que l’assertion a=x^{i +1} est rétablie, avec une valeur de l’exposant  supérieure à celle de i.
Cependant,  la donnée introduite est n, et non pas i . Il faut donc comparer i et n.
Or par l’initialisation a = x et i = 0. Nous constatons que le programme calcule a = x^{n} si et si seulement n > 1.

 

Il n’est pas très facile de corriger le programme.

Il me semble mieux comprendre ce programme que l’auteur.  Il paraît probable que le programmeur  a mal choisi son test d’arrêt, et qu’il a cherché à le corriger en introduisant la variable t calculée ligne (12) dont la valeur est constante. Son calcul dans la boucle est inattendu.

Il est plus important de considérer les situations que les actions, et éviter cette question  « Comment faire ? » et préférer une réflexion sur les relations.

Pour rédiger le programme, il faut d’abord proposer une situation générale :
Supposons que l’on ait fait une partie du travail, et calculé a=x^i pur un i\leq n. On écrirait : (8)  assert a == x^i and i \leq n
Si i == n, c’est fini, sinon il faut se rapprocher de la solution en faisant croître i   

Il reste à voir le démarrage, c’est-à-dire trouver des valeurs de a et i telles que l’assertion soit vérifiée pour tout n positif ou nul. Il faut prendre i=0 et donc a=x^0 = 1. D’où le nouveau programme correct (pour x \neq 0) ci-contre.



08. Contrat plus ou moins implicite
<iframe loading="lazy" src="https://www.youtube.com/embed/YVR0G4Nluao" frameborder="0" height="%%hauteur%%" width="%%largeur%%"></iframe> 12. D’une idée, l’autre
Page suivante