Anda di halaman 1dari 30

El lenguaje de especificacin OCL

-1-

Ingeniera del Software I


El lenguaje de especificacin OCL
1 cuatrimestre 2006

Limitaciones del diagrama de clases...................................................................................................................... 2


OCL (Object Constraint Language) ..................................................................................................................... 2
Tipos de definiciones............................................................................................................................................... 3
Tipos de datos.......................................................................................................................................................... 5
Constructores, constantes e identificadores.......................................................................................................... 6
Operaciones centrales sobre tipos no predefinidos .............................................................................................. 7
Operaciones asociadas a los tipos bsicos predefinidos ....................................................................................... 9
Operaciones asociadas a los tipos de Coleccin.................................................................................................. 11
Operaciones asociadas a colecciones especficas ................................................................................................ 17
Jerarqua de tipos ................................................................................................................................................. 18
Operacin de tuplas .............................................................................................................................................. 20
Operaciones de clase y de metaclase.................................................................................................................... 21
Sobre la especificacin de efectos colaterales ..................................................................................................... 22
Expresiones LET ................................................................................................................................................... 23
En relacin a la creacin de expresiones-objetos de una clase.......................................................................... 24
Sobre el uso de las clases de asociacin del diagrama de clases ........................................................................ 25
Sobre el uso de la herencia ................................................................................................................................... 26
Sobre los valores indefinidos................................................................................................................................ 27
Un ejemplo............................................................................................................................................................. 27
Bibliografa............................................................................................................................................................ 30

El lenguaje de especificacin OCL


-2-

Limitaciones del diagrama de clases


Es sabido que dentro del lenguaje de modelado UML el diagrama de clases es una poderosa
herramienta de modelizacin de la naturaleza propia de la informacin. En este diagrama se
estructura la informacin especificando los tipos de objetos referidos (clases) con sus
referencias inter-clases (asociaciones y clases de asociacin junto con sus correspondientes
multiplicidades y roles), adems de las relaciones jerrquicas entre clases (herencia,
especializacin, generalizacin). El objetivo del uso de esta herramienta es establecer una
abstraccin respecto a todos los casos particulares posibles, ofreciendo un marco sintctico para
definir un modelo de la realidad, separando aquellos casos particulares correctos (los
contemplados dentro del diagrama de clases, que es una abstraccin de todos ellos), de los que
no. A esta separacin que provee el diagrama entre los casos particulares correctos y los
incorrectos, lo vamos a llamar el invariante inherente al diagrama, que representa las
restricciones propias que debe cumplir el modelo.
Sin embargo, estas restricciones provistas por el diagrama, si bien son semnticas (de
significado), terminan siendo limitadas por la sintaxis de los componentes del mismo. Pero
seguramente existen otro tipo de restricciones que pueden presentarse, asociadas a condiciones
que se deben aplicar sobre los objetos representados, y que se deben cumplir. Estas
restricciones son ms amplias que las determinadas por la sintaxis del diagrama, ya que se
expresan mediante condiciones. Para poder expresar estas condiciones es necesaria la existencia
de un lenguaje de especificacin que provea un marco para poder escribirlas. Dentro del
contexto de UML y asociado al diagrama de clases, deberan estar anexadas estas condiciones
escritas en este lenguaje que expresen todas estas restricciones, junto a otras caractersticas que
no se pueden reflejar en el diagrama y que s se pueden reflejar con este lenguaje.

OCL (Object Constraint Language)


El lenguaje de especificacin OCL aparece en el documento Semntica de UML como
lenguaje propuesto para especificar las restricciones del diagrama de clases, junto a otro tipo de
definiciones. OCL se puede utilizar en cualquier contexto en que se use el diagrama de clases al
que est asociado (como por ejemplo, en el modelo conceptual, en el de anlisis o en el diseo).
OCL es un lenguaje hbrido orientado a objetos-funcional, y es tipificado, porque usa el
concepto de tipos de datos. Estos tipos de datos se encuentran jerarquizados a travs de
relaciones de inclusin. Tambin existen varios tipos bsicos predefinidos (similares a los de
cualquier lenguaje), y unos pocos tipos paramtricos (o estructurados) predefinidos. Los tipos
no predefinidos van a estar asociados a las clases del diagrama de clases.
El componente central construdo por este lenguaje es la expresin, que se manipula a travs
de operaciones que garantizan la transparencia referencial y la falta de efectos colaterales. Estas
son caractersticas compartidas con los lenguajes funcionales, que son declarativos. Toda
expresin vlida para el lenguaje OCL debe tener asociado un tipo de datos. Las expresiones se
pueden mapear fcilmente al concepto de objetos, ya que cada tipo bsico no predefinido se
puede vincular a una clase del diagrama, y algunas de las operaciones de un tipo bsico no
predefinido se mapean a los atributos y mtodos/responsabilidades de la clase original. Las
asociaciones entre clases tambin se modelan dentro de los tipos de OCL usando los roles de

El lenguaje de especificacin OCL


-3-

ambas clases participantes en la asociacin, que deben estar rotulados (en ambos extremos). El
rol de una segunda clase en una asociacin con la clase, expresa que ese rol es un
pseudoatributo del tipo de dato vinculado a la clase original.
Como se puede ver, todos los componentes asociados a las clases, tambin se ven reflejados en
los tipos de OCL.
Las expresiones del lenguaje OCL se estructuran hasta llegar a su punto ms alto, que es el
de formar parte de una definicin. En cada definicin de OCL se describe cada restriccin
semntica del diagrama de clases, junto a otras propiedades tambin descriptas con expresiones.
Cada definicin en OCL se aplica a lo que se llama un contexto, que representa el destinatario
del diagrama de clases sobre quien se aplica esa definicin. Entre estos contextos se encuentran:
- Una clase (se aplica a todas expresiones-objetos cuyo tipo de datos asociado es el
vinculado a esta clase).
- Un mtodo/responsabilidad de una clase.
- Un atributo derivado de una clase.
- Un mtodo/responsabilidad derivado (tambin llamado query) de una clase.
En OCL se permite utilizar recursin en todas las definiciones que se necesiten.

Tipos de definiciones
1) Invariantes
context idclase
inv: [[Descripcin del invariante]] expBool
Representa una condicin (restriccin semntica) que deben cumplir todas las expresionesobjetos pertenecientes al tipo de datos vinculados a la clase idclase. La condicin a cumplirse se
expresa en la expresin expBool que es de tipo Boolean (lgico). La expresin booleana debe
evaluar en verdadero si se aplica a expresiones-objetos pertenecientes al tipo de la clase en
cuestin que son vlidos bajo este invariante. Para el resto de las expresiones-objetos (que son
invlidas segn este invariante), la expresin debe evaluar en falso.
Estos invariantes pueden tener una descripcin optativa (que se escribe entre corchetes).
En la prctica se podr observar que el mismo invariante (que en realidad no es de una clase
ni de una expresin-objeto, sino del modelo propiamente dicho) se puede describir partiendo de
diferentes contextos, aunque por supuesto, la dificultad de expresarlo puede ser mayor si se
opta por un contexto inadecuado.
2) Invariantes (definiciones) de mtodo/responsabilidad
context idclase::idmetodo([out|in/out] par1:T1,...,[out|in/out] parn:Tn)[:Tres]
pre: [[Descripcin precondicin]] expBool

El lenguaje de especificacin OCL


-4-

post: [[Descripcin postcondicin]] expBool


