gestione delle informazioni turistiche relative a una ... del software/mamei.pdf · un itinerario...

38
Università degli Studi di Modena e Reggio Emilia Gestione delle informazioni turistiche relative a una grande città mediante il modello MDT di Marco Mamei matr. 2050 Anno Accademico 1999-2000

Upload: hoangkien

Post on 05-Dec-2018

216 views

Category:

Documents


0 download

TRANSCRIPT

Università degli Studi di Modena e Reggio Emilia

Gestione delle informazioni turistiche relative a una grande città mediante il modello MDT

di

Marco Mamei matr. 2050

Anno Accademico 1999-2000

2

Indice Requisiti e Specifiche Caratteristiche Generali………………………………………3 Funzionalità Richieste……………………………..……….…5

Modello statico MDT Attrazioni Storico Culturali……………………………….…..7 Strutture di Accoglienza e Attrazioni Turistiche……………..12 Itinerari………………………..…………………………..…22

Modello funzionale MDT Visualizzazione di informazioni…………….……………..…29

Inserimento, Eliminazione e Modifica…………………….…34

3

Requisiti e Specifiche Caratteristiche Generali Un grande Tour Operator intende organizzare soggiorni guidati nelle più grandi capitali europee e quindi necessita di gestire le informazioni relative a tale scopo. In particolare le informazioni da gestire riguardano: attrazioni storico culturali, strutture turistiche e informazioni relative agli itinerari giornalieri per la visita della città.

Attrazioni Storico Culturali: Informazioni riguardanti edifici interessanti da un punto di vista storico culturale, musei, monumenti, piazze. In generale, dal punto di vista turistico, risulta interessante riportare le relazioni di vicinanza tra i suddetti luoghi. Per una più efficiente organizzazione delle informazioni la città è divisa in quartieri, si deve rappresentare il quartiere di appartenenza di tutte le suddette attrazioni storico culturali.

Strutture di Accoglienza e Attrazioni Turistiche: Informazioni riguardanti le strutture presenti all’ interno della città. Le strutture turistiche sono strutture di accoglienza, cinema, discoteche, ristoranti, birrerie.Ogni struttura turistica ha un indirizzo e un periodo di apertura annuale, inoltre è importante l’informazione riguardante l’orario settimanale e gli eventuali giorni di chiusura. Le strutture di accoglienza sono a loro volta suddivise in hotel, alberghi, bedVsbreakfast, ostelli. E’ necessario mantenere le informazioni sulla disponibilità di una struttura di accoglienza per ogni giorno del suo periodo di apertura, per poter consentire eventuali prenotazioni.

4

Itinerari: Informazioni riguardanti i possibili itinerari giornalieri per la visita alla città. Un itinerario giornaliero è suddiviso in tappe che vengono percorse a piedi o con mezzi pubblici, ogni itinerario prevede al massimo tre tappe da percorrere a piedi. Ogni tappa ha un punto di inizio e un punto di fine che sono le attrazioni storico culturali che vengono visitate in quell’ itinerario. Le tappe di un itinerario devono essere consecutive. Un itinerario è composto da un minimo di due fino a un massimo di sei tappe, mentre una tappa può appartenere una sola volta a un certo itinerario. Dal punto di vista turistico è necessario sapere se una tappa interessa una certa attrazione storico culturale, nel senso che la costeggia. I luoghi di inizio e fine tappa, essendo delle visite vere e proprie, sono a maggior ragione inclusi in questa categoria.

5

Funzionalità Richieste Il sistema prevede due tipi di funzionalità: di visualizzazione e di inserimento/modifica.

Funzionalità di visualizzazione • Visualizzazione di tutte le tappe che interessano una

determinata attrazione storico culturale • Visualizzazione della/delle tappe con il maggior numero di

luoghi di interesse. • Visualizzazione delle strutture di accoglienza che in una

certa data hanno un numero di posti disponibili almeno pari a quello richiesto da input.

