samedi 20 février 2016

B Method, Méthode B, Machine abstraite, Spécification formelle

Une galante introduction à la notion de machine abstraite en B

En rangeant des papiers, je suis tombé sur "Le journal secret, n° 7 de mai 1938, Revue d'éducation sexuelle. J'en ai hérité de ma mère sage-femme. Le premier article s'intitule "Donneuses" de Lait. Comment on "trait" les femmes.

 Je vais en scanner les pages. Que d'évolutions depuis 38 !
Cherchant sur la Toile, je n'ai pas trouvé l'histoire de cette revue, mais je suis tombé sur un de mes cours ! je le reproduit ici.
A ce sujet, la conférence 2014 sur la Méthode B a lieu en France, à Toulouse. Nous l'avions initialisée à Nantes.
http://www.irit.fr/ABZ2014/
http://www.methode-b.com/2014/04/abz-2014-toulouse-du-2-au-5-juin/

Une galante introduction à la notion de machine abstraite en B
(c) Henri Habrias
Département informatique
I.U.T. de Nantes
7- 01- 2001


«Le baron Warseberg, malgré qu’il entretenait la demoiselle Laforest voyait encore les filles de la Varenne. Il puisa dans le flanc de Mlle Dorville ce poison destructeur, qu’il procura à Mlle Laforest, qui de son côté en fit présent à M. Saimson, mousquetaire, avec qui elle greluchonait, lequelle par la même voie en fit cadeau à Mlle Ricourt, de la Comédie Italienne, qui, sans façon la voitura à M. de la Ferté, intendant des Menus Plaisirs, qui en gratifia Mlle Rozetti, qui, de même, me la souffla… »
Mémoires du chevalier de Fontainieu qui raconte les origines d’une galanterie (entendez une blennorragie) qu’il attrapa, in Le Journal Secret, Revue d’éducation sexuelle, 1et Mai 1938
NOTA 1 :
Cette spécification est écrite en utilisant la notation ASCII de B. Son avantage : disponible sur tout clavier et utilisable en HTML. Vous trouverez ici les tableaux de correspondance entre le notation dite "mathématique" de B et la notation ASCII.
NOTA 2 :
Cette spécification n'a pas été vérifiée avec l'Atelier B. Nous vous proposons de vous en servir lors du premier td d'Atelier B.
MACHINE
Galanterie
SETS
PERSONNE ; SEXE = {masc, fem}; NOM ;
METIER
/* Les SETS sont des ensembles qui n’ont aucun élément en commun. On les appelle aussi « ensembles de base ». Ce sont des ensembles finis et non vides (comme on construit tous les autres ensembles à partir d’eux, si ils étaient vides on obtiendrait des ensembles vides !) . On ne peut écrire des énoncés comme PERSONNE \/ SEXE ou encore PERSONNE := PERSONNE – {pp}. Les SETS sont en quelque sorte des constantes.
On construit des ensembles à l’aide du produit cartésien et de l’opérateur ensemble des parties (ou encore ensemble des sous-ensembles d’un ensemble).
Ici, le set SEXE est défini en extension. */
VARIABLES
APourSexe, AdonnéGalanterieA, ApourMétier, Personnes
DEFINITIONS
Homme == APourSexe~ [{masc}] ;
Femme == APourSexe~ [{fem}] ;
/* APourSexe~ [{masc}]
dénote l’image relationnelle de l’ensemble singleton {masc} par l’inverse de la fonction APourSexe.
Le symbole ~ dénote la relation inverse (on dit aussi réciproque). Ces définitions utilisent la spécification de la fonction APourSexe qui est donnée dans l'invariant (voir ci-dessous).
Le symbole == dénote en ASCI une définition. A ne pas confondre avec le symbole = dénotant le prédicat d’égalité. */
/* Les définitions sont ce que les informaticiens appellent des « macro » (macro-instructions). Ce ne sont pas des variables. Une variable peut se trouver en partie gauche d’une substitution ( :=). Ce n’est pas le cas d’une définition. Une définition est un nom de morceau de texte de spécifications. */
INVARIANT
Personnes < : PERSONNE &
APourSexe : Personnes --> SEXE &
ADonnéGalanterieA : Homme <-> Femme &
ADonnéGalanterieA /\ ADonnéGalanterieA~ = {} &
APourMétier : Personnes +-> METIER
/* L’invariant est un prédicat. Tout état du système doit respecter l’invariant. */
/* : est la notation ASCII pour l’appartenance.
& est la notation ASCII pour le « et » logique.
  A < : B est le prédicat d’inclusion de l’ensemble A dans l’ensemble B
A --> B est l’ensemble des fonctions totales (on dit en français, applications) de l’ensemble A vers l’ensemble B)
A <-> B est l’ensemble des relations quelconques de A vers B. Voir exemple de relation avec des diagrammes sagittaux, avec des "tables relationnelles" (pour causer comme les gens des "bases de données")
A +-> B est l’ensemble des fonctions partielles de l’ensemble A vers l’ensemble B. */
/* L’invariant est un prédicat. Ici il s’agit d’une conjonction de prédicats élémentaires.
Personnes < : PERSONNE se paraphrase ainsi : « Personnes est une variable qui prend comme valeurs un sous-ensemble de l’ensemble PERSONNE. »
APourSexe : Personnes --> SEXE se paraphrase ainsi : «  APourSexe est une variable qui prend comme valeur un élément de l’ensemble de toutes les fonctions totales (on dit dans les livres de mathématiques français, application) de l’ensemble Personnes vers l’ensembleSEXE. En d’autres termes, ApourSexe est une variable qui est une fonction totale (le verbe être est ici utilisé dans le sens de l’appartenance ensembliste) »
ADonnéGalanterieA : Homme <-> Femme se paraphrase ainsi « AdonnéGalanterieA est une variable qui prend comme valeur un élément de l’ensemble de toutes les relations quelconques de l’ensemble Homme vers Femme »
ADonnéGalanterieA /\ ADonnéGalanterieA~ = {} se paraphrase ainsi « si une personne p1 donne galanterie à une personne p2 alors p2 ne donne pas galanterie à p1. Ceci permet aussi d'exprimer que l'on ne se donne pas galanterie à soi-même.»
APourMétier : Personnes +-> METIER se paraphrase ainsi « ApourMétier est une variable qui prend comme valeur un élément de l’ensemble de toutes les fonctions partielles de Personne vers METIER »
*/
INITIALISATION
ApourSexe, AdonnéGalanterieA, ApourMétier, Personnes := {},{},{}, {}
/* := est le symbole de la substitution simple. Ici on fait quatre substitutions en parallèle.
On pouvait aussi écrire en B, ainsi :
ApourSexe := {} ||
AdonnéGalanterieA := {} ||
ApourMétier := {} ||
Personnes := {}
Notons que dans une machine abstraite B, on n’a pas le droit d’utiliser le séquencement (noté par ;), lequel est réservé aux étapes suivantes du raffinage. */
/* On doit s’assurer qu’il y a au moins un état qui satisfait l’invariant. */
/* Voici un état du système décrit par le texte fourni */