Define la aplicabilidad de un mtodo/responsabilidad (de nombre idmetodo, existente dentro
de la clase idclase con parmetros formales par1 a parn de tipo T1 a Tn , y con imagen de tipo
Tres -slo en el caso que retorne una expresin-). Las clusulas out o in/out asociadas
opcionalmente a cada parmetro indican que el parmetro correspondiente puede ser de slo
salida (escritura) o de entrada/salida; en el caso de no indicarse nada, el parmetro ser de slo
entrada (lectura). La clusula pre refleja la precondicin de este mtodo/responsabilidad,
expresada en la primera expresin booleana expBool, que deber retornar verdadero slo para
aquellas expresiones-objetos para la cual este mtodo sea aplicable. La clusula post refleja la
postcondicin de este mtodo/responsabilidad, expresada en la segunda expresin booleana
expBool, que deber retornar verdadero slo cuando el estado final de la expresin-objeto al que
se le aplic este mtodo/responsabilidad es consistente con el accionar del mismo.
No existiran problemas si el mtodo/responsabilidad retorna una expresin y no modifica el
estado interno de la expresin-objeto original, ya que la postcondicin slo verificara el
resultado que retorna. Pero si no retorna un valor (porque en realidad modifica el estado interno
de la expresin-objeto original), la naturaleza de la postcondicin es distinta que la anterior, ya
que existe un efecto colateral de por medio. En este ltimo caso no se especifica cmo se
actualiza el estado interno de la expresin-objeto original (ya que esto no sera declarativo),
sino la condicin en que debe quedar la expresin-objeto original luego de aplicarle este
mtodo/responsabilidad, al igual que los parmetros modificados que sean de tipo out o
in/out. Este invariante terminara reflejando en forma declarativa su definicin en s misma.
Estos casos (de existencia de efectos colaterales) se explicarn ms tarde.
3) Definicin de atributos derivados
context idclase::idatributo:T
derive: expT
Define un atributo derivado de nombre idatributo existente en la clase idclase, y que retornar
una expresin de tipo T. La expresin retornada por este atributo derivado, al aplicarla sobre
una expresin-objeto de la clase en cuestin, retornar la expresin expT, que tambin deber
ser de tipo T.
4) Definicin de mtodos/responsabilidades derivados (queries)
context idclase::idmetodo(par1:T1,...,parn:Tn):T
[pre: [[Descripcin precondicin]] expBool]
body: expT
Define un mtodo/responsabilidad derivado. Como es un mtodo/responsabilidad, el
contexto es idntico al de un mtodo/responsabilidad comn, con la diferencia que siempre
retornar una expresin (que deber ser de tipo T) y no provocar efectos colaterales. La
clusula pre optativa determina si es aplicable o no (segn el resultado de expBool) a cada
expresin-objeto de la clase. En forma anloga a los atributos derivados, en la clusula body se

El lenguaje de especificacin OCL


-5-

especifica cul ser el valor retornado para cada expresin-objeto de la clase que sea aplicable,
a travs de la expresin expT, que ser de tipo T.

Tipos de datos
1) Predefinidos
a) Bsicos
- Boolean (valores lgicos)
- Integer (valores enteros)
- Real (valores reales)
- String (valores de cadenas de caracteres)
- OCLAny (el tipo supremo jerrquico de todos los tipos no estructurados)
- OCLType (el tipo asociado a los metatipos -todo tipo puede verse como una
expresin de tipo OCLType-)
b) Estructurados
- Collection(T)
- Set(T)
- Bag(T)
- OrderedSet(T)
- Sequence(T)
- Tuple{id1:T1,..., idn:Tn}
El tipo Set(T) corresponde a los conjuntos de expresiones de tipo T, que no contienen
repeticiones y sus expresiones contenidas no poseen un orden posicional.
El tipo Bag(T) corresponde a los bags de expresiones de tipo T, que permiten contener
repeticiones y donde sus expresiones contenidas no poseen un orden posicional.
El tipo OrderedSet(T) corresponde a los conjuntos ordenados de expresiones de tipo
T, que no contienen repeticiones y sus expresiones contenidas poseen un orden posicional.
El tipo Sequence(T) corresponde a las secuencias (listas) de expresiones de tipo T, que
permiten contener repeticiones y donde sus expresiones poseen un orden posicional.
El tipo Collection(T) corresponde a las colecciones de expresiones de tipo T. Es un
tipo que es abstracto y superior jerrquico de los cuatro anteriores.
El tipo Tuple{id1:T1,..., idn:Tn} (con n>0) corresponde a las tuplas
(registros/records) con campos de nombre id1 a idn , donde cada uno de ellos debe tener
asociada una expresin de tipo T1 a Tn respectivamente.
2) No predefinidos
Corresponden a cada clase y enumerado del diagrama de clases. Toda clase o enumerado C
se mapear al tipo asociado TC de OCL. Sin embargo, como abuso de notacin es normal

El lenguaje de especificacin OCL


-6-

referirse al tipo como C (el mismo nombre de la clase), aunque no lo haremos en el resto de
este apunte. Aqu expresamos al tipo de la clase C como TC slo a los efectos de distinguir la
diferencia de conceptos entre clase y tipo.
En OCL cada atributo de una clase, al aplicarse a una expresin del tipo asociado a la clase,
retorna una expresin que tambin tendr un tipo asociado. Con esto, decimos que todo atributo
tiene tambin un tipo asociado. Esto ya se dijo en la definicin de atributos derivados, cuando
se expres que stos retornan una expresin de un tipo resultante especificado. Con esto,
decimos que todo atributo atrib tiene asociado en OCL el tipo de dato Tatrib. Este tipo no es
necesariamente nuevo (como en el caso de los provenientes de clases o enumerados). Al no
definir un tipo necesariamente nuevo, en este apunte diremos que el tipo retornado es T.
Si utilizamos el diagrama de clases dentro del contexto del diseo, seguramente cada
atributo de cada clase tendr su tipo de datos asociado en forma explcita en la misma clase del
diagrama, y con esto se puede mapear al tipo correspondiente de OCL. El problema que existe
en el diagrama de clases del modelo conceptual es que en las clases conceptuales no se
especifican tipos de datos. Esto sugiere la idea de existencia de dominios -como abstracciones
respecto a los tipos- (los atributos de las clases conceptuales retornan un objeto de un dominio,
en lugar de una expresin-objeto de un tipo de datos). En este caso hay que realizar un mapeo
implcito de los dominios de los atributos a tipos bsicos de OCL para poder expresar
condiciones en OCL que se apliquen sobre los valores retornados por estos atributos.

Constructores, constantes e identificadores


1) Tipos predefinidos
a) Tipos bsicos
- Constructores de tipo Boolean: constantes true, false
- Constructores de tipo Integer: constantes enteras (Ej: 5, 8, -76, ...)
- Constructores de tipo Real: constantes reales (Ej: -7.5, 5.9, 0.0, ...)
- Constructores de tipo String: constantes string entre comillas simples (Ej:
Hola, , 7*, ...)
b) Tipos estructurados
- De tipo Collection(T): no posee constantes ni constructores, porque es abstracto.
- Constructores de tipo Set(T): de la forma Set {exp1, exp2, ..., expn}, con n0,
y donde las expresiones exp1 a expn son todas de tipo T.
- Constructores de tipo Bag(T): de la forma Bag {exp1, exp2, ..., expn}, con n0,
y donde las expresiones exp1 a expn son todas de tipo T.
- Constructores de tipo OrderedSet(T): de la forma OrderedSet {exp1, exp2,
..., expn}, con n0, y donde las expresiones exp1 a expn son todas de tipo T.
- Constructores de tipo Sequence(T): de la forma Sequence {exp1, exp2, ...,
expn}, con n0, y donde las expresiones exp1 a expn son todas de tipo T.

El lenguaje de especificacin OCL


-7-

- Constructores de tipo Tuple{id1:T1, ..., idn:Tn}: de la forma Tuple {id1:T1 =


exp1,..., idn:Tn = expn}, donde las expresiones exp1 a expn son todas de tipo T1 a
Tn respectivamente. En general, los tipos de los campos en las expresiones de tipo
tupla pueden omitirse.
2) Tipos no predefinidos
Slo los tipos asociados a los enumerados del diagrama de clases poseen constantes. Si c
fuera un valor dentro del enumerado E del diagrama de clases, entonces la expresin TE::c es
de tipo TE.
3) Identificadores especiales
self: representa a cada expresin-objeto de una clase a las que se le quiere verificar una
propiedad o aplicar un atributo derivado o un mtodo/responsabilidad (derivado o no). Es
reconocida nicamente en las clusulas inv, pre, post, derive y body.
result: representa al valor retornado por un mtodo/responsabilidad comn que retorna
una expresin. Es reconocida nicamente en las clusulas post.
4) Parmetros
Los parmetros de mtodos/responsabilidades (comunes o derivados) se pueden utilizar en
aquellas clusulas pre, post, y body de aquellas definiciones donde aparecieron en la
clusula context.

Operaciones centrales sobre tipos no predefinidos


