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.