A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Jpf@fe.up.pt www.fe.up.pt/~jpf Métodos Formais em Engenharia de Software Especificação Baseada em Modelos em VDM++ (2ª parte) João Pascoal Faria jpf@fe.up.pt.

Apresentações semelhantes


Apresentação em tema: "Jpf@fe.up.pt www.fe.up.pt/~jpf Métodos Formais em Engenharia de Software Especificação Baseada em Modelos em VDM++ (2ª parte) João Pascoal Faria jpf@fe.up.pt."— Transcrição da apresentação:

1 jpf@fe.up.pt www.fe.up.pt/~jpf
Métodos Formais em Engenharia de Software Especificação Baseada em Modelos em VDM++ (2ª parte) João Pascoal Faria

2 Índice Estrutura de uma especificação em VDM++ Tipos e classes
Funções e operações Tipos de dados básicos: booleanos, numéricos, caracteres e “quotes” Tipos de dados compostos: conjuntos, sequências, records, uniões, enumerações e tipos opcionais Modelação de estado com classes, atributos, associações e restrições Modelação de tipos de dados (tipos de valores de atributos) Modelação de atributos e associações unidireccionais Modelação (formalização) de restrições com invariantes Modelação de comportamento com operações Modelação de associações bidireccionais Modelação de associações ordenadas Integração com Rational Rose

3 Estrutura de uma especificação em VDM++
class <class-name> end <class-name> instance variables ... Paradigma OO Internal object state types values functions operations ... Paradigma funcional Definitions Paradigma OO thread ... Dynamic behaviour sync ... Synchronization control

4 Tipos e classes Tipos são tipos valor (value types)
Caso de tipos básicos (bool, nat, real, char, ...), tipos compostos (set, seq, map, etc.) e novos tipos definidos com type Instâncias são valores puros imutáveis Comparação e atribuição operam com os próprios valores Variável do tipo valor T (nome de um tipo) tem os próprios dados Classes são tipos referência (reference types) Definidas com class Instâncias são objectos mutáveis acedidos por uma referência Comparação e atribuição operam com as referências Variável do tipo referência para C (nome de uma classe) não tem os próprios dados, mas apenas uma referência para o objecto com os dados Referência para nada indicada com nil em VDM++ Abordagem recomendada em VDM++: Usar classes para modelar o estado (mutável) do sistema e tipos para modelar tipos de valores de atributos

5 Funções e operações Operações: consultam ou modificam estado de objectos (representado por variáveis de instância) ou estado global do sistema (representado por variáveis estáticas) Corpo de uma operação é uma instrução simples ou composta Pode ter instruções de atribuição Pode declarar variáveis Pode ter pré e pós-condição Funções: convertem entradas em saídas Funções puras sem efeitos laterais, isto é, sem acesso a variáveis de instância ou variáveis estáticas Corpo de uma função é uma expressão simples ou composta Não pode ter instruções de atribuição Normalmente são associadas a tipos

6 Tipos básicos: booleanos
Símbolo: bool Valores: true, false Operadores No caso de “and”, “or” e “=>”, o segundo operando só é avaliado se isso for necessário para determinar o resultado Na realidade, segue lógica de 3 valores (3º valor significa valor não definido) ver detalhes no manual (fonte: langmanpp_a4.pdf)

7 Tipos básicos: numéricos
Símbolo Descrição Valores nat1 Número natural não nulo 1, 2, 3, … nat Número natural 0, 1, 2, … int Número inteiro …, -2, -1, 0, 1, … rat real Número racional Número real (mesmo que “rat”, pois só números racionais podem ser representados no computador) …, , …, 0, …, 3, 16.23, …

8 Tipos básicos: numéricos
Note: The types stated for operands are the most general types allowed. This means for instance that unary minus works for operands of all five types (nat1, nat, int, rat and real). (fonte: langmanpp_a4.pdf)

9 Tipo básicos: caracteres
Símbolo: char Valores: 'a', 'b', …, '1', '2', …, '+', '-', … Operadores: Não tem o tipo string, mas admite strings literais com aspas (tipo seq of char)

10 Tipos básicos: “quotes”
Sintaxe: identificador entre < > Usado normalmente para definir tipos enumerados (ver adiante) Exemplos: <Branco>, <Preto>, … Operações: = <>