1) Atributos (comunes o derivados)
Si atrib es un atributo de la clase C que retorna una expresin de tipo T, y x es una
expresin de tipo TC, entonces x.atrib es una expresin de tipo T, que retorna el valor
del atributo atrib asociado a la expresin x. Se considera dentro de las posibilidades,
que un atributo pueda retornar una expresin de un tipo estructurado (como por ejemplo,
un conjunto).
2) Pseudoatributos de multiplicidad 1 (simple)
Si psatrib es un pseudoatributo de la clase C que la asocia a la clase D, y x es una
expresin de tipo TC, entonces x.psatrib es una expresin de tipo TD. Retorna la
expresin del tipo TD que se asocia va el rol psatrib a la expresin x.
3) Pseudoatributos de multiplicidad 0..1, 0..*, 1..* (mltiple)

El lenguaje de especificacin OCL


-8-

Si psatrib es un pseudoatributo de la clase C que la asocia a la clase D, y x es una


expresin de tipo TC, entonces x.psatrib es una expresin de tipo Set(TD). Retorna
las expresiones del tipo TD que se asocian va el rol psatrib a la expresin x. Las
retorna como un set (conjunto) porque no pueden existir elementos repetidos, y no
existe un orden de aparicin en la coleccin retornada.
4) Pseudoatributos de multiplicidad 0..1, 0..*, 1..* con label {ordered}
Si psatrib es un pseudoatributo de la clase C que la asocia a la clase D, y x es una
expresin de tipo TC, entonces x.psatrib es una expresin de tipo
OrderedSet(TD). Es similar al caso anterior, y retorna a las expresiones resultantes
como un orderedset (conjunto con orden posicional) porque no pueden existir elementos
repetidos, y existe un orden de aparicin en la coleccin retornada (indicado por la
etiqueta {ordered}).
5) Mtodos/responsabilidades (comunes o derivados) que retornan un valor
Si met es un mtodo/responsabilidad de la clase C que recibe n parmetros de tipo T1 a
Tn, y retorna una expresin de tipo T, y existen expresiones exp1 a expn que son de tipo
T1 a Tn respectivamente, y x es una expresin de tipo TC, entonces
x.met(exp1,...,expn) es una expresin de tipo T. Retorna el resultado de la
aplicacin del mtodo/responsabilidad met a la expresin x, usando como parmetros a
las expresiones exp1 a expn.
6) Mtodos/responsabilidades (comunes o derivados) que no retornan un valor
Si met es un mtodo/responsabilidad de la clase C que recibe n parmetros de tipo T1 a
Tn, y existen expresiones exp1 a expn que son de tipo T1 a Tn respectivamente, y x es una
expresin de tipo TC, entonces x.met(exp1,...,expn) es una operacin vlida
(aunque no es una expresin, ya que no retorna ningn resultado). Aplica el
mtodo/responsabilidad met a la expresin x, usando como parmetros a las
expresiones exp1 a expn.
Hay que tener en cuenta es considerado como operacin vlida, aunque no puede ser
usado como expresin en ningn contexto. Como ya se dijo antes, esto no impide
definir su invariante como cualquier mtodo/responsabilidad (y no ser vlido usar el
identificador especial result dentro de su clusula post).
7) Mtodos/responsabilidades de clase (slo para contados casos)
Si met es un mtodo/responsabilidad de clase de la clase C que recibe n parmetros de
tipo T1 a Tn, y retorna una expresin de tipo T, y existen expresiones exp1 a expn que son
de tipo T1 a Tn respectivamente, entonces Tc.met(exp1,...,expn) es una expresin
de tipo T. Retorna el resultado de la aplicacin del mtodo/responsabilidad met a la
clase C, usando como parmetros a las expresiones exp1 a expn.

El lenguaje de especificacin OCL


-9-

Todas estas operaciones se pueden componer sucesivamente utilizando esta notacin.


El significado de la operacin de aplicacin de atributo es obtener la expresin asociada al
atributo de una expresin dada.
El significado de la operacin de aplicacin de pseudoatributo es obtener la o las
expresiones-objeto asociadas a una expresin dada en funcin de la asociacin con la clase de
las expresiones-objeto obtenidas. Esto permite pasar de una clase a otra. A la composicin de
pseudoatributos se la suele llamar informalmente navegacin por el diagrama de clases.
El significado de la operacin de aplicacin de mtodo/responsabilidad es obtener la
expresin-objeto asociada a la aplicacin de este mtodo/responsabilidad, si es que ste retorna
una expresin. En OCL los mtodos/responsabilidades que no retornan un valor no se utilizan
dentro de otros contextos del modelo (ms all de la especificacin de su propio invariante con
pre y post).

Operaciones asociadas a los tipos bsicos predefinidos


Algunas de estas operaciones binarias se escriben sintcticamente como funciones infijas
(que se escriben entre sus dos argumentos), o con la notacin postfija caracterstica de la
orientacin a objetos, que se aplica al primero de sus dos argumentos, y el segundo argumento
se pasa como su nico parmetro. Lo mismo ocurre con las operaciones unarias, de las que
algunas se escriben con la notacin prefija funcional, y otras con la notacin postfija que se
aplica a su nico argumento y no posee parmetros.
1) De tipo Boolean
(exp1: Boolean and exp2: Boolean): Boolean
(exp1: Boolean or exp2: Boolean): Boolean
not(exp: Boolean): Boolean
(exp1: Boolean xor exp2: Boolean): Boolean
(exp1: Boolean implies exp2: Boolean): Boolean
Representan la conjuncin (and), disyuncin (or), negacin (not), disyuncin exclusiva
(xor) e implicacin material (implies).
(if (exp: Boolean) then (exptrue: T) else (expfalse: T) endif): T
Representa el if funcin, infijo de tres argumentos.
(exp1: T = exp2: T): Boolean
(exp1: T <> exp2: T): Boolean
(exp1: T < exp2: T): Boolean
(exp1: T <= exp2: T): Boolean
(exp1: T > exp2: T): Boolean

El lenguaje de especificacin OCL


- 10 -

(exp1: T >= exp2: T): Boolean


Representan los operadores relacionales. El tipo T no puede ser cualquiera, sino un tipo que
tenga definido estos operadores.
2) De tipo Integer
(exp1: Integer + exp2: Integer): Integer
(exp1: Integer - exp2: Integer): Integer
(exp1: Integer * exp2: Integer): Integer
(exp1: Integer / exp2: Integer): Integer
Integer.abs(): Integer
Integer.div(exp: Integer): Integer
Integer.mod(exp: Integer): Integer
Integer.min(exp: Integer): Integer
Integer.max(exp: Integer): Integer
Representan las operaciones de suma (+), resta (-), producto (*), cociente (/, div), valor
absoluto (abs), resto (mod), mnimo (min) y mximo (max).
3) De tipo Real
(exp1: Real + exp2: Real): Real
(exp1: Real - exp2: Real): Real
(exp1: Real * exp2: Real): Real
(exp1: Real / exp2: Real): Real
Real.floor(): Real
Real.round(exp: Integer): Real
Representan las operaciones de suma (+), resta (-), producto (*), cociente (/), parte entera o mayor nmero entero devuelto como nmero real que es menor o igual al nmero real dado(floor) y valor redondeado a una cantidad de decimales dada (round).
4) De tipo String
String.size(): Integer
String.concat(exp: String): String
String.substring(exp1, exp2: Integer): String
String.toUpper(): String
String.toLower(): String
String.toInteger(): Integer
String.toReal(): Real

El lenguaje de especificacin OCL


- 11 -

Representan las operaciones de cantidad de caracteres -longitud- (size), concatenacin de


dos cadenas (concat), obtencin de una subcadena de una cadena dada desde una
determinada posicin tomando una cierta cantidad de caracteres a partir de all (substring),
la conversin a maysculas (toUpper), a minsculas (toLower), a entero (toInteger) y a
real (toReal).
La precedencia de operadores de tipos bsicos es similar a la de la mayora de los lenguajes
clsicos. Se usan los parntesis dentro de expresiones para cambiar la precedencia de las
evaluaciones de sus subexpresiones.

Operaciones asociadas a los tipos de Coleccin


