Automatizando a criação de uma base de conhecimento em Prolog para gerenciar os acessos a um site

Autor: Rafael Alencar <rafael.alencar at eafb.org.br>

Introdução

O presente artigo pretende demonstrar o uso da linguagem de programação lógica Prolog
para a construção de uma base de conhecimento sobre os acessos a um
site. Esta base será criada de forma dinâmica e automatizada, agregando
novas informações a cada acesso ao site. Será possível formular
diversas consultas com alto nível de complexidade e que necessitem de
certo grau de inferência, de forma simples e relativamente próxima da
linguagem natural. A base de conhecimento será capaz de responder, por
exemplo, questões como:

"Quais IPs de classe A acessaram o site em um final de semana à noite, entre os meses de janeiro e março do ano de 2004?"

Inicialmente o artigo abordará os conceitos básicos de programação em
lógica e da linguagem Prolog, visto que esta segue um paradigma
declarativo, opondo-se ao tradicional paradigma procedural, presente
nas linguagens mais difundidas como C, C++ e Java. Enquanto no
paradigma procedural se define como um problema deve ser resolvido, no
declarativo define-se apenas que informações são conhecidas e o quê
deve ser feito, deixando-se a cargo da linguagem o modo de resolução do
problema – o que é realizado de forma transparente ao usuário.

Também será abordado o processo de instalação e uso do compilador GNU Prolog,
antes do tópico que demonstrará a construção e manipulação da base de
conhecimento. Esta será composta por um arquivo texto, inicialmente
possuindo alguns fatos e regras, no qual serão apensadas novas
informações a cada visita à página web.

A linguagem Prolog

Prolog é uma linguagem de programação lógica matemática. Ela foi criada
em 1972 na Universidade de Aix-Marseille, por um grupo de pesquisadores
sob a liderança de Alain Colmerauer. O termo Prolog é um acrônimo para PROgrammation en LOGique,
uma vez que o programador precisa apenas descrever a estrutura lógica
do problema a ser solucionado, deixando a cargo da linguagem a forma
como este será solucionado.

O objetivo inicial do Prolog era a resolução de problemas baseados em
linguagem natural, ou seja, linguagens faladas pelos seres humanos.
Portanto, possui algumas oposições básicas em relação às linguagens de
programação tradicional, como: processamento simbólico ao invés de
processamento numérico, soluções heurísticas ao contrário de soluções
algorítmicas e capacidade de apresentar múltiplas soluções e soluções
parcialmente corretas para um determinado problema.

Essas características, aliadas à facilidade de representação, inserção
e recuperação de conhecimento, capacidade de dedução e recursividade
natural tornam a linguagem Prolog extremamente poderosa para resolução
de problemas como:

  • Análise de teoremas matemáticos;
  • Inteligência Artificial;
  • Sistemas especialistas;
  • Processamento de linguagem natural;
  • Redes semânticas;
  • Banco de dados etc.

A estrutura fundamental da linguagem Prolog são os fatos, as regras e as consultas. Estes conceitos serão introduzidos, em um nível básico, nos tópicos abaixo, conjuntamente com a noção de estruturas:

Fatos

Os fatos determinam informações e relações entre os
objetos descritos, e denotam para o sistema uma verdade incondicional.
Por exemplo, o horário de acesso a um site pode ser definido pelo
seguinte fato:

acessou(‘76.74.248.57′, ’21:40’).

O termo "acessou", também chamado de predicado, define uma relação, que
possui dois argumentos, sendo eles dois objetos: um endereço IP e um
horário de acesso. Em Prolog, os predicados e os objetos devem iniciar
com letra minúscula ou número. Os argumentos devem ser separados por
vírgulas, e o fato deve ser encerrado com ponto final. É importante
notar que acessou(‘76.74.248.57′, ’21:40′) não equivale a
acessou(’21:40’, ‘76.74.248.57’).

Regras