11 Conjuntos Sintaxe: set of T, em que T é um tipo qualquer
Construção por enumeração: {e1, e2, …, en} Conjunto vazio: { } Conjunto de números primos até 10: {1, 3, 5, 7, 9} Construção em compreensão: {e | bd1, bd2, ..., bdm & P} Constructs a set by evaluating the expression e on all the bindings for which the predicate P evaluates to true. A binding is either a set binding or a type binding . A set binding bdn has the form pat1, ..., patp in set s where pati - pattern (normally simply an identifier) s - set constructed by an expression A type binding is similar, in the sense that in set is replaced by a colon (:) and s is replaced with a type expression. Notice that type bindings cannot be executed by the interpreter because in general they are not executable. Construção de intervalo de inteiros: {lower, …, upper} {1, ... , 6} é o mesmo que {1, 2, 3, 4, 5, 6} {6, ..., 1} é o mesmo que { }

12 Conjuntos Sintaxe de operadores

13 Conjuntos Semântica de operadores

14 Conjuntos Semântica de operadores (cont.)

15 Conjuntos

16 Sequências Sintaxe: seq of T - sequência (lista) de 0 ou mais elementos do tipo T seq1 of T - sequência (lista) de 1 ou mais elementos do tipo T Construção por enumeração: [e1, e2, …, en] Construção de intervalo de inteiros: [i1, …, i2] Construção em compreensão: [e | id in set S & P] Constructs a sequence by evaluating the expression e on all the bindings for which the predicate P evaluates to true. The expression e will use the identifier id. S is a set of numbers and id will be matched to the numbers in the normal order (the smallest number first).

17 Sequências

18 Sequências

19 Sequências

20 Sequências Obtenção de sub-sequência: s(n1, …, n2)
Adicionado versão 0.2 Obtenção de sub-sequência: s(n1, …, n2) Dá a sub-sequência de s compreendida entre os índices n1 e n2 inclusivé Se n1 < 1 , considera-se n1 = 1 Se n2 > len s , considera-se n2 = len s Exemplo: [1, 3, 5, 7, 11, 13, 17, 19](1, ..., 3) = [1, 3, 5]

21 Uniões, enumerações e tipos opcionais
União: T1 | T2 | … | Tn União dos tipo T1, …., Tn Ser do tipo T1 | … | Tn significa ser do tipo T1 ou … ou do tipo Tn is_Ti(x) - verificar se o valor x é do tipo Ti Tipos enumerados são definidos através de “Union” (|) e “Quote” (identificador entre <>) Exemplo: <Branco> | <Preto> | … (tipo enumerado Cor) Tipo opcional: [T] Mesmo que T | nil Ser do tipo [T] é o mesmo que ser do tipo T ou ter o valor nil (valor não definido)

22 Records (tipos compostos)
:- Campo ignorado na comparação de recods

23 Records

24 Records

25 Records com variantes (usando uniões)

26 Records Adicionado versão 0.2

27 Modelação de estado com classes, atributos, associações e restrições
Sistema de Registo Civil Pessoa - nome: String - dataNascimento: Date - sexo: Sexo - dataFalecimento[0..1]: Date associação unidireccional (seta indica sentido de navegação) -pai -mae 0..1 0..1 * * multiplicidade de atributo (neste caso indica atributo opcional) Restrições: R1 – O pai tem de ser do sexo masculino R2 – A mãe tem de ser do sexo feminino R3 – O falecimento tem de ser posterior ao nascimento R4 – Os pais têm de nascer antes dos filhos (evita ciclos)

28 Modelação de tipos de dados (tipos de valores de atributos)
Em VDM++, é recomendável modelar tipos de valores de atributos como tipos (type), e não como classes (class) Porquê? Comparação e atribuição referem-se aos dados e não a referências ... No exemplo anterior, é necessário definir os tipos String (não está predefinido em VDM++) Date (não está predefinido em VDM++) Sexo Em VDM++, os tipos têm de ser definidos dentro de classes O tipo “Sexo” pode ser definido directamente dentro da classe “Pessoa” Quanto aos tipos “String” e “Date”, para facilitar a reutilização, será melhor definir em classes separadas (e.g. “StringUtils” e “DateUtils”), junto com funções utilitárias a eles associadas

29 Modelação do tipo “String” (1)
O tipo String não está predefinido em VDM++, mas é facilmente definido como uma sequência de caracteres: types String = seq of char; Podemos também definir um tipo String1 que não aceita strings vazias (usando seq1 – sequência de 1 ou mais): types String1 = seq1 of char; Todas as operações sobre sequências podem ser usadas com strings Felizmente, o VDM++ aceita strings literais com aspas "eu sou" é equivalente a ['e', 'u', ' ', 's', 'o', 'u']