Las operaciones de coleccin se aplican siempre sobre una expresin de tipo Collection (o
de alguno de sus cuatro subtipos concretos), y pueden o no tener parmetros. La expresin de
tipo coleccin que es receptora de esta operacin se escribe antes de la operacin. Entre la
coleccin receptora y la operacin debe ir el smbolo -> (que reemplazara en este caso al
caracter . tradicional). El operador -> , como el . , tambin se puede componer
sucesivamente, si no existieran errores de tipos.
Como siempre, las aplicaciones de estas operaciones no provocan efectos colaterales.
Esta es la lista de operaciones existentes:
Collection(T)->size(): Integer
Retorna la cantidad de elementos que posee la coleccin.
Collection(T)->empty(): Boolean
Retorna si la coleccin est vaca (no contiene elementos).
Collection(T)->notEmpty(): Boolean
Retorna si la coleccin no est vaca (contiene algn elemento).
Collection(T)->includes(exp: T): Boolean
Retorna si la expresin pasada como parmetro pertenece a la coleccin. El tipo T debe
poseer la igualdad y la desigualdad.
Collection(T)->excludes(exp: T): Boolean
Retorna si la expresin pasada como parmetro no pertenece a la coleccin. El tipo T debe
poseer la igualdad y la desigualdad.
Collection(T)->includesAll(exp: Collection(T)): Boolean

El lenguaje de especificacin OCL


- 12 -

Retorna si la expresin-coleccin pasada como parmetro est includa en la coleccin


original. El tipo T debe poseer la igualdad y la desigualdad.
Collection(T)->excludesAll(exp: Collection(T)): Boolean
Retorna si la expresin-coleccin pasada como parmetro es disjunta respecto a la coleccin
original. El tipo T debe poseer la igualdad y la desigualdad.
Collection(Integer)->sum(): Integer
Collection(Real)->sum(): Real
Retorna el resultado de la suma de los elementos que componen la coleccin.
Set(T)->including(exp: T): Set(T)
Bag(T)->including(exp: T): Bag(T)
OrderedSet(T)->including(exp: T): OrderedSet(T)
Sequence(T)->including(exp: T): Sequence(T)
Retorna una coleccin que es la misma que la original, con el agregado de un nuevo
elemento, indicado por la expresin dada. El tipo de la coleccin retornada es el mismo que el
de la original.
Set(T)->union(exp: Set(T)): Set(T)
Set(T)->union(exp: Bag(T)): Bag(T)
Bag(T)->union(exp: Set(T)): Bag(T)
Bag(T)->union(exp: Bag(T)): Bag(T)
OrderedSet(T)->union(exp: OrderedSet(T)): OrderedSet(T)
OrderedSet(T)->union(exp: Sequence(T)): Sequence(T)
Sequence(T)->union(exp: OrderedSet(T)): Sequence(T)
Sequence(T)->union(exp: Sequence(T)): Sequence(T)
Retorna la unin de dos colecciones. Se asume que si alguna de las dos es de un tipo que
admite repeticiones, entonces la coleccin retornada podr contener repeticiones.
Set(T)->intersection(exp: Set(T)): Set(T)
Set(T)->intersection(exp: Bag(T)): Set (T)
Bag(T)->intersection(exp: Set(T)): Set (T)
Bag(T)->intersection(exp: Bag(T)): Bag(T)
OrderedSet(T)->intersection(exp: OrderedSet(T)): OrderedSet(T)
OrderedSet(T)->intersection(exp: Sequence(T)): OrderedSet(T)
Sequence(T)->intersection(exp: OrderedSet(T)): OrderedSet(T)
Sequence(T)->intersection(exp: Sequence(T)): Sequence(T)

El lenguaje de especificacin OCL


- 13 -

Retorna la interseccin de dos colecciones. Se asume que si alguna de las dos es de un tipo
que no admite repeticiones, entonces la coleccin retornada no podr contener repeticiones.
Set(Collection(T))->flatten(): Set(T)
Bag(Collection(T))->flatten(): Bag(T)
OrderedSet(Collection(T))->flatten(): OrderedSet(T)
Sequence(Collection(T))->flatten(): Sequence(T)
Retorna el aplanado de una coleccin de colecciones, eliminando un nivel de colecciones.
Dicho de otra forma, retorna la concatenacin de todos los elementos de la coleccin de
colecciones original (que son colecciones). El tipo mandatorio de la coleccin resultante es el
ms externo.
Las siguientes operaciones son de orden superior, ya que como parmetro de estas
operaciones se especifican funciones implcitas representadas por una variable ligada (bounded
variable) y una expresin-cuerpo que admite apariciones libres de la variable ligada
especificada (y que hace referencia a ella misma).
Collection(T)->forAll(var | exp: Boolean): Boolean
Retorna si todos los elementos de la coleccin original cumplen con la condicin dada. La
condicin se expresa en el parmetro de esta operacin, usando una variable ligada (var) que se
instancia con cada elemento de la coleccin, y la condicin a testear sobre cada uno de ellos
(expresin lgica exp). Esta expresin exp admite apariciones libres de la variable var.
Collection(T)->forAll(var1, var2 | exp: Boolean): Boolean
Retorna lo mismo que la siguiente expresin (suponiendo que c es una expresin de tipo
Collection(T)):
c->forAll(var1 | c->forAll(var2 | exp))
Collection(T)->exists(var | exp: Boolean): Boolean
Retorna si alguno de los elementos de la coleccin original cumple con la condicin dada.
La condicin se expresa en el parmetro de esta operacin, usando una variable ligada (var) que
se instancia con cada elemento de la coleccin, y la condicin a testear sobre cada uno de ellos
(expresin lgica exp). Esta expresin exp admite apariciones libres de la variable var.
Set(T)->select(var | exp: Boolean): Set(T)
Bag(T)->select(var | exp: Boolean): Bag(T)
OrderedSet(T)->select(var | exp: Boolean): OrderedSet(T)
Sequence(T)->select(var | exp: Boolean): Sequence(T)
Retorna a todos los elementos de la coleccin original que cumplen con la condicin dada en
el parmetro. La variable ligada var se vincula a cada elemento de la condicin, y la expresin

El lenguaje de especificacin OCL


- 14 -

lgica exp retorna si el elemento dado queda o no en la coleccin resultante. La coleccin


resultante ser del mismo tipo que la original.
Set(T)->reject(var | exp: Boolean): Set(T)
Bag(T)->reject(var | exp: Boolean): Bag(T)
OrderedSet(T)->reject(var | exp: Boolean): OrderedSet(T)
Sequence(T)->reject(var | exp: Boolean): Sequence(T)
Retorna a todos los elementos de la coleccin original que no cumplen con la condicin dada
en el parmetro.
Set(T1)->collect(var | exp: T2): Bag(T2)
Bag(T1)->collect(var | exp: T2): Bag(T2)
OrderedSet(T1)->collect(var | exp: T2): Sequence(T2)
Sequence(T1)->collect(var | exp: T2): Sequence(T2)
Retorna un mapeo de todos los elementos de la coleccin original a una coleccin resultante
de la misma cantidad de elementos, donde cada elemento de la coleccin resultante es el
mapeado de la misma posicin en la coleccin original (si posee orden posicional). La funcin
de mapeo se expresa con la variable ligada var (que se sustituye por cada elemento de la
coleccin original) y la expresin-cuerpo exp que indica el valor a retornar en la coleccin
resultante para la expresin original dada. El tipo de la expresin-cuerpo ser el mismo que el
de los elementos de la coleccin resultante.
Como luego de la aplicacin de esta operacin se pueden generar elementos repetidos en la
coleccin resultante que provienen de elementos distintos de la coleccin original, se asume
que la coleccin resultante debe admitir repetidos (de ah que no se retornan conjuntos), para
lograr mantener la misma cantidad de elementos respecto a la cantidad de elementos de la
coleccin original.
Collection(T1)->isUnique(var | exp: T2): Boolean
Retorna si todos los elementos de la coleccin, al mapearse cada uno de ellos al mapeo
propuesto (anlogo a la operacin collect) da como resultado una coleccin con todos
valores distintos (dos a dos). El tipo T2 debe poseer la igualdad y desigualdad.
Collection(T)->iterate(var1 ; var2: T2 = expinicial | exp: T2): T2
Retorna la aplicacin sucesiva de la funcin binaria de variables ligadas (var1,var2) y cuerpo
exp, iterando por cada uno de los valores de la coleccin original -que son los valores usados en
la sustitucin de la variable var1- y donde cada resultado parcial -indicado en la expresin expse usa como parmetro-acumulador del paso siguiente -en la variable var2-. El valor resultado
original ser dado en la expresin expinicial. El tipo T2 que se escribe luego de la variable var2
debe ser obligatorio.
Ms fcilmente, el resultado de esta operacin se ve reflejado por el siguiente
pseudoalgoritmo (donde la coleccin original est indicada por la variable c):