• Visualizzazione del numero totale di posti liberi in data odierna, in tutte le strutture di accoglienza di tipo e categoria specificati da input.

• Visualizzazione degli itinerari che costeggiano due attrazioni storico culturali specificate da input.

Funzionalità di inserimento e modifica • Prenotazione in una struttura di accoglienza e conseguente

aggiornamento della disponibilità • Inserimento di una tappa • Inserimento di un’attrazione di interesse per una tappa • Eliminazione di una tappa che non interessa alcuna

attrazione storico culturale.

6

La Scelta del Modello Il modello che si userà per rappresentare la realtà precedentemente specificata sarà il modello MDT. Tale scelta è motivata dal fatto che, in questo modo è possibile catturare una maggior conoscenza rispetto al modello OMT, non tanto dal punto di vista grafico in cui quest’ ultimo possiede una miglior rappresentazione, quanto per l’aspetto dinamico.

7

Modello Statico MDT: In questo capitolo attraverso le primitive value, object, context e virtual vengono individuate e descritte le entità e le relazioni significative. La trattazione è suddivisa nelle seguenti tre sezioni:

1. Attrazioni Storico Culturali 2. Strutture di Accoglienza e Attrazioni Turistiche 3. Itinerari

Nelle quali sono descritte le entità in stretta relazione, secondo la rappresentazione precedente. Al termine di ogni sezione è riportato lo schema grafico delle entità descritte.

Attrazioni Storico Culturali Value punto x: real y: real Object quartiere nome: string mandatory laws L1: forall s1, s2 in Instances itis (ident(s1) eq ident(s2) ⇔ s1.nome eq s2.nome) /* in questo modo esprimo il fatto che il nome identifica univocamente il settore. Si può esprimere lo stesso vinicolo utilizzando gli attributi mandatory unique. Nel seguito della trattazione userò questa ultima notazione */

8

/* Definisco l’ entità generale “Attrazione Storico Culturale”, dalla quale ottengo per specializzazione i diversi tipi di attrazioni turistiche con attributi e leggi specifiche. */ Object AttrazioneStoricoCulturale nome: string mandatory unique tipo: string mandatory descrizione: string quartiere_di_appartenenza: quartiere mandatory posizione: punto mandatory Value AnnoStorico anno: integer periodo: AC, DC Object Edificio is a AttrazioneStoricoCulturale tipo_di_edificio: string aperto_al_pubblico: boolean costruito_nel: AnnoStorico laws L1: tipo eq Edificio Object Museo is a AttrazioneStoricoCulturale tipo_di_museo: string numero_sale: integer numero_opere: integer laws L1: tipo eq Museo L2: numero_sale gl 0 L3: numero_opere gl 0

9

Object Monumento is a AttrazioneStoricoCulturale tipo_di_monumento: string costruito_nel: AnnoStorico laws L1: tipo eq Monumento Object Piazza is a AttrazioneStoricoCulturale area: real laws L1: tipo eq Piazza L2: area gl 0 Il Context successivo descrive le relazioni di vicinanza fra due attrazioni turistiche Context Vicinanza attr1, attr2: AttrazioneStoricoCulturale distanza: real laws L1: distanza eq CALCOLA_DISTANZA(attr1. posizione, attr2.posizione) /* invoco la funzione CALCOLA_DISTANZA che misura le distanze fra i punti o fra linee o fra punto e linea, in base agli oggetti che le vengono passati */ L2: distanza le 600 /* considero vicini solo i luoghi che sono distanti 600m l’uno dall’altro. La natura del context mi garantisce che non compaia due volte la stessa coppia di luoghi */ L3: ident(attr1) ne ident(attr2) /* attr1 e attr2 devono essere diversi */

10

Context stessa_ubicazione is a Vicinanza collocazione: string laws L1: forall r in Instances itis r.distanza eq 0 /* in questa relazione ho una restrizione sui vincoli della relazione vicinanza, in questo caso le due attrazioni storico culturali hanno la stessa posizione. ES: un monumento in una piazza o un museo in un edificio */ L2: attr2 ne monumento and attr1 ne piazza and (attr1 ne edificio and attr2 ne museo) /* in questo context intendiamo che l’attr1 sia situata “dentro” l’attr2 */

