1. Flickr em JML
Pedro Pereira Ulisses Costa
Métodos Formais em Engenharia de Software
18 de Dezembro de 2008
Pedro Pereira, Ulisses Costa Flickr em JML
2. Sumário
1 JML
O que é?
Direitos e Deveres
Isolamento e ajuda no debugging
Linguagem formal e abstracta
2 ESC/Java2
3 JMLUnit
4 Alloy Revisitado
5 De Alloy para JAVA e JML
Pedro Pereira, Ulisses Costa Flickr em JML
3. Sumário
1 JML
O que é?
Direitos e Deveres
Isolamento e ajuda no debugging
Linguagem formal e abstracta
2 ESC/Java2
3 JMLUnit
4 Alloy Revisitado
5 De Alloy para JAVA e JML
Pedro Pereira, Ulisses Costa Flickr em JML
6. Sumário
1 JML
O que é?
Direitos e Deveres
Isolamento e ajuda no debugging
Linguagem formal e abstracta
2 ESC/Java2
3 JMLUnit
4 Alloy Revisitado
5 De Alloy para JAVA e JML
Pedro Pereira, Ulisses Costa Flickr em JML
7. Design by contract
Contracto entre classe e clientes
Classe explicı́ta os direitos e deveres
Cliente cumpre os deveres
Classe atribui direitos
Pedro Pereira, Ulisses Costa Flickr em JML
8. JML melhora o código
JML são anotações verificadas no programa
Anotações são puras
Pode ajudar no debugging
Isola os erros evitando propagação
Pedro Pereira, Ulisses Costa Flickr em JML
9. Especificação em JML
O JML é melhor que JAVAdoc (linguagem natural vs
linguagem formal)
JML é mais abstracto que código
Não é necessário dar o algoritmo detalhado
Racioncı́nio modular
Compreensão mais rápida dos métodos
No pior caso basta ler os contractos dependentes do método
O cliente não pode concluir mais nada para além dos
contractos
Pedro Pereira, Ulisses Costa Flickr em JML
10. Sumário
1 JML
O que é?
Direitos e Deveres
Isolamento e ajuda no debugging
Linguagem formal e abstracta
2 ESC/Java2
3 JMLUnit
4 Alloy Revisitado
5 De Alloy para JAVA e JML
Pedro Pereira, Ulisses Costa Flickr em JML
11. Estados do JML
76 54
01 23
normal post state
76 54
01 23
pre state
normal behaviour 44
throwing de excepcao
%%
76 54
01 23
exceptional post state
/. -,
() *+
excepcao
exceptional behaviour
33
java.lang.Error
''
/. -,
() *+
fora do alcance
Pedro Pereira, Ulisses Costa Flickr em JML
12. Isolamento e ajuda no debugging
...
/*@
@ public normal_behaviour
@ requires unameA != null && unameB != null;
@ requires m_users.containsKey(unameA) && m_users.containsKey(unameB);
@ requires m_users.get(unameA) instanceof User;
@ ensures (( User) m_users.get(unameA)). getContacts ().contains(unameB);
@ assignable m_users;
@ also
@ public exceptional_behaviour
@ requires unameA == null || unameB == null;
@ signals_only NullPointerException ;
@ signals ( NullPointerException ) true;
@ assignable nothing;
@*/
public void add_contact (String unameA , String unameB)
throws NullPointerException {
User u = (User) users.get(unameA );
Vector contacts = u. getContacts ();
if( !contacts.contains(unameB) ) {
contacts.add(unameB );
u. setContacts (contacts );
users.put(unameA , u);
}
}
...
Pedro Pereira, Ulisses Costa Flickr em JML
13. Quando a pré-condição falha
Exception in thread main org.jmlspecs.jmlrac.runtime.JMLInternalPreconditionError: by method Flickr.add contact
Flickr.java
...
/*@
@ public normal_behaviour
@ requires unameA != null;
@ requires unameB != null;
@ requires m_users. containsKey(unameA);
@ requires m_users. containsKey(unameB);
@ requires m_users.get(unameA) instanceof User;
@ ...
@*/
public void add_contact
(String unameA , String unameB)
throws NullPointerException {
User u = (User) users.get(unameA );
...
}
...
Main.java (Culpado)
...
Flick f = new Flickr ();
...
f. add_contact ("Pedro","Ulisses");
...
Utilizadores não estão registados no Flickr
O objecto com esse nome não é instância de User
NOTA: verificação com instanceof não seria necessária em JAVA5
Pedro Pereira, Ulisses Costa Flickr em JML
14. Quando a pós-condição falha
Exception in thread ”main” org.jmlspecs.jmlrac.runtime.JMLInternalNormalPostconditionError: by method
Flickr.add contact
Flickr.java (Culpado)
...
/*@
@ public normal_behaviour
@ ...
@ ensures (( User) m_users.get(unameA))
@ . getContacts ()
@ .contains(unameB);
@ assignable m_users;
@*/
public void add_contact
(String unameA , String unameB)
throws NullPointerException {
...
}
...
Main.java
...
Flick f = new Flickr ();
...
f. add_contact ("Pedro","Ulisses");
...
Método add contact ou nos métodos que este usa
Pedro Pereira, Ulisses Costa Flickr em JML
15. Quando a pós-condição falha
Quando o erro é de outros métodos
Exception in thread "main" org.jmlspecs.jmlrac.runtime.
JMLInternalNormalPostconditionError : by method User.setContacts
...
at Flickr. internal$add_contact (Flickr.java :246)
...
at Main. internal$main (Main.java :17)
...
Flickr.java
...
/*@
@ public normal_behaviour
@ ...
@ ensures m_files.containsKey(mname);
@ (*^linha 246 *)
@ ...
@*/
public void add_media
(String uname , String mname)
throws NullPointerException {
...
}
...
O JML aqui tenta ser preciso em vão.
User.java (Culpado)
...
/*@ public normal_behaviour
@ requires contacts != null;
@ ensures m_contacts.equals(contacts);
@ assignable m_contacts;
@ also
@ public exceptional_behaviour
@ requires contacts == null;
@ signals_only NullPointerException ;
@ signals ( NullPointerException ) true;
@ assignable nothing;
@*/
public void setContacts (Vector contacts) {
this.contacts = new Vector ();
}
...
Pedro Pereira, Ulisses Costa Flickr em JML
16. Sumário
1 JML
O que é?
Direitos e Deveres
Isolamento e ajuda no debugging
Linguagem formal e abstracta
2 ESC/Java2
3 JMLUnit
4 Alloy Revisitado
5 De Alloy para JAVA e JML
Pedro Pereira, Ulisses Costa Flickr em JML
17. Linguagem natural vs Linguagem formal
Pedro Pereira, Ulisses Costa Flickr em JML
18. Mais abstracto que código
Especificação do método del user
/*@ public normal_behaviour
@ requires uname != null;
@ requires m_users. containsKey (uname);
@ ensures !m_users. containsKey (uname);
@ assignable m_users , m_files , m_groups;
@ also
@ public exceptional_behaviour
@ requires uname == null;
@ signals_only NullPointerException ;
@ signals ( NullPointerException ) true;
@ assignable nothing;
@*/
Não é necessário dar o algoritmo detalhado
O contracto mantem-se, o cliente nunca é afectado
O contracto é muitas das vezes mais pequeno que o código
Pedro Pereira, Ulisses Costa Flickr em JML
19. Linguagem formal e abstracta
public void del_user(String uname) throws NullPointerException {
User u = (User) users.get(uname );
for( Iterator i = users.values (). iterator (); i.hasNext (); ) {
User u_temp = (User) i.next ();
Vector contacts = u_temp. getContacts ();
Vector favourites = u_temp. getFavourites ();
if( contacts.remove(uname) || favourites.removeAll(u_temp.getPStream ()) ) {
u_temp. setContacts (contacts );
u_temp. setFavourites (favourites );
users.put(u_temp.getUname (), u_temp );
}
}
for( Iterator i = u.getPStream (). iterator (); i.hasNext (); )
files.remove(i.next ());
for( Iterator i = groups.values (). iterator (); i.hasNext (); ) {
Group g_temp = (Group) i.next ();
Vector members = g_temp.getMembers ();
Vector pool = g_temp.getPool ();
if( members.remove(uname) || pool.removeAll(u.getPublics ()) ) {
g_temp.setMembers(members );
g_temp.setPool(pool );
groups.put(g_temp.getGname (), g_temp );
}
}
users.remove(uname );
}
Pedro Pereira, Ulisses Costa Flickr em JML
20. Sumário
1 JML
O que é?
Direitos e Deveres
Isolamento e ajuda no debugging
Linguagem formal e abstracta
2 ESC/Java2
3 JMLUnit
4 Alloy Revisitado
5 De Alloy para JAVA e JML
Pedro Pereira, Ulisses Costa Flickr em JML
21. ESC/Java2
Validação dos tipos de dados e sı́ntax
Detecta:
referências para apontadores nulos
casts ilegais
indexação de arrays fora dos limites
Pedro Pereira, Ulisses Costa Flickr em JML
22. ESC/Java2
Não suporta todas as especificações JML
Pode indicar falsos negativos/positivos
Pedro Pereira, Ulisses Costa Flickr em JML
23. Sumário
1 JML
O que é?
Direitos e Deveres
Isolamento e ajuda no debugging
Linguagem formal e abstracta
2 ESC/Java2
3 JMLUnit
4 Alloy Revisitado
5 De Alloy para JAVA e JML
Pedro Pereira, Ulisses Costa Flickr em JML
24. JMLUnit
Gera Test Cases para métodos
Usa pré-condições para filtar input
Usa invariantes/pós-condições para capturar as falhas dos
testes
Pedro Pereira, Ulisses Costa Flickr em JML
25. JMLUnit
Apenas tinhamos excepções NullPointerException
...
return new java.lang.String [] {
"ulisses", "pedro", ...
}
...
switch(n) {
case 0: return new User("pedro");
case 1: return new User("ulisses");
...
}
...
Pedro Pereira, Ulisses Costa Flickr em JML
26. Sumário
1 JML
O que é?
Direitos e Deveres
Isolamento e ajuda no debugging
Linguagem formal e abstracta
2 ESC/Java2
3 JMLUnit
4 Alloy Revisitado
5 De Alloy para JAVA e JML
Pedro Pereira, Ulisses Costa Flickr em JML
27. Propriedades de uma HashTable?
all u : f.users[Uname] | lone f.users.u
all n : f.users.User | lone f.users[n]
Pedro Pereira, Ulisses Costa Flickr em JML
28. O que é uma HashTable?
cada objecto está associado a uma imagem e vice-versa;
não existem objectos ou imagens repetidas.
Pedro Pereira, Ulisses Costa Flickr em JML
29. Injectividade e Simplicidade
injectividade a mesma imagem não pode relacionar dois objectos
diferentes
simplicidade o mesmo objecto não pode relacionar duas imagens
diferentes
Pedro Pereira, Ulisses Costa Flickr em JML
30. Sobrejectividade e Totalidade
sobrejectividade cada imagem está relacionada com pelo menos
um objecto
totalidade cada objecto está relacionado com pelo menos uma
imagem
Pedro Pereira, Ulisses Costa Flickr em JML
31. Refinamento
// media associado ao pstream tem de existir
all u : f.users[Uname] | u.pstream in f.files.Media
// nao ha media "solto"
f.files.Media in f.users[Uname ]. pstream
// media associado ao user e unico
all u : f.users.User | no f.users[u]. pstream & f.users[Uname - u]. pstream
Pedro Pereira, Ulisses Costa Flickr em JML
32. Relação comments
pred comments_inj_sur_ent [ f : Flickr ] {
// comments injectiva
all x, y : f.users.User , z : f.files[Mname ]. comments[Uname] {
z in f.files[Mname ]. comments[x] && z in f.files[Mname ]. comments[y]
=> x=y
}
// comments sobrejectiva
all x : f.files[Mname ]. comments[Uname] | one y : f.files[Mname ]. comments.
Comment {
y in f.files[Mname ]. comments.x
}
// comments inteira (total)
all x : f.files[Mname ]. comments.Comment | some y : f.files[Mname ]. comments[
Uname] {
y in f.files[Mname ]. comments[x]
}
}
Pedro Pereira, Ulisses Costa Flickr em JML
34. Invariante global
pred inv_Flickr [ f : Flickr ] {
users_bijection [f]
files_bijection [f]
groups_bijection [f]
comments_inj_sur_ent [f]
inv_User[f]
inv_Media[f]
inv_Group[f]
}
Pedro Pereira, Ulisses Costa Flickr em JML
35. Sumário
1 JML
O que é?
Direitos e Deveres
Isolamento e ajuda no debugging
Linguagem formal e abstracta
2 ESC/Java2
3 JMLUnit
4 Alloy Revisitado
5 De Alloy para JAVA e JML
Pedro Pereira, Ulisses Costa Flickr em JML
36. create user
pred create_user [ f, f’ : Flickr , n :
Uname ] {
n !in f.users.User
one u : User {
u !in f.users[Uname]
no u.pstream
no u.public
no u.contacts
no u.favourites
f’. users = f.users + n->u
}
f’. files = f.files
f’. groups = f.groups
}
/*@ public normal_behaviour
@ requires uname != null;
@ ensures m_users. containsKey (uname);
@ assignable m_users;
@ also
@ public exceptional_behaviour
@ requires uname == null;
@ signals_only NullPointerException ;
@ signals ( NullPointerException ) true;
@ assignable nothing;
@*/
public void create_user (String uname)
throws NullPointerException {
if( !users.containsKey (uname) ) {
User u = new User(uname );
users.put(uname , u);
}
}
Pedro Pereira, Ulisses Costa Flickr em JML
37. Invariantes
// apenas podem ser tornadas publicas fotos do resp. photostream
all u : f.users[Uname] | u.public in u.pstream
// media do pstream tem de estar registado
f.users[Uname ]. pstream in f.files.Media
// um user nao pode ser o seu proprio contacto
all n : f.users.User | n !in f.users[n]. contacts
// apenas podem ser tornadas publicas media do resp. photostream
//@ public invariant ( forall User u; m_users.values ().contains(u); u.
getPStream (). containsAll (u.getPublics ()));
// media de um photostream tem de estar registado
//@ public invariant ( forall User u; m_users.values ().contains(u); m_files.
keySet ().containsAll(u.getPStream ()));
// um utilizador nao pode ser o seu proprio contacto
//@ public invariant ( forall User u; m_users.values ().contains(u); !(u.
getContacts ().contains(u.getUname ())));
Pedro Pereira, Ulisses Costa Flickr em JML