El lenguaje de especificacin OCL


- 15 -

res := expinicial
paraCada i indice de c
(0 i size(c)-1, creciente)
res := ((var1, var2) exp) (c[i],res)
fin-paraCada
retornar res
la expresin de la parte derecha de la asignacin del rengln 3 significa la aplicacin de una
funcin de dos parmetros. Se espera que tanto var1 como var2 existan como subexpresiones de
exp (aunque esto puede no ser as).
Esta operacin es anloga al mtodo tambin llamado collect del lenguaje orientado a
objetos Smalltalk, y a la funcin foldl del lenguaje funcional Haskell.
Todas las operaciones de coleccin que reciben parmetros de la forma (var | exp) (como
forAll, exists, select, reject, collect y isUnique) pueden ser escritos con otra
sintaxis, a saber:
Collection(T)->operacion(var | exp)
Collection(T)->operacion(var: T2 | exp)
Collection(T)->operacion(exp)
El segundo caso es anlogo al primero, con la diferencia que se agrega el tipo de la variable
ligada var. Este tipo aqu especificado T2 slo puede ser T (el tipo de la coleccin) o un subtipo
de T. En el caso que se indique que este tipo T2 es T, estamos en un caso idntico al primer caso
(donde el tipo de la variable ligada var es T). Pero si se indicara que este tipo es un subtipo de
T, expresamos que dentro de la expresin exp se puede realizar un typecast sobre el tipo T por
este subtipo T2 para las apariciones de la variable-expresin var (similar al uso de la operacin
OCLasType). Los vnculos de variables reconocidos en la expresin exp son los reconocidos
por el contexto de la expresin general ms la variable var. El uso de typecasts y de la
operacin OCLasType se comentar despus.
En el tercer caso, la variable var no aparece, y no puede aparecer libre como subexpresin de
la expresin exp. En exp todos los mtodos/responsabilidades, atributos y pseudoatributos
aplicados a un receptor no especificado, son asumidos que se aplican en primera instancia a
cada elemento de la coleccin, y en segunda instancia, a self. Si hubiera algn problema de
ambigedad, no se puede elegir esta opcin de sintaxis, y se debe optar por alguna de las dos
primeras.
Como caso aparte, en la operacin forAll con el iterador sobre pares de elementos de la
coleccin dada, la expresin lgica del cuerpo del mtodo/responsabilidad puede contener
apariciones libres de estas dos variables ligadoras, y que se ligaran a todos los pares de
elementos.
Notacin de punto aplicada a colecciones:

El lenguaje de especificacin OCL


- 16 -

Existe la notacin de aplicaciones de atributos y pseudoatributos a colecciones con la


notacin del punto (aplicados como si no fueran colecciones). La definicin es la siguiente:
Si c es una expresin de tipo Collection(T) y psatrib es un pseudoatributo (o atributo)
sobre el tipo T, se define lo siguiente:

c->collect(psatrib)

(si psatrib no es PAM)

c->collect(psatrib)->flatten()

(si psatrib es PAM)

c.psatrib

PAM es el resumido de pseudoatributo mltiple.


De la definicin anterior se pueden deducir los tipos retornados por las aplicaciones de
atributos o pseudoatributos a colecciones, que son los siguientes:
a) Si psatrib es un pseudoatributo mltiple de la clase A asociado a la clase B (se aplica a
expresiones de tipo TA y retorna expresiones de tipo Set(TB)):
c: Set(TA) c.psatrib: Bag(TB)
c: Bag(TA) c.psatrib: Bag(TB)
c: OrderedSet(TA) c.psatrib: Sequence(TB)
c: Sequence(TA) c.psatrib: Sequence(TB)
b) Si psatrib es un pseudoatributo simple de la clase A asociado a la clase B (se aplica a
expresiones de tipo TA y retorna expresiones de tipo TB):
c: Set(TA) c.psatrib: Bag(TB)
c: Bag(TA) c.psatrib: Bag(TB)
c: OrderedSet(TA) c.psatrib: Sequence(TB)
c: Sequence(TA) c.psatrib: Sequence(TB)
c) Si atrib es un atributo simple de la clase A (se aplica a expresiones de tipo TA y retorna
expresiones de tipo T):
c: Set(TA) c.atrib: Bag(T)
c: Bag(TA) c.atrib: Bag(T)
c: OrderedSet(TA) c.atrib: Sequence(T)
c: Sequence(TA) c.atrib: Sequence(T)
Esto vale para cualquier tipo T, an si se tratara de un tipo estructurado.

El lenguaje de especificacin OCL


- 17 -

Operaciones asociadas a colecciones especficas


(exp1: Set(T) - exp2: Set(T)): Set(T)
Retorna la diferencia entre dos conjuntos.
Set(T)->symmetricDifference(exp: Set(T)): Set(T)
Retorna la diferencia simtrica entre dos conjuntos.
Bag(T)->count(exp: T): Integer
Sequence(T)->count(exp: T): Integer
Retorna la cantidad de apariciones de la expresin dada en la coleccin. El tipo T debe tener
definida la operacin de igualdad.
Bag(T)->asSet(): Set(T)
OrderedSet(T)->asSet(): Set(T)
Sequence(T)->asSet(): Set(T)
Retorna la conversin de la coleccin dada en un Set. En el Set resultante el orden posicional
y la cantidad de apariciones se pierden.
Set(T)->asBag(): Bag(T)
OrderedSet(T)->asBag(): Bag(T)
Sequence(T)->asBag(): Bag(T)
Retorna la conversin de la coleccin dada en un Bag. En el Bag resultante el orden
posicional se pierde, y la cantidad de apariciones resultantes de los elementos si la coleccin
original es un conjunto es 1 para todos.
Set(T)->asOrderedSet(): OrderedSet(T)
Bag(T)->asOrderedSet(): OrderedSet(T)
Sequence(T)->asOrderedSet(): OrderedSet(T)
Retorna la conversin de la coleccin dada en un OrderedSet. En el OrderedSet resultante la
cantidad de apariciones se pierden, y el orden posicional de los elementos si la coleccin
original no tiene orden se crea con el orden natural sobre el tipo T (el tipo T debe tener definida
la operacin menor o igual).
Set(T)->asSequence():Sequence(T)
Bag(T)->asSequence(): Sequence(T)
OrderedSet(T)->asSequence(): Sequence(T)

El lenguaje de especificacin OCL


- 18 -

Retorna la conversin de la coleccin dada en una Sequence. Sobre la Sequence resultante se


crea el orden posicional con el orden natural sobre el tipo T si la coleccin original no era
ordenada, y crea la cantidad de apariciones de los elementos en 1 si la coleccin original era un
conjunto.
OrderedSet(T)->first(): T
Sequence(T)->first(): T
Retorna el primer elemento de la coleccin con orden posicional (si es que existe).
OrderedSet(T)->last(): T
Sequence(T)->last(): T
Retorna el ltimo elemento de la coleccin con orden posicional (si es que existe).
OrderedSet(T)->at(exp: Integer): T
Sequence(T)->at(exp: Integer): T
Retorna el elemento de la posicin exp dada de la coleccin con orden posicional (si es que
existe).
Sequence(T)->append(exp: Sequence(T)): Sequence(T)
Retorna la concatenacin de la secuencia exp luego de la secuencia original.
Sequence(T)->prepend(exp: Sequence(T)): Sequence(T)
Retorna la concatenacin de la secuencia exp antes de la secuencia original.
Sequence(T)->subSequence(exp1, exp2: Integer): Sequence(T)
Retorna la subsecuencia de la secuencia original que comienza en la posicin exp1, y posee
exp2 cantidad de elementos a partir de all.

Jerarqua de tipos
Los tipos de datos se encuentran jerarquizados a travs del concepto de inclusin. Los tipos
includos
heredan
todas
las
propiedades
(atributos,
peudoatributos
y
mtodos/responsabilidades) de sus tipos superiores (los que lo incluyen). La relacin de
inclusin estricta este tipos se refleja con el siguiente operador:
T1 < T2 def T1 es un subtipo estricto de T2

El lenguaje de especificacin OCL


- 19 -

