Gestione delle informazioni turistiche relative a una grande città

Transcript

Gestione delle informazioni turistiche relative a una grande città
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
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
2
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.
3
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.
4
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.
5
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.
6
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 */
7
/* 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
8
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 */
9
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 */
10
Vediamo lo schema grafico delle entità descritte nella sezione
precedente:
distanza
x
real
Punto
y
Vicinanza
Quartiere
posizione
attr1
Quartiere
di appart.
nome
attr2
string
nome
stessa
ubicazione
tipo
descrizione
Edificio
string
Monumento
Tipo
Museo
Tipo
Edificio
boolean
Costruito
nel
Costruito
nel
AnnoStorico
Piazza
Museo
Tipo
Monum.
Aperto
al pubbl
collocazione
Attrazione
Storico Cult.
Num.
Opere
Num.
Sale
string
real
integer
AC
DC
11
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
12
/* 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 */
13
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
14
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))
15
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*/
16
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)
17
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)
18
/* 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 */
19
Vediamo lo schema grafico delle entità descritte nella sezione
precedente:
1…12
1…31
mm
intervallo
data
gg
data1
val
1900…
2100
anno
data
d1
bis
data2
a1
i
d2
d
dVsd
prima
minore
uguali
dVsintervallo
boolean
appartiene
uguali
primo
minore
0…23
oVso
o1
ore
o2
Orario
0…59
minuti
pomerigg
dalle
mattino
dalle
mattino
alle
Orario
settimanale
pomerigg
alle
day
(set of)
Orario
giornaliero
giorni
chiusura
0…7
giorno
lun,mar
…dom
20
piazza,
viale,
via
string
string
tipo
toponimo
fax
indirizzo
email
nome
cods
integer
num
civico
tel
ind
Stuttura
tipo
orario
apertura
rist,
birreria,
disco
Orario
settimanle
hotel,
albergo,
bVsb,
tipo acc
data
1…5
Struttura
Accoglienza
categoria
intervallo
data
giorno
s
periodo
apertura
disponibilità
num
posti
parcheggio
aperto
boolean
capienza
max
completa
integer
posti_liberi
tot_posti_liberi
al_completo
21
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
22
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))
23
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 */
24
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 */
25
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 */
26
Vediamo lo schema grafico delle entità descritte nella sezione
precedente:
ad anello
consecutive
boolean
string
chiuso
percorso Vs
percorso
uguali
stessi
inizio
fine
p1
p2
Attrazione
Storico Cult.
codice
integer
inizio
tempo
perc
real
percorso
fine
lunghezza
tappa
itinerairo
27
a_piedi
in_corr.
tappa
più lunga
(list of)
real
tipo
tot_lungh
Attrazione
Storico Cult.
tappa
integer
A
num tappe
n_comp
T
tappe
(list of)
interessa
itinerario
by
by
real
max_lungh
attr costeggiate
(set of)
attrazioni
itinerario
cod
itinerario
string
28
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 */
29
• 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 */
30
• 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 */
31
• 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) ) )
32
• 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 */
33
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 */
34
• 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
}
35
• 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
}
36
• 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
37
ident(TAPP)) or
(ident(last(x.tappe)) ne ident(TAPP)) ) )
itis DELINSTANCES(x) in itinerario
/* infine elimino la tappa */
DELINSTANCES(TAPP) in tappa
}
38