11

Vediamo lo schema grafico delle entità descritte nella sezione precedente:

Piazza Monumento MuseoEdificio

Attrazione Storico Cult.

real

collocazione

string

AnnoStorico

integerboolean

string

Punto

real

Vicinanza Quartiere

Num.Sale Num.

Opere

Apertoal pubbl

Costruito nel

Costruitonel

Tipo Edificio

Tipo Monum.

Tipo Museo

x

y

distanza

attr1

attr2

posizione

nome

tipo

descrizione

Quartiere di appart. nome

stessa ubicazione

string

AC DC

12

Strutture di Accoglienza e Attrazioni Turistiche Value anno val: 1900…2100 bis: boolean laws L1: bis ⇔ ((val mod 4 eq 0) and (val mod 100 ne 0)) or (val mod 400 eq 0) Value data gg: 1...31 mm: 1...12 a1: anno laws L1: mm in (4, 6, 9, 11) ⇒ gg le 30 L2: a1.bis and mm eq 2 ⇒ gg le 29 L3: not a1.bis and mm eq 2 ⇒ gg le 28

13

/* Il seguente Virtual permette di confrontare due date e stabilire se la prima è minore della seconda o se sono uguali. */ Virtual dVsd (d1, d2: data) prima_minore: boolean uguali: boolean laws L1: prima_minore ⇔ (d1.anno lt d2.anno) or ((d1.anno eq d2.anno) and (d1.mm lt d2.mm)) or ((d1.anno eq d2.anno) and (d1.mm eq d2.mm) and (d1.gg lt d2.gg)) L2: uguali ⇔ ((d1.anno eq d2.anno) and (d1.mm eq d2.mm) and (d1.gg eq d2.gg)) Value intervallo_data data1, data2: data laws L1: dVsd(d1=data1, d2=data2).prima_minore /* la prima data deve essere minore della seconda; un intervallo deve durare più di un giorno */

14

Virtual dVsintervallo (d: data, i: intervallo_data) /* questo virtual verifica l’appartenenza di una data a un dato intervallo */ appartiene: boolean laws L1: appartiene ⇔ ((dVsd(d1=i.data1, d2=d).prima_minore) or (dVsd(d1=i.data1, d2=d).uguali)) and ((dVsd(d1=d, d2=i.data2).prima_minore) or (dVsd(d1=d, d2=i.data2).uguali)) /* una data appartiene ad un intervallo anche se coincide con l’inizio o con la fine dell’ intervallo */ Vlaue indirizzo tipo: (piazza, via, viale) toponimo: string num_civico: integer Value orario ore: 0…23 minuti: 0…59

15

Virtual oVso (o1, o2: orairo) /* questo virtual confronta due orari */ primo_minore: boolean uguali: boolean laws L1: primo_minore ⇔ (o1.ore lt o2.ore) or ((o1.ore eq o2.ore) and (o1.minuti lt o2.minuti)) L2: uguali ⇔ ((o1.ore eq o2.ore) and (o1.minuti eq o2.minuti)) Value orariogiornaliero giorno: (lun, mar, mer, giov, ven, sab, dom) mattinodalle, mattinoalle: orario pomeriggiodalle, pomeriggioalle: orario laws L1: oVso (o1=mattinodalle, o2=mattinoalle).primo_minore and oVso (o1=pomeriggiodalle, o1=pomeriggioalle).primo_minore L2: (mattinodalle.ore gt 7) and (mattinoalle.ore le 20) L3: (pomeriggiodalle.ore gt 14) and (pomeriggioalle.ore le 20) /* queste leggi verificano la correttezza dell’orario giornaliero*/ Value orariosettimanale day: set of orariogiornaliero giornichiusura: 0…7 laws L1: card(day) le 7 L2: forall o1,o2 in day itis o1.giorno ne o2.giorno /* non possono esistere due giorni uguali in un orariosettimanale */ L3: giornichiusura eq (7 MINUS card(day))

