Correction TD Ocl

Télécharger au format pdf ou txt
Télécharger au format pdf ou txt
Vous êtes sur la page 1sur 4

TD – Spécifications

Contraintes OCL : correction

Master TI 1ère Année – UPPA – Eric Cariou

Contraintes récursives sur les personnes (diag. du cours)


Contraintes récursives sur personnes :

context Person def: pasDansMesAncetres(personneCherchee : Person) : Boolean =


if parents -> isEmpty()
result = true
else
results = parents -> excludes(personneCherchee) and
parents -> forAll( parent | parent.pasDansMesAncetres(personneCherchee))
endif

context Person def: pasDansMesDescendants(personneCherchee : Person) : Boolean =


if children -> isEmpty()
result = true
else
results = children -> excludes(personneCherchee) and
parents -> forAll( children | children.pasDansMesDescendants(personneCherchee))
endif

Ne peut pas se marier avec un de ses descendants ou un de ses ancetres

context Person def: conjoint : Person =


self.wife -> union (self.husband) -> any(true)

context Person
inv: self.isMarried implies
self.pasDansMesAncentres(conjoint) and self.pasDansMesDescendants(conjoint)

Corrections du TD
Exercice 1
1 Un diplôme universitaire est composé d’un ensemble ordonné d’années. Chaque année offre un
ensemble de matières, certaines étant obligatoires, d’autres optionnelles. Chaque matière a une certaine
durée (en heure) et compte pour un certain nombre d’ECTS. Une matière n’est proposée que pour une
seule année.

Rien à ajouter.

2 Une matière optionnelle peut avoir des prérequis, c’est-à-dire une liste de matières optionnelles que
l’étudiant doit avoir suivi dans les années précédentes du diplôme.

context Matiere
inv: type=#Optionnel implies
etudiant -> forAll ( e | e.matiere -> includesAll(prerequis))

1
Vérifier que les prerequis sont bien dans les années précédentes :

context Matiere inv:


let indexAnnee : Integer = self.annee.diplome.annee -> indexOf(self.annee) in
self.prerequis -> forAll ( p | p.annee.diplome.annee -> indexOf(p.annee) < indexAnneee)

3 Chaque matière que suit ou a suivi un étudiant est notée. Une note de -1 signifie que l’étudiant n’a
pas encore été évalué pour cette matière.

Rien à faire.

4 Un étudiant a validé une année s’il a obtenu la moyenne aux matières de cette année et qu’il a
passé les évaluations pour toutes les matières de cette annnée.

-- les matières d’un étudiant pour une année


context Etudiant def: matieresAnneeEtudiant(Annee a) : Set(Matiere) =
self.matieres -> select ( m | m.annee = a)

-- les évaluations des matières d’un étudiant pour une année


context Etudiant def: evalMatieresParAnnee(Annee a) : Set(EvalMatiere) =
self.matieresAnneeEtudiant(a).evalMatiere -> select (
evalMatiere.etudiant = self)

-- pour chaque évaluation d’année, on a validee = vrai si toutes les matières de


-- l’étudiant pour cette année ont été évaluées (note =/= -1) et si la moyenne est >= 10
context Etudiant inv:
self.evalAnnee -> forAll (ea | ea.validee implies
self.evalMatieresParAnnee(ea.annee) -> forAll( note <> -1) and
(self.evalMatieresParAnnee(ea.annee).note -> sum() /
self.evalMatieresParAnnee(ea.annee) -> size() ) >= 10)

5 Un étudiant a obtenu un diplome s’il a validé toutes les années de ce diplome.

context Etudiant def: evalAnneeDiplome(Diplome d) : Set(EvalAnnee) =


self.evalAnnee -> select ( ea | ea.annee.diplome = d)

context Etudiant inv:


self.evalDiplome -> forAll ( ed | ed.obtenu implies
self.evalAnneeDiplome(ed.diplome) -> size () = ed.diplome.annee -> size() and
self.evalAnneeDiplome(ed.diplome) -> forAll ( ea | ea.validee ))