Las reglas propias del operador < de inclusin de tipos son las siguientes:
- Si A es una clase y B es una subclase de A en el diagrama de clases, entonces TB < TA
- T < OCLAny (para todo tipo T no estructurado)
- T1 < T2 Set(T1) < Set(T2)
- T1 < T2 Bag(T1) < Bag(T2)
- T1 < T2 OrderedSet(T1) < OrderedSet(T2)
- T1 < T2 Sequence(T1) < Sequence(T2)
- Set(T) < Collection(T)
- Bag(T) < Collection(T)
- OrderedSet(T) < Collection(T)
- Sequence(T) < Collection(T)
- T < T Tuple{id1:T1,...,idi:T,...,idn:Tn} <
Tuple{id1:T1,...,idi:T,...,idn:Tn}
- Integer < Real
- T1 < T2 y T2 < T3 T1 < T3
- T : OCLType
(en realidad, aqu no se especifican jerarquas)
Las reglas de la herencia implcita por la existencia del operador jerrquico < de inclusin de
tipos son las siguientes:
Sea TA < TB, y las expresiones expA y expB de tipos TA y TB respectivamente.
a) Si es vlida la expresin expB.attrib que retorna una expresin de tipo T,
(obtencin de un atributo), entonces tambin ser vlida la expresin expA.attrib,
tambin retornando una expresin de tipo T, autodefinida anlogamente a la anterior.
b) Si es vlida la expresin expB.psattrib que retorna una expresin de tipo T,
(obtencin de un pseudoatributo), entonces tambin ser vlida la expresin
expA.psattrib, tambin retornando una expresin de tipo T, autodefinida
anlogamente a la anterior.
c) Si es vlida la operacin expB.met(exp1,...,expn) con expresiones-parmetros
exp1 a expn que son de tipo T1 a Tn respectivamente (aplicacin de un
mtodo/responsabilidad que no retorna un valor), entonces tambin ser vlida la
operacin expA.met(exp1,...,expn) sin retornar ninguna expresin como resultado,
autodefinida anlogamente a la anterior (a menos que met no se encuentre definido
como mtodo/responsabilidad propio de la clase asociada al tipo heredado).
d) Si es vlida la expresin expB.met(exp1,...,expn) con expresiones-parmetros
exp1 a expn que son de tipo T1 a Tn respectivamente, que retorna una expresin de tipo T,
(aplicacin de un mtodo/responsabilidad que retorna un valor), entonces tambin ser
vlida la expresin expA.met(exp1,...,expn), tambin retornando una expresin de

El lenguaje de especificacin OCL


- 20 -

tipo T, autodefinida anlogamente a la anterior (a menos que met no se encuentre


definido como mtodo/responsabilidad propio de la clase asociada al tipo heredado).
Tanto para los atributos como los pseudoatributos de multiplicidad 1 heredados de los tipos
superiores, se permite usar el agregado @pre como si se tratara de un componente propio del
tipo heredado. Ninguno de ellos puede encontrarse definido dentro de la clase del tipo
heredado.
Se aceptan mltiples jerarquas asociadas a una misma clase, al igual que la existencia de
herencia mltiple (ya que estas dos caractersticas son aceptadas en el diagrama de clases). El
uso de herencia mltiple conlleva el problema de mtodos/responsabilidades, pseudoatributos y
mtodos/responsabilidades distintos de igual nombre heredados por ms de un tipo superior en
distintas ramas de las jerarquas superiores de la herencia mltiple. Estos casos de choques de
nombres no son permitidos, y no existe un mecanismo de desambiguacin de estos nombres.
Tambin se aceptan las reglas de sobrecarga/redefinicin de mtodos/responsabilidades en
los subtipos. Para estos casos, el mtodo/responsabilidad definido en el tipo heredado
redefine el mtodo/responsabilidad del mismo nombre heredado de los tipos superiores. Para
poder realizar esto manteniendo la tipificacin, es necesario establecer reglas de
covarianza/contravarianza/invarianza entre los tipos de los parmetros correspondientes de los
dos mtodos/responsabilidades (el heredado y el redefinido), al igual que entre los tipos de las
expresiones retornadas por los dos mtodos/responsabilidades (si ambos retornan una
expresin). A pesar de esta necesidad, no est claramente definido cmo son las reglas de
concordancia de tipos para estos casos en OCL.
Este concepto se encuentra presente en los chequeos de tipos de los lenguajes de programacin
orientados a objetos tipificados (Eiffel, Object Pascal, Java, C++, etc).
Al poder redefinir mtodos/responsabilidades en subtipos, aparece una especie de
contraherencia en algunos casos puntuales contemplados en el siguiente caso: si un tipo T
est asociado a una clase abstracta, y todos sus subtipos descendientes definen un
mtodo/responsabilidad llamado met no heredado por T (donde cada uno posee su propio
cdigo) con tipos consistentes entre todos ellos de los parmetros, y con tipos consistentes entre
todos ellos de las expresiones retornadas (si todos retornaran una expresin), entonces el tipo T
contrahereda de todos sus hijos la cscara del mtodo/responsabilidad met. Esto significa
que el mtodo/responsabilidad contraheredado no posee cdigo dentro del tipo T, y en el caso
de que ocurra una aplicacin de met sobre una expresin de tipo T, se delegar en la aplicacin
del mtodo/responsabilidad met del subtipo verdadero para esa aplicacin en especial (esto
ocurre porque T est asociado a una clase abstracta), en lugar de existir un error de binding de
mtodos/responsabilidades.

Operacin de tuplas
Los campos de una tupla se comportan como si fueran atributos. Estos campos se utilizan
sobre una tupla para proyectar sus valores. O sea que vale lo siguiente:

El lenguaje de especificacin OCL


- 21 -

Si x es una expresin de tipo Tuple{id1:T1, ..., idn:Tn}, entonces x.idi es una


expresin de tipo Ti (con 1 i n).

Operaciones de clase y de metaclase


Dada una clase C del diagrama de clases, se le puede aplicar la siguiente operacin de clase:
TC.allInstances(): Set(TC)
Retorna el conjunto de todas las expresiones-objeto de la clase C.
Existen otras operaciones que se aplican a cualquier clase, relacionadas con
metainformacin. Estas se aplican en realidad sobre las expresiones-objeto del tipo de las clases
del modelo, que son las expresiones del tipo OCLType. Estas son las operaciones:
OCLType.name(): String
Retorna el nombre de la clase.
OCLType.attributes(): Set(String)
Retorna el conjunto de los nombres de todos los atributos de la clase.
OCLType.associationEnds(): Set(String)
Retorna el conjunto de los nombres de todos los pseudoatributos (roles) de la clase.
OCLType.operations(): Set(String)
Retorna el conjunto de los nombres de todas las operaciones (mtodos/responsabilidades).
OCLType.supertypes(): Set(OCLType)
Retorna el conjunto de los tipos inmediatamente superiores a la clase.
OCLType.allSupertypes(): Set(OCLType)
Retorna el conjunto de los tipos superiores a la clase (los inmediatamente superiores y sus
tipos ancestros).
En este apunte no trataremos con el resto de los componentes sintcticos relacionados con
metainformacin (metadata).

El lenguaje de especificacin OCL


- 22 -

Sobre la especificacin de efectos colaterales


El lenguaje OCL, pese a su naturaleza declarativa, permite tambin especificar efectos
colaterales. Esto ocurre claramente en la definicin de invariantes de mtodo/responsabilidad,
que no retornan un valor, ya que el nico fin es que produzcan un efecto colateral.
Los efectos colaterales quedan reflejados en las clusulas post de definiciones de
invariantes de mtodo/responsabilidad, y afectan a los siguientes componentes sintcticos:
- La expresin self.
- Expresiones independientes de la expresin self y de los parmetros del
mtodo/responsabilidad.
- Los parmetros del mtodo/responsabilidad que sean out o in/out.
La expresin lgica expresada en las clusulas post reflejar las condiciones que se
aplicarn a la expresin result (para especificar el valor retornado, como se vio antes -si
corresponde-), a la expresin self u otra independiente (para indicar el estado a posteriori que
tendrn stas -si corresponde-) y a los parmetros de tipo out o in/out (para indicar el
estado a posteriori que tendrn stos -si corresponde-).
La expresin self y las expresiones independientes dentro de las clusulas post ya
dijimos que evalan en el valor que tendrn a posteriori. La aplicacin de un atributo a stas
expresiones en las clusulas post se referir al valor de ese atributo que tendrn esas
expresiones a posteriori. Adems de existir expresiones de la forma x.atrib (donde en este
caso nos referiremos a x como la expresin self o una expresin independiente), tambin
existen otras de la forma x.atrib@pre (slo dentro de las clusulas post) que representan el
valor retornado por el atributo atrib aplicado a la expresin x en el momento de la evaluacin
de la precondicin (el mismo valor que retornara la expresin x.atrib dentro de la clusula
pre correspondiente). Esto ltimo tambin se puede utilizar para pseudoatributos de
multiplicidad 1.
Con esto, se pueden escribir expresiones resultantes que reflejen modificaciones de estados
internos (contenido de atributos o pseudoatributos) de self y las otras expresiones
independientes, en funcin de los valores de los mismos atributos o pseudoatributos que
posean a priori.
Para representar efectos colaterales sobre los parmetros out o in/out es ms complejo.
La dificultad reside en que no est permitido usar el sufijo @pre sobre atributos de estos
parmetros dentro de las clusulas post.
Lo que se usa aqu es cambiar la naturaleza del mtodo/responsabilidad en cuestin. El
mtodo/responsabilidad deber retornar una expresin de tipo Tuple que deber poseer los
siguientes campos:

El lenguaje de especificacin OCL


- 23 -

- result: Deber ser del tipo de la expresin retornada, y contendr el valor de la


expresin retornada. Si el mtodo/responsabilidad no devuelve expresiones, este campo no
deber existir.
- pari: Deber ser del tipo del parmetro pari (el campo tendr el mismo nombre del
parmetro formal) y contendr el valor que poseer ese parmetro a posteriori. Este campo
deber existir slo si pari es out o in/out.
Esto modifica el concepto del valor retornado, ya que el ideado originalmente termina siendo
slo un campo de la tupla retornada (que encima se llama result). A su vez, la tupla
retornada deber ser asociada (como siempre, como cualquier expresin retornada realmente) a
la expresin result usada por el mtodo/responsabilidad en su clusula post.
Si se desea, puede especificarse en la declaracin de mtodos/responsabilidades con efectos
colaterales sobre parmetros, que el tipo retornado es el del campo result de la tupla (el tipo
retornado pensado originalmente -si es que corresponde-).
Esta ltima forma de tratar los efectos colaterales puede resumirse como que todo efecto
colateral (destructivo/no declarativo) sobre un determinado item puede expresarse finalmente
como una transformacin sin efectos colaterales del item original, retornando el item original
con todas sus modificaciones aplicadas. Este razonamiento era muy comn para tratar efectos
colaterales dentro de lenguajes declarativos primitivos.
Sin embargo, esta forma particular de tratar los efectos colaterales trae una consecuencia que
puede ser beneficiosa: en todos los contextos donde se invoque a un mtodo/responsabilidad
con efectos colaterales sobre algunos parmetros, se podr hacer referencia en forma
transparente tanto al valor a priori de estos parmetros in o in/out, como al valor a
posteriori. Para lograr esto, se utilizan las funciones de proyeccin sobre la tupla (a travs de
sus campos-parmetros y del valor resultante original).
Por ejemplo, se especifica el siguiente mtodo/responsabilidad:
context Persona::actEdad(dif:Integer, in/out hermanos:Set(Persona)):String
Y en otro contexto se puede hacer referencia a l de la siguiente manera:
x
x.actEdad(10, h)
x.actEdad(10, h).result
x.actEdad(10, h).hermanos

(es una persona)


(es la tupla resultante de la aplicacin)
(es el string resultante)
(es el segundo parmetro modificado)

En este caso, la expresin h y la expresin x.actEdad(10, h).hermanos corresponden a los


valores a priori y a posteriori del segundo parmetro de la aplicacin del mtodo actEdad, y se
podrn usar arbitrariamente dentro del contexto que las contiene, en forma transparente.

Expresiones LET

El lenguaje de especificacin OCL


- 24 -

Existe otro tipo de expresiones, muy utilizada para no repetir o simplificar evaluaciones. Son
las expresiones LET, que son expresiones con la siguiente sintaxis:
let var: T = exp1 in exp2
La evaluacin de esta expresin let consta de la evaluacin de la expresin exp2,
reemplazando antes todas las apariciones libres de la variable var (que dentro de exp2 es usada
como expresin) por la expresin exp1. El tipo de var (T) debe especificarse, y debe coincidir
con el tipo del la expresin exp1.
Dentro de la expresin exp2 se reconocen como expresiones a las vinculaciones a variables
reconocidas en el contexto de la expresin let, y a esta nueva variable var (que slo es local a
la expresin let).

En relacin a la creacin de expresiones-objetos de una clase


La creacin de objetos de una clase es una operacin de naturaleza destructiva. Es por eso
que stas no se modelan con OCL, que es declarativo. Lo que s se puede hacer con OCL es
verificar o establecer caractersticas de los objetos en funcin de su creacin. Para ello se puede
utilizar la siguiente operacin:
OCLAny.OCLisNew(): Boolean
Esta operacin (que se puede utilizar nicamente en la clusula post de la especificacin de
un mtodo/responsabilidad), retorna si la expresin-objeto receptora del mensaje fue
recientemente creada (durante la ejecucin del mismo mtodo/responsabilidad -que no es
especificado en OCL-).
Relacionado con esto, en OCL se permite especificar el valor que tendr un atributo o
pseudoatributo de un objeto no derivado, inmediatamente despus del momento de su creacin.
Esto se hace con una nueva clusula init, donde se especifican los valores iniciales de
atributos y pseudoatributos de los objetos en el momento de su creacin. El contexto utilizado
es un atributo o pseudoatributo propio de una clase, caracterstico de todas las instancias de esa
misma clase. Esta es su sintaxis:
context idclase::idatributo:T
init: expT
Con esto se especificar que el valor inicial que tendr el atributo o pseudoatributo no
derivado idatributo (de tipo T) para objetos pertenecientes a la clase idclase en el momento de su
creacin, ser la expresin expT (que tambin debe ser de tipo T). Como est permitido
especificar valores iniciales tambin para los pseudoatributos, se podrn retornar expresiones de
un tipo estructurado de alguna coleccin. Tambin se pueden especificar valores iniciales de
algn tipo de tupla.

El lenguaje de especificacin OCL


- 25 -

Dentro de la expresin expT se puede utilizar la expresin self (hacer una referencia al
objeto recientemente creado), siempre y cuando de l se obtengan valores de atributos o
pseudoatributos, para los cuales su valor inicial haya sido especificado en una clusula init
anterior.

Sobre el uso de las clases de asociacin del diagrama de clases


Sean A y B clases, y C una clase de asociacin entre A y B (vamos a llamar tambin TA, TB y
TC a los tipos asociados a las clases A, B y C respectivamente). Sean expA, expB y expC
expresiones de tipos TA, TB y TC respectivamente, y dado el siguiente diagrama:

Valen las siguientes expresiones (ya vistas desde el comienzo):


expA.rol2 retorna una expresin de tipo Set(TB).
expB.rol1 retorna una expresin de tipo TA.
Adems de este caso, dentro del contexto de dos clases que se encuentran asociadas (A y B
en este caso), se puede usar el nombre de la clase de asociacin como pseudoatributo de los
tipos de las dos clases asociadas por esa asociacin. Lo retornado en este ltimo caso son aquel
o aquellas instancias de la asociacin (como si fueran pares) que poseen el valor de la expresin
del tipo de la clase origen, pero vistas como expresiones-objeto pertenecientes al tipo de la
clase de asociacin (TC). La multiplicidad de este pseudoatributo-clase de asociacin es la
misma que la multiplicidad del rol destino de la misma asociacin. O sea que tambin vale lo
siguiente:
expA.C retorna una expresin de tipo Set(TC).
expB.C retorna una expresin de tipo TC.
Por otro lado, dentro del contexto de un tipo-clase de asociacin, para toda expresin-objeto
de ese tipo, se puede obtener con qu expresiones de los dos tipos asociados se asocia (siempre
ser de multiplicidad 1). Para esto se utiliza como pseudoatributo los nombres de los roles de la
relacin original. O sea que vale:

El lenguaje de especificacin OCL


- 26 -

expC.rol1 retorna una expresin de tipo TA.


expC.rol2 retorna una expresin de tipo TB.
Existe un caso que vale la pena distinguirlo, que es cuando la asociacin se presenta entre
una clase A y s misma (no existira una clase B). Este sera el caso:

El problema ocurre con las referencias al pseudoatributo-clase de asociacin C dentro del


