Documentos de Académico
Documentos de Profesional
Documentos de Cultura
-- Expresiones de especificación --
Índice
1 Operadores lógicos
2 Cuantificadores
2.1 \forall | \exists
2.2 \max | \min | \product | \sum
2.3 \num_of
3 Expresiones primarias JML para
3.1 Variable
3.2 Método
3.3 Objeto
3.4 Clase
3.5 Hilo
4 Bibliografía
5 Anexos de sintaxis
Operadores lógicos
Si a y b son expresiones booleanas JML, las siguientes también son expresiones booleanas
JML.
!a ("¬a")
a && b ("a ʌ b")
a || b (" a v b")
a ==> b ("a implica b")
a <== b ("a está implicado por b")
a <==> b ("a es equivalente a b") ó ("a si y solo si b")
a <=!=> b ¬ ("a es equivalente a b")
Donde:
La notación <==> se puede leer si y solo si. Tiene el mismo significado para los valores
booleanos que == pero tiene una precedencia más baja. Por lo tanto, la expresión:
La notación <=!=> se puede leer no es equivalente a tiene el mismo significado para los
valores booleanos que != pero con una precedencia más baja. Por lo tanto, la expresión:
Las expresiones a ambos lados de estos operadores deben ser de tipo boolean y el
tipo del resultado también es boolean.
Por lo tanto:
De manera similar:
Cuantificadores
\forall | \exists
Sintaxis. Si a y b son expresiones booleanas JML y x es una variable de tipo t las siguientes
también son expresiones booleanas JML.
Ejemplo3.
(\forall int i, j ; 0 <= i && i < j && j < 10 ; arr[ i ] <= arr[ j ] )
Estos cuantificadores son llamados generalizados, que devuelven el máximo, mínimo, producto
o suma de los valores de las expresiones dadas, donde las variables satisfacen el rango dado.
La expresión en el cuerpo debe ser de tipo numérico incorporado, como int o double; El tipo de
la expresión cuantificada en su conjunto es el tipo de su cuerpo. Por ejemplo, las siguientes
aserciones son todas verdaderas:
Ejemplo8.
Ejemplo9.
\num_of
Este cuantificador devuelve el número de valores para sus variables para las cuales el rango y
la expresión en su cuerpo son verdaderos. El cuerpo debe tener un tipo booleano y toda la
expresión cuantificada tiene un tipo long. El significado de este cuantificador está definido por
la siguiente ecuación:
Ejemplo10.
i = 0 : 0*2 < 6 V
i = 1 : 1*2 < 6 V
i = 2 : 2*2 < 6 V
i = 3 : 3*2 < 6 F
Expresiones primarias
Las palabras clave JML que se relacionan a continuación y que son usadas en expresiones
empiezan con una barra diagonal inversa (\) para evitar el conflicto con los nombres de las
variables del programa, son los atributos considerados en expresiones JML para elementos de
un programa.
# Expresión Variable Método Objeto Clase Hilo
1 \fresh() Objetos
asignados
recientemente
2 \only_assigned() Únicas
variables
asignadas
\not_assigned() Variables que
3 no debieron ser
asignadas
\not_modified() Variables que
4 no debieron
modificarse
Únicas
\only_accessed() variables que
5
debieron ser
accesadas
6 \old() Valor previo
11 \lblpos
Etiquetas a
expresiones
12 \lblneg
16 \only_captured(…) Captura de
referencias
17 \working_space() Espacio de
almacenamiento
18 \max() Objetos de
bloqueo
19 \reach() Referencia
20 \space() Almacena-
miento
21 \is_initizalied() Inicialización
estática
22 \invariant() Estados
válidos
23 \lockset() Conjunto
de
bloqueos
(1) \fresh(spec-expression-list) objetos que fueron asignados solo en post-estado
Este operador afirma que objetos se asignaron recientemente. Por ejemplo, \fresh(x, y) afirma
que x e y no son nulos y que los objetos vinculados a estos identificadores no se asignaron en
el pre-estado. Los argumentos de \fresh pueden tener cualquier tipo de referencia, y el tipo de
la expresión general es booleana.
verifica que el objeto zSc que almacena un número aleatorio generado recientemente. De esta
forma se asegura de que un objeto de número aleatorio existente no se reutilice accidental o
maliciosamente, lo que evita una cierta clase de fallas de seguridad de valor nuevo.
Este operador afirma que la ejecución del método solo se asigna al subconjunto de los grupos
de datos nombrados por los campos dados. Puede ser usado en la postcondición (normal y
excepcional) de un método (quizás implícitamente en una restricción de historial).
Esto incluye las asignaciones directas en el cuerpo del método y las asignaciones durante las
llamadas realizadas por el método (y los métodos a los que se llamó, etc.).
Este operador se puede aplicar a campos concretos, modelos o fantasmas. Cuando se aplica a
un campo modelo, el significado es que las ubicaciones concretas en el grupo de datos de ese
campo modelo pueden asignarse durante la ejecución del método. El tipo de una expresión
\only_assigned es booleana.
Este operador afirma que las ubicaciones en el grupo de datos no fueron asignadas durante la
ejecución del método que se especifica (o todos los métodos a los que se aplica una restricción
de historial). Se puede usar en postcondiciones normales y excepcionales (clausulas ensures y
signals) y en restricciones de historial.
Este operador afirma que los valores de los campos nombrados son los mismos en el pre-
estado y post-estado del método. Se puede usar únicamente en postcondiciones normales y
excepcionales (cláusulas ensures y signals) y en restricciones de historial.
Este operador se puede aplicar a campos concretos, modelos o fantasmas. Cuando se aplica a
un campo modelo, el significado es que solo el valor del campo modelo no ha cambiado, no
obstante los campos concretos involucrados en su representación pueden haber cambiado. El
tipo de una expresión \not_modified es booleana. Es equivalente a x == \old(x);
Por ejemplo, \only_accessed (xval, yval) dice que el método no leyó campos fuera del grupo de
datos xval e yval. Esto incluye las lecturas directas en el cuerpo del método y las lecturas
durante las llamadas realizadas por el método (y los métodos a los que se llamó, etc.). Un
predicado como \only_accessed (x.f) se refiere a todo el grupo de datos nombrado por x.f no
solo a la ubicación x.f en sí misma. El operador \only_accessed puede aplicarse tanto a
campos concretos, modelos o fantasmas. Cuando se aplica a un campo modelo, el significado
es que se permite acceder a las ubicaciones (concretas) en el grupo de datos de ese campo
modelo durante la ejecución del método. El tipo de una expresión \only_accessed es boolean.
(6) old-expession
Una expresión de la forma \old (Expr) se refiere al valor que tenía la expresión Expr en el
estado previo de un método. Se refiere entonces al valor que tenía la expresión Expr cuando el
control llegó por última vez a la etiqueta de declaración Label. Es decir, se refiere al valor de la
expresión justo antes de que el control llegara por última vez a la declaración a la que se
adjunta la etiqueta.
Este operador retorna el tipo dinámico1 de una expresión (un valor del tipo \TYPE). Su
argumento puede ser de tipo primitivo. Es análogo en Java a Object.getClass().
indefinido si E es nulo.
igual a E.getClass()2 si E tiene un tipo de referencia no genérico.
igual a t.class si E tiene un tipo primitivo t
1
Es el tipo que es comprobado en tiempo de ejecución y puede ser el tipo declarado o un subtipo del tipo declarado.
Es de anotar, que el tipado dinámico es más adecuado para el prototipado.
2
El método getClass() se encuentra definido en Object como un método que devuelve una representación en
tiempo de ejecución de la clase del objeto sobre el cual podemos acceder a una serie de características del objeto
por ejemplo: el nombre de la clase, el nombre de su superclase y los nombres de los interfaces que implementa.
Por ejemplo: si c es una variable de tipo estático3 Collection que contiene un objeto de
la clase HashSet, entonces \typeof(c) es HashSet.class, que es lo mismo que
\type(HashSet).
(8) \nonnullelements(spec-expression)
Este operador se puede usar para afirmar que una matriz y sus elementos no son nulos. Por
ejemplo, \nonnullelements(myArray), es equivalente a:
Este operador toma un argumento de tipo \TYPE y retorna un valor de tipo \TYPE. Si el
argumento es del tipo array, el resultado es el tipo de ese array, es decir devuelve el tipo
compartido por todos los elementos del array.
En consecuencia, \elemtype devuelve nulo si el argumento no es del tipo matriz, pero indefinido
si el argumento es nulo.
3
Es el tipo declarado para la variable en el código fuente y su comprobación de tipificación se realiza durante la
compilación.
El argumento de \elemtype debe ser una expresión de tipo \TYPE que JML considera igual que
java.lang.Class y su resultado también tiene tipo \TYPE.
Este operador se puede usar para introducir literales de tipo \TYPE en expresiones. Una
expresión de la forma \type(T), donde T es un nombre de tipo, tiene el tipo \TYPE. Dado que en
JML \TYPE es lo mismo que java.lang.Class, una expresión de la forma \type(T) significa lo
mismo que T.class, si T es un tipo de referencia. Si T es un tipo primitivo, entonces \type(T) es
equivalente al valor del campo TYPE del tipo de referencia correspondiente. Por lo tanto,
\type(boolean) es igual a Boolean.TYPE.
Estas expresiones entre paréntesis que comienzan con \lblneg y \lblpos se pueden usar para
adjuntar etiquetas a las expresiones. Estas etiquetas pueden imprimirse en varios mensajes
mediante herramientas de soporte, para por ejemplo identificar una aserción que falló. Tal
expresión tiene una etiqueta y un cuerpo.
\lblneg
Por ejemplo, en
La forma usando \lblpos tiene una sintaxis similar, pero debe usarse para advertencias cuando
el valor de la expresión encerrada es true.
(13) \duration(expression)
Este operador describe el número máximo especificado de ciclos de máquina virtual necesarios
para ejecutar la llamada al método o la expresión de invocación explícita del constructor que es
su argumento. Por ejemplo, \duration(myStack.push(o)) es el número máximo de ciclos de
máquina virtual necesarios para ejecutar la llamada myStack.push(o), de acuerdo con el
contrato del tipo estático del método push del tipo myStack, cuando se pasa el argumento o.
Para una máquina virtual Java dada, un ciclo de máquina virtual se define como el mínimo del
máximo sobre todas las instrucciones de la máquina virtual Java, i, del tiempo necesario para
ejecutar la instrucción i. La expresión de argumento pasada a \duration debe ser una llamada
a método o una expresión de invocación de constructor explícito; El tipo de expresión \duratión
es long.
(14) \only_called(method-name-list)
Este operador afirma que la ejecución del método solo se invocó desde el subconjunto de
métodos dado en la method-name-list. Puede ser usado en precondiciones normales y
excepcionales (cláusulas ensures y signals) y en restricciones de historial. El tipo de una
expresión \only_called es boolean.
Por ejemplo, \only_called(p, q) dice que métodos, aparte de p y q, fueron llamados durante la
ejecución de este método.
\only_accessed(store-ref-list)
Este operador afirma que la ejecución del método solo lee de un subconjunto de los grupos de
datos nombrados por los campos dados. Puede ser usado en la postcondición de un método,
en precondiciones normales y excepcionales (cláusulas ensures y signals) y en restricciones
de historial.
Este operador se puede aplicar a campos concretos, modelos o fantasmas. Cuando se aplica a
un campo modelo, el significado es que se permite acceder a las ubicaciones (concretas) en el
grupo de datos de ese campo modelo durante la ejecución del método. El tipo de la expresión
\only_accessed es boolean.
(15) \result
Es el valor que es retornado por un método. Puede ser usada únicamente con las cláusulas
ensures, duration y workingspace en cualquier método, excepto métodos no-void
constructores.
(16) \only_captured(store-ref-list)
Este operador afirma que la ejecución del método solo capturó referencias de un subconjunto
de los grupos de datos nombrados por los campos dados. Se puede aplicar tanto a campos
concretos, modelos o fantasmas. Cuando se aplica a un campo modelo, el significado es que
las ubicaciones (concretas) en el grupo de datos de ese campo modelo pueden capturarse
durante la ejecución del método. El tipo de una expresión \only_captured es booleana.
Se captura una referencia cuando se almacena en un campo (a diferencia de una variable
local). Por lo general, un método captura un parámetro formal (o una referencia almacenada en
un campo estático) asignándolo a un campo en el receptor del método (el objeto este), un
campo en algún objeto (o un elemento de matriz) o a un campo estático.
Por ejemplo, \only_captured(xv, yv) dice que el método no capturó referencias, fuera de los
grupos de datos de xv e yv.
(17) \working_space(expression)
Se debe tener en cuenta que la expresión utilizada como argumento para \working_space
debe considerarse como citada, en el sentido de que no debe ejecutarse; por lo tanto, el
método o constructor llamado no necesita estar libre de efectos secundarios.
Los argumentos detallados son necesarios en la especificación de la llamada porque las
llamadas a diferentes métodos, es decir, aquellos con diferentes parámetros, pueden usar
tomar diferentes cantidades de espacio. La expresión de argumento debe ser una llamada a
método o una expresión de invocación de constructor explícito; El tipo de resultado de una
expresión \ working_space es long.
(18) \max(spec-expression)
Este operador devuelve el "mayor" (como lo define <) de un conjunto de objetos de bloqueo,
dado un conjunto de bloqueo como argumento. El resultado es de tipo Object.
(19) \reach(spec-expression)
Este operador permite referirnos al conjunto de objetos alcanzables desde algún objeto en
particular. La sintaxis \reach (x) denota el JMLObjectSet más pequeño que contiene el objeto
denotado por x, si lo hay y todos los objetos accesibles a través de todos los campos de
objetos en este conjunto.
Es decir, si x es null, entonces este conjunto está vacío; de lo contrario este contiene x, todos
los objetos accesibles a través de todos los campos de x, todos los objetos accesibles a través
de todos los campos de estos objetos, y así sucesivamente, recursivamente. Si x denota un
campo modelo (o grupo de datos), entonces \reach(x) denota al JMLObjectSet más pequeño
conteniendo los objetos alcanzables desde x o accesibles desde los objetos referenciados por
los campos en ese grupo de datos.
(21) \is_initialized(reference-type)
Este operador devuelve verdadero solo cuando su argumento de tipo de referencia es una
clase que ha finalizado su inicialización estática. Es de tipo booleano.
(22) \invariant_for(spec-expression)
Este operador devuelve verdadero solo cuando su argumento satisface el invariante de su tipo
estático. Por ejemplo \invariant_for((MyClass)o) es verdadero cuando o satisface el invariante
de MyClass. Toda la expresión \invariant_for es de tipo boolean.
(23) \lockset
La primitiva \lockset denota el conjunto de bloqueos en poder del hilo actual. Es de tipo
JMLObjectSet.
Bibliografía
Leavens, G. T., Poll, E., Clifton, C., Cheon, Y., Ruby, C., Cok, D., ... & Dietl, W. (2008). JML
reference manual.
Anexos de sintaxis