Enquanto os fatos definem informações incondicionalmente verdadeiras, as regras podem ser verdadeiras, caso determinadas condições sejam satisfeitas. Em Prolog, pode-se definir se um IP pertence à classe A, pela seguinte regra:

classe_a(OCT1, OCT2, OCT3, OCT4) :-
   OCT1 > 0, OCT1 < 126;
   OCT1 = 126, OCT2 = 0, OCT3 = 0, OCT4 = 0.

Onde "classe_a" é o nome da regra, e "OCT1", "OCT2", "OCT3" e "OCT4"
são variáveis (iniciam com letra maiúscula) que representam os quatro
octetos que compõe um endereço IP. O símbolo ":-" significa se,
e separa a regra em conclusão à esquerda e corpo à direita. No corpo da
classe, a vírgula representa uma conjunção, semelhante ao operador
lógico AND. O ponto-e-vírgula representa uma disjunção, assemelhando-se
ao operador lógico OR.

Assim, a regra acima define que um IP é de classe A se o valor de seu primeiro octeto estiver entre 1 e 125 ou se ele for 126 e os demais octetos possuírem valor 0.

Consultas

Uma consulta é uma seqüencia de um ou mais objetivos
propostos ao sistema pelo usuário. Para obter uma resposta, o Prolog
busca satisfazer os objetivos que compõe a consulta, a partir de
deduções diretas ou indiretas a partir de sua base de conhecimento.
Assim, a consulta do usuário pode ser entendida como um teorema a ser
provado, com base nos axiomas representados pelo conjunto das cláusulas
que constituem o programa.

Se a consulta proposta for verdadeira, o sistema retornará yes, e, caso contrário, no.
Caso hajam variáveis envolvidas na consulta, e esta seja verdadeira, o
sistema retornará o valor ou conjunto de valores das variáveis para os
quais a consulta será válida.

As consultas podem ser realizadas no modo interativo do Prolog, que inicia-se com o operador ?-.
Seguem algumas consultas relativas ao fato e à regra definidos nos
exemplos acima (% e /**/ são comentários, respectivamente, de uma linha
e de múltiplas linhas):

% "o IP 76.74.248.57 acessou o site às 21:40 horas?"
?- acessou(‘76.74.248.57′, ’21:40’).
yes

% "a que horas o IP 76.74.248.57 acessou o site?"
?- acessou(‘76.74.248.57’, Horario).
Horario = ’21:40′
yes

% "o IP 76.74.248.57 é de classe A?"
?- classe_a(200, 131, 10, 131).
no

Estruturas

Estruturas são objetos que possuem vários
componentes. Estes, por sua vez, também podem ser estruturas. Por
exemplo, a data de acesso a um site pode ser armazenada sob a forma de
uma estrutura com quatro componentes: dia, mês, ano e dia por extenso.
Estes objetos devem ser agrupados em uma única estrutura por um símbolo
funcional (functor), que no exemplo abaixo será "data":

data(27, 12, 2009, domingo).

No exemplo, os 4 argumentos são constantes (lembrando que variáveis
iniciam-se com letra maiúscula ou _). Em Prolog todos os objetos
estruturados são árvores. No caso do exemplo anterior, o functor
"data" é a raiz, e os quatro argumentos são as folhas da árvore.
Podemos tornar as buscas de informações em estruturas mais genéricas e
eficientes utilizando-se a variável anônima "_". Seguem alguns exemplos
de consulta relativos a estrutura definida acima:

% "qual dia da semana foi 27/12/2009?"
?- data(27, 12, 2009, NOME).
NOME = domingo
yes

% "que dia caiu em um domingo?"
?- data(DIA, _, _, domingo).
DIA = 27
yes

GNU Prolog

Para a demonstração do tema proposto neste artigo será utilizado o compilador GNU Prolog,
que na presente data encontra-se na versão 1.3.0. A linguagem Prolog
não possui grande padronização, e existem diversas outras
implementações, com alguns recursos e sintaxes diferentes, como o
SWI-Prolog e o Visual Prolog.