contexto de la clase A, ya que habra que hacer explcito el rol origen de las expresionesobjeto del tipo de la clase A a las que se refiere. Esto se hace escribiendo entre corchetes el rol
dentro de la asociacin:
expA.rol2 retorna una expresin de tipo Set(TA).
expA.rol1 retorna una expresin de tipo TA.
expA[rol1].C retorna una expresin de tipo Set(TC)(toma a expA desde rol1).
expA[rol2].C retorna una expresin de tipo TC (toma a expA desde rol2).

Sobre el uso de la herencia


Existen varias operaciones aplicables a cualquier tipo de expresin muy relacionadas con el
concepto de herencia y con la idea de tratar a los tipos de datos como datos propiamente dichos
(ya se mencion antes de OCLType, que es el metatipo), como por ejemplo, expresar
expresiones lgicas de la forma el tipo de la expresin var45 es Set(Integer). Esto se
relaciona con la idea de que una expresin es de un tipo, pero tambin es de todos los
supertipos de se (por el polimorfismo de inclusin propio de la herencia). Estas operaciones
son:
OCLAny.OCLisKindOf(exp: OCLType): Boolean
Retorna si el tipo de la expresin receptora (de tipo OCLAny) es exp o subtipo de exp.
OCLAny.OCLisTypeOf(exp: OCLType): Boolean
Retorna si el tipo de la expresin receptora (de tipo OCLAny) es exactamente exp.

El lenguaje de especificacin OCL


- 27 -

T1.OCLasType(T2: OCLType): T2
Retorna la misma expresin recibida (de tipo T1), aunque se asume que el tipo de esta
expresin retornada es de tipo T2. Representa el typecast elegante de la orientacin a objetos,
donde debe ocurrir que T2 < T1. El objetivo del uso de esta operacin es poder aplicar algn
atributo, pseudoatributo o mtodo/responsabilidad de un subtipo del tipo de la expresin si se
sabe con seguridad que tambin pertenece a ese subtipo.

Sobre los valores indefinidos


Dependiendo de la semntica de los mtodos/responsabilidades, la aplicacin de stos a
expresiones pueden retornar valores indefinidos, si el resultado no est contemplado dentro de
los valores posibles a retornar (se podra decir que el valor retornado no forma parte de la
imagen), independientemente de cul fuera su tipo esttico.
Todos los mtodos/responsabilidades, atributos y pseudoatributos se consideran estrictos, con
lo que si uno de sus parmetros (o la expresin-objeto receptora) es indefinida (<undefined>),
su resultado tambin ser indefinido. Existen muy pocos casos donde no existe estrictez, y est
relacionado a operaciones sobre los valores lgicos, a saber:
if true then r else <undefined> endif = r
if false then <undefined> else r endif = r
true or <undefined> = true
false and <undefined> = false
false implies <undefined> = true
Relacionado con este tema, se puede utilizar la siguiente operacin (no estricta):
OCLAny.OCLisUndefined(): Boolean
Retorna si la expresin receptora (de tipo OCLAny) es indefinida. Se usa bsicamente para
la captura de errores.

Un ejemplo
Dado el siguiente diagrama de clases, se especificarn luego algunas restricciones y
definiciones con OCL:
Existen embarcaciones pesqueras. Cada una de ellas tiene un nombre, un largo y ancho (estos
dos ltimos en metros), donde no puede ser ms ancha que larga. Posee tambin un mximo
nmero de tripulantes, aunque su tripulacin es estable (siempre es tripulada por los mismos
marinos). Nunca la cantidad de tripulantes estables debe exceder a su cantidad mxima. Las
embarcaciones pueden tener un propietario, que no necesariamente es marino. Tanto los
marinos como los que no lo son, poseen un nombre, un apellido y un telfono. Los no marinos

El lenguaje de especificacin OCL


- 28 -

poseen adems un nmero de fax, cuya caracterstica debe ser la misma que la de su nmero
de telfono.
Cada marino dentro de una embarcacin cumple un rol dentro de la misma, que puede ser
capitn, marinero o grumete. Dentro de una embarcacin slo puede haber exactamente un
capitn. A lo sumo, el 10% de la tripulacin de una embarcacin puede ser grumete.
Toda embarcacin debe estar inscripta en una asociacin de pesqueros. Cada asociacin se
compone de uno o ms socios, que son los nicos autorizados a formar parte de las
tripulaciones de barcos pesqueros inscriptos en la asociacin de la que son socios. Los no
marinos pueden obtener las asociaciones donde estn inscriptas las embarcaciones de su
propiedad.
Cada embarcacin puede realizar salidas de pesca en una fecha determinada, que no pueden
ser ms de dos por da. En ella, los integrantes de la tripulacin (que son los nicos que
pescan) pescan en forma independiente, y cada uno obtiene una cierta cantidad de kilos de
pescado. Esta cantidad de kilos de pescado por tripulante puede incrementarse, siempre y
cuando el peso total de pescado en la embarcacin no exceda los 1000 kilos. Se quiere conocer
tambin la cantidad de kilos de pescado en total para cada salida de pesca.

Invariantes:

El lenguaje de especificacin OCL


- 29 -

Ninguna embarcacin puede ser ms larga que ancha.


context: Embarcacion
inv: self.largo >= self.ancho

Nunca la cantidad de tripulantes estables de una embarcacin debe exceder a su cantidad


mxima.
context: Embarcacion
inv: self.tripulantes->size() <= self.maxTripulantes

Los propietarios no marinos poseen adems un nmero de fax, cuya caracterstica debe ser la
misma que la de su nmero de telfono.
context: Civil
inv: self.fax.caracteristica = self.telefono.caracteristica
(se asume que existe la propiedad caracteristica para las expresiones de tipo Telef)

El dominio Rol se compone de {capitan, marinero, grumete}. Este tambin poda


ser representado como una clase enumerada.
Dentro de una embarcacin slo puede haber exactamente un capitn.
context: Embarcacion
inv: self.embarcado->select(e|e.rol = capitan)->size() = 1

A lo sumo, el 10% de la tripulacin de una embarcacin puede ser grumete.


context: Embarcacion
inv: self.embarcado->select(e|e.rol = grumete)->size() /
self.tripulantes->size()) <= 0.1

Cada asociacin se compone de uno o ms socios, que son los nicos autorizados a formar
parte de las tripulaciones de barcos pesqueros inscriptos en la asociacin de la que son socios.
context: Embarcacion
inv: self.inscripta.socios->includesAll(self.tripulantes)

Cada embarcacin puede realizar salidas de pesca en una fecha determinada, que no pueden
ser ms de dos por da.
context: Pesca
inv: self.realizada.realiza->
select(s|s.fechaSalida = self.fechaSalida)->size() <= 2

Las embarcaciones donde pescan los pescadores debe ser la misma que la de ellos mismos
pensados como embarcados. (esta es una restriccin existente debido a la estructura del
diagrama de clases).
context: Salida
inv: self.pescoEn.realizada = self.pescadores.tripula

Definicin de atributos derivados:


Superficie de una embarcacin.
context: Embarcacion::superficie: MetrosCuad
derive: self.largo * self.ancho
(se asume que existe el dominio MetrosCuad resultante
expresiones de dominio Metros)

de multiplicar dos veces a dos

El lenguaje de especificacin OCL


- 30 -

Peso total de la pesca de una salida.


context: Salida::pesoPesca: Peso
derive: self.Pesca.pesoPesca->asSet()->sum()

Definicin de responsabilidades:
Las pescas pueden incrementarse (siempre y cuando no excedan los 1000 kilos en la
embarcacin).
context: Pesca::incrPesca(p: Peso)
pre: self.pescoEn.pesoPesca + p <= 1000
post: self.pesoPesca = self.pesoPesca@pre + p

Definicin de responsabilidades derivadas (queries):


Asociaciones .que agrupan a embarcaciones pertenecientes a la flota de un civil.
context: Civil::getAs(): Set(Asociacion)
body: self.flota.inscripta

Bibliografa
- UML 2.0 OCL Specification (documento de la OMG publicado en Internet en
http://www.omg.org/docs/ptc/03-10-14.pdf).
- Object Constraint Language Specification (documento de Internet ubicado en
http://umlcenter.visual-paradigm.com/umlresources/obje_11.pdf).
- Muchos otros documentos extrados de Internet.

Anda mungkin juga menyukai