30 Modelação do tipo “String” (2)
Para promover a reutilização, reúnem-se numa classe as definições de tipos e funções relacionadas com strings (esta classe funciona apenas como módulo, e não como uma verdadeira classe com objectos) class StringUtils types public String = seq of char; public String1 = seq1 of char; functions public static SubString(s: String, offset, length : nat) res: String == s((offset + 1), ... , (offset + length)) pre length = 0 or offset + length <= len s; end StringUtils

31 Modelação do tipo “Date” (1)
Diferentes hipóteses para representar uma data e respectivas vantagens e desvantagens (a melhor solução depende das operações que queremos realizar!): Record com três nºs naturais com o ano, mês e dia Um nº natural com a data codificada no formato YYYYMMDD Um nº natural com dias decorridos desde uma data de referência (e.g. 1/1/1) Criar uma data dado o ano mês e dia fácil relativamente fácil difícil Obter o ano, mês e dia de uma data Datas válidas nem todas as datas são válidas todas as datas são válidas Comparar datas Subtrair datas Somar ou subtrair um certo número de dias a uma data

32 Modelação do tipo “Date” (2)
Modelação do tipo Date com records: class DateUtils types public Date :: year : nat month: nat day : nat inv d == IsValidDate(d.year, d.month, d.day) ; functions public static IsValidDate(year, month, day : nat) res : bool == year >= 1 and month >= 1 and month <= 12 and day >= 1 and day <= DaysOfMonth(year, month); public static IsLeapYear(year: nat) res : bool == year mod 4 = 0 and year mod 100 <> 0 or year mod 400 = 0; ... invariante exemplo de instância do tipo Date só aqui termina a definição do tipo Date

33 Modelação do tipo “Date” (3)
Modelação do tipo Date com records (cont.): public static DaysOfMonth(year, month: nat) res : nat == ( cases month : , 3, 5, 7, 8, 10, 12 -> 31, , 6, 9, 11 -> 30, > if IsLeapYear(year) then 29 else end ) pre month >= 1 and month <= 12; public static IsAfter(d1, d2: Date) res : bool == d1.year > d2.year or d1.year = d2.year and d1.month > d2.month or d1.year = d2.year and d1.month = d2.month and d1.day > d2.day; end DateUtils Exemplo de uma data: mk_Date(2005, 10, 25)

34 Modelação do tipo “Date” (4)
Modelação do tipo Date com nº natural no formato YYYYMMDD: class DateUtils types public Date = nat inv d == IsValidDate(d div 10000, (d div 100) mod 100, d mod 100); functions IsValidDate, DaysOfMonth, IsLeapYear como antes public MakeDate(year : nat, month : nat, day : nat) res : Date == year * month * day pre IsValidDate(year, month, day); public Year(d : Date) res : nat == d div 10000; public Month(d : Date) res : nat == (d div 100) mod 100; public Day(d : Date) res : nat == d mod 100; public IsAfter(d1: Date, d2: Date) res : bool == d1 > d2; end DateUtils

35 Modelação do tipo “Sexo”
É um tipo enumerado Tipos enumerados são modelados através de “Union” (|) e “Quote” (<>) class Pessoa types Sexo = <Masculino> | <Feminino>; end Pessoa

36 Modelação de atributos e associações unidireccionais
class Pessoa types public Sexo = <Masculino> | <Feminino>; public Date = DateUtils`Date; sinónimo local public String = StringUtils`String; sinónimo local instance variables private nome: String; private sexo: Sexo; private dataNascimento : Date; private dataFalecimento : [Date] := nil; private pai: [Pessoa] := nil; private mae: [Pessoa] := nil; ` (acento grave) serve para aceder a membro duma classe Atributos obrigatórios Atributo opcional (admite nil, i.e. valor não definido) Associações unidireccionais para 0 ou 1 (usa rolenames)! Variáveis de instância guardam referências para objectos, e não os próprios objectos

37 Modelação (formalização) de restrições com invariantes
-- O pai tem de ser do sexo masculino (R1) e ter data de nascimento -- anterior (R4) inv pai <> nil => pai.sexo = <Masculino> and DateUtils`IsAfter(dataNascimento, pai.dataNascimento); -- A mãe tem de ser do sexo feminino (R2) e ter data de nascimento inv mae <> nil => mae.sexo = <Feminino> and DateUtils`IsAfter(dataNascimento, mae.dataNascimento); -- O falecimento não pode ser anterior ao nascimento (R3) inv dataFalecimento <> nil => not DateUtils`IsAfter(dataNascimento, dataFalecimento); Restrições inter- objecto Restrições intra- objecto É aqui que se começa a tirar vantagem de VDM++ …

