Está en la página 1de 9

Java Modeling Languaje (JML)

-- Expresiones de especificación—

Ejemplo de \invariant()

Este es un ejemplo de una clase invariante en el lenguaje de programación Java con Java
Modeling Language . El invariante debe ser verdadero después de que finalice el constructor y en
la entrada y salida de todas las funciones miembro públicas. Las funciones de miembros públicos
deben definir condiciones previas y posteriores para ayudar a garantizar que la clase sea
invariante.

public class Date {

public static void main(String[] args) {


Date f = new Date(20,5);
System.out.println("Dia " + f.dia());
System.out.println("Hora " + f.hora());
}

int /*@ spec_public @*/ day;


int /*@ spec_public @*/ hour;

/*@ invariant day >= 1 && day <= 31; @*/ // class invariant
/*@ invariant hour >= 0 && hour <= 23; @*/ //class invariant

/*@
@ requires d >= 1 && d <= 31;
@ requires h >= 0 && h <= 23;
@*/

public Date(int d, int h) { // constructor


day = d;
hour = h;
}

/*@
@ requires d >= 1 && d <= 31;
@ ensures day == d;
@*/

public void setDay(int d) {


day = d;
}

/*@
@ requires h >= 0 && h <= 23;
@ ensures hour == h;
@*/

public void setHourt(int h) {


hour = h;
}

public int dia() {


return day;
}

public int hora() {


return hour; }

Ejecución ok en JML2 RAC:

Ejemplo de \max()
Es un cuantificador generalizado, Se aplican sobre expresiones numéricas como enteros o
números con coma flotante:

public class Max {

public static void main(String[] args) {


int[] a= {5,4,8,6,3,2,9};
System.out.println(“Numero Maximo “+ áximo(a) );
}
/*@ requires a ¡= null && a.length > 1; ensures
\result == (\max int i; 0<=i && i < a.length;
a[i]);
ensures (* no se modifica el array *) && (\forall int i;
0 <= i && i< a.length;
a[i] == \old(a[i]));
@*/ static int
áximo(int[] a){ int max
= a[0]; for(int i = 0; i <
a.length; i++)
{
if(max<a[i])
{
max=a[i];

}
}
return (max);

Ejecución ok en JML2 RAC :


package pro;
public class Prog1 {

public static void main(String[] args) {


int pagos;
int vector[] = {1,2,3};
int vrSuma;
System.out.println("suma "+ suma(1,2));
Persona per1 = crearPersona(50,60, "pepita", 10000);
Persona per2 = crearPersona(60, 70, "juanita", 20000);
pagos = sumarpagos(per1, per2);
System.out.println("Pagos "+ pagos);
vrSuma=sumaVector(vector);
System.out.println("SumaVector "+ vrSuma);
}

Ejemplo de \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.

Ejemplo de \typeof(spec-expression)

retorna el tipo de una expresión. 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().

//@ requires \typeof(x) <: \type(int) && \typeof(y) <: \type(int);


//@ requires (\lblneg x_Existe x != 0);

Ejemplo \only_captured()

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.

//@ ensures x>=0 && \only_captured(x) && \typeof(\result) <: \type(int);


private static int suma(int x, int y){
return x+y;
}

Ejemplo \elemtype()
Retorna el tipo de dato de un array 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.

Ejemplo old()
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.

/**Clausula \old
**Refiere al valor que tenía la expresión Expr en el estado previo de un método.
* En una expresión de la forma \old(Expr , Label) , Label debe ser una
etiqueta definida en el método actual.
*/

//@requires
//@ensures
//@expresión-antigua :: = \old ( expresión-especificación [ , ident ] )
//@ | \pre ( expresión-especificación )0

//@ requires vector !=null && (\forall int i ; 0<=i && i<vector.length;
vector[i] != 0) &&
//@ \elemtype(\typeof(vector)) == \type(int);
//@ ensures (\forall int j; 0 <= j && j < vector.length; vector[ j ] ==
\old(vector[ j ]));
private static int sumaVector(int[] vector){
int i=0, suma=0;
while(i<vector.length){
suma=suma+vector[i];
i++;
}
//vector[0]=0;
return suma;
}

private static int sumarpagos(Persona p1, Persona p2) {


int pago;
Persona per3 = crearPersona(60, 70, "laurita", 5000);
pago = p1.getpago() + p2.getpago() + per3.getpago();
return pago;
}
Ejemplo de \fresh()

Objetos que fueron asignados solo en post-estado. Este operador afirma que objetos se asignaron
recientemente.
//@ ensures \fresh(\result);

public static Persona crearPersona(int peso, int edad, String nombre, int
pago){
Persona per1 = new Persona(peso, edad, nombre, pago);
return per1;
}
}

class Persona {

private /*@ spec_public@*/ int peso;


private /*@ spec_public@*/ int edad; private /*@
spec_public@*/ int pago;
private /*@ non_null spec_public @*/ String nombre;

Ejemplo 2 de \invariant()

//@ invariant peso >=0;


//@ invariant edad >=0;
//@ invariant pago >=0;

public Persona(int peso, int edad, String nombre, int pago){


this.peso =peso;
this.edad = edad; this.nombre =
nombre;
this.pago= pago;
}

//@ ensures \result == this.pago;


public int getpago(){ return pago; }

//@ ensures \result == this.peso;


public int getPeso(){ return peso; }

//@ ensures \result == this.nombre; public


String getNombre(){ return nombre; }

//@ ensures \result == this.edad; public


int getEdad(){ return edad; }
public /*@ pure @*/ boolean
esMayorDeEdad(){ if (edad >= 18) return
true;
else return false;
}

//@ public ghost boolean edadValida = false;


//@ requires valor >= 0;
//@ assignable edad;
//@ assignable edadValida;
//@ ensures edad == valor;

public void setEdad(int valor){


if (valor < 0){
this.edad = 0;
//@ set edadValida = false;
}
else {
this.edad = valor;
//@ set edadValida = true;
}
}

Ejemplo 2 \old()

//@ requires valor >= 0;


//@ ensures (\result == \old(this.peso)+valor) &&
//@ \only_assigned(this.edad, this.nombre) &&
//@ \result == this.peso;
public int incrementarPeso(int valor){
System.out.println("Nombre "+ nombre);
System.out.println("Edad "+ edad);
this.peso = this.peso + valor; return
this.peso;
}

Ejemplo de \only_accessed()

Unicos datos que debieron ser accesados. Este operador se usa en una postcondición de un
método que especifica que la ejecución del método únicamente lee de un subconjunto de los
grupos de datos nombrados por los campos dados.

Ejemplo de \only_assigned()
Ejecución de método únicamente se asignó a determinadas variables 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.

//@ requires valor >= 0;


//@ ensures (\result == \old(pago)+valor) && \only_accessed(pago)
//@ && edad == \old(edad) && peso == \old(peso) && nombre == \old(nombre)
//@ && \only_assigned(pago) //@
&& \result == pago;
public int incrementarPago(int valor){
pago = pago + valor;
return pago;
}
}
Ejecucion ok en JML2 RAC

Ejemplo de \ nonnullelements ()
Este operador se puede utilizar para afirmar que una matriz y sus elementos no son nulos
________________________________________________________________________________
public static void elementosNoNulos () {
ArrayList<String> myArray = new ArrayList<String>();
myArray.add("a");
myArray.add("b");
myArray.add("c");
if (myArray != null) {
System.out.println("NO ES NULO");
}else {
System.out.println("ES NULO");
}

También podría gustarte