Personnes = {Warseberg, Dorville, Lafores, Saimson, Ricourt, de la Ferté, Rozetti, Fontainieu}ApourSexe = {(Warseberg, masc), (Dorville, fem), (Laforest, fem), (Saimson, masc), (Ricourt, fem), (de la Ferté, masc), (Rozetti, fem), (Fontainieu, masc)}
AdonnéGalanterieA = { Dorville, Warseberg), (Warseberg, Laforest), (Laforest, Saimson), (Saimson, Ricourt), (Ricourt, de la Ferté), (de la Ferté, Rozetti), (Rozetti, Fontainieu)}
ApourMétier = { (Saimson, mousquetaire), (Ricourt, comédienne), (de la Ferté, intendant des Menus Plaisirs), (Fontainieu, chevalier)}
*/
OPERATIONS
NouvellePersonne (Sexe) =
PRE
Sexe : SEXE &
PERSONNE – Personnes /= {}
/* Le signe = ici ne dénote pas le prédicat d’égalité mais une définition. */
/* La précondition est la plus faible précondition pour que l’opération respecte l’invariant.
Par exemple, si l’invariant est x < 10, la plus faible précondition pour que l’opération x := x + 1 respecte cet invariant (ce qui s’écrit [x := x + 1] (x < 10) ) est : x + 1 < 10 soit x < 9. C’est bien la plus faible (x = 0 par exemple sera bien plus forte (serait plus exigeante que ce qui est suffisant)).*/
/* Si l’on respecte la précondition, l’opération conduira à un état respectant l’invariant. On a « typé » le paramètre d’entrée de l’opération et on s’assure qu’il reste des personnes qui ne sont pas encore « nées » */

THEN
ANY pp WHERE pp : PERSONNE – Personnes THEN
Personnes := Personnes \/ {pp} ||
ApourSexe := ApourSexe \/ {pp |-> Sexe}
/* Le symbole ASCII \/ dénote l’union ensembliste. pp |-> Sexe est un couple. Le symbole ASCII |-> sert à exprimer un couple (maplet). */
/* On fait un choix indéterministe (ANY pp WHERE) dans l’ensemble des personnes non encore « nées ». On spécifie deux substitutions en parallèle. Si on ne faisait pas la substitution ApourSexe := ApourSexe \/ {pp |-> Sexe}, on ne respecterait pas l’invariant (pour toute personne, on doit avoir enregistré de quel sexe est cette personne). */
END ;
END ;
NouvelleGalanterie (Pers1, Pers2) =
PRE
Pers1 : Personnes &
Pers2 : Personnes &
Pers2 |-> Pers1 /: AdonnéGalanterieA
THEN
AdonnéGalanterieA : = AdonnéGalanterieA \/ {Pers1 |-> Pers2}
END ;
SupressionPersonne (Pers) =
PRE
Pers : Personnes &
Pers / : dom (APourMétier) &
Pers /: (dom (AdonnéGalanterieA) \/ ran (AdonnéGalanterieA))
/* / :  est le symbole ASCII pour la négation de l’appartenance ensembliste
dom (APourMétier) désigne le domaine de la relation APourMétier */
/* Si on n’avait pas la contrainte Pers / : dom (ApourMétier), il faudrait « enlever » le couple (Pers |-> ApourSexe (Pers)) de l’ensembleApourSexe.
Attention ! Nous venons de faire un abus de langage. On n’enlève pas un élément d’un ensemble. L’ensemble {1, 2, 3} est l’ensemble {1, 2, 3} ad vitam aeternam. Ce n’est pas une variable.
Il aurait fallu dire « substituer à la variable ApourSexe, l’ensemble égal à la valeur actuelle de cette variable moins l’ensemble singleton {(Pers |-> ApourSexe (Pers))}. */

THEN
Personnes := Personnes – {Pers} ||
APourSexe := {Pers} <|| ApourSexe
/* Le symbole ASCII <|| est celui de l’antirestriction de domaine. */

END ;
Galants <- font="" quiaattrap="">
BEGIN
Galants := dom (AdonnéGalanterieA) \/ ran (AdonnéGalanterieA)
END
END
/* dom (R) représente le domaine de la relation RA. ran (R) représente le codomaine de la relation R . Le symble ASCII \/ est celui de l'union ensembliste.  */
.
Nouvelle spécification
Si nous modifions la liste des variables et l’invariant en supprimant la variable Personnes, et en ajoutant Personnes dans les définitions :
Personnes == dom (ApourSexe), nous devons modifier les opérations :

OPERATIONS
NouvellePersonne (Sexe) =
PRE
Sexe : SEXE &
PERSONNE – Personnes /= {}
THEN
ANY pp WHERE pp : PERSONNE – Personnes THEN
ApourSexe := ApourSexe \/ {pp |-> Sexe}
END ;
END ;
NouvelleGalanterie (Pers1, Pers2) =
PRE
Pers1 : Personnes &
Pers2 : Personnes &
Pers2  |-> Pers1 :/ AdonnéGalanterieA
THEN
AdonnéGalanterieA : = AdonnéGalanterieA \/ {Pers1  |-> Pers2}
SupressionPersonne (Pers) =
 PRE
Pers : Personnes &
Pers / : dom ((AdonnéGalanterieA) \/ ran (AdonnéGalanterieA))
THEN
ApourMétier := {Pers} <|| ApourMétier
 END