38 Modelação de comportamento com operações
Pessoa -pai - nome: String - dataNascimento: Date - sexo: Sexo - dataFalecimento[0..1]: Date -mae 0..1 0..1 * * + Pessoa(nome: String, dataNascimento: Date, sexo: Sexo, pai : [Pessoa], mae: [Pessoa], dataFalecimento: [Date]) + Falece(dataFalecimento: Date) + GetNome() : String + GetSexo() : Sexo + GetDataNascimento() Date + GetPai() : [Pessoa] + GetMae() : [Pessoa] + GetDataFalecimento() : [Date] Construtores Operações de actualização Operações de consulta Neste exemplo as operações são triviais ...

39 Modelação de comportamento com operações
class Pessoa ... operations -- construtor public Pessoa (nome0: String, sexo0: Sexo, dataNascimento0: Date, pai0, mae0: [Pessoa], dataFalecimento0: [Date]) res : Pessoa == ( nome := nome0; sexo := sexo0; dataNascimento := dataNascimento0; pai := pai0; mae := mae0; dataFalecimento := dataFalecimento0; return self ) pre -- conjunção dos invariantes, aplicados aos argumentos! (pai0 <> nil => pai0.sexo = <Masculino> and DateUtils`IsAfter(dataNascimento0, pai0.dataNascimento)) and (mae0 <> nil => mae0.sexo = <Feminino> and DateUtils`IsAfter(dataNascimento0, mae0.dataNascimento)) and (dataFalecimento0 <> nil => not DateUtils`IsAfter(dataNascimento0, dataFalecimento0)); Nome do argumento diferente da variável de instância respectiva, para desambiguar (não se pode desambiguar com self. …) Em VDM++, o construtor devolve o próprio objecto (chamado “self” em vez de “this”) Fim aula 28/10/2005. Formalização de pré-condições

40 Modelação de comportamento com operações
… actualizações public Falece(dataFalecimento1 : Date) == dataFalecimento := dataFalecimento1 pre not DateUtils`IsAfter(dataNascimento, dataFalecimento1); -- consultas public GetNome() res : String == return nome; public GetSexo() res : Sexo == return sexo; public GetDataNascimento() res : Date == return dataNascimento; public GetPai() res : [Pessoa] == return pai; public GetMae() res : [Pessoa] == return mae; public GetDataFalecimento() res : [Date] == return dataFalecimento; end Pessoa Pós-condições não foram definidas pois são trivialmente semelhantes ao corpo das operações!

41 Modelação de associações bidireccionais
Dada uma pessoa, pretende-se navegar não só para o pai e a mãe, mas também para os filhos (em sentido inverso) Pessoa - nome: String - dataNascimento: Date - sexo: Sexo - dataFalecimento[0..1]: Date -pai -mae + GetFilhos() : set of Pessoa 0..1 0..1 * filhos filhos * {or} Em rigor, rolename não devia ser igual pelas duas associações, mas a verdade é que não há problema, pois as associações são mutuamente exclusivas nesta direcção! Quando não tem seta num dos extremos, a associação é bidireccional (navegável nos dois sentidos)

42 Modelação de associações bidireccionais
VDM++ (tal como Java, C#, etc.) não tem suporte directo para associações bidireccionais, é necessário modelar por duas associações unidireccionais, com restrições adicionais (invariantes) para garantir a consistência Nas variáveis de instância da classe Pessoa, acrescenta-se private filhos: set of Pessoa := { }; É necessário acrescentar invariantes para garantir a consistência entre as referências para “filhos”, “pai” e “mae”: inv sexo = <Masculino> => forall f in set filhos & f.pai = self; inv pai <> nil => self in set pai.filhos; inv sexo = <Feminino> => forall f in set filhos & f.mae = self; inv mae <> nil => self in set mae.filhos; Associação para 0 ou mais é modelada com “set of” Verifica-se que

43 Modelação de associações bidireccionais
O construtor preenche “filhos”, garantindo a consistência public Pessoa (nome0 : String, sexo0 : Sexo, dataNascimento0 : Date, pai0, mae0: [Pessoa], dataFalecimento0 : [Date]) res : Pessoa == ( nome := nome0; sexo := sexo0; dataNascimento := dataNascimento0; dataFalecimento := dataFalecimento0; pai := pai0; mae := mae0; filhos := { }; if pai0 <> nil then pai0.AddFilho(self); if mae0 <> nil then mae0.AddFilho(self); return self ) pre (como antes); private AddFilho(filho: Pessoa) == filhos := filhos union {filho}; public GetFilhos() res : set of Pessoa == return filhos;

44 Modelação de associações bidireccionais
Limitação de VDM++: O construtor vai quebrar os invariantes destinados a garantir a consistência das associações pai/filhos e mae/filhos! Isto acontece porque, infelizmente, na versão actual de VDM++ e VDM Tools, os invariantes são verificados após cada atribuição, em vez de o serem unicamente no final da execução da operação! Em geral, não são bem suportados invariantes inter-objecto (relacionando diferentes objectos) em que os objectos relacionados têm de ser actualizados em simultâneo Solução de recurso: comentar os invariantes (servem apenas como “lembrete”), e garantir que as operações não violam esses invariantes

45 Modelação de associações ordenadas
A um pessoa corresponde um conjunto ordenado (sequência sem repetições) de zero ou mais ex-cônjuges (por ordem cronológica) Pessoa +Casam(p1: Pessoa, p2: Pessoa) +DivorciamSe(p1:Pessoa, p2:Pessoa) +GetConjuge() : [Pessoa] +GetExConjuges(): seq of Pessoa -conjuge {ordered} * -exConjuges 0..1 0..1 * {sexos opostos} {sexos opostos} As associações são simétricas: se A é (ex)cônjuge de B, então B é (ex)cônjuge de A! Um associação simétrica é automaticamente bidireccional!

46 Modelação de associações ordenadas
Associações ordenadas são modeladas com sequências (seq) As sequências admitem repetidos Se não pretendermos repetidos, acrescenta-se um invariante class Pessoa instance variables private conjuge : [Pessoa] := nil; private exConjuges : seq of Pessoa := [ ] ; -- simetria de "conjuge" e "exConjuges" -- inv conjuge <> nil => conjuge.conjuge = self; -- inv forall ex in set elems exConjuges & self in set elems ex.exConjuges; -- (ex)conjuges sao de sexos opostos inv conjuge <> nil => self.sexo <> conjuge.sexo; inv forall ex in set elems exConjuges & self.sexo <> ex.sexo; -- ausência de repetidos em exConjuges (interessa?) inv forall i, j in set inds exConjuges & i <> j => exConjuges(i) <> exConjuges(j); Comentado por limitação de VDM++

47 Modelação de associações ordenadas
operations public static Casam(p1: Pessoa, p2: Pessoa) == ( p1.SetConjuge(p2); p2.SetConjuge(p1) ) pre p1.conjuge = nil and p2.conjuge = nil and p1.sexo <> p2.sexo; public static DivorciamSe(p1: Pessoa, p2: Pessoa) == ( p1.ConjugeParaExConjuge(); p2.ConjugeParaExConjuge() ) pre p1.conjuge = p2 and p2.conjuge = p1; private ConjugeParaExConjuge() == ( exConjuges := exConjuges ^ [conjuge]; conjuge := nil ); private SetConjuge(conjuge1: Pessoa) == conjuge := conjuge1; public GetConjuge() res : [Pessoa] == return conjuge; public GetExConjuges() res : seq of Pessoa == return exConjuges; end RegistoCivil Há uma inconsistência na especificação se uma pessoa se divorciar duas vezes da mesma pessoa! Qual é? Como se corrige?

48 Integração com Rational Rose
Rational Rose – ferramenta de modelação visual em UML líder de mercado (agora da IBM) Necessário instalar o addin “The VDM++ Toolbox v6.8.6-Lite\uml\inst_addin.exe” Permite exportar/importar diagramas de classes

49 Integração com Rational Rose

50 Referências e leituras adicionais
Manual de VDM++ (langmanpp_a4.pdf) Manual de VDMTools (usermanpp_a4.pdf) Modelling Systems: Practical Tools and Techniques in Software Development, John Fitzgerald and Peter Gorm Larsen, Cambridge University Press, 1998.  (existe na biblioteca da FEUP) Validated Designs for Object-oriented Systems. John Fitzgerald, Peter Gorm Larsen, Paul Mukherjee, Nico Plat and Marcel Verhoef. ISBN: Springer Verlag, New York Specification of Software Systems, V.S. Alagar and K. Periyasamy, ISBN: , Springer, 1998.


Carregar ppt "Jpf@fe.up.pt www.fe.up.pt/~jpf Métodos Formais em Engenharia de Software Especificação Baseada em Modelos em VDM++ (2ª parte) João Pascoal Faria jpf@fe.up.pt."

Apresentações semelhantes


Anúncios Google