3 O M´etodo B para Desenvolvimento Formal de Software
3.1.5 Substituic¸˜oes generalizadas
Nesta sec¸˜ao introduzimos substituic¸˜oes mais elaboradas, denominadas “generalizadas” que, como a pr´opria denominac¸˜ao sugere, s˜ao obtidas a partir da generalizac¸˜ao do conceito de substituic¸˜ao simples visto na sec¸˜ao anterior. Apresentamos aqui apenas algumas substituic¸˜oes utilizadas com maior freq¨uˆencia em uma m´aquina.
Substituic¸˜ao de pr´e-condic¸˜ao
Voltemos ao exemplo do contador e vamos supor que a operac¸˜ao de incremento com parˆametro n˜ao tivesse pr´e-condic¸˜ao:
increment (n) b=
BEGIN value := value + n END;
Nesse caso, o usu´ario da operac¸˜ao poderia tentar passar um valor inv´alido no parˆametro n, por exemplo, um valor superior a 100. Isto obviamente quebraria o invariante da m´aquina e, conseq¨uentemente, a especificac¸˜ao como um todo, uma vez que os conceitos fundamentais da especificac¸˜ao, descritos no invariante, n˜ao seriam satisfeitos. Assim, para que o usu´ario seja in- formado dessas restric¸˜oes, o especificador deve tornar expl´ıcito quais s˜ao as pr´e-condic¸˜oes que devem ser satisfeitas antes que se tente “execut´a-la”. Isto ´e feito atrav´es de uma substituic¸˜ao generalizada denominada substituic¸˜ao de pr´e-condic¸˜ao. Sendo P um predicado e S uma substituic¸˜ao, a generalizac¸˜ao de pr´e-condic¸˜ao tem a forma:
PRE P THEN S END
No nosso exemplo, com pr´e-condic¸˜ao, temos:
increment (n) b=
PRE n ∈ INT ∧ n > 0 ∧ value + n ≤ 100 THEN value := value + n
END;
Uma interpretac¸˜ao informal da especificac¸˜ao desta operac¸˜ao seria: “Se o usu´ario da operac¸˜ao passar no seu parˆametro n uma vari´avel inteira, maior que 0 e que somada `a vari´avel
valuen˜ao resulte em um valor superior a 100 (valor m´aximo que o contador pode atingir), ent˜ao a execuc¸˜ao da operac¸˜ao manter´a a m´aquina em um estado v´alido. Caso contr´ario, o resultado da execuc¸˜ao da operac¸˜ao ´e imprevis´ıvel”.
Formalmente, tendo uma substituic¸˜ao da forma PRE P THEN S END, para que esta possa ser aplicada e que se estabelec¸a uma p´os-condic¸˜ao R, devemos ter:
[PRE P THEN S END]R⇔ P ∧ [S]R
Para o caso no qual o predicado R ´e o invariante da m´aquina e revisando a noc¸˜ao de obrigac¸˜ao de prova para uma operac¸˜ao, temos a obrigac¸˜ao de prova que deve ser verificada para uma operac¸˜ao com pr´e-condic¸˜ao:
I∧ P ⇒ [PRE P THEN S END]I
I∧ P ⇒ P ∧ [S]I, que se reduz a:
A sentenc¸a acima diz que se o invariante da m´aquina e a pr´e-condic¸˜ao da operac¸˜ao fo- rem v´alidos antes da aplicac¸˜ao da operac¸˜ao, ent˜ao a substituic¸˜ao da parte then da operac¸˜ao no invariante deve resultar em um predicado verdadeiro.
Substituic¸˜ao m ´ultipla
A substituic¸˜ao m´ultipla ´e utilizada para substituir mais de uma vari´avel em uma operac¸˜ao, ou quando se tem mais de uma vari´avel para ser inicializada na m´aquina. Por exemplo, po- der´ıamos ter uma operac¸˜ao cr´edito que, al´em de armazenar um valor, retornasse o status da operac¸˜ao:
res <-- credito (cr) b= PRE cr ∈ NAT ∧ cr > 0
THEN quantia := quantia + cr || res := 1 END
Na operac¸˜ao acima, temos uma substituic¸˜ao m´ultipla (||). Ressalte-se que n˜ao h´a ordem na aplicac¸˜ao de cada uma das duas substituic¸˜oes simples. Por este motivo, esta substituic¸˜ao n˜ao pode ser utilizada em uma implementac¸˜ao, uma vez que n˜ao pode ser efetivada em c´odigo na maioria das linguagens de programac¸˜ao.
Formalmente, a substituic¸˜ao m´ultipla (para duas vari´aveis) tem a forma: [x := E || y := F]P ou
[x, y := E, F]P, que ´e uma outra forma de notac¸˜ao
Substituic¸˜ao de escolha n˜ao-determin´ıstica
A substituic¸˜ao de escolha n˜ao-determin´ıstica permite que se especifique duas ou mais substituic¸˜oes que correspondem a comportamentos diversos que uma mesma operac¸˜ao de uma m´aquina abstrata pode assumir. A denominac¸˜ao “substituic¸˜ao de escolha” vem do fato de que, no momento da implementac¸˜ao, o implementador da m´aquina deve escolher qual substituic¸˜ao dentre aquelas especificadas ir´a ser implementada. Ou, de outra forma, que comportamento a operac¸˜ao ter´a.
Formalmente, n´os temos:
Onde S e T s˜ao substituic¸˜oes e R ´e um predicado. Podemos interpretar a sentenc¸a acima como: “Qualquer que seja a substituic¸˜ao escolhida pelo implementador entre S e T, ela deve satisfazer ao predicado R”.
A seguir exemplificamos o uso da substituic¸˜ao de escolha em uma operac¸˜ao, retirada de [WORDSWORTH, 1996], que associa uma conta a um cliente. A substituic¸˜ao deixa a crit´erio do implementador a escolha entre associar a conta ao cliente ou retornar a resposta
noroom, que equivale a dizer que n˜ao foi poss´ıvel executar a atribuic¸˜ao da conta. Em CHOICE temos um primeiro caso e na parte OR a outra substituic¸˜ao que pode ser escolhida. Outros casos (substituic¸˜oes) podem ser inclu´ıdos acrescentando-se mais ORs.
resp <-- new_acct_old_cust (cust, acct) b= PRE
cus ∈ customers ∧ acct ∈ ACCTNO ∧ acct ∈ accounts/
THEN
CHOICE resp := success || owner(acct) := cust OR resp := noroom
END END
Substituic¸˜ao condicional
A substituic¸˜ao condicional tem a forma:
[IF P THEN S ELSE T END]R⇔ (P ⇒ [S]R) ∧ (¬P ⇒ [T ])R
Esta substituic¸˜ao pode ser parafraseada por: “Se o predicado P ´e verdadeiro, ent˜ao a substituic¸˜ao S da parte THEN satisfaz ao predicado R. Caso contr´ario, ou seja, quando P for falso, a substituic¸˜ao T da parte ELSE satisfaz ao predicado R”.
A operac¸˜ao abaixo ´e uma vers˜ao da operac¸˜ao cr´edito vista na subsec¸˜ao 3.1.5 que utiliza a substituic¸˜ao condicional na forma IF-THEN-ELSE-END.
res <-- credito (cr) b= PRE cr ∈ NAT
THEN
IF cr > 0
THEN quantia := quantia + cr || res := 1 ELSE res := 0
END END
A substituic¸˜ao condicional tamb´em pode ser utilizada sem o else, na forma IF-THEN-END, ou pode ser encadeada com outras substituic¸˜oes IF por meio da introduc¸˜ao de um ou mais ELSIFs, na forma IF-THEN-ELSIF-THEN-ELSE-END.
Substituic¸˜ao skip
Uma substituic¸˜ao generalizada que n˜ao tem efeito algum ´e a substituic¸˜ao skip, definida por: [skip]R⇔ R
Apesar de ter qualquer efeito, esta substituic¸˜ao ´e bastante usual. Por exemplo, skip pode ser ´util na definic¸˜ao de novas substituic¸˜oes, como o caso da substituic¸˜ao condicional que n˜ao possui a parte else.
IF P THEN S ELSE skip END ≡ IF P THEN S END