END
Quelques opérations supplémentaires :
Opération donnant l'ensemble des personnes à l'origine de la "galanterie" d'une personne donnée
/* Voici une opération ayant paramètre d'entrée et paramètre de sortie.*/
/* ADonnéGalanterieA+ est la fermeture transitive et non réflexive d'une relation.
Exemple :
soit la relation R = {(1,2), (2, 3), (3, 4)}
R2= R ; R = {(1, 3), (3, 4)}
Le symbole ; est celui de la composition "en avant".
R3 = R2; R = {(1, 4)}
R4= R; R = {(1, 4)}. On a obtenu la fermeture transitive. Ici elle n'est pas réflexive : on n'a pas de couple dont la partie gauche est égale à la partie droite. */
/* Remarquons que les paramètres d'entrée sont typés dans la précondition. Mais que ce n'est pas le cas des paramètres de sortie. On ne peut vérifier leur type lors de l'appel de l'opération. Leur typage est fourni après le THEN. */
ALOrigine <-- font="" pers="" quialorgine="">
PRE
pers : ran (ADonnéGalanterie)
THEN
ALOrigine :=  (ADonnéGalanterieA+)~ [{pers}]
END
Opération donnant l'ensemble des femmes ayant transmis la "galanterie"
/* Le symbole ASCII <| est celui de la restriction du domaine d'une relation. */

Fem <-- atransmis="</font">
BEGIN
Fem := dom (Femme <| ADonnéGalanterieA)
END
Nous n'avons pas vérifié cette spécification. Il doit certainement y avoir des erreurs !Exercice :
- Vérifiez cette spécification avec l'atelier B, à savoir :
1) Vérifier  la syntaxe, le typage des variables
2) Générer les obligations de preuve
3) Prouver chacune...mais il se peut que certaines spécifications d'opération ne respectent pas l'invariant. En conséquence, vous ne pourrez prouver que :
Précondition &  invariant implique que la substitution établit l'invariant
Et la suite ?
Avant d'aller plus loin, remarquons que :
Dans une spécification abstraite :
on peut avoir de l'indéterminisme. Nous en avons eu un exemple ici avec le choix indéterministe dans un ensemble.
Normal ! on ne veut pas tout dire dès le début. On laisse des décisions pour la suite de la conception.
on a des préconditions

Normal ! quand on spécifie par exemple une opération de division, on veut que ce soit une fonction. Et la fonction division ne donne pas comme résultat : "je ne peux pas diviser" ! Propos étonnant ?! Non, voyez vos livres de mathématiques.
Mais vous savez qu'une fonction a un "domaine de définition". La précondition s'assure que l'on est bien dans le domaine de définition.
on n'a pas de séquencement

Normal ! on veut être abstrait et ne pas être contraint par le séquencement (qui va nous être imposé par la suite par l'ordinateur). Si on veut rester proche de l'expression du besoin par le client, il ne faut pas être obligé de choisir, dès la spécification, un séquencement là où c'est hors de propos.
Par la suite :

On raffine une machine abstraite. Le raffinage consiste à se rapprocher d'une implantation. Le raffinage se fait "à signature" identique. C'est-à-dire que l'on ne change pas les paramètres des opérations.
Quand on écrit une machine qui raffine une autre machine, dans l'invariant de la nouvelle machine, on relie les variables de la machine abstraite aux variables de la machine concrète (on appelle cet invariant, invariant de collage (gluing invariant).
On introduit :

- le séquencement
- on diminue l'indéterminisme
- on affaiblit les préconditions
On a des machines dites REFINEMENT
jusqu'à arriver à des machines dites IMPLEMENTATION
dans lesquelles :

- il n'y aura plus de parallèlisme (on ne trouvera plus le symbole ||)
- on trouvera la séquence (;) et la boucle
- il n'y aura plus de préconditions dans le code des opérations
A chaque étape, il faudra prouver que le raffinage est correct.
Donc, en B, on distingue deux ensembles de preuves :

- les preuves d'opération (qui sont faites à un niveau d'abstraction)
- les preuves de raffinage (qui portent sur la relation de raffinage entre une opération abstraite et une opération plus concrète).
Bibliographie
J.R. Abrial, The B-Book, Assigning programs to meanings, Cambridge University Press, 1996
ISBN : 0 521 49619 5

mercredi 17 juin 2015

Exposé de J.R. Abrial au Collège de France, avril 2015

Je vous signale l'exposé au Collège de France de JR Abrial

http://www.college-de-france.fr/site/gerard-berry/seminar-2015-04-01-17h30.htm

Cette présentation est celle d’un chercheur vieillissant qui porte un
regard historique sur les trente dernières années de son travail.

Il y a deux sortes de chercheurs : les prolifiques et les monomaniaques.
Je fais partie de la seconde catégorie, car j'ai toujours pratiqué le même
genre d’investigations, à savoir la spécification et la construction
vérifiée de systèmes informatisés.

Ce travail, autant théorique que pratique, s’est concrétisé au cours de
toutes ces années dans trois formalismes voisins : Z, B et Event-B (dont
je ne suis pas, loin de là, le seul contributeur). Je vais tenter
d’expliciter comment les idées que contiennent ces formalismes et les
outils correspondants ont lentement émergés de façon parfois erratique.

Je tenterai aussi de préciser les multiples influences qui ont participé à
cette évolution. En particulier, je montrerai comment plusieurs
réalisations industrielles ont permis de progresser dans ce domaine. Mais
je soulignerai aussi les échecs et parfois les rejets de la part de
communautés tant universitaires qu’industrielles.

Pour finir, je proposerai quelques réflexions et approches pour le
financement de recherches telles que celle-ci.

-- 


mercredi 27 mars 2013

Le langage de prototypage me to

H. Habrias

Voir chapitre XI, VDM et me too de H. Habrias, Introduction à la spécification, Masson,1993

EVALUATION D'UNE EXPRESSION