16

Object struttura cods: string mandatory unique nome: string mandatory tipo: (struttura_di_accoglienza, cinema, discoteca, ristorante, birreria) tel: string fax: string e-mail: string orario_apertura: orario_settimanale ind: indirizzo mandatory laws L1: forall s1, s2 in Instances itis (ident(s1) eq ident(s2)) ⇔ (s1.ind eq s2.ind) /*Una struttura è identificata univocamnete, oltre che dal codice, anche dall’indirizzo; non possono esistere due strutture con lo stesso indirizzo*/

17

Object struttura_di_accoglienza is a struttura tipoacc: (hotel, albergo, bedVsbreakfast, ostello) numero_posti: integer parcheggio: boolean periodo_apertura: intervallo_data aperto: boolean categoria: 1…5 class attributes capienzamax: integer laws L1: let oggi=GETDATE( ) /* questa funzione mi restituisce la data odierna */ L2: tipo eq bedVsbreakfast ⇒ numero_posti le 10 L3: tipo eq ostello ⇒ (not parcheggio) and (categoria eq null) L4: dVsintervallo(d=oggi, i=periodo_apertura).appartiene ⇔ aperto /* la struttura di accoglienza è aperta se la data odierna appartiene al suo periodo di apertura, in questo caso l’aperura non riguarda l’orario giornaliero*/ L5: tipo eq struttura_di_accoglienza L6: capienzamax eq MAX(numero_posti for x in Instaces)

18

Object disponibilità /* questo object associa ad ogni struttura_di_accoglienza, per ogni giorno del suo periodo di apertura il numero di posti ancora disponibili */ s: struttura_di_accoglienza giorno: data posti_liberi: integer completa: boolean class attributes tot_posti_liberi: integer al_completo: integer laws L1: let oggi=GETDATE( ) /* questa funzione mi restituisce la data odierna */ L2: forall d1, d2 in Instances itis (ident(d1) eq ident(d2)) ⇔ ((ident(d1.s) eq ident(d2.s)) and (di.giorno eq d2.giorno)) /* ogni istanza è identificata dalla struttura e dalla data */ /* inseriamo di seguito i vincoli sulla data */ L3: (dVsi(d:giorno, i=s.periodo_apertura).appartiene) /* per ogni istanza il giorno deve appartenere al periodo di apertura della struttura */ L4: ((dVsd(d1=oggi, d2=giorno).prima_minore) or (dVsd(d1=oggi, d2=giorno).uguali)) /* non devono esistere istanze riguardanti date antecedenti a quella odierna */ L5: giorno.a1 le oggi.a1 /* vengono gestite le disponibilità fino alla fine dell’anno corrente */ L6: postiliberi le numero_posti /* la disponibilità non può essere superiore alla capienza massima della struttura */ L7: completa ⇔ (posti_liberi eq 0)

19

/* Inseriamo ora le leggi per gli attributi di classe */ L8: tot_posti_liberi eq sum (d.posti_liberi for d in Instances) /* è un atributo di classe che riferisce il numero di posti liberi nelle strutture di accoglienza della città */ L9: al_completo eq card( d in Instances where (d.completo and d.giorno eq oggi)) /* corrisponde al numero di struture al completo nella data odierna */

20

Vediamo lo schema grafico delle entità descritte nella sezione precedente:

0…7

Orario

Orario giornaliero

Orario settimanale

lun,mar…dom

0…59

0…23

boolean

1900…2100

1…31

1…12

intervallo data

data

anno

dVsd

oVso

dVsintervallo

val

data1

d1

appartiene

giorno

day (set of)

giorni chiusura

bisprima

minore

uguali

o2 o1

minuti

ore

pomeriggalle

pomeriggdalle

mattino dalle

mattino alle

uguali

d2 i d

data2

mm

gg

a1

primo minore

21

Struttura Accoglienza

Stuttura