Em um sistema operacional Linux Debian-like, podemos instalar o GNU Prolog com o comando:

# aptitude install gprolog

Um programa em Prolog deve ser escrito em um arquivo texto,
geralmente com a extensão .pl, o que as vezes causa confusão com
arquivos Perl. Uma vez instalado o GNU Prolog, podemos testá-lo criando
um arquivo teste.pl, com o seguinte conteúdo:

% programa de teste na linguagem Prolog

acessou(ip(200, 131, 10, 131), data(27, 12, 2009, domingo)).
acessou(ip(127, 0, 0, 1), data(22, 12, 2009, terca)).

classe_a(OCT1, OCT2, OCT3, OCT4) :-
OCT1 > 0, OCT1 < 126;
OCT1 = 126, OCT2 = 0, OCT3 = 0, OCT4 = 0.

final_de_semana(data(_, _, _, DIA)) :-
   DIA = sabado; DIA = domingo.

Para executar o GNU Prolog, usa-se o comando:

$ gprolog
GNU Prolog 1.3.0
By Daniel Diaz
Copyright (C) 1999-2007 Daniel Diaz
| ?-

O programa que será compilado para a consulta deve ser especificado com o comando consult, passando-se o caminho completo do arquivo teste.pl:

?- consult(‘caminho/teste.pl‘).
compiling teste.pl for byte code…
teste.pl compiled, 11 lines read – 2039 bytes written, 22 ms

A partir deste ponto já é possível realizar consultas, como nos exemplos abaixo:

% "que IP acessou o site em um domingo do ano de 2009?"
?- acessou(IP, data(_, _, 2009, domingo)).
IP = ip(200,131,10,131)
yes

% "que IP de classe A acessou o site em um domingo do ano de 2009?"
?- acessou(ip(OCT1, OCT2, OCT3, OCT4), data(_, _, 2009, domingo)), classe_a(OCT1, OCT2, OCT3, OCT4).
no

% "qual o primeiro octeto dos ips que acessaram o site?"
?- acessou(ip(OCT1, _, _, _), _).
OCT1 = 127 ? ;
OCT1 = 200
yes

Deve-se observar que, quando uma variável pode possuir mais de um valor
(como no terceiro exemplo), o usuário deve pressionar ";" para ver o
próximo valor, <ENTER> para finalizar a consulta e "a" para ver
todas os resultados.

É possível visualizar o conteúdo da base pelo comando listing:

?- listing.
classe_a(A, B, C, D) :-
   (   A > 0,
       A < 126
       ;   A = 126,
       B = 0,
       C = 0,
       D = 0
   ).

final_de_semana(data(_, _, _, A)) :-
   (   A = sabado
       ;   A = domingo
   ).

acessou(ip(200, 131, 10, 131), data(27, 12, 2009, domingo)).
acessou(ip(127, 0, 0, 1), data(22, 12, 2009, terca)).

(4 ms) yes

Para finalizar o GNU Prolog, basta digitar o comando:

?- halt.

Gerenciando os acessos a um site

Regras e estruturas

Este tópico descreverá em detalhes a implementação de uma base de
conhecimento em Prolog que agrega informações a cada acesso a um site,
para posteriores consultas. O primeiro passo será a criação das regras
iniciais da base de conhecimento e a definição de como será a estrutura
utilizada para representar os acessos ao site, ou seja, como será
representado o conhecimento. Tomando-se como pertinentes as informações
do IP que acessou a página e a data e o horário em que este acesso
ocorreu, pode-se definir a seguinte estrutura para os acessos:

acesso(ip(octeto1, octeto2, octeto3, octeto4), data(dia, mes, ano, dia_da_semana), horario(hora, minuto)).

É possível criar uma variedade de regras para a base de conhecimento.
Abaixo serão definidas as principais, relacionadas ao endereço IP, data
e horário. Elas deverão ser salvas no arquivo BC.pl, que será a base de
conhecimento utilizada.