6 Un étudiant ne peut pas être inscrit dans une année s’il n’a pas validé les années précédentes du
diplôme.

context Diplome inv:


etudiant -> forAll ( e |
-- sélectionne les annees suivies par l’étudiant dans ce diplome
let anneesEtudiant = e.annee -> select ( a | a. diplome = self) in
-- récupère l’index max des années dans la liste des années du diplome
let indexMaxAnneesEtudiant = anneesEtudiant -> collect (ae |
self.indexOf(ae)) -> max() in

2
indexMaxAnneesEtudiant = anneesEtudiant -> size() -1 and
Sequence (0 .. (indexMaxAnneesEtudiant -1)) -> forAll ( i |
anneesEtudiants -> includes(self.annee.at(i)))

7 Pour une année donnée, un étudiant doit suivre un certain nombre de matières pour un nombre
total de 30 ECTS.

context Etudiant inv:


self.annee -> forAll ( a | self.matieresAnneeEtudiant(a).ECTS -> sum() = 30)

8 Un étudiant peut suivre ou avoir validé un diplôme de type Master seulement s’il a validé une
Licence (non professionnelle).

context Etudiant inv:


self.diplome -> exists( d | d.type=#MasterPro or d.type=#MasterRech) implies
self.diplome -> exists ( d | d.type=#Licence)

9 Un enseignant doit assurer au minimum 192h d’enseignement.

context Enseignant inv:


self.matiere.duree -> sum() >= 192

10 Deux étudiants n’ont pas le même numéro d’étudiants.

context Etudiant inv:


Etudiant.allInstances -> forAll ( e1, e2 | e1.numero = e2.numero implies e1 = e2)

3
Exercice 2
1 Classe Personnne, l’anniversaire d’une personne est aujourd’hhui : void anniversaire()

context Personne::anniversaire()
post: age = age@pre +1

2 Classe Personne, la personne déménage : void demenager(nouvelleAdr : String)

context Personne::void demenager(nouvelleAdr : String)


post: adr = nouvelleAdr

3 Classe Etudiant, l’étudiant s’inscrit dans un nouveau diplômevoid inscriptionDiplome(d : Diplome)

context Etudiant::inscriptionDiplome(dip : Diplome)


pre:
-- etudiant pas déjà inscrit
self.diplome -> excludes (dip)
post:
-- inscrit et c’est le seul diplome en cours
self.diplome = self.diplome@pre -> including(dip) and
self.diplome -> select (d | d = dip) -> forAll (d | d.enCours = true) and
self.diplome -> reject (d | d = dip) -> forAll (d | d.enCours = false)

4 Classe Etudiant, l’étudiant s’inscrit dans une année du diplôme en cours : void inscriptionAnnee(a :
Annee)

context Etudiant::inscriptionAnnee(a : Annee)


pre:
-- l’annee est bien celle du diplome en cours
let dip = self.diplome -> select (d | d = a.diplome) in
dip -> size() = 1 and dip -> forAll (enCours) and
-- pas d’annee en cours pour l’étudiant
not(self.annee -> exists (enCours))
post:
-- l’annee en cours est rajoutée dans les années de l’étudiant
self.annee = self.annee@pre -> including(a) and
self.annee.evalAnnee -> select (ea | ea.etudiant = self) -> forAll(enCours)

5 Classe Enseignant, retourne le nombre d’étudiants des cours de l’enseignant nbEtudiants() :


Integer

context Enseignant::nbEtudiants() : Integer


post: result = self.matieres.etudiant -> asSet() -> size()

6 Classe Annee, le nombre d’étudiants inscrits par année et par diplôme : nbEtudiants() : Integer

context Annee::nbEtudiants() : Integer


post: result = self.matieres.etudiant -> asSet() -> size()

Vous aimerez peut-être aussi