s

orario apertura

boolean

integer

intervallodata

1…5

hotel, albergo, bVsb,

rist, birreria, disco

string

Orario settimanle

data

disponibilità

indirizzo

string

piazza, viale, via

integer

tipo

num civico

toponimo

parcheggioaperto

giorno

numposti

periodo apertura

categoria

tipo acc

tipo

nome

completa

posti_liberi

tot_posti_liberi

al_completo

cods

indtel

fax

email

capienza max

22

Itinerari Object percorso /* con questo object definisco un percorso con le sue caratteristiche e sia itinerario che tappa sono specializzazioni di questo object */ codice: string mandatory unique /* itinerari e tappe sono identificati da un codice univoco all’ interno dell’oggetto “percorso” */ tempo_perc: integer lunghezza: real inizio,fine: AttrazioneStoricoCulturale chiuso: boolean laws L1: chiuso ⇔ ident(inizio) eq ident(fine) /* il percorso è chiuso se inizia e finisce nello stesso luogo */ L2: lunghezza gl 0

23

Virtual percorsoVspercorso (p1, p2: percorso) /* questo vitual permette di confrontare due percorsi */ consecutivi: boolean uguali: boolean stessi_inizio_fine: boolean ad_anello: boolean laws L1: consecutivi ⇔ (ident(p1.fine) eq ident (p2.inizio) and (ident(p1.inizio) ne ident(p2.fine)) /* due percorsi sono consecutivi se la fine del primo coincide con l’inizio del secondo, ma non formano un anello */ L2: uguali ⇔ (p1.codice eq p2.codice) /* due percorsi sono uguali se hanno lo stesso codice */ L3: stessi_inizio_fine ⇔ (p1.codice ne p2.codice) and (ident(p1.inizio) eq ident(p2.inizio)) and (ident(p1.fine) eq ident(p2.fine)) /* due percorsi possono avere tracciati diversi, ma iniziare e terminare negli stessi punti */ L4: ad_anello ⇔ (ident(p1.fine) eq ident (p2.inizio) and (ident(p1.inizio) eq ident(p2.fine))

24

Object tappa is a percorso /* la tappa è una specializzazione di percorso e quindi ne eredita gli attributi */ tipo: (a_piedi, in_corriera, in_metropolitana) class attributes num_tappe: integer tot_lunghezza: real tappa_più_lunga: set of tappa laws /* laws sugli attributi di classe */ L1: num_tappe eq card(t in Instances) L2: tot_lunghezza eq SUM(t.lunghezza for t in Instances) /* questo attributo rappresenta il numero totale di metri di tutti gli itinerari per la visita alla città */ L3: forall x in tappa_più_lunga itis (x.lunghezza eq MAX(x2.lunghezza for x2 in Instances) /* definisco la/le tappe di lunghezza massima */

25

Object itinerario is a percorso tappe: list of tappa num_componenti: integer class attributes max_lungh: real laws L1: let tipo_piedi=card(T in tappe where (T.tipo eq a_piedi)) L2: let tipo_corriera=card(T in tappe where (T.tipo eq in_corriera)) L3: let tipo_metro=card(T in tappe where (T.tipo eq in_metropolitana)) L4: num_componenti eq card(tappe) L5: lunghezza eq SUM(t.lunghezza for t in tappe) L6: ident(inizio) eq ident(FIRST(tappe).inizio) L7: ident(fine) eq ident(LAST(tappe).fine) /* ho definito gli attributi di percorso, ora definisco gli attributi di classe, quelli cioè che riguardano tutte le istanze di tipo itinerario */ L8: max_lungh eq MAX(s.lunghezza for s in Instances) /* rappresenta la massima lunghezza fra i vari itinerari turistici */ ora descrivo i vincoli da soddisfare */ L9: (num_componenti ge 2) and (num_componenti le 6) /* vincolo sul numero di tappe in un itinerario */ L10: forall t1, t2 in tappe itis (ident(t1) ne ident(t2)) /* una tappa può essere una sola volta in un sentiero */ L11: forall t in tappe itis (percorsoVspercorso(p1=t, p2=NEXT(t)).consecutivi) /* vincolo sulla consecutività delle tappe */ L12: tipo_piedi le 3 /* un itinerairo può avere al massimo tre tappe da percorrere a piedi */ L13: forall s1, s2 in Instances suchthat (ident(s1) ne ident(s2)) ⇒ (exists tappa1 in s1.tappe and tappa2 in s2.tappe suchthat not (percorsoVspercorso(p1=tappa1, p2=tappa2).uguali) /* se due percorsi sono diversi allora hanno una tappa diversa */

26

Context interessa /* questo context associa ad una tappa una sua attrazione storico culturale di interesse. I luoghi di inizio e fine fanno parte delle attrazioni storico culturali interessate */ T: tappa A: AttrazioneStoricoCulturale laws /* i luoghi di interesse di una tappa devono essere ad una distanza max di 50m dal tracciato della tappa */ L1: CALCOLA_DISTANZA(T,A.posizione) le 50 /* per calcolare la distanza reciproca utilizzo la stessa funzione usata nel context vicinanza, in questo caso “tappa” che è il primo parametro viene considerata come una linea, con posizioni iniziale e finale date dai due luoghi di partenza e arrivo */ Context attrazioni_itinerairo by interessa, itinerario /* con questo context by definisco una lista di tutti i luoghi di interesse di un itinerario utilizzando il context interessa e l’oggetto itinerario */ cod_itinerario: string attr_costeggiate: set of AttrazioneStoricoCulturale laws /* un’attrazione storico culturale è costggiata da un itinerairo se è un luogo di interesse per una delle sue tappe */ L1: forall ac in attr_costeggiate itis (exists i in interessa.Instances, t in itinerairo.Instances suchthat ( (ident(i.A) eq ident (ac)) and (t.codice eq cod_itinerario) and (exists tap in t.tappe suchthat ident(tap) eq ident(i.T)) ) ) /* un itinerario visita un’attrazione storico culturale se esiste una tra le tappe che lo compongono, che interessa quel posto */

27

Vediamo lo schema grafico delle entità descritte nella sezione precedente:

real

boolean

integer

string

tappa itinerairo

percorso

Attrazione Storico Cult.

percorso Vs percorso

p2p1

inizio

fine

stessiiniziofine

uguali

consecutive

ad anello

chiuso

codice

tempo perc

lunghezza

28

real

real

integer

string

itinerario

Attrazione Storico Cult.

T

by

tot_lungh

attr costeggiate (set of)

cod itinerario

tipo

a_piedi in_corr.

interessa

tappa

attrazioni itinerario

by

A

tappe (list of)

num tappe

max_lungh

n_comp

tappa più lunga (list of)

29

Modello Funzionale MDT: Le funzioni richieste verranno realizzate attraverso l’uso delle primitive View e Event, ovviamente un sistema reale deve supportare molte più funzioni di quelle indicate, ma l’obiettivo della tesina non è quello di essere esaustiva nella rappresentazione delle esigenze reali, ma quello di mostrare l’utilizzo di tutte le primitive messe a disposizione dal modello MDT.

Visualizzazione di informazioni: View

• Visualizzazione di tutte le tappe che interessano una determinata attrazione storico culturale

View visita_attrazioni (nome: string) from interessa ris: set of tappa laws L1: forall r in ris itis (exists x in interessa.Instances suchthat (x.A.nome eq nome) and (ident(x.T) eq ident(r)) /* per ogni tappa del risultato deve esistere un’istanza di interessa che leghi la tappa al luogo inserito da input */ L2: forall x in interessa.Instances suchthat (x.A.nome eq nome) itis (exists r in ris suchthat ident(r) eq ident(x.T)) /* per ogni istanza di interessa che contiene il luogo indicato da input deve esiste in ris la tappa corrispondente */

30

• Visualizzazione della/delle tappe con il maggior numero di luoghi di interesse.

View più_luoghi from interessa, tappa ris: set of tappa laws L1: forall r in ris itis (let totale=set of I in interessa.Instances where (ident(I.T) eq ident(r)) forall r2 in tappa.Instances itis (let totale2=set of I in Interessa.Instances where (ident(I.T) eq ident(r2)) and not(percorsoVspercorso(p1=r,p2=r2).uguali) ⇒ card(totale) ge card(totale2))) /* per ogni tappa del risultato calcolo l’insieme di luoghi interessati. La cardinalità di questo insieme deve essere maggiore o uguale a quella di tutte le altre tappe */ L2: forall x in tappa.Instances suchthat ( not exists y in tappa.Instances suchthat ( let totx=set of I interessa.Instances where (ident(I.T) eq ident(x) let toty=set of I interessa.Instances where (ident(I.T) eq ident(y) toty ge totx and toty ne totx)) itis exists r in ris suchthat ident(r)=ident(x) /* viceversa ogni tappa avente un numero di luoghi interessanti maggiore o uguale a quello di tutte le altre tappe deve appartenere al risultato */

31

• Visualizzazione delle strutture di accoglienza che in

una certa data hanno un numero di posti disponibili almeno pari a quello richiesto da input.

View strutture_acc_disponibili (g: data, posti: integer) form disponibilità ris: set of struttura_di_accoglienza laws L1: forall r in ris itis ( exists d in disponibilità.Instances suchthat ( ( ident(d.s) eq ident(r)) and (d.giorno eq g) and (d.posti_liberi ge posti))) /* per ogni struttura di accoglienza inclusa nel risultato, deve esistere nell’ object disponibilità una sua istanza che soddisfi le condizioni imposte sul giorno e sui posti */ L2: forall d in disponibilità.Instances suchthat ( (d.giorno eq g) and (d.posti_liberi ge posti) ) itis ( exists r in ris suchthat ident(r) eq ident(d.s)) /* il risultato della view deve essere completo */

32

• Visualizzazione del numero totale di posti liberi in

data odierna, in tutte le strutture di accoglienza di tipo e categoria specificati da input.

View posti_totali (tipo: string, cat: integer) form disponibilità ris: integer laws L1: let oggi=GETDATE( ) L2: ris eq SUM(d.posti_liberi for d in disponibilità.Instances where ((dVsd(d1=oggi,d2=d.giorno).uguali) and (d.s.tipoacc eq tipo) and (d.s.categoria eq cat) ) )

33

• Visualizzazione degli itinerari che costeggiano due

attrazioni storico culturali specificate da input. View collegamenti (nome1, nome2: string) from attrazioni_itinerario ris: set of itinerario laws /* per ogni itinerario in ris, deve esistere una istanza di attrazioni_itinerario che associa all’itinerario i due luoghi indicati */ L1: forall r in ris itis (exists x in attrazioni_itinerario.Instances suchthat ( x.cod_itinerairo eq r.codice and ( exists v1, v2 in x.attr_costeggiate suchthat (v1.nome eq nome1 and v2.nome eq nome2)))) L2: forall x in attrazioni_itinerario.Instances suchthat (exists v1, v2 in x.attr_costeggiate suchthat( v1.nome eq nome1 and v2.nome eq nome2)) itis (exists r in ris suchthat r.codice eq x.cod_itinerario) /* per ogni istanza di attrazioni_itinerario contenente i due luoghi indicati, deve esistere il sentiero corrispondente in ris */

34

Inserimento, Eliminazione, Modifica: Event

• Prenotazione in una struttura di accoglienza e conseguente aggiornamento della disponibilità.

Event prenotazione on disponibilità d: data cod_struttura: string n_posti: integer precondition /* verifico che esista una istanza di disponibilità con la data e la struttura specificate e che il numero di posti liberi sia maggiore o uguale al numero di posti richiesto */ L1: exists x in disponibilità.Instances suchthat ( (x.s.codice eq cod_struttura) and (d eq x.giorno) and (x.posti_liberi ge n_posti) ) operation { postiliberi eq (old_posti_liberi MINUS n_posti) } /* aggiorno il numero di posti ancora a disposizione */

35

• Inserimento di una tappa.

Event inserimento_tappa on tappa, percorso, AttrazioneStoricoCulturale new_codice: string new_tempo_perc: integer new_lunghezza: real new_inizio, new_fine: string new_tipo: (a_piedi, in_corriera, in_metropolitana) precondition /* la tappa non deve già essere presente */ L1: not exists t in tappa.Instances suchthat (t.codice eq new_codice) L2: not exists p in percorso.Instances suchthat (p.codice eq new_codice) /* devono esistere le attrazioni storico culturali di inizio e fine */ L3: exists l1,l2 in AttrazioneStoricoCulturale.Instances suchthat ( (l1.nome eq new_inizio) and (l2.nome eq new_fine) ) operation { let ATTR1=l1 in AttrazioneStoricoCulturale.Instances suchthat l1.nome eq new_inizio let ATTR2=l2 in AttrazioneStoricoCulturale.Instances suchthat l2.nome eq new_fine T1.codice=new_codice T1.tempo_perc=new_tempo_perc T1.lunghezza=new_lunghezza T1.inizio=ATTR1 T1.fine=ATTR2 T1.tipo=new_tipo NEWINSTANCES(T1) in tappa }

36

• Inserimento di un’attrazione di interesse per una

tappa.

Event tappa_attrazione on tappa, AttrazioneStoricoCulturale, interessa cod_tappa: string nome_attr: string precondition /* controllo l’esistenza di una tappa con il codice specificato */ L1: exists t in tappa.Instances suchthat (t.codice eq cod_tappa) /* controllo l’esistenza dell’attrazione storico culturale specificata */ L2: exists a in AttrazioneStoricoCulturale.Instances suchthat a.nome=nome_attr /* controllo che non esista già un’associazione fra l’attrazione e la tappa specificate */ L3: not exists i in interessa.Instances suchthat ( (i.A.nome eq nome_attr) and (i.T.codice eq cod_tappa) ) operation { let TAP=t in tappa.Instances suchthat x.codice eq cod_tappa let ATTR=a in AttrazioneStoricoCulturale.Instances suchthat (a.nome=nome_attr) I.T=TAP I.A=ATTR NEWINSTANCES(I) in interessa }

37

• Eliminazione di una tappa che non interessa alcuna attrazione storico culturale.

/* Oltre alla tappa considerata si dovranno controllare anche tutti gli itinerari che la contengono, questi dovranno essere a loro volta eliminati se:

1. contengono due tappe 2. la tappa considerata non è la prima o l’ultima

Questo è motivato dal fatto che in seguito all’eliminazione della tappa, nell’itinerario non sarebbero più verificati i vincoli sul numero di tappe e sulla loro consecutività. */ Event elimina_tappa on tappa, interessa, itinerario cod_tappa: string precondition /* la tappa deve esistere */ L1: exists t in tappa.Instances suchthat t.codice eq cod_tappa /* devo controllare che non esistano luoghi di interesse per la tappa */ L2: not exists i in Interessa.Instances suchthat (i.T.codice eq cod_tappa) operation { let TAPP=t in tappa.Instances suchthat (t.codice=cod_tappa) /* prima di eliminare la tappa devo controllare gli itinerari che la contengono */ let ITI=set of itiner in itinerario.Instances suchthat (exists ta in itiner.tappe suchthat (ta.codice=cod_tappa)) /* tra questi elimino gli itinerari con 2 tappe e quelli in cui la tappa considerata non è la prima o l’ultima */ forall x in ITI suchthat ( (x.num_componenti eq 2) or ( (ident(first(x.tappe)) ne

38

ident(TAPP)) or (ident(last(x.tappe)) ne ident(TAPP)) ) ) itis DELINSTANCES(x) in itinerario /* infine elimino la tappa */ DELINSTANCES(TAPP) in tappa }