UML: Constraints-OCL Corso IS I - 2002/03 Gianna Reggio Versione 0.0
Constraints Permettono di specificare delle limitazioni sui componenti di un modello (classi, associazioni,operazioni) Il numero degli iscritti ad un torneo è una potenza di due Il punteggio di una partita consiste di 120 punti divisi tra le due coppie partecipanti Le coppie partecipanti ad un torneo sono tutte fatte di giocatori distinti …. Solo prescrittive Se una constraint è violata, allora il modello è errato/inconsistente Starting point Integrity constraint su database, SQL Specifiche logiche (es. logica di Hoare) Constraint predefinite is query per le operazioni, frozen
Forma delle constraint Testuale (date a parte) context Class inv: Condition Ogni istanza di Class in ogni momento deve soddisfare Condition context Class::Operation(x1:T1,…,X2:Tn): T pre: Condition1 post: Condition2 Condition1 deve essere vera prima di ogni chiamata di Operation e Condition2 deve essere vera dopo ogni chiamata di Operation Grafica messe in una nota collegata all’elemento constrained (il context, che quindi non viene riportato) Linguaggio per esprimere Condition, non fissato da UML Si può usare Linguaggio naturale Linguaggio di programmazione (Java, C++,…) Linguaggio formale di specifica (Z) OCL, allegato alla definizione di UML
OCL (Object Constraint Language) Privo di side effects (linguaggio puramente funzionale) Tipi ed espressioni Soliti tipi base collection (supertito dei tipi strutturati) perché in OCL non c’è nulla corrispondente al prodotto cartesiano/record? Costrutti per riferirsi al contesto Self, nomi dei parametri Costrutti per riferirsi agli elementi del modello UML constrained Classi nel modello come nuovi tipi con possibilità di chiamare le loro operazioni, accedere ai loro attributi e navigare le loro associazioni
Tipi base costanti
Collection valori strutturati (composti da altri valori) perchè fondamentali per UML ????? tipi parametrici Collection(Type), Set(Type), Bag(Type), Sequence(Type), tipo astratto Collection Bag Set Sequence tipi concreti multinsiemi (insiemi con elementi ripetuti) liste ordinate
Collection: valori (costanti) Set{ 1 , 2 , 5 , 88 } = Set{88 , 2 , 1 , 5 , 2, 5 } Set{ 'apple' , 'orange', 'strawberry' } Sequence{ 1, 3, 2, 3 } ≠ Sequence{ 3, 1, 2, 3 } Bag{ 'ape', 'nut' } = Bag{'nut', 'ape’ } Bag{1 , 3 , 4, 3, 5 } ≠ Bag{1 , 3 , 4, 5 } Sequence{ 1..8 } = Sequence{ 1, 2, 3, 4, 5, 6, 7, 8 }
Collection: operazioni (1) select (ritorna la sottocollezione degli elementi che verificano una condizione) collection->select(v:Type |bool-expr-with-v )[:Collection(Type)] tipo degli elementi di collection varianti equivalenti collection->select(v | bool-expr-with-v ) collection->select( bool-expr-with-v ) reject (ritorna la sottocollezione degli elementi che non verificano una condizione) collection->reject(v:Type | bool-expr-with-v )[:Collection(Type)] collect (ritorna la collezione data dalle valutazioni di un’espressione sugli elementi di un’altra collezione) collection->collect(v: Type | expr-with-v )[:Collection(Type’)] tipo di expr-with-v
Collection: operazioni (2) forall (controlla se tutti gli elementi di una collezione verificano una condizione) collection->forall(v:Type | bool-expr-with-v )[:Boolean] exists (controlla se almeno un elemento di una collezione verifica una condizione) collection->exists(v:Type | bool-expr-with-v )[:Boolean] includes (controlla se una collezione contiene un elemento) collection->includes(expr)[:Boolean] isEmpty (controlla se una collezione è vuota) collection->isEmpty(expr)[:Boolean] …. quelle ovvie di set, bag, e sequence (vedere reference) hanno tutte la sintassi collection->op(….)
Classi come tipi OCL ogni classe C definita nel modello corrente è un tipo per OCL sia o: C accedere ad un attributo attr: T di o o.attr applicare un’operazione op ad o o.op(e1,…,en) navigare lungo un’associazione ass da C in C1 o.ass = la collection di tutti le istanze di C1 in relazione con o rispetto ad ass [:Collection(C1)]
Riferisi al contesto context C inv: bool-expr self: generico elemento di C (si può omettere) context c: C inv: bool-expr c: generico elemento di C context op(x1:T1,…xn:Tn):T pre: bool-expr self: oggetto che esegue op (si può omettere) x1,…,xn: i valori dei parametri post: bool-expr self: oggetto che esegue op (si può omettere) x1,…,xn result: il risultato ritornato dall’esecuzione di op
post-condition cosa significano self.attr, self.op(…), self.ass in una post-condition ? ambiguità alla fine della chiamata dell’operazione ? basta scrivere self.attr, self.op(…), self.as prima della chiamata dell’operazione ? basta scrivere self.attr@pre, self.op@pre(…), self.as@pre
Esempi (relativi a BRISCOLA.gif) il valore di una carta è compreso tra 1 e 10 context Carta inv: self.valore>0 and self.valore<=11 Il vincitore di uno scontro è lo sfidante o lo sfidato context Scontro inv: vincitore = sfidato or vincitore = sfidante una coppia è fatta da due giocatori differenti context c: Coppia inv: c.primo <> c.secondo oppure context c: Coppia inv: c.primo.nome <> c.secondo.nome or c.primo.cognome <> c.secondo.cognome
Esempi (relativi a BRISCOLA.gif) Vince uno scontro la coppia che ha vinto per prima 3 partite “ci devono essere 3 partite vinte dalla coppia vincitore e le partite sono meno di 6” context Scontro inv: partite->size=>3 and partite->size<6 and partite->exists(P1,P2,P3| P1<>P2 and P1<>P3 and P2<>P3 and P1.vince = vincitore and P2.vince = vincitore and P3.vince = vincitore) non vi ricorda niente dal vostro passato recente ???