Pretendemos construir uma gramática que defina o que é uma mensagem de correiro
electrónico (vulgo email). Vamos começar com uma versão muito simples e,
incrementalmente, acrescentando ``novas funcionalidades''.
%DCG 'email'. Versao 1
email --> cabec, corpo.
cabec --> [from], [:], [nome], dest.
dest --> [to], [nome], [cc], listanomes.
listanomes --> [].
listanomes --> [nome], listanomes.
corpo -->[texto].
Esta versão permite reconhecer, como emails válidos, mensagens do género:
?- email([from,:,nome,to,nome,cc,nome,texto],[]).
yes
Acrescentemos agora um argumento que permita enviar mensagens de conteúdo arbitrário (e não apenas mensagens com conteúdo texto):
%DCG 'email'. Versao 2
email --> cabec, corpo(TXT).
cabec --> [from], [:], [nome], dest.
dest --> [to], [nome], [cc], listanomes.
listanomes --> [].
listanomes --> [nome], listanomes.
corpo(TXT) --> [TXT].
que nos permitirá reconhecer mensagens como
?- email([from,:,nome,to,nome,cc,'Ola'],[]).
yes
Vamos agora imaginar que, dada uma mensagem, estamos não só interessados em saber se ela é, ou não, válida, mas também, no caso de válida, saber a quantas pessoas ela se destina. Para isso vamos usar mais um argumento (Conta):
% DCG 'email'. Versao 3
email(Conta) --> cabec(Conta), corpo(TXT).
cabec(Conta) --> [from], [:], [nome], dest(Conta).
dest(Conta) -->
[to], [nome], [cc], listanomes(C), {Conta is C+1}.
listanomes(0) --> [].
listanomes(N) --> [nome], listanomes(N1), {N is N1+1}.
corpo(TXT) --> [TXT].
Podemos agora 'enviar um email a 4 amigos':
?- email(C,[from,:,nome,to,nome,cc,nome,nome,nome,'ola'],[]).
C = 4
yes