3 * 4;= 12;
{(a, b) | a <- b="" font="">
=  {(1,3), (1,4), (2,3), (2,4)};

OBJET ET OPERATIONS

n == e;

affecte le résultat de l'évaluation de e au nom n.
mise à jour de l'environnement en liant n à l'évaluation de e.

aime == { ("Dudule, "Paulette"), ("Paulette", "Dutonf"), ("Dutonf", "Logique")};=  AIME;
aime;
= {(Dudule, Paulette), (Paulette, Dutonf), (Dutonf, Logique)};
nouveauaime == {("Dutonf", "Bouffe"), ("Dutonf", "Logique")};
= NOUVEAUAIME;
nouveauaime;
= {(Dutonf, Bouffe), (Dutonf, Logique)};
aime == aime union nouveauaime;
= AIME;
aime;
 
= {("Dudule, "Paulette"), ("Paulette", "Dutonf"), (Dutonf, Bouffe), (Dutonf, Logique)};

Vous voulez observer les noms des objets en cours de stockage dans l'environnement

obs;= {NOUVEAUAIME,AIME};

Avons-nous défini des opérations ?

ops;= {};
non !

Les opérations sont définies comme des fonctions

sq(x) = x * x;= SQ;
ops;
= {SQ};

Vous voulez sauver votre environnement dans un fichier.

save("nomfichier");

et recharger ce fichier
 
load("nomfichier");
Nombres, chaînes, etc.
 
obj1 == 1;
= OBJ1;obj1;
= 1;
10;
= 10;
-10.421;
= -10.421;
x == 31;
=X;
-X;
= -31;
is_numer(5);
= TRUE;
is_number("Dudule");
= FALSE;
"Hello";
= Hello;
salut(n) == ["Hello", n];
= SALUT;
salut("Dudule");
= [Salut, Dudule];
is_string("Dudule");
= TRUE;
is_string(["Dudule", "Dutonf"]);
= FALSE;
"Dudule" = "Dutonf";
= FALSE;
"Dudule" > "Dudule";
= FALSE;

6 + 7;
= 13;
23 - 8;
= 15;
7 * 8;
= 56;
40.0 / 3;
= 13.3333333;
13 truncate 3;
= 4;
37 mod 10;
= 7;
true;
= TRUE;
true and false;
= FALSE;
true and true;
= TRUE;
true or false;
= TRUE;
false or (false and false);
= FALSE;
not(false);
= TRUE;
true => true;
= TRUE;

true => false;
= FALSE;
false = false;
TRUE;
true = false;
= FALSE;
["a", {"longue", "complexe"}, "expression"] =
["a", {"longue", "complexe"}, "expression"] ;
= TRUE;
3 /= (2 * 2);
= TRUE;
{1,2,3} /= {3,2,1};
= FALSE;

Conditionnelle

sum(x,y) == if x = 0 then y else 1 + sum(x - 1, y);
= SUM;sum(15,4);
= 19;

Enfin, voici la définition de fonctions !
 
sq(x) == {i*i | i <- font="" x="">
=SQ;sq({3,4,5,6});
= {9,16,25,36);
cp(x, y) == {(p,q) | p <-x font="" q="" y="">
CP;

cpsq(x) == cp(sq(x),sq(x));
= CPSQ;
cpsq({1,2,3});
= {(1,1), (1,4), (1,9), (4, 1), (4,4), (4,9), (9,1), (9,4), (9,9)};

Application de fonction

double(x) == {i * 2 | i<- font="" x="">
= DOUBLE;double({3,4});
= {6, 8);
double(double({3,4}));
= {12, 16};

Lambda expressions
 
(lambda(x,y). (x * x) + (y * y))(2,3)
= 13;

Définitions locales
 
 let n1 == e1,...,nk == ek in e
retourne le valeur de e, évaluée dans un contexte enrichi par la liaison des noms ni aux valeurs ei
La portée des noms n1 à nk est e. Donc l'expression ei ne peut utiliser un de snoms n1 à nk.let x == 3, y == 4 in x + y;
= 7;
a == 2;
= A;
let a == 3, b == a * a in b;
= 4;
mais
let a == 3
in   let b == a * a
      in  b;
= 9;

Et voici les ensembles
 
{"Dudule", "Paulette"};
= {Dudule, Paulette);{};
= {};
a == { "pommes", "poires", "scoubidou"};
= A;
{ x * x | x <- font="">
= {4,16,36};

Avec filtre ?
 
{ x * x | x <- 3="" font="" x="">= {1,4,9};

On a bien sûr toutes les opérations ensemblistes :
union,
intersection
member
difference
subset
card
quantificateur universel :

all n in s . b

quantificateur existentiel

exists n in s .b

Et les relations

bouffe == {("bouillie", "pomme de terre"), ("purée", "pomme de terre")};
= BOUFFE;is_relation (bouffe);
= TRUE;
is_relation (10);
= FALSE;
dom(bouffe);
= {bouillie, purée};
rng(bouffe);
= {pomme de terre);

et le reste , voir feuille Quick Reference Guide
Les Maps

prix == { "radio" ->20, "cassette" ->110, "couteau" ->20};
= PRIX;prix["couteau"];
= 20;

et bien sûr la surcharge (plus exactement, l'écrasement)

m1 overwr m2

Bibliographie :
Software Design and Prototyping using me too (1990)
 by H Alexander, V Jones 

jeudi 11 février 2010

samedi 21 juin 2008

Retraite ...mais ça continue !

L'auteur de ce bloc-notes part en retraite...mais continuera à alimenter ce bloc-notes.

mercredi 28 novembre 2007

Les notes de TD et de "DS" sont affichées

J'ai noté largement (j'ai considéré parfois que la réponse, bien qu'ayant aucun sens, était forcément une étourderie comme tout le monde en fait. Et j'ai mis la note max à la question. Bof ! on ne donne pas un diplôme de médecin, n'est-ce pas. Et il faut être productif.)

Il se peut qu'il y ait des erreurs de recopie de notes. Vous pouvez venir vérifier vos copies et dossiers. M'adresser un courriel pour un rdv.

Il me reste à refaire ce cours en Bac+4 dans deux mois. Et ce sera fini pour moi de ce cours au moins dans notre bonne université.

Peut-être une autre vie professionnelle ailleurs ...

Heureusement, les écrits servent à d'autres. Ce courriel semble le dire :

"
Bonjour,

Juste un petit mot de félicitations pour
votre excellent livre sur la

mesure du logiciel. Je l'avais lu il y a
7 ou 8 ans mais je l'ai

redécouvert cette semaine durant le calme
d'août... Il est simple et

agréable à lire. J'ai eu votre email via
google et suis arrivé sur IUT

de Nantes. Vos élèves ont de la chance.
Bravo.


XXXXXXX
Direction du Pilotage des Systèmes
d'Information

Groupe XXXXXX

Je n'ai donc pas perdu tout mon temps
et volé ma paye.

Il s'agit d'un très grand groupe qui
vient de signer un très très
gros contrat dont nous a parlé la presse.

Si j'ai des notes de 0,1 en TD j'ai mis
un 19,9 à un étudiant.


Pour clore ce bloc-notes, cette citation
extraite de

Erik Orsenna, Voyage au pays du coton,
Petit précis

de mondialisation, Le livre de poche

"- Comment vois-tu l'avenir de la Chine ?
- Pas différent de son passé. Mon pays
a toujours été la première puissance du monde.

Sauf durant les deux derniers siècles.
Dans vingt ans,

elle aura recouvré son rang.
- Et vous ne craignez pas la concurrence
indienne ?

- L'Inde est trop démocratique. Elle y
perd beaucoup d'énergie.

Bo nous parle souvent de Paris , où il
est resté 6 ans [...]

Une question le préoccupe :
- Pourquoi, en France, n'aimez-vous pas
les enfants ?

Je m'étonne, me récrie, le prie de développer.
- En France, vous ne travaillez pas
assez. Donc vous préparez mal

l'avenir de vos enfants.
Et il enfonce le clou :
- Chaque année, la dette de la France
augmente. Seuls ceux qui

ne travaillent pas assez s'endettent.
Et qui doit rembourser ?

Les enfants.
Que répondre? "

page 275-276

dimanche 25 novembre 2007

Des copies non identifiées !!!

J'en fait quoi ?

On lance une expertise graphologique ?

samedi 24 novembre 2007

Où la plupart d'entre vous ont trouvé une partie des réponses faites

aux questions :
  • Qu'est ce qu'un test fonctionnel,
  • Qu'est ce qu'un test structurel,
  • Qu'est ce qu'un test statique,
  • Qu'est ce qu'un test dynamique,
  • Qu'est ce qu'un test boîte blanche,
  • Qu'est ce qu'un test boîte noire
  • Qu'est-ce qu'un oracle de test
du "DS" ?

Les réponses étaient dans le poly et répétées, commentées en cours.

Dans un blog d'ancien étudiant ?

Je vous rappelle qu'il vaut mieux consulter, si vous voulez voir ailleurs, les sites d'universités reconnues ou lire les livres recommandées dans notre bibliographie.

Dans d'autres matières, des collègues m'ont signalé de telles pratiques. Désolantes !

Lire des dizaines de fois la même réponse fumeuse - qui est passée au téléphone arabe -, parfois erronée, bien sûr non illustrée par le moindre exemple, ou pire un exemple en contradiction avec les interprétations possibles du texte fourni ....

Exemple :

Test structurel :
"On a un succès à l'état complet du système que l'on vérifie à chaque ligne"

mercredi 7 novembre 2007

Les pièges de la Toile

lire ici

Ce que je lis dans les copies

quand il y a quelque chose à lire ... Rappelons que nous vous avions annoncé la plupart des questions lors des cours ("je vous demanderai cela lors du contrôle car c'est le b a ba"), que les autres questions étaient dans le poly, etc.



- J'ai lu des choses étonnantes sur les chemins dans un graphe de contrôle. J'ai donné un graphe (celui d'un if then else) : 3 noeuds, 4 arcs. Certains m'ont donné comme chemin, une suite de 4 noeuds.

- J'ai demandé "Qu'est-ce que l'homme-mois ?", dans plus des 3/4 des cas je n'ai pas obtenu la réponse. Au mieux des choses comme "si 6 hommes travaillent sur un projet pendant un mois, on dira que le projet vaut 6 homme-mois ou 1 homme pendant 6 mois".
Je suis inquiet. J'avais bien insisté en fournissant même deux graphiques pour faire comprendre et utilisé l'analogie avec une surface. Si on prend comme unité de mesure 20 m2. Si on a un rectangle de 2 mètres sur 10 mètres il est mesuré par 1 "vingt mètres carrés"?. Si on a un rectangle de 4 mètres sur 5, il est mesuré par 1 "vingt mètres carrés".

En conséquence, à la question "Quelle critique fait-on à cette unité ?" j'obtiens un discours dont il est difficile d'inférer du sens.

- "un homme-mois est une unité de mesure de l'efficacité d'un programme" suit un blabla dont j'extrais : "cette unité de mesure n'est pas très efficace" !!! Veuillez me rappeler combien d'heures d'économie et gestion en deux ans ?

Je peux changer "programme" par "programmeur", ce n'est pas mieux !

J'ai aussi obtenu des réponses comme : "un homme-mois représente la quantité de travail fournie par un homme travaillant un mois" ! Etonnant, n'est-ce pas !
C'est comme la mesure du niveau d'étude. Etudiant-année mesure la quantité de connaissances (de travail ?!) fournie par un étudiant au statut d'étudiant pendant un an". Les fameux "Bac + 2, Bac + 4". Moi, j'ai un sacré niveau : Bac + 43.

Et voici encore :

"Un homme-mois est une évaluation du nombre de ligne de code fournit par un développeur en 1 mois".

SSII vous pouvez prendre de la graine là dedans pour vos facturations ! Pour l'orthographe, attention ! il reste encore des gens qui tiquent quand ils reçoivent des factures bourrées de fautes d'orthographe.

Rappel : l'homme-mois sert à mesurer l'effort. Si on a dépensé la paye d'un homme pendant un mois, on a fait un effort d'un homme-mois. C'est commode pour facturer ! ce n'est pas fameux pour faire de la planification !
On peut faire beaucoup d'effort pour former les étudiants, ça ne veut pas dire que les étudiants ont fait beaucoup de travail !

J'ai trouvé aussi 'Un homme-mois est une unité de mesure représentant le nombre d'hommes affectés à un projet pendant un mois" !
Et 1O hommes-mois, ça fait combien ?
Le même étudiant note comme critique "Cette unité n'est pas fixe". Facile, la critique. On écrit une c... et en suite on dit que c'est une c...

Bien sûr ces étudiants se sont dispensé d'étudier le cours sur la théorie de la mesure. Ils savaient, voyons !


Dans une société où la mesure se généralise ....ouille yayaye !

- Qu'est-ce qu'un oracle de test ? "Cela correspond à la succession de test automatique" !!!
L'étudiant fournit l'exemple donné en cours (ouf ! un qui a écouté ! merci, merci !) : "ex. d'oracle automatique : Pour le calcul de la racine carré c'est : résultat au carré = entrée ?" Vous voyez la relation entre la réponse à la question et l'exemple ? J'ai enfin compris !
J'avais aussi donné l'exemple du logiciel de calcul de la taxe d'habitation, en demandant comment obtient-on l'oracle de test.
Quel plaisir que la lecture des copies ! des énigmes à résoudre !

J'avais en cours fait référence à l'oracle de Delphes (lors de la présentation de la méthode de Delphes pour estimer). Mais en lisant les copies, je pense que beaucoup ne savent pas ce qu'est qu'un oracle.

P.S. je viens de lire la même "définition" de l'oracle de test dans une autre copie. Il semble qu'au lieu d'utiliser le polycopié des étudiants soient allés sur la Toile (ç'est bien mieux !) et comme souvent, y prennent le plus mauvais.

Je pense aussi au futur plaisir des utilisateurs de logiciels et d'informaticiens devant lire "spécifications" et "commentaires de code".

- Je demandais d'exposer en quelques lignes la méthode "agile" X-Programming. J'avais insisté sur le fait que la méthode consistait à commencer par écrire les jeux de tests AVANT de commencer à coder. Très bien ! (une manière de dire sans le dire explicitement, qu'il faut spécifier avant de coder. Beaucoup (parmi ceux ayant écrit quelque chose) ont écrit des choses comme "aucune analyse, juste du code". Coco, ça c'est une méthode de nouvelle génération ! C'est comme la prose, vous la pratiquiez sans le savoir. Comme quoi, l'enseignement ne sert à rien.

- Il y a eu un cours et un td sur "la méthode des points de fonctions" (avec analyse critique de cette méthode). J'ai demandé en contrôle d'exposer cette méthode. Je lis des choses comme :

"La méthode des points de fonction permet de voir la rentabilité du programme. C'est une alternative au nombre de lignes de codes." !!!!
"Elle sert à calculer l'efficacité d'une tâche" !!!

- j'avais des questions sur le vocabulaire élémentaire des tests.
A test boîte blanche, j'ai eu plusieurs fois cette phrase (où a-t-elle été recopiée ?) : "On vérifie à chaque ligne l'état complet du système"

- Je demandais de dire en quelques lignes ce qu'est le CMM (maintenant on a le CMMI). J'avais adressé à tous le courriel de la région des Pays de la Loire qui finance la formation des entreprises de la région pour qu'elles "montent les gradins" du CMM (je ne sais plus trop comment motiver ! il en fait des efforts le prof !), je n'ai obtenu que quelques réponses. En voici une :

"Le CMM est un ensemble de 24 macros-processus organisés en 5 catégories"
Processus de quoi , de qui , de ??? mystère et boule de gomme. Je ne pense pas que ceux qui n'ont pas écouté le cours, n'ont pas lu le poly des transparents vont savoir avec de texte ce qu'est le CMM.

- Orthographe

Plusieurs fois j'ai lu
"dans cette exemple",

"résonnement".
Raisonner comme un tambour ... Résonner ...

et j'ai sous les yeux :

"dinamique"
"on vérifit"
"avec les entrées définient à partir de ces entrées" !!!!
Ceci en deux lignes !
"les votants souhaiterais"
"valeure"
"l'invariant est définie", j'ai aussi "est définit" et du "on définie", "ont définit". Et je vais retrouver cela dans les rapports de stage ! Prions Saint Taxeror




- Plus de la moitié de la promo (chut !) est incapable de passer d'un code en pseudo pascal avec un while dans lequel est imbriqué un if then, au graphe de contrôle (la promo a eu un cours sur les graphes !) . Dire qu'il y a 35 ans dans les initiations à l'informatique en 1 semaine, on obtenait du 90 % de bon résultat à cet exercice. Le niveau monte. Il faut maintenant de nombreuses années pour atteindre le niveau.
Vous me direz que "pas de problème, il y a des logiciels qui font le boulot. Donner le graphe de contrôle d'un programme" (d'ailleurs, je vous en ai fait utiliser un)... mais si on ne comprend pas ce qu'ils affichent !


- A la question annoncée et donc posée sur les échelles de mesure, question essentielle, au bout de 40 copies, je n'ai trouvé qu'une seule réponse ! On continuera à faire n'importe quoi avec les entiers !

J'exagère ! j'ai eu par exemple "types d'échelles : mètre, décimètre, centimètre, micromètre, picomètre" Eh ! je n'avais mis que 5 cases ! J'ai donc évité le nanomètre. Il faut dire que le mètre convient bien pour faire de la mesure en informatique, non ?
Rappelons que nous avons donné : nominale, ordinale, intervalle, ratio, absolue.

Bof, les profs peuvent ajouter 10 points à chaque étudiant, même si la notation est sur une échelle ordinale (rappel : quand il fait 10 ° celsius, il ne fait pas deux fois plus chaud que quand il fait 5° celsius !), la théorie c'est inutile, voyons.

Au fait, avec les mètres, centimètres etc on a une échelle ratio. La transformation admissible est M' = aM avec a >0. On apprend cela dans les petites classes. Si vous mesurez 1 mètre, vous mesurez 100 centimètres.

Bon, j'arrête.

P.S. : je rappelle que les corrigés ont été distribués AVANT le contrôle. On fait des efforts !

mardi 23 octobre 2007

Corrigé Gestion de version

Q1. Donner deux raisons d'utiliser un système de gestion de version
lors du développement d'un projet.

R1. Plusieurs réponses possibles parmi
- gérer le développement entre plusieurs personnes
- système de sauvegarde
- un même référentiel pour tous les développeurs
- mise à disposition d'outils pour gérer la sauvegarde/restauration,
les conflits, l'historiques...
- gérer plusieurs distributions ou branches de développement
- conserver un historique et revenir en arrière

Q2. Donner les grandes étapes de la mise en versionning initiale d'un
projet à l'aide de subversion.

R2. J'ai volontairement donné une description étendue des étapes (je
ne m'attends pas à autant de la part des étudiants)
0. Création d'un répertoire référentiel sur un serveur subversion
(svn) (réalisée par l'administrateur du serveur svn)
1. Création sur une machine locale des sources du projet à versionner
selon une structure en 3 répertoires trunk, tags et branches (réalisée
par un développeur)
2. L'Import des sources au sein du référentiel (réalisée par le développeur)
3. La suppression des sources en local (réalisée par le développeur)
4. La récupération d'une première copie locale (checkout) (réalisée
par le développeur)
Par la suite, une fois une première récupération réalisée, le
développeur met à jour le référentiel avec des commandes "commit" et
récupère les mises à jour effectuées par d'autres à l'aide de la
commande "update".

corrigé du DS

Presque toutes les questions ont fait l'objet de solutions dans le poly des transparents du cours ou lors des TD.

Le sujet du DS

Sans les graphes (sujet donc incomplet)

Question sur Gestion de version (sur 5)
Réponse à faire sur une feuille annexe séparée.
Q1. Donner deux raisons d'utiliser un système de gestion de version
lors du développement d'un projet.
Q2. Donner les grandes étapes de la mise en versionning initiale d'un
projet à l'aide de Subversion.

Question 1 (sur 5)
Dudule a prévu de coder sur quatre positions les valeurs des cinq critères a, b, c et d. Chacun de ces cinq critères prennent leur valeur dans l’ensemble 0..5.
Question :
Si on considère abcd comme un entier, abcd  0000 … n, quelle est la valeur de n.

Question 2 (sur 4)
Soit le programme suivant :
1. pos_sum(a, num_of_entrie, sum)
2. sum = 0
3. int i = 1
4. while (i<=num_of_entries) 5. if a[i] > 0
6. sum = sum + a[i]
7. endif
8. i = i+1
9. end while
10. end pos_sum


Question 2.1 Faire le graphe de contrôle dont les nœuds seront des séquences. Vous les étiquetterez par le ou les numéros de lignes du programme. Vous étiquetterez les arcs par les prédicats.














Question 2.2 Faire le graphe de contrôle selon la notation de Warnier (norme AFNOR).















Question 2.3 Donnez un cas de test qui couvre toutes les décisions

Question 3 (sur 4)
Soit le programme suivant
Procedure REWRITEFICHIER (option:byte;var avorter:boolean);
(* INSTRUCTION REWRITE AVEC MESSAGE D'ERREUR *)
(* option : 0 = ECHECS.CAT, 1 = PARTIE *)
Var erreur:integer;
reponse:char;
Begin
avorter:=false;
repeat
rewrite(fichier);
erreur:=ioresult;
if erreur<>0
then
begin
case option of
0:ERREURDISQUE(5,reponse);
1:ERREURDISQUE(11,reponse);
end;
case reponse of
'a','A':avorter:=true;
end;
end;
until (erreur=0) or (avorter);
End;


Question 1
Faites le graphe de contrôle dont les nœuds seront des séquences. (utiliser une feuille annexe). Vous avez bien lu : les nœuds sont des séquences (ne faites pas un nœud par instruction, à moins que ce soit une séquence maximale).
Question 2
Quelle est la formule du nombre cyclomatique ?



Question 3
Critique de la « mesure de Mc Cabe » (complexité cyclomatique )







Question 4
Quelle est la valeur de la mesure de McCabe pour ce programme ?




Questions 4 (sur 7 )
Question 1
Qu’est-ce qu’un oracle de test ?



Question 2
Qu’appelle-t-on
- test fonctionnel

- test structurel

- test statique

- test dynamique

- test boîte blanche

- test boîte noire


Question 5 (sur 2)
Qu’est-ce que le CMM ?







Question 6 (sur 2 )
Soit le graphe de flot de contrôle suivant :














Quels sont les chemins :
- sensibles aux erreurs

- révélateurs d’erreurs


Question 7 (sur 3)
Soit le graphe de flot de contrôle suivant :












Question 1 Donnez un jeu de test (une seule valeur peut suffire) qui sensibilise un chemin couvrant tous les nœuds.

Question 2 Est-ce que la couverture de tous les nœuds est suffisante pour faire apparaître l’anomalie de ce programme ?

Question 3 Passez au critère « couverture de tous les arcs ». Est-ce que votre DT réponse à la question 1 couvre tous les arcs ?


Question 8 (sur 5)

Quels sont les types d'échelles de mesure ? Pour chacun, donnez le nom du type, un exemple, la transformation admissible entre représentations dans le même type d'échelle.
Réponse 6
TYPE D'ECHELLE (nom) TRANSFORMATION ADMISSIBLE EXEMPLES




















Question 9 (sur 2)
Le comité de pilotage du projet Titanic est composé de 85 personnes. Il est réuni pour classer trois candidats au poste de chef de ce projet titanesque. Nous respecterons ici l'anonymat de ces candidats que nous désignerons pas une lettre.
Voici le résultat du vote :
Pour A > B > C : 23 voix
Pour A > C > B : 5 voix
Pour B > A > C : 12 voix
Pour B > C > A : 17 voix
Pour C > A > B : 10 voix
Pour C > B > A : 18 voix

Quel est le résultat de l'agrégation des préférences de tous les membres du comité ? (vous devez donner comme réponse un ordre, par exemple A>C>B)


Vos commentaires.














Quel problème peut-on rencontrer ?









Question 10 (sur 4)
Question 1 A quoi sert la « méthode des points de fonction » ?





Question 2 Exposez la méthode des points de fonction




















































Question 11 (sur 2)
Exposez en quelques phrases la méthode « agile » X-Programming




















Question 12 (sur 2)
Soit le programme
1 sum = 0
2. read(n),
3. i = 1
4. while (i<=n) 5. read(number) 6. sum = sum + number 7. i=i+1 8.end while 9.print (sum) donnez la dr chaîne pour la variable sum « Tester les dr chaîne », est-ce du test du flot de contrôle ou du test du flot de données ? Question 13 (sur 6 ) Question 1 (sur le langage metoo) Soit : double(x) == {i * 2 | i<- x}; = DOUBLE; Donnez un exemple d'application de cette fonction, i.e. écrivez d'abord l'application et ensuite le résultat de cette application (dit autrement, ce que vous fournissez à me too et ce qu'il vous répond). Je fournis par exemple : Metoo répond : Question 2 Si l'on saisit ce qui suit, que répondra me too ? double(double({3,4})); Question 3 Soit : sq(x) == {i*i | i <- x}; =SQ; Si l'on saisit : sq({3,4,5,6}); que répondra me too ? Question 4 Soit : cp(x, y) == {(p,q) | p <-x, q<- y}; me too répond : CP; cpsq(x) == cp(sq(x),sq(x)); me too répond : = CPSQ; Si on saisit : cpsq({1,2,3}); Que répondra me too rappel : (2, 8) est le couple (2, 8) en me too comme habituellement dans les livres de maths. Question 5 Quelle(s) différence(s) entre un invariant de machine B et un invariant en me too ? Question 14 (sur 2) Qu'est-ce qu'un homme-mois ? Critiques de cette unité de mesure Question 15 (sur 6) Soit la spécification algébrique suivante : Spec BOOL0 Sorte Bool Opérations vrai, faux : --> Bool
not_ : Bool --> Bool
_and_ : Bool Bool --> Bool
_ or_ : Bool Bool --> Bool
Axiomes
not vrai = faux
not not a = a
a and vrai = a
a and faux = faux
(a and b) and c = a and (b and c)
a and b = b and a
a or b = not((not a) and (not b))
Une spécification algébrique SPEC ne donne que des règles de syntaxe. Pour lui donner une sémantique dénotationnelle, on lui associe une Algèbre A.
On va prendre trois algèbres : B, B0 et B1 interprétant BOOL0 (en fait on ne vous en fournira que 2, l’autre est dans le polycopié)
Avec les ensembles supports de Bool
Bbool = {v, f}
B0Bool = {f}
B1Bool = {v, f, bottom}

Dans l’algèbre B, on prend Bbool = {v, f}
Et on interprète les opérateurs comme des fonctions :

fauxB, vraiB : --> Bbool
not B : Bbool --> Bbool
andB, orB : Bbool * Bbool --> BBool
Avec les définitions :
fauxB = f, vraiB = v
notB(f) = v, notB(v) = f
andB(f,f) = andB(f,v) = andB(v, f) = f, andB(v,v) = v
orB(f,f) = f, orB(f,v) = orB(v,f) = orB(v,v) = v

Dans l’Algèbre B0, on prend B0Bool = {f}
Et on interprète les opérateurs comme des fonctions :
fauxB0, vraiB0 : --> B0Bool
notB0 : B0Bool --> B0Bool
andB0, orB0 : B0Bool * B0Bool --> B0Bool
Avec les définitions :

fauxB0 = vraiB0 = f
notB0(f) = f, andB0(f,f) = orB0(f,f) = f

Question 1
Evaluez le terme
t = not faux and vrai
dans l’algèbre B
Donnez le détail de cette évaluation.



Question 2
Evaluez le terme t dans l’algèbre B0



Question 3
Quand dit-on qu’une algèbre est un modèle d’une spécification ?




Question 4
Qu’appelle-t-on confusion ?
Donnez un exemple pris dans les interprétations ci-dessus.






Question 5
Qu’appelle-t-on rossignol (junk) ? Donnez un exemple pris dans les interprétations ci-dessus.



Question 16 finale (sur 2)
Qu’est-ce que MVC (Modèle Vue Contrôleur) ? Expliquez en quelques lignes

Notation de dossiers de TD identiques

la note sera égale à : note "normale" du dossier de TD/ nombre de dossiers identiques à ce dossier

vendredi 19 octobre 2007

Réécriture

Dans le TD sur Spéc algébriques nous avons deux petits exos de réécriture.

Une très bonne présentation de la réécriture sur wikipedia

mercredi 17 octobre 2007

Le dernier cours

a eu lieu ce matin. Pour ceux, nombreux, qui étaient absents, voici ce qui a été traité :
  • design patterns
  • modèle MVC
  • spécifications algébriques
Vous devez étudier la partie Fiabilité. Je vous ai fourni ici le corrigé du TD sur Fiabilité.

Le prochain TD, le dernier, portera sur Spécifications algébriques.

metoo et lambda expressions

Revoir le cours de Spec1 sur B

Application à metoo

Ex. 1
Vous avez entré
union-a-b(a1, b1);
Tapez
union-a-b;
metoo répond
lambda(a1, b1). '(metoo set union a1 b1)'.

Ex2
Tapez
union_a_b();
metoo attendait un ensemble (c'est le type des opérandes de l'opérateur union), mais il a trouvé False. En effet, les arguments non trouvés étant remplacés par False, metoo essaie quand même d'évaluer la lambda expression. Dans ce cas, l'échec est patent.

Ex 3
essai(ens, dom, ran) == ens overwr {dom -> ran};
construit un ensemble de maplets (de couples)

Tapez
essai({}, d1, r1);
metoo renvoie une image du maplet créé
{d1 -> r1};
Tapez
essai({d1 -> r1}, d2, r2);
metoo renvoie
{d1 -> r1, d2 -> r2};
Tapez maintenant
essai({d1 -> r1});
Il manquait deux arguments, mais metoo a quand même évalué la fonction et on observe :
'd1-> r1, false -> false};
Tapez maintenant
union_a_b(1, 2);
metoo repond encore que les types des opérandes sont erronés, car on trouve des integers au lieu d'ensembles

Voyons les fonctions prédéfinies de metoo telles que :

inv_

Tapons
inv_cte;
metoo répond
TRUE;
On constate qu'alors que nous avons oublié de définir cet invariant, metoo le considère comme vrai. Normal. Un invariant est une contrainte. TRUE c'est le moins contraignant !

mk_

Tapons
mk_cpte;

metoo répond

lambda(arg-2, arg-1). '(metoo-construct-rec (quote cpte) (quote (comp1 comp2)) (list arg-2 arg-1) inv_cpte)';

Ainsi vous voyez que :
mk_cpte est une lambda expression :
  • qui a deux arguments, les champs définis
  • qui évalue inv_cpte
  • et qui rend une liste enregistrant les constructions faites, pour les stocker en mémoire.
Tapons
mk_cpte();
metoo répond
mk_cpte(false, false).

mardi 16 octobre 2007

CMMI (voir deuxième cours de TGL)

Madame, Monsieur,

Vous êtes une société de service ou un éditeur de logiciel des Pays de la Loire ?… Connaissez-vous le CMMI ?

Le CMMI est un modèle Qualité constitué des bonnes pratiques du développement logiciel, qui visent ainsi à améliorer la visibilité et l’efficacité de vos projets.

Le Syntec Informatique, La DRIRE et la région Pays de la Loire ont élaboré le « Programme CMMI des Pays de la Loire » à destination des sociétés de service des Pays de la Loire pour les aider à mettre en place le modèle CMMI. Cette aide se traduit par des subventions pour l’accompagnement et par le financement à 100% de la formation officielle de 3 jours « Introduction to CMMI ».

Le groupe FORTEAM a été choisi pour être l’assistant à maîtrise d’ouvrage de ce programme ainsi que le maître d’œuvre.

Si vous souhaitez de plus amples renseignements, contactez-nous.

Plus de renseignements :
L’extranet du programme CMMI des Pays de la Loire : www.cmmipdl.com
Le programme CMMI des Pays de la Loire : conseil.e-testing.fr/cmmi-pdl.asp