| Anotação Estrutural de Documentos e sua Semântica | ||
|---|---|---|
| Prev | Capítulo 8. Validação Semântica com Modelos Abstractos | Next |
A questão pertinente do momento é: Como se irão especificar as restrições? Em que linguagem?
Como já foi discutido no capítulo anterior, há duas opções: desenvolver uma nova linguagem, ou, utilizar uma existente. Uma vez que o que se está a desenvolver é um protótipo e a escolha de uma linguagem existente pouparia algum trabalho, foi esta a opção escolhida.
Para se poder manipular elementos SGML e especificar restrições sobre eles a escolha natural seria uma linguagem de especificação baseada em modelos. Como já foi exemplificado na secção anterior e em [RAH95], cada definição de um elemento no DTD tem um modelo implícito e cada instância desse elemento pode ser convertida numa expressão algébrica desse modelo. No protótipo descrito mais à frente Figura 8-2, utiliza-se uma ferramenta de conversão automática, dtd2cam, para traduzir o DTD para um modelo na linguagem de especificação de SETs, CAMILA [ABNO97, BA95]. Depois desta conversão, o analista pode escrever as restrições em CAMILA uma vez que estas são naturalmente integradas no modelo calculado automaticamente a partir do DTD. Em termos práticos, cada restrição irá corresponder a um predicado que deverá sempre retornar o valor booleano verdade, caso contrário uma mensagem de erro terá de ser enviada ao utilizador.
Na nossa implementação, as restrições são especificadas por um conjunto de regras; cada regra, é um par formado por uma condição (a negação da respectiva restrição) e a reacção que lhe fica associada.
Os casos práticos trabalhados são de alguma complexidade e têm problemas muito específicos, o que os torna impróprios para exemplificar o sistema. Assim, recorre-se a um exemplo mais pequeno, com complexidade suficiente para ilustrar as ideias e o protótipo.
Exemplo 8-2. Reis e Decretos
Um documento é composto por uma lista de decretos proclamados por um determinado rei.
Apresenta-se a seguir o respectivo DTD:
<!DOCTYPE rei [
<!ELEMENT rei -- (nome, cognome, datan,
datam,decreto+)>
<!ELEMENT decreto -- (data, corpo)>
<!ELEMENT (nome,cognome,datan,datam,data)
-- (#PCDATA)>
<!ATTLIST (datan,datam,data)
valor CDATA #IMPLIED
tipo CDATA #FIXED date>
<!ELEMENT corpo -- (#PCDATA)>
]>Repare-se na declaração dos atributos tipo e valor para os elementos relacionados com datas. O atributo tipo tem um valor fixo que será usado mais tarde pelo processador de restrições (o validador semântico) para inferir o tipo do seu conteúdo. O atributo valor será utilizado para guardar a forma normalizada das datas; o processador usará o valor deste atributo, sempre que este estiver instanciado, em vez do conteúdo do elemento.
O texto seguinte é uma instância do referido documento, escrita de acordo com o DTD.
<rei>
<nome>D.Dinis</nome>
<cognome>O Lavrador</cognome>
<datan valor='1270.09.23'>23 de Setembro de
1270</datan>
<datam valor='1370.09.23'>23 de Setembro de
1370</datam>
<decreto>
<data valor='1300.07.15'>Ao décimo quinto dia
do mês de Agosto do ano 1300:</data>
<corpo>A partir do dia de hoje, apenas
bicicletas poderão circular na cidade de
Braga.</corpo>
</decreto>
<decreto>
<data>1389.11.03</data>
<corpo>O McDonalds passará a vender vinho verde
em vez de COCA-COLA.</corpo>
</decreto>
</rei>Observando o DTD e a respectiva instância pode-se identificar de imediato algumas condições que devem ser verificadas:
A data de cada decreto deverá sempre estar compreendida entre a data de nascimento (datan) e a data de falecimento (datam) do respectivo rei.
O nome do rei deverá constar da nossa base de dados de pessoas famosas.
Para se adicionar estas condições de contexto ao nosso sistema de validação, adiciona-se ao DTD a declaração de entidades externas onde as condições estarão especificadas. Este método para associar restrições ao DTD representa apenas uma das três opções possíveis para o fazer e que são discutidas mais à frente (Secção 8.3).
<!DOCTYPE rei [ <!NOTATION CAM SYSTEM "camila.exe"> <!ELEMENT rei - - (nome,cognome,datan,datam,decreto+)> <!ENTITY rei-rest SYSTEM "rei.cam" NDATA CAM> ... <!ELEMENT decreto - - (...)> <!ENTITY decreto-rest SYSTEM "decreto.cam" NDATA CAM> ]>
Neste caso, utiliza-se uma entidade para cada conjunto de restrições.
No contexto do exemplo, pode-se escrever as seguintes restrições (utilizando a linguagem CAMILA):
rei(r) =
{ if(nome_(r) notin PessFamDB
→ nome_(r) ++ "Não existe..."),
if(datan_(r) > datam_(r)
→ nome_(r) ++ "Morreu antes de nascer."),
if(datam_(r) - datan(r) > 120
→ nome_(r) ++ "Viveu demais!"),
if(!all( x←decreto_l(r) :
datan_(r) < data_(x) /\
data_(x) < datam_(r))
→ nome_(r) ++ "fez um decreto fora da sua vida!")
};Se o modelo instanciado tivesse os seguintes valores:
r = ("D.Dinis", "O Lavrador",
"1265.06.24", "1211.04.12", ...)datan_(r) = "1265.06.24"
datam_(r) = "1211.04.12"
Este conjunto de valores faria disparar a regra
if(datan_(r) > datam_(r)que produziria como resultado a concatenação ("++") do nome do rei ("nome_(r)") com a string "Morreu antes de nascer.".