Escolar Documentos
Profissional Documentos
Cultura Documentos
R. M. Teles
Technical Report
C. L. de Carvalho
RT-INF_000-09
December
2009
Relatrio Tcnico
Dezembro
The contents of this document are the sole responsibility of the authors.
O contedo do presente documento de nica responsabilidade dos autores.
Instituto de Informtica
Universidade Federal de Gois
www.inf.ufg.br
Cedric L. de Carvalho
ronneesley@gmail.com
cedric@inf.ufg.br
16/12/2009
Introduo
A linguagem Prolog foi criada em 1972 por Alain Colmerauer e Robert Kowalski. O
nome Prolog signica Programmation en Logique referenciando diretamente o paradigma de
programao em lgica matemtica.
Apesar de ser uma linguagem muito boa para o desenvolvimento de sistemas inteligentes,
poucas pessoas programam neste paradigma, este fato se torna mais claro quando o tema
desenvolvimento de grandes softwares para mesa de trabalho ou para a World Wide Web (Web)
[1].
Nestas duas categorias de softwares existe uma grande preocupao na interao com o
usurio.
Os programas criados na linguagem Prolog resultam em executveis via console, onde
o interrogador deve saber digitar as perguntas ou adicionar novas asseres, utilizando uma
linguagem que no natural atravs dos fatos e regras denidos pelo programador.
Ao contrrio da linguagem Prolog, muitos programas feitos na linguagem Java [7] objetivam uma interface rica com o usurio, tanto na criao de softwares para mesa de trabalho
quanto para Web, principalmente com a criao do JavaFX [6].
Desta forma, pode-se pensar em criar um ncleo de raciocnio na linguagem Prolog e uma
interface grca na linguagem Java. O grande problema como integrar os programas feitos
nestas duas linguagens de paradigmas diferentes.
Existem vrios arcabouos que fazem a integrao ou que simulam as regras de inferncia denidas por um programa Prolog ou denidas diretamente na linguagem Java. Porm
utilizar tais simuladores no so viveis tendo em vista que eles no conseguem simular todos
os comportamentos de inferncia. Logo, a ideia que permite uma melhor continuidade e aprimoramento do software utilizar um programa que interaja diretamente com um interpretador
Prolog.
Esta interao pode ser feita atravs da API (Application Programming Interface) JPL,
uma interface bidirecional entre Prolog e Java, que utiliza a implementao SWI-Prolog [8].
Na seo 2 ser mostrado como compilar os programas necessrios e congurar o ambiente para interao do programa Java com o programa Prolog. Na seo 3 sero apresentadas
as principais classes de integrao com o Prolog. Na seo 4 sero apresentados exemplos de
implementaes de interao de programas escritos na linguagem Java com programas escritos
em Prolog. Finalmente, na seo 5, so apresentadas as consideraes nais.
Congurao do Ambiente
Esta seo apresenta as conguraes necessrias para compilao do SWI-Prolog e integrao com a linguagem Java. Nota-se que no ser objeto de estudo desta seo a instalao
da linguagem Java.
2.1
Instalao do SWI-Prolog
Esta subseo apresenta como instalar o SWI-Prolog no sistema operacional Linux. Antes
de iniciar a instalao necessrio obter o cdigo fonte do SWI-Prolog no endereo http:
//www.swi-prolog.org/download/stable.
Depois de extrair o arquivo, normalmente nomeado como pl-VERSO.tar.gz, onde VERSO o nmero da verso do SWI-Prolog, necessrio executar o comando ./congure, se
nenhuma dependncia de biblioteca for encontrada o comando make pode ser executado em
seguida, aps este comando, necessrio executar comando make install com o usurio root
para instalar o SWI-Prolog no sistema operacional.
2.2
Aps todo o processo de compilao e instalao, para informar ao programa Java que
deve utilizar esta biblioteca necessrio adicionar o parmetro java.library.path com o valor da
pasta "/usr/local/lib/pl-VERSO/lib/ARQUITETURA-linux".
Desta forma o comando de execuo do programa : java -jar meu.jar Djava.library.path="/usr/local/lib/pl-VERSO/lib/ARQUITETURA-linux". Nota-se que o arquivo jpl.jar deve estar no classpath ou ento passado como parmetro ao executvel java.
Para realizar esta congurao no NetBeans [5], necessrio editar as propriedades do
projeto e adicionar o parmetro assim como apresentado na Figura 1.
Esta seo apresenta as principais classes e funes utilizadas na integrao de um programa Java com um programa Prolog. A Figura 2 apresenta estas classes e funes utilizando a
notao da UML (Unied Modeling Language) [2].
3.1
A classe Query
A classe Query utilizada para realizar consultas no Prolog. Uma consulta pode ser aberta
pelo mtodo open() ou fechada pelo mtodo close()1 , quando aberta, mantem uma conexo com
o motor do Prolog.
Como pode ser visto na Figura 2, a classe Query implementa a interface Enumeration
do Java. Desta forma, pode-se chamar sucessivas vezes o mtodo hasMoreElements(), caso a
consulta tenha sucesso ser retornado true, caso contrrio false.
Para obter um elemento do resultado necessrio chamar o mtodo nextElement() que
retorna uma Hashtable. Os elementos da Hashtable so termos da classe Term, mapeados pelos
nomes das variveis que esto associados.
Atravs do mtodo oneSolution() possvel visualizar apenas a primeira soluo. Para
obter todas as solues de uma nica vez, pode-se utilizar o mtodo allSolutions().
1
3.2
A classe Term a classe abstrata para as classes Compound, Atom, Variable e outras
classes menos importantes. Desta forma, no possvel criar uma instncia direta da classe
Term, mas sim de suas subclasses.
Como uma alternativa, pode-se utilizar o mtodo textToTerm() da classe Util para criar
um termo assim como feito no Prolog.
A classe Variable representa uma varivel do Prolog.
3.3
Exemplo de implementao
O primeiro e mais clssico exemplo uma rvore genealgica [3]. A Figura 3 apresenta
a rvore genealgica, onde cada vrtice representa uma pessoa e cada arco representa a relao
genitor.
1
2
3
/ P r i m e i r o n v e l da r v o r e /
pessoa ( joao ) .
pessoa ( maria ) .
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
pessoa ( jose ) .
pessoa ( raimunda ) .
/ Segundo n v e l da r v o r e /
pessoa ( s e b a s t i a o ) .
pessoa ( v i l a n i ) .
/ l t i m o n v e l da r v o r e /
pessoa ( ronneery ) .
pessoa ( ronneesley ) .
/ R e l a e s de g e n i t o r e s /
g e n i t o r ( joao , s e b a s t i a o ) .
g e n i t o r ( maria , s e b a s t i a o ) .
g e n i t or ( jose , v i l a n i ) .
g e n i t o r ( raimunda , v i l a n i ) .
genitor ( sebastiao , ronneery ) .
genitor ( vilani , ronneery ) .
genitor ( sebastiao , ronneesley ) .
genitor ( vilani , ronneesley ) .
4.1
Um primeiro programa que pode ser feito em Java a lista das pessoas declaradas no
programa Prolog. Em Prolog esta lista poderia ser obtida atravs da pergunta pessoa(X), onde
X uma varivel.
O Exemplo 2 apresenta o cdigo Java para a consulta das pessoas. Nota-se que o ambiente
deve estar congurado assim como foi apresentado na seo 2.
1
2
3
4
5
6
7
8
9
10
11
12
13
package j a v a p r o l o g ;
import j a v a . u t i l . H a s h t a b l e ;
import j p l . ;
public class ConsultaPessoas {
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
Query q u e r y = new Query ( " c o n s u l t " ,
new Term [ ] { new Atom ( " . . / . . / r e c u r s o s / p r o l o g / p a r e n t e s . p l " ) } ) ;
try {
query . h a s S o l u t i o n ( ) ;
14
V a r i a b l e X = new V a r i a b l e ( "X" ) ;
15
Query c o n s u l t a P e s s o a s = new Query ( " p e s s o a " , new Term [ ] { X } ) ;
16
17
System . o u t . p r i n t l n ( " L i s t a g e m de p e s s o a s " ) ;
18
while ( c o n s u l t a P e s s o a s . hasMoreElements ( ) ) {
19
Hashtable tabela = consultaPessoas . nextSolution ( ) ;
20
21
System . o u t . p r i n t l n ( t a b e l a . g e t (X . name ( ) ) ) ;
22
}
23
24
} c a t c h ( P r o l o g E x c e p t i o n pe ) {
25
System . o u t . p r i n t l n ( "O a r q u i v o P r o l o g no f o i e n c o n t r a d o . " ) ;
26
27
pe . p r i n t S t a c k T r a c e ( ) ;
28
}
29
}
30 }
No Exemplo 2,
as linhas 8 e 9 preparam a consulta consult(../../recursos/prolog/parentes.pl). Neste caso no necessrio colocar os apstrofes
(), pois o prprio arcabouo JPL ir coloc-los.
A linha 12 executa a consulta da varivel query, caso algum erro seja encontrado, ser
lanada uma exceo, modicando o uxo do programa para o bloco de cdigo catch, nas
linhas 24 a 28.
Se a primeira consulta for executada com sucesso, ento pode-se preparar a segunda consulta que pessoa(X). Para montar esta consulta, necessrio declarar uma varivel chamada X
na linha 14 e criar a varivel consultaPessoas assim como apresentado na linha 15.
Finalmente, nas linhas 17 a 22, so exibidos os resultados da consulta pessoa(X). Para
isto, criou-se o lao da linha 18 que ir buscar os resultados enquanto houverem2 .
A linha 19 solicita o prximo resultado que ser armazenado na Hashtable chamada
tabela. E a linha 21 exibe o resultado na sada padro, atravs do nome da varivel X.
O Exemplo 3 apresenta o resultado da execuo do Exemplo 2.
1
2
3
4
5
6
7
8
9
L i s t a g e m de p e s s o a s
joao
maria
jose
raimunda
sebastiao
vilani
ronneery
ronneesley
4.2
Nota-se que a funo hasMoreElements() poderia ser substituda pela funo hasMoreSolutions().
1 package j a v a p r o l o g ;
2
3 import j a v a . u t i l . H a s h t a b l e ;
4 import j p l . ;
5 import j p l . V a r i a b l e ;
6
7 public class ConsultaGenitores {
8
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
9
Query q u e r y = new Query ( " c o n s u l t " ,
10
new Term [ ] { new Atom ( " . . / . . / r e c u r s o s / p r o l o g / p a r e n t e s . p l " ) } ) ;
11
12
try {
13
query . h a s S o l u t i o n ( ) ;
14
15
V a r i a b l e X = new V a r i a b l e ( "X" ) ;
16
Query c o n s u l t a P e s s o a s = new Query ( " p e s s o a " , new Term [ ] { X } ) ;
17
18
System . o u t . p r i n t l n ( " L i s t a g e m de g e n i t o r e s " ) ;
19
while ( c o n s u l t a P e s s o a s . hasMoreElements ( ) ) {
20
Hashtable tabela = consultaPessoas . nextSolution ( ) ;
21
22
Term p e s s o a = ( Term ) t a b e l a . g e t (X . name ( ) ) ;
23
24
V a r i a b l e P a i = new V a r i a b l e ( " P a i " ) ;
25
Query c o n s u l t a P a i s = new Query ( " g e n i t o r " ,
26
new Term [ ] { P a i , p e s s o a } ) ;
27
28
if ( consultaPais . hasSolution ()) {
29
int cont = 0;
30
while ( c o n s u l t a P a i s . hasMoreElements ( ) ) {
31
i f ( c o n t ++ ! = 0 ) System . o u t . p r i n t ( " e " ) ;
32
33
Hashtable tabelaPai = consultaPais . nextSolution ( ) ;
34
35
System . o u t . p r i n t ( t a b e l a P a i . g e t ( P a i . name ( ) ) ) ;
36
}
37
38
System . o u t . p r i n t ( " s o o s g e n i t o r e s de " ) ;
39
System . o u t . p r i n t l n ( p e s s o a . name ( ) ) ;
40
}
41
}
42
} c a t c h ( P r o l o g E x c e p t i o n pe ) {
43
System . o u t . p r i n t l n ( "O a r q u i v o P r o l o g no f o i e n c o n t r a d o . " ) ;
44
45
pe . p r i n t S t a c k T r a c e ( ) ;
46
}
47
}
48 }
1
2
3
4
5
L i s t a g e m de g e n i t o r e s
j o a o e m a r i a s o o s g e n i t o r e s de s e b a s t i a o
j o s e e r a i m u n d a s o o s g e n i t o r e s de v i l a n i
s e b a s t i a o e v i l a n i s o o s g e n i t o r e s de r o n n e e r y
s e b a s t i a o e v i l a n i s o o s g e n i t o r e s de r o n n e e s l e y
4.3
Se as pesquisas mostradas nas subsees 4.1 e 4.2 fossem alteradas para retornarem dados
no lugar de imprimi-los na sada padro, seria possvel construir uma interface visual amigvel,
assim como apresentada na Figura 4.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
java . u t i l . ArrayList ;
java . u t i l . Hashtable ;
java . u t i l . List ;
jpl .;
p u b l i c c l a s s PessoaDAO {
/ / A r q u i v o com o s f a t o s e r e g r a s do P r o l o g
public s t a t i c String fonteProlog =
" . . / . . / recursos / prolog / parentes . pl " ;
/
L i s t a t o d a s as p e s s o a s
/
p u b l i c L i s t l i s t a r ( ) throws E x c e p t i o n {
/ / C r i a uma l i s t a p a r a a r m a z e n a r a s p e s s o a s
L i s t l i s t a = new A r r a y L i s t ( ) ;
/ / C r i a a c o n s u l t a do c d i g o f o n t e
Query q u e r y = new Query ( " c o n s u l t " ,
new Term [ ] { new Atom ( f o n t e P r o l o g ) } ) ;
/ / V e r i f i c a s e o c d i g o f o n t e pde s e r a b e r t o
query . h a s S o l u t i o n ( ) ;
/ / Cria a c o n s u l t a : pessoa (X ) .
V a r i a b l e X = new V a r i a b l e ( "X" ) ;
Query c o n s u l t a P e s s o a s = new Query ( " p e s s o a " , new Term [ ] { X } ) ;
/ / A d i c i o n a a s p e s s o a s na l i s t a , e n q u a n t o h o u v e r s o l u e s
while ( c o n s u l t a P e s s o a s . hasMoreElements ( ) ) {
Hashtable tabela = consultaPessoas . nextSolution ( ) ;
l i s t a . add ( t a b e l a . g e t (X . name ( ) ) ) ;
}
/ / Fecha a s c o n s u l t a s a b e r t a s
query . c l o s e ( ) ;
consultaPessoas . close ( ) ;
/ / R e t o r n a a l i s t a de p e s s o a s
return l i s t a ;
}
/
R e t o r n a um l i t e r a l com o s nomes d o s g e n i t o r e s de uma p e s s o a
/
public String g e n i t o r e s ( String pessoa ) {
/ / C r i a uma v a r i v e l de r e s p o s t a , i n i c i a l m e n t e v a z i a
10
11
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/ / A d i c i o n a o nome do g e n i t o r
}
/ / Fecha a s c o n s u l t a s
query . c l o s e ( ) ;
consultaGenitores . close ( ) ;
/ / R e t o r n a o s nomes d o s g e n i t o r e s s e p a r a d o s p o r e
return r e s p o s t a ;
}
/
R e t o r n a o s f i l h o s de uma p e s s o a
/
public String f i l h o s ( String pessoa ) {
String resposta = "" ;
Query q u e r y = new Query ( " c o n s u l t " ,
new Term [ ] { new Atom ( f o n t e P r o l o g ) } ) ;
query . h a s S o l u t i o n ( ) ;
/ / Cria a c o n s u l t a : g e n i t o r ( pessoa , X ) .
V a r i a b l e X = new V a r i a b l e ( "X" ) ;
Query c o n s u l t a F i l h o s = new Query ( " g e n i t o r " ,
new Term [ ] { new Atom ( p e s s o a ) , X } ) ;
/ / A d i c i o n a na r e s p o s t a o s f i l h o s
int cont = 0;
while ( c o n s u l t a F i l h o s . hasMoreElements ( ) ) {
i f ( c o n t ++ ! = 0 ) r e s p o s t a += " e " ;
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
}
117 }
12
Consideraes nais
Agradecimento
Ao Prof. Dr. Plnio de S Leito Jnior pela avaliao do presente texto e pelas sugestes
feitas, as quais muito contriburam para a melhoria do texto original.
Referncias
[1] BERNERS-LEE, T; CAILLIAU, R. WorldWideWeb: Proposal for a HyperText Project.
http://www.w3.org/Proposal, 1990.
13