# MLD
Les attributs sont par défaut `NOT NULL`.
Les transformations non-triviales sont justifiées.
## Classes de base
```
Gare(#nom:string, #ville:string, adresse:string, horaire:heure)
Ligne(#code:int, nom:string)
Hotel(#adresse : string, nom : string, nb_etoiles : int)
Taxi(#numero : int, marque : string, tarif : int, tel : int)
Transport(#numero : int, compagnie : string, type : {bus, velo, tramway})
```
## Classes issues d'héritages
* Héritage `Voyageur` : héritage par la classe mère.
Justification : L'héritage est presque complet. La classe mère est abstraite, la classe RegulierV a quelques attributs propre, toutes les associations sont avec la classe mère. Un attribut supplémentaire de domaine booléen pour chaque classe fille est ajouté à la classe mère, afin de distinguer les tuples.
```
Voyageur(#id:integer, nom : string, prenom:string, adresse: string, num_tel:integer[10], num_carte:integer, statut:{voyageur|grandVoyageur|grandVoyageurPlus}, regulier : boolean)
avec num_carte UNIQUE, NOT(regulier AND (NOT num_carte OR NOT statut)), NOT(NOT regulier AND (num_carte OR statut))
```
>Contraintes simples :
>1. `num_carte UNIQUE` car la clé primaire propre de RegulierV est réintégrée à la classe mère, au même titre qu'un autre attribut, mais elle n'officiera pas en tant que clé candidate car elle pourra contenir des valeurs nulles. Elle sera néanmoins unique.
>2. `NOT (num_carte AND NOT regulier)`
>3. `NOT (statut AND NOT regulier)`
>4. `(num_carte NOT NULL AND statut NOT NULL AND regulier NOT NULL) XOR (NOT regulier)` car l'héritage est exclusif et la classe mère abstraite.
* Héritage `Train` : héritage par la classe mère et traduction des contraintes sur les attributs constants.
Justification : L'héritage est complet c'est à dire que les classes filles ne définissent pas d'attributs autre que ceux hérités, cette solution est donc optimum. La classe Train est abstraite, toutes les associations sont avec cette classe mère.
Un attribut supplémentaire de discrimination t (pour "type"), est ajouté à la classe mère, afin de distinguer les tuples.
```
Train(#num:int, placemax:const int, classe1:const bool, vitessemax:const int, type:{RER|TER|TGV}, code_ligne=>ligne)
avec (type=RER => (placemax=place_max_RER AND classe1=false AND vitessemax=vitsse_max_RER), type=TER => (placemax=place_max_TER AND classe1=true AND vitessemax=vitesse_max_TER), type=TGV => (placemax=place_max_TGV AND classe1=true AND vitessemax=vitesse_max_TGV)
```
Contraintes simples :
1. `(type=RER AND placemax=place_max_RER AND classe1=false AND vitessemax=vitsse_max_RER) XOR (type=TER AND placemax=place_max_TER AND classe1=true AND vitessemax=vitesse_max_TER) XOR (type=TGV AND placemax=place_max_TGV AND classe1=true AND vitessemax=vitesse_max_TGV)`car l'héritage est exclusif, la classe mère abstraite et les attributs constants.
* Héritage `Calendrier` : héritage par classe fille.
Justification : L'héritage n'est pas complet, on exclut a priori l’héritage par la classe mère. Les classes filles ont leurs propres attributs mais pas leur propres associations. La classe mère est abstraite donc on n'exclut pas un héritage par classe fille s'il n'y a pas d'association problématique. Nous sommes dans un cas problématique d'héritage par les classes filles avec association 1:N (entrante) sur la classe mère. La solution consiste à ajouter autant de clés étrangères que de classes filles et à gérer le fait que ces clés ne peuvent pas être co-valuées.
```
RegulierC(lundi:bool,...,dimanche:bool)
ExceptionnelC(ajout:bool,jour_debut:date,jour_fin:date) avec jour_debut<=jour_fin
```
* Héritage `Calendrier` : proposition : par référence c'est plus simple pour la relation Horaire pour indiquer qu'il n'y a qu'un seul calendrier par horaire
```
Calendrier(#id : integer)
RegulierC(#id=>Calendrier, lundi:bool,...,dimanche:bool)
ExceptionnelC(#id=>Calendrier, ajout:bool,jour_debut:date,jour_fin:date) avec jour_debut<=jour_fin
```
> L'héritage par référence implique deux contraintes complexes et nécessite deux classes de plus.
> 1. `INTERSECTION (PROJECTION (RegulierC, id), PROJECTION (ExceptionnelC, id)) = {}`
> 2. `PROJECTION (Calendrier, id) = PROJECTION (RegulierC, id) UNION PROJECTION (ExceptionnelC, id)`
## Classes issues d'associations
* Concerne entre Calendrier et Horaire : ajout de clé côté horaire
```
Horaire(#id : integer, arrivee:heure, depart:heure, train=>Train, RangArret=>Arret.rang, CodeArret=>Arret.code, regulierC=>RegulierC)
R1 = Jointure(Horaire, Train, Horaire.train=Train.num)
R2 = Restriction(R1, R1.CodeArret!=R1.code_ligne)
IF R2!={} THEN "ERROR"
```
Contrainte :
1. `regulierC XOR exceptionnelC` car une horaire ne peut concerner qu'un calendrier qui sera exceptionnel ou régulier.
2. `train.code_ligne=arret.code_ligne `
* Se situe sur entre Arrêt et Ligne : clé côté Arrêt.(on suppose que la clé d'arrêt c'est rang et ligne)
* Se fait dans entre Arrêt et Gare : clé côté Arrêt
```
Arret(#rang: int, arret: bool, #code_ligne=>Ligne, nom_gare => Gare, ville => Gare)
```
* Départ/arrivée entre Horaire et Trajet : clé côté Trajet.
* Correspond entre Trajet et Billet : clé côté Trajet.
```
Trajet(#place: int, #id=>Billet, horaire_depart => Horaire.id, horaire_arrivee => Horaire.id)
```
`horaire_depart` est l'horaire de départ issu de l'association `depart`
`horaire_arrivee` est l'horaire d'arrivée issu de l'association `arrivee` (on ne récupère qu'un seul des 2 attributs de la classe `Horaire` à chaque fois : l'heure de départ dans la 1er cas, l'heure d'arrivée dans le 2ème).
> Préciser dans la NdC qu'on peut être tenté d'ajouter les attributs départ et arrivée de l'horaire de départ et de l'horaire d'arrivée (donc 4 horaires en tout par trajet)
* Réserve entre Voyageur et Billet : clé côté Billet.
```
Billet(#id:int, gare_depart:string, depart:heure, gare_arrivee:string, arrivee:heure, assurance:bool, prix:int, voyageur=>Voyageur)
```
```
Propose_taxi(#num_taxi=>Taxi, #id_billet=>Reservation, #id_voyageur=>R``
Propose)
```
```
Propose_hotel(id_billet=>Reservation, #id_voyageur=>Reservation)
```
```
Propose_transport(#numero=>Transport, #id_billet=>Reservation, #id_voyageur=>Reservation)
```
* Réservation entre Voyageur et Billet : attributs ajoutés à la relation Billet (à laquelle on a déjà ajouté la clé de voyageur)
```
Reservation(#id_billet=>Billet, #id_voyageur:int, paiement:string)
```
```
ExceptionnelC_Horaire(#horaire=>Horaire.id, exceptionnelC=>ExceptionnelC)
```
Contraintes globales :
```
Projection(Jointure(Trajet,Horaire ; Trajet.horaire_depart=Horaire.id),Horaire.train) = Projection(Jointure(Trajet,Horaire ; Trajet.horaire_arrivee=Horaire.id),Horaire.train)
R1 = Jointure(Trajet,Horaire ; Trajet.horaire_depart=Horaire.id)
R2 = Jointure(R1, Horaire ; R1.Horaire_arrivee=Horaire.id and R1.train!=Horaire.train)
IF R2!={} THEN "ERROR"
R1 = Jointure(Horaire, Train, Horaire.train=Train.num)
R2 = Restriction(R1, R1.CodeArret!=R1.code_ligne)
IF R2!={} THEN "ERROR"
```
| :exclamation: Préciser qu'on est conscients de la redondance dans la NdC |
---