/*** regras relacionadas ao IP ***/

% classe A: 1.0.0.0 – 126.0.0.0
classe_a(ip(OCT1, OCT2, OCT3, OCT4)) :-
   OCT1 > 0, OCT1 < 126;
   OCT1 = 126, OCT2 = 0, OCT3 = 0, OCT4 = 0.

% classe B: 128.0.0.0 – 191.255.0.0
classe_b(ip(OCT1, _, OCT3, OCT4)) :-
   OCT1 > 127, OCT1 < 191;
   OCT1 = 191, OCT3 = 0, OCT4 = 0.

% classe C: 192.0.0.0 – 223.255.255.254
classe_c(ip(OCT1, _, _, OCT4)) :-
   OCT1 > 191, OCT1 < 223;
   OCT1 = 223, OCT4 < 255.

% classe D: 224.0.0.0 – 239.255.255.255
classe_d(ip(OCT1, _, _, _)) :-
   OCT1 > 223, OCT1 < 240.

% classe E: 240.0.0.0 – 247.255.255.254
classe_e(ip(OCT1, _, _, OCT4)) :-
   OCT1 > 239, OCT1 < 247;
   OCT1 = 247, OCT4 < 255.

/*** regras relacionadas a data ***/

final_de_semana(DIA_SEMANA) :-
   DIA_SEMANA = sabado;
   DIA_SEMANA = domingo.

/*
   O operador \+ representa a negação por falha. Deve-se observar
   que o Prolog assume que todos os dados que são necessarios para
   resolver uma consulta estao na base de conhecimento, na chamada
   "hipotese do mundo fechado". Assim, questoes sobre fatos nao
   conhecidos retornam FALSO, e sua negacao retorna VERDADEIRO, o
   que pode nao ser coerente com o que se espera da base:

   ?- dia_de_semana(feriado).
   yes
*/

dia_de_semana(DIA_SEMANA) :-
   \+ final_de_semana(DIA_SEMANA).

/*** regras relacionadas ao horario ***/

% 06:00h – 11:59h
manha(HOR) :-
   HOR > 5, HOR < 12.

% 12:00h – 17:59h
tarde(HOR) :-
   HOR > 11, HOR < 18.

% 06:00h – 12:00h
noite(HOR) :-
   \+ manha(HOR),
   \+ tarde(HOR).

/*** abaixo serao adicionados dinamicamente os registros de acesso ao site, sob a forma de estruturas Prolog ***/

A página de testes

Para a página web que será utilizada, será necessário instalar um
servidor web, no exemplo o Apache, e a linguagem PHP, que será
empregada em um trecho da página para apensar informações na base
Prolog, a cada acesso. Em sistemas baseados em Debian, segue o comando
para instalação:

# aptitude install apache2 php5

Logo após, a página index.php deverá ser criada no diretório /var/www/,
que por padrão é a pasta raiz do servidor Apache. Como o que importa é
o código PHP que adicionará conteúdo a base de conhecimento em Prolog,
e não o layout e conteúdo da mesma, ela poderá ter a seguinte
estrutura:

<html>
<head><title>Bem-vindo!</title></head>
<body>
<h1>Obrigado pela visita!</h1>
<!– Conteúdo da página –>

<?php
// aqui ficará o código em php
?>

</body>
</html>

Segue abaixo o código em PHP comentado:

<?php
// abre a base de conhecimento para adicionar novos fatos sobre os acessos
$bc = fopen("BC.pl", "a");

// obtém o IP do visitante
$ip = $_SERVER[‘REMOTE_ADDR’];

// se o acesso foi realizado por localhost, define o ip como 127.0.0.1
if($ip == "localhost" || $ip =="::1") $ip = "127.0.0.1";

// separa o IP em octetos
$octetos = split("\.", $ip);

// escreve no arquivo a estrutura "acesso"
fwrite($bc, sprintf("acesso(ip(%s, %s, %s, %s), ", $octetos[0], $octetos[1], $octetos[2], $octetos[3]));
// obtém o tempo local e define os dias da semana em minúsculas e sem acento
$tempo = localtime(time(), 1);
$nomes = array("domingo", "segunda", "terca", "quarta", "quinta", "sexta", "sabado");

// escreve no arquivo as estruturas "data" e "horário"
fwrite($bc, sprintf("data(%s, %s, %s, %s), ", date(d), date(m), date(Y), $nomes[$tempo[tm_wday]]));
fwrite($bc, sprintf("horario(%s, %s)).\n", date(H), date(i)));

// fecha o arquivo
fclose($bc);
?>

Conforme foi mostrado, o arquivo BC.pl será a base de conhecimento, e
deverá inicialmente ser criado na pasta /var/www/ e possuir as regras
definidas acima. A medida que a página index.php for acessada, serão
inseridos novos fatos, relativos às visitas ao site.

Testando a base de conhecimento

A partir do momento em que o
arquivo BC.pl possuir fatos relativos às visitas ao site, será
possível, através do GNU Prolog, realizar diversas consultas. Bastará
determinar que o arquivo a ser consultado será o /var/www/BC.pl, antes
de se formular questões.

GNU Prolog 1.3.0
By Daniel Diaz
Copyright (C) 1999-2007 Daniel Diaz
| ?- consult(‘/var/www/BC.pl’).
compiling /var/www/BC.pl for byte code…
/var/www/BC.pl compiled, 65 lines read – 5131 bytes written, 24 ms

Agora, questões complexas como o exemplo proposto na introdução deste artigo podem ser solucionadas de forma simples e natural:

"Quais IPs de classe A acessaram o site em um final de semana à noite, entre os meses de janeiro e março do ano de 2004?"

?- acesso(IP, data(_, MES, 2004, DIA_SEMANA),
horario(H,_)), classe_a(IP), final_de_semana(DIA_SEMANA), noite(H), MES
> 0, MES < 4.

Uma possível resposta válida seria:

DIA_SEMANA = sabado
H = 21
IP = ip(100,0,0,42)
MES = 3

Nota-se que uma base de conhecimento em Prolog, mesmo neste exemplo
simples, permite inserção de informações e suas inter-relações de forma
simples, e, também, fácil recuperação de dados, mesmo quando se
necessita de inferência e cruzamento de informações.

Conclusão

Este artigo pretendeu contribuir com uma pequena demonstração do
emprego criativo de uma linguagem de especificação lógica, que possui
enorme diferença de abordagem em relação às linguagens mais difundidas
atualmente. Aprender um novo paradigma de programação é uma experiência
muito valiosa para profissionais da área de TI, uma vez que expande o
modo de pensar e permite diferentes abordagens para a resolução de
problemas.

A linguagem Prolog é muito mais extensa e poderosa do que foi
apresentado neste artigo, que limitou-se a introduzir noções básicas e
uma aplicação de exemplo. Existem diversos conceitos que não foram
abordados (operadores, listas, bactrackingk, formatação de entrada e saída etc), para se evitar que ele se tornasse muito extenso e complexo.

Aqueles que se interessaram pela linguagem podem estudar pela
referência bibliográfica deste artigo, sendo recomendado o livro
Introdução à programação Prolog, de Luiz Palazzo, em português.

Referências bibliográficas

PALAZZO, Luiz. – Introdução à programação Prolog. Pelotas: Editora da Universidade Católica de Pelotas, 1997.

The GNU Prolog web site
http://www.gprolog.org/

Wikipédia, a enciclopédia livre – Prolog
http://pt.wikipedia.org/wiki/Prolog


http://www.vivaolinux.com.br/artigo/Automatizando-a-criacao-de-uma-base-de-conhecimento-em-Prolog-para-gerenciar-os-acessos-a-um-site

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s