Você está na página 1de 34

Universidade Federal de Campina Grande - UFCG

Centro de Cincias e Tecnologia - CCT


Departamento de Sistemas e Computao - DSC

APOSTILA: INTRODUO PROGRAMAO EM LGICA

Alexandre de Andrade Barbosa


aab@dsc.ufcg.edu.br
Joseluce de Farias Cunha
joseluce@dsc.ufcg.edu.br

34 pginas
2006

Av. Aprgio Veloso, 882  Bodocong


Caixa Postal 10.106
58.109-970  Campina Grande  PB  Brasil
Fone: 310-1119  Fax: 310-1273

APOSTILA: INTRODUO PROGRAMAO EM


LGICA
Alexandre de Andrade Barbosa
Departamento de Sistemas e Computao
E-mail: aab@dsc.ufcg.edu.br
Joseluce de Farias Cunha
Departamento de Sistemas e Computao
E-mail: joseluce@dsc.ufcg.edu.br
Av. Aprgio Veloso, 882  Bodocong  Caixa Postal 10.106
CEP 58109-970  Campina Grande  PB  Brasil
Fone: 310-1119  Fax: 310-1273 (DSC)

Resumo

Esta apostila foi criada como material de apoio disciplina de Lgica


Matemtica do curso de Cincia da Computao da Universidade Federal
de Campina Grande - UFCG. O contedo apresentado neste material
relacionado Programao em Lgica, mais especicamente linguagem
Prolog. Nenhuma reviso sobre Lgica Matemtica apresentada, assim,
necessrio que o leitor j possua conhecimento sobre Lgica Proposicional e Lgica de 1a Ordem. Este texto possu nvel introdutrio, uma
vez que conhecimentos avanados sobre a linguagem no sero explorados
na disciplina em questo.

Palavras-chave: Programao em lgica, Prolog, Lgica.

Sumrio
1 Introduo

2 Implementaes de Prolog

3 Sintaxe SWI-Prolog

4 Utilizando o SWI-Prolog

5 Fatos, Regras e Consultas

10

6 Listas

16

1.1
1.2

3.1
3.2

5.1
5.2
5.3
6.1
6.2
6.3
6.4

O que Programao em Lgica/Prolog? . . . . . . . . . . . . . . . . . . .


Como Prolog funciona? . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Os comandos write e read . . . . . . . . . . . . . . . . . . . . . . . . . . .


Comentrios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

4
4

7
8

Regras . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Regras recursivas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Como Prolog responde consultas . . . . . . . . . . . . . . . . . . . . . . . . 15
Checagem de pertinncia
Concatenao . . . . . .
Adicionando elementos .
Excluindo elementos . .

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

17
17
18
18

7 Aritmtica

19

8 Corte de uxo

21

9 Exemplos

22

10 Exerccios

27

Lista de Figuras
1
2
3
4
5

Tela inicial do SWI-Prolog Editor . .


rvore genealgica . . . . . . . . . .
Relao descendente. . . . . . . . . .
rvore para a expresso 2 a + b c
Jogo Torre de Hanoi . . . . . . . . .

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

9
10
14
19
24

Introduo

Esta apostila foi criada para apoiar a disciplina Lgica Matemtica, em sua parte nal
relacionada Programao em Lgica. O contedo apresentado aqui possui nvel introdutrio, uma vez que a disciplina em questo no far uso de recursos avanados da
linguagem. Estudos mais avanados sobre a Programao em Lgica devero realizados
em disciplinas posteriores.
O contedo deste texto busca fornecer aspectos mais prticos relacionados linguagem
Prolog, o funcionamento interno da linguagem no ser detalhado neste material. Caso o
leitor deseje se aprofundar no estudo da linguagem, recomenda-se a leitura de [1], [2], [3]
e [4], nos quais este texto baseado.
Espera-se que aps a leitura deste material o leitor seja capaz de:

compreender e executar programas Prolog;


modicar programas Prolog;
escrever programas Prolog bsicos e intermedirios.

1.1

O que Programao em Lgica/Prolog?

Existem diversos paradigmas de programao, hoje, o paradigma mais utilizado o


paradigma procedural. As linguagens Java, Pascal, C/C++ so ditas linguagens procedurais, pois, nestes programas necessrio implementar um procedimento para resolver
determinado problema. Outro paradigma de programao o paradigma imperativo, que
possui a linguagem LISP como sua representante mais famosa. A Programao em Lgica faz parte do paradigma de programao denominado declarativo ou descritivo, neste,
deve-se implementar uma descrio do problema e no um conjunto de instrues.
A linguagem Prolog uma representante do paradigma declarativo, esta a representante mais famosa da Programao em Lgica, a qual se baseia no clculo de predicados.
Prolog foi criada em 1972 por Colmerauer e Roussel, um programa Prolog no possui
cdigo para manipular a memria ou realizar desvios condicionais. Isso no signica que
Prolog seja superior s outras linguagens, pode-se armar apenas que a linguagem mais
adequada para solucionar uma determinada categoria de problemas. Esta categoria diz
respeito aos problemas onde necessrio representar algum tipo de conhecimento, por exemplo, em aplicaes que realizem computao simblica, na compreenso de linguagem
natural ou em sistemas especialistas.

1.2

Como Prolog funciona?

Um programa Prolog constitui-se de uma coleo de fatos (base de dados) e regras (relaes lgicas), esses tens descrevem o domnio de um determinado problema. Esta
descrio do problema avaliada por um interpretador, o qual utilizando um motor de
inferncia realiza dedues em busca de concluses vlidas para consultas realizadas pelos usurios. Assim, pode-se armar que a computao destes programas equivalente a
prova de um teorema em lgica.

Os fatos de Prolog permitem a denio de predicados por meio da declarao de


quais tens pertencentes ao universo (ou domnio) satisfazem os predicados. Por exemplo,
pode-se denir o predicado homem(x) e utilizar este para denir quais elementos do universo possuem tal predicado, no caso x homem. Vale salientar que responsabilidade
do programador manter a denio de um predicado consistente. Por exemplo, poderia ser criado o predicado come(x,y) para representar que x come y ou y come x, o
programador que dever especicar os fatos de maneira consistente.
As regras Prolog so descries de predicados por meio de condicionais. Por exemplo,
pode-se denir o predicado pai(x), signicando que  x pai, atravs da regra: pai(X) :prole(X,_), homem(X). A regra signica que x pai se x possui ao menos um lho.
O usurio interage com o programa atravs de consultas (queries ). Por exemplo, sejam
dados os fatos:

homem(pedro).
homem(joao).
mulher(maria).
mulher(teresa).
o usurio pode realizar a consulta homem(X). e receber as seguintes respostas X=pedro;
X=joao; No, signicando que pedro e joao so homens, o No indica que no existem mais
respostas que satisfaam a consulta.
As computaes em Prolog utilizam os conceitos de clusulas de horn, resoluo e
encadeamento para trs (backtracking ), com estes possvel realizar a computao de
maneira equivalente a uma deduo em Lgica de 1a ordem.
Tanto fatos quanto regras so representados atravs de clusulas de horn, ou seja,
so frmulas que contm predicados ou negao de predicados conectados por disjunes,
onde ao menos um predicado no uma negao. Quanticadores no so representados
explicitamente, porm, a linguagem trata uma regra como se ela estivesse universalmente
quanticada. Utilizando a regra de inferncia da particularizao universal repetidas
vezes, possvel retirar os quanticadores e fazer com que uma varivel assuma qualquer
valor do domnio de representao.
Para realizar uma deduo Prolog utiliza unicao e a regra de inferncia da resoluo. Assim, duas clusulas do origem a um resolvente quando possuem predicados
correspondentes, sendo um positivo (no negado) e outro negativo (negado). Quando o
usurio realiza uma consulta o motor de inferncia tenta resolver metas, sendo que uma
meta pode conter submetas, quando no existem mais metas para serem satisfeitas em
uma linha de resoluo, o sistema utiliza encadeamento para trs (backtracking) em busca
de outras respostas possveis.
Ao longo desta apostila os conceitos citados sero exemplicados, no entanto, as explicaes fornecidas sobre o funcionamento destes na linguagem Prolog no sero detalhadas.

Implementaes de Prolog

Diversas implementaes da linguagem Prolog podem ser encontradas, o que para muitos
constitui um problema, pois estas nem sempre so totalmente compatveis. Atualmente,
5

existem verses livres e comerciais criadas para os principais sistemas operacionais. Algumas das implementaes mais conhecidas so:

Win-Prolog [5] - respeita a sintaxe de Edinburgo, a implementao mais prxima


do dialeto puro. A verso 4.6, a mais recente, est disponvel apenas para Windows
(98, ME, NT, 2k, XP). um sistema comercial, mas possui uma verso para testes
gratuita.
Open Prolog [6] - disponvel unicamente para Macintosh (Mac OS 7.5 ou superior).
Respeita a sintaxe padro ISO, baseada na sintaxe de Edinburgo. um software
gratuito, desde que seu autor seja avisado de sua utilizao.
Ciao Prolog [7] - distribudo gratuitamente, possui licena Library General Public
License (LGPL). Respeita a sintaxe padro ISO, pode ser utilizada em diversos
sistemas operacionais, tais como, Windows (98, NT, 2k, XP), Linux, SunOS, Solaris,
MacOS X, entre outros.
YAP Prolog [8] - criado pela Universidade do Porto em parceria com a Universidade Federal do Rio de Janeiro. Uma das principais caractersticas desta implementao sua velocidade. Respeita a sintaxe padro ISO, tambm compatvel
com outras implementaes de Prolog, tais como, Quintus e SICStus. A verso 5.1.1
pode ser utilizada em diversas distribuies Linux e Windows.
SWI Prolog [9] - software gratuito, sob a licena Lesser GNU Public License. Pode
ser utilizado nas plataformas Windows, Linux e MacOS. Possui diversas ferramentas
de edio grca, tais como, J-Prolog Editor e SWI-Prolog-Editor (recomendado).
Permite a utilizao da linguagem Prolog por outras linguagens, tais como, C/C++
e Java. uma das implementaes mais utilizadas atualmente.
SICStus Prolog [10] - um software comercial, mas possui verso gratuita para
avaliao. Respeita a sintaxe padro ISO e pode ser usada nas plataformas Windows
(2k e XP), Linux, Solaris 7, MacOS X e algumas distribuies Unix. Assim como o
SWI, possui interfaces para comunicao com outras linguagens, por exemplo, C &
C++, .NET, Java, Visual Basic e Tcl/Tk.
Amzi! Prolog [11] - pode ser utilizado de maneira conjunta a IDE Eclipse,
permite tambm comunicao com outras linguagens. Possui distribuies gratuitas
e comerciais, que podem ser utilizadas em sistemas operacionais diversos, tais como,
Windows, Linux, Solaris e HP/UX.
Visual Prolog [12] - bastante diferente da verso padro de Prolog, fortemente
tipado. Tambm conhecido como PDC Prolog ou Turbo Prolog, possui distribuies
gratuitas e comerciais para Windows e Linux. Fornece um ambiente complto para
programao, porm, um dialeto mais complexo que o original.
Outras distribuies Prolog conhecidas so: GNU Prolog [13], XSB [14] e Trinc Prolog
[15]. A implementao utilizada ao longo desta apostila a SWI-Prolog, todo cdigo
utilizado nos exemplos e exerccios apresentados aqui foram desenvolvidos nesta verso
de Prolog.
6

Sintaxe SWI-Prolog

Assim como todas as linguagens de programao, existem algumas regras que devem ser
respeitadas pelo programador. Os dados representados em Prolog podem ser um dos
seguintes tipos:

variveis - devem ser iniciados com letras maisculas ou underscore (_), seguidos
de qualquer caractere alfanumrico. Caso uma varivel seja denida apenas com
underscore, ela ser considerada uma varivel annima, ou seja, no se deseja saber
seu valor. Ex.: X, Y1, _Nome, ...;
no variveis;

 atmicas;
tomos - so constantes expressas atravs de palavras. Devem ser iniciados
com letra minscula seguida de qualquer caractere alfanumrico. Caso seja
necessrio denir um tomo com letra maiscula ou nmero, deve se usar
aspas simples. Ex.: joao, `Joo', `16', `Mary s', ...;
inteiros - qualquer nmero que no contenha um ponto (.) ser considerado
um inteiro. Caracteres ASCII entre aspas duplas so considerados inteiros.
Ex.: 1, 6, -3, a (interpretado como 97), ...;
nmeros em ponto utuante - qualquer nmero com um ponto e pelo menos
uma casa decimal. Ex.: 5.3 (correto), 7.8 (correto), 7. (incorreto);

 no atmicas;
listas - uma seqencia de elementos ordenados. Uma lista declarada
entre colchetes e os elementos devem ser separados por vrgula. Pode-se
separar a cabea (1o. elemento) do corpo (demais elementos) de uma lista
utilizando |. Ex.: [ a, b, c], [a | b, c ], ... .

3.1

Os comandos write e read

O comando write exibe o valor do parmetro no dispositivo de sada corrente. O dispositivo padro o monitor, assim, o comando write(`Teste de impresso.'). ir exibir a
mensagem Teste de impresso. na tela do monitor. O mesmo comando pode ser utilizado
para imprimir o valor de qualquer varivel.
No entanto, no existe um comando padro Prolog para escrita de expresses formatadas. Devido a isso, o SWI-Prolog utiliza comandos de extenso, um deste o
comando writef do C-Prolog de Edinburgo. Este comando possui a seguinte sintaxe
writef(Formato, Argumentos). Onde as opes para determinar a formatao so:

%w - imprime o termo;
%d - imprime o termo ignorando seu tipo, por exemplo, \n impresso como uma
string.
%s - imprime o termo como uma string;
7

%Nc - imprime o termo de modo centralizado numa quantidade N de colunas;


%Nl - imprime o termo alinhado esquerda numa quantidade N de colunas;
%Nr - imprime o termo alinhado direita numa quantidade N de colunas;
Para gerar alguns caracteres deve se usar seqencias de escape, estas so:

\n - cria uma nova linha;


\l - criar um separador de linha, o resultado igual ao produzido por \n;
\r - retorna ao incio da linha;
\t - tabulao;
\% - imprime o smbolo %;
\nnn - onde n um nmero decimal, produz o caractere ASCII com o cdigo
informado.
O comando read l um valor no dispositivo de entrada corrente e unica (atribui)
o valor uma varivel. O dispositivo de entrada padro o teclado, assim, o comando
read(X). ir ler um valor do teclado e unicar este valor com a varivel X.

3.2

Comentrios

Assim como em outras linguagens de programao Prolog possui caracteres, ou seqencias de caracteres, que identicam um trecho de comentrios. Os comentrios no so
levados em considerao pelos interpretadores, porm, so importantes para que outras
programadores possam compreender mais facilmente a codicao de um programa.
Em Prolog existem dois tipos de comentrios, estes so identicados pelos smbolos
% e /* */. O smbolo % expressa que tudo aquilo que estiver entre ele e o nal da
linha deve ser tratado como comentrio. Os smbolos /* */ indicam que tudo que estiver
entre /* e */ ser tratado como comentrio, pode-se observar exemplos de comentrios
no trecho de cdigo abaixo:
/ D e s c r i o dos p r e c i d a d o s homem e mulher
e l e m e n t o s do u n i v e r s o de r e p r e s e n t a o .
homem( pedro ) .
% r e p r e s e n t a o f a t o de
homem( j o a o ) .
% r e p r e s e n t a o f a t o de
mulher ( maria ) . % r e p r e s e n t a o f a t o de
mulher ( t e r e s a ) . % r e p r e s e n t a o f a t o de

s o b r e t o d o s os
/
que pedro homem .
que j o a o homem .
que maria mulher
que t e r e s a mulher .

Consideraes mais detalhadas sobre a sintaxe, os tipos de dados permitidos e sobre


outros comandos podem ser encontrados no manual do SWI-Prolog, disponvel em [16].

Utilizando o SWI-Prolog

Aps realizar o download e a instalao do SWI-Prolog e do SWI-Prolog-Editor, inicie


o editor, ser apresentada a tela deste, a qual deve ser similar a exibida na Figura 1.
Pode-se observar que a tela se divide em duas janelas editveis, identicadas na imagem
com os nmeros 1 e 2. A rea 1 corresponde a janela de edio do programa, a rea 2 a
janela de interao do usurio com o interpretador. Para que se possa realizar qualquer
interao com o programa que est sendo editado necessrio, aps salvar o arquivo, clicar
sobre boto de consulta, identicado com o nmero 3. Caso o arquivo seja alterado e o
boto no seja acionado o interpretador ir trabalhar com a ltima verso do programa
que foi consultada. O nmero 4 identica o prompt de comandos, a partir deste que
podem ser enviados os comandos para o interpretador. Todo comando enviado para o
interpretador deve obrigatoriamente ser nalizado pelo caractere ponto (.). Por exemplo,
o comando ?- write(Teste) no resultar em uma impresso, enquanto o comando ?write(Teste) . resultar na impresso da string `Teste'. O smbolo ?- ser usado nos
exemplos e exerccios apresentados para representar o prompt de comandos, ele no deve
ser digitado.
As outras funcionalidades (e.g. salvar, abrir, debug, ... ) existentes no sistema so
similares ou idnticas aes encontradas em diversos sistemas. Maiores detalhes de
funcionamento do programa podem ser encontradas no manual do sistema.

Figura 1: Tela inicial do SWI-Prolog Editor

Fatos, Regras e Consultas

Como j foi armado, um programa Prolog captura a descrio de um determinado problema. O programador deve implementar um conjunto de fatos e regras relacionados ao
problema em questo. Ao longo de toda esta seo sero apresentados alguns fatos, regras
e consultas Prolog que podem constituir um programa. Para facilitar a explicao destes
conceitos ser implementado um programa que descreva as relaes de uma famlia. A
Figura 2 exibe a rvore genealgica de uma famlia, nesta possvel observar que existem
diversos tipos de relao, por exemplo, bob pai de pat, pam av de ann, ann irm
de pat, jim lho de pat, entre outras.

Figura 2: rvore genealgica


Para se representar estas relaes em Prolog, inicialmente pode-se criar a relao
genitor(x, y), signicando que x genitor de y. Ento, podemos inserir na janela de
edio do programa os seguintes fatos:
g e n i t o r (pam ,
g e n i t o r ( tom ,
g e n i t o r ( tom ,
g e n i t o r ( bob ,
g e n i t o r ( bob ,
g e n i t o r ( pat ,

bob ) .
bob ) .
liz ).
ann ) .
pat ) .
jim ) .

Estas clusulas descrevem toda a informao sobre a relao genitor existente na rvore
apresentada (domnio). Aps a denio desta relao podem ser realizadas consultas no
sistema, para isso basta clicar no boto de consulta, e digitar perguntas no prompt de
comandos, tal como exibido a seguir:
3 ? g e n i t o r ( pat , jim ) .
Yes
4 ? g e n i t o r ( jim , pat ) .
No

a consulta rotulada com o nmero 3, retorna a resposta yes (sim), isso ocorre pois o
motor de inferncia encontrar o fato correspondente e responder positivamente. J para
10

a pergunta rotulada com o nmero 2, a resposta retornada No (no), pois o programa


no possui nenhum fato que indique que pat genitora de jim.
As consultas apresentadas exemplicam o tipo mais simples de consulta, quando um
fato da base j satisfaz a pergunta. Consultas mais interessantes so possveis, por exemplo, pode-se indagar quem so os genitores de um determinado sujeito, ou quem so
os lhos de deste na base de fatos do exemplo. Para isso, pode-se digitar no prompt de
comandos as seguintes perguntas:
5 ? g e n i t o r (X, bob ) .
X = pam ;
X = tom ;
No
6 ? g e n i t o r ( bob , X ) .
X = ann ;
X = pat ;
No
7 ? g e n i t o r (X,Y ) .
X = pam
Y = bob ;
X = tom
Y = bob ;
X = tom
Y = liz ;
X = bob
Y = ann ;
X = bob
Y = pat ;
X = pat
Y = jim ;
No

a consulta rotulado com o nmero 5, indaga quem so os pais do indivduo bob. Isso
ocorre pois X uma varivel, assim, o motor de inferncia realiza substituies sobre esta
para encontrar quais fatos da base satisfazem a indagao. O mesmo ocorre na consulta
rotulada com o nmero 6, porm, esta indaga quais so os lhos do indivduo bob. A
consulta rotulada com o nmero 7 exibe pares genitor-lho, observe que o ordem das
respostas idntica a ordem dos fatos inseridos na base.
Os exemplos exibidos at o momento ilustram consultas simples, possvel, por exemplo, realizar consultas sobre fatos que no esto diretamente descritos. Diga-se, por
exemplo, que se deseja saber quem so os avs de determinado sujeito, apesar de no
existir um fato que determine esta relao pode-se criar uma consulta que realize esta
pergunta. Para isso, pode-se digitar no prompt de comandos a seguinte pergunta:
8 ? g e n i t o r (Y, jim ) , g e n i t o r (X,Y ) .
Y = pat
X = bob ;
No

a consulta pode ser interpretada como Y genitor de jim e X genitor de Y, ou seja,
essa consulta busca quem o pai do pai de um sujeito. Note que as clusulas esto
separadas por uma vrgula (,), para o SWI-Prolog a vrgula representa uma conjuno,
enquanto um ponto e vrgula (;) representa uma disjuno. Ento, uma seqencia de
11

clusulas separadas por vrgula s sera satisfeita se e somente se todas as clusulas forem
satisfeitas. Do mesmo modo, pode-se armar que uma seqencia de clusulas separadas
por ponto e vrgula sera satisfeita se ao menos uma clusula for satisfeita.
Um outro conectivo importante a negao. Para exemplicar a utilizao deste conectivo sero denidos os predicados homem(x) e mulher(x), signicando que x homem e
x mulher respectivamente. Assim, so denidos os fatos:
mulher (pam ) .
homem( tom ) .
homem( bob ) .
mulher ( l i z ) .
mulher ( pat ) .
mulher ( ann ) .
homem( jim ) .

aps denidos os fatos, podemos indagar, por exemplo, quem a me de bob, ou seja,
deseja-se saber quem o genitor de bob que mulher. Para isso, pode-se digitar no prompt
de comandos a seguinte pergunta:
9 ? g e n i t o r (X, bob ) , mulher (X ) .
X = pam ;
No

a mesma consulta poderia ser realizada atravs da seguintes pergunta:


10 ? g e n i t o r (X, bob ) , not (homem(X ) ) .
X = pam ;
No

5.1

Regras

Muitas outras consultas podem ser realizadas sobre uma base de fatos, porm, muito
mais interessante utilizar regras, pois o poder de expresso obtido muito maior. Para
exemplicar o uso de regras ser denida a relao prole(y,x), signicando que y prole
de x. Esta relao a relao inversa de genitor(x,y), assim, pode-se armar que y
prole de x se x genitor de y. Para isso, pode-se criar a seguinte regra na janela de
edio do programa:
p r o l e (Y,X) : g e n i t o r (X,Y ) .

o smbolo :- pode ser lido como se. A parte da regra a esquerda do smbolo :- denominada de concluso (ou cabea), j a parte a direita deste chamada de condio (ou
corpo). Assim, para responder a consulta o interpretador Prolog precisa satisfazer parte
condicional da regra, uma vez que no existem fatos relacionados a prole, para ento
obter uma concluso. Para isso, so utilizadas substituies, at que se satisfaa a parte
condicional ou no existam mais possibilidades de substituio.
Consultas so realizadas sobre regras da mesma maneira como se estas fossem fatos,
por exemplo, para indagar quem a prole do indivduo tom deve-se digitar no prompt de
comandos a seguinte consulta:
11 ? p r o l e (X, tom ) .

12

X = bob ;
X = liz ;
No

para satisfazer a regra o interpretador Prolog substituiu a varivel X at que encontrou


o fato genitor(tom, bob), o qual corresponde a parte condicional da regra prole(Y,X)
:- genitor(X,Y), aps as substituies adequadas. Posteriormente foi encontrado o fato
genitor(tom, liz), o qual tambm pode satisfazer a regra, nenhuma outra substituio
resultou em sucesso.
Outras relaes podem ser denidas para o exemplo. Pode-se denir as relaes
mae(x,y) e avos(x,y), apresentadas anteriormente como consultas. Para isso, deve-se
digitar na janela de edio do programa as seguintes regras:
mae (X,Y) : g e n i t o r (X,Y) , mulher (X ) .
avos (X, Z ) : g e n i t o r (X,Y) , g e n i t o r (Y, Z ) .

Um outra relao que pode ser denida a relao irma(x,y), signicando x irm de
y. Note que deve-se ter cuidado na denio deste relacionamento, pois, pode-se denir
este atravs da seguinte regra:
irma (X,Y) : g e n i t o r ( Z ,X) , g e n i t o r ( Z ,Y) , mulher (X ) .

porm, esta regra permite uma pessoa seja irm de si mesma, para comprovar isso basta
realizar a seguinte consulta:
12 ? irma ( pat , pat ) .
Yes

o programador deve estar atento a especicaes deste tipo, para descrever corretamente
a relao necessrio indicar que x e y precisam ser diferentes, assim a regra correta seria:
irma (X,Y) : g e n i t o r ( Z ,X) , g e n i t o r ( Z ,Y) , mulher (X) , not (X = Y ) .

Uma diferena bsica entre uma regra e um fato que um fato sempre uma informao verdadeira, j uma regra precisa ser avaliada para que se possa determinar se
esta verdadeira ou no. Regras podem depender diretamente de um fato, como no exemplo anterior ou de outras regras (inclusive dela mesma). Regras denidas em termos
de si mesma so chamadas de regras recursivas ou recorrentes, este tipo de regra ser
apresentado na seo seguinte.

5.2

Regras recursivas

A recurso um dos elementos mais importantes da linguagem Prolog, este conceito


permite a resoluo de problemas signicativamente complexos de maneira relativamente
simples. A construo de uma regra recursiva ser apresentada atravs da denio da
relao descendente(x,y), signicando que y um descendente de x, tal como ilustrado
na Figura 3. possvel denir esta relao utilizando a relao genitor, assim, uma
descendncia direta, ou seja, quando x genitor de y, seria representada com a seguinte
regra:
d e s c e n d e n t e (X, Z ) : g e n i t o r (X, Z ) .

13

Figura 3: Relao descendente.


Para outros casos de descendncia, que no uma descendncia direta, poderiam ser
utilizadas seguintes regras:
d e s c e n d e n t e (X, Z ) : g e n i t o r (X,Y) , g e n i t o r (Y, Z ) .
d e s c e n d e n t e (X, Z ) : g e n i t o r (X,Y) , g e n i t o r (Y,W) , g e n i t o r (W, Z ) .
...

porm, esta soluo seria limitada e trabalhosa. Usando recurso possvel obter uma
soluo bem mais simples e completa para a relao de descendncia. Para isso,
necessrio denir a seguinte armao  x um descendente de z se existe um y, tal que,
x seja genitor de y e y seja um descendente de z , a seguinte regra descreve isso:
d e s c e n d e n t e (X, Z ) : g e n i t o r (X,Y) , d e s c e n d e n t e (Y, Z ) .

assim, utilizando as duas regras, pode-se descrever a relao de descendncia de maneira


correta. As duas regras so necessrias, pois o uso somente da primeira regra s seria
suciente para casos de descendncia direta (equivalente relao genitor ), enquanto o
uso exclusivo da segunda regra levaria a uma busca innita de descendncia. Ento, a
regra Prolog para relao de descendncia incorpora as seguintes regras:
d e s c e n d e n t e (X, Z ) : g e n i t o r (X, Z ) .
d e s c e n d e n t e (X, Z ) : g e n i t o r (X,Y) , d e s c e n d e n t e (Y, Z ) .

Pode-se ento realizar consultas na base de exemplo sobre a relao de descendncia,


para isso, basta escrever a seguinte consulta:
13 ? d e s c e n d e n t e (pam ,X ) .
X = bob ;
X = ann ;
X = pat ;
X = jim ;
No

com isso so exibidos os nomes de todos os descendentes de pam.


14

O programa completo que descreve as relaes familiares discutidas nesta seo pode
ser observado a seguir:
/ Programa P r o l o g s o b r e r e l a e s f a m i l i a r e s . /
g e n i t o r ( pam , bob ) . % f a t o
g e n i t o r ( tom , bob ) . % f a t o
g e n i t o r ( tom , l i z ) . % f a t o
g e n i t o r ( bob , ann ) . % f a t o
g e n i t o r ( bob , pat ) . % f a t o
g e n i t o r ( pat , jim ) . % f a t o
mulher (pam ) . % f a t o
mulher ( l i z ) . % f a t o
mulher ( pat ) . % f a t o
mulher ( ann ) . % f a t o
homem( tom ) . % f a t o
homem( bob ) . % f a t o
homem( jim ) . % f a t o
p r o l e (Y,X) : g e n i t o r (X,Y ) . % r e g r a
mae (X,Y) : g e n i t o r (X,Y) , mulher (X ) . % r e g r a
avos (X, Z ) : g e n i t o r (X,Y) , g e n i t o r (Y, Z ) . % r e g r a
irma (X,Y) : g e n i t o r ( Z ,X) , g e n i t o r ( Z ,Y) , mulher (X ) . % r e g r a
d e s c e n d e n t e (X, Z ) : g e n i t o r (X, Z ) . % r e g r a
d e s c e n d e n t e (X, Z ) : g e n i t o r (X,Y) , d e s c e n d e n t e (Y, Z ) . % r e g r a r e c u r s i v a

Um conjunto de regras utilizados para descrever uma nica relao , em geral,


chamada de procedimento (procedure ). Assim, as regras relacionadas descendncia,
ilustradas no exemplo, podem ser denominadas de procedimento.

5.3

Como Prolog responde consultas

Uma consulta Prolog sempre um conjunto de metas. Quando uma pergunta feita,
Prolog precisa satisfazer todas as metas. Isso, como j armado, equivalente a provar
um teorema ou realizar uma deduo. Para isso, Prolog busca vericar se a(s) meta(s)
so conseqncias lgicas dos fatos e regras contidos no programa. Para ilustrar o procedimento executado para responder uma consulta ser utilizado o programa de exemplo,
relacionado relacionamentos familiares.
Diga-se que a consulta ?- descendente(tom, pat). seja realizada. Sabe-se que descendente(bob, pat) um fato existente no programa. Este fato seria derivado a partir da
primeira regra relacionada a descendncia. Alm disso, sabe-se que a regra genitor(tom,
bob) um fato. Com isso, e o fato derivado descendente(bob, pat) pode-se concluir descendente(tom, pat) utilizando a segunda regra relacionada descendncia existente no
programa. Isso ilustra o que foi utilizado pra realizar a prova, ser apresentado agora
como esta prova foi obtida.
Prolog encontra uma prova na ordem inversa a forma ilustrada anteriormente. Prolog
inicia com uma meta e, utilizando regras, substitui estas metas por novas metas, at que
uma meta seja satisfeita por um fato.
Assim, feita a pergunta descendente(tom, pat), Prolog procede da seguinte maneira.
Para satisfazer esta meta procurada alguma clusula (fato ou regra) da qual a meta
possa ser deduzida. Ento, so encontradas as duas regras relacionadas descendncia
existentes no programa, pois, a cabea da regra corresponde meta. Como a regra de15

scendente(X,Z) :- genitor(X,Z). aparece primeiro, e como a meta atual descendente(tom,


pat), as variveis so substitudas, tal como a seguir:
X = tom, Z = pat
a meta descendente(tom, pat) substituda pela meta genitor(tom, pat). Como no existe
uma clusula onde a cabea seja correspondente a esta, Prolog realiza um encaminhamento
para trs, ou seja, retorna a meta original para tentar encontrar uma maneira alternativa
de satisfaz-la.
Ento, a regra descendente(X,Z) :- genitor(X,Y), descendente(Y,Z). ser utilizada.
Mais uma vez, as variveis X e Z sero substitudas por tom e pat respectivamente,
porm Y ainda no foi substituda. Assim, a meta atual d lugar as metas genitor(tom,Y),
descendente(Y, pat).
Prolog deve agora satisfazer a conjuno de metas genitor(tom,Y), descendente(Y,
pat), isso feito na ordem em que as metas esto escritas, ou seja, primeiramente Prolog
ir tentar satisfazer genitor(tom,Y). Realizando uma busca por clusulas que satisfaam
a meta, Prolog encontra o fato genitor(tom, bob), assim, Y substituda por bob. Com
isso, a meta atual descendente(bob, pat).
Para satisfazer esta meta a regra descendente(X,Z) :- genitor(X,Z) ser usada novamente. Observe que esta uma nova seqencia de prova, sendo assim, as substituies
anteriores no possuem nenhuma relao com esta. Com isso, Prolog usa um novo conjunto de variveis, e assim, pode-se reescrever a regra como descendente(X1,Z1) :- genitor(X1,Z1). Assim, como a cabea deve corresponder meta, as seguintes substituies so
realizadas:
X = bob, Z = pat
e ento, a meta atual trocada para nova meta genitor(bob, pat). Como esta satisfeita
por um fato presente no programa o procedimento acaba.

Listas

Listas so um dos tipos de dados mais teis existentes na linguagem Prolog, diz-se que uma
lista uma seqncia ordenada de uma quantidade qualquer de elementos. Os elementos
de uma lista podem ser de qualquer tipo, tais como, nmeros ou tomos.
Os elementos contidos em uma lista devem ser separados por vrgulas, e precisam estar
entre colchetes. Por exemplo, uma lista pode conter os nomes dos indivduos do exemplo
da seo anterior, esta lista seria denida como:
[pam, liz, pat, ann, tom, bob, jim]
Existem dois tipos de listas, as listas vazias e as no vazias. Uma lista vazia representada por [ ]. Listas no vazias podem ser divididas em duas partes, so elas:

cabea - corresponde ao primeiro elemento da lista;


cauda - corresponde aos elementos restantes da lista.
Por exemplo, para a lista:
16

[pam, liz, pat, ann, tom, bob, jim]


pam a cabea, enquanto [liz, pat, ann, tom, bob, jim] a cauda. Observe que a cauda
uma nova lista, que por sua vez tambm possui cabea e cauda. Assim, pode-se dizer
que o ltimo elemento de uma lista possui uma cauda vazia (uma lista vazia). Pode-se
especicar que um elemento de uma lista tambm uma lista, assim, pode-se representar
listas tais como:
Hobbies1 = [tenis, musica]. Hobbies2 = [sky, comida]. Lista = [ann, Hobbies1, tom,
Hobbies2].
possvel separar as partes de uma lista utilizando uma barra vertical, assim, pode-se
escrever Lista = [cabea | cauda]. Com isso, possvel determinar as seguintes listas:
[a | b, c] = [a, b, c]
possvel realizar uma srie de operaes sobre listas, as sees seguintes exibem
algumas destas aes.

6.1

Checagem de pertinncia

Para se checar se um determinado elemento pertence uma lista deve-se utilizar a relao
member(x,y), que indica se x pertence y, por exemplo:
3 ? member ( a , [ a , b , c ] ) .
Yes
4 ? member ( a , [ [ a , b ] , c ] ) .
No
5 ? member ( [ a , b ] , [ [ a , b ] , c ] ) .
Yes

na consulta rotulada com o nmero 3, a um elemento da lista, uma vez que corresponde
cabea desta. J a consulta rotulada com o nmero 4, indica que a no pertence lista,
isso ocorre por que o elemento contido na lista uma outra lista [a,b] e no o tomo a.
Isso ilustrado na consulta rotulada com o nmero 5.

6.2

Concatenao

Para realizar a concatenao de listas pode-se utilizar o predicado append(L1,L2,L3)., este


predicado concatena a lista L1 e L2 exibindo o resultado em L3. O Mesmo predicado pode
ser utilizado para decompor listas. Para denir a relao de concatenao, necessrio
satisfazer as seguintes restries:

um argumento uma lista vazia - caso algum argumento seja vazio a concatenao
resultar na repetio do argumento no vazio;
nenhum dos argumentos vazio - a concatenao resulta na adio de todos os
elementos da segunda lista ao nal da primeira lista.
Visto isso, tem-se os exemplos:
17

conc([a,b], [], [a,b]) = true


conc([a,b], [c,d], [a,b,c,d]) = true
Para denir esta relao pode-se implementar as seguintes regras:
conc ( [ ] , L , L ) .
conc ( [ X| L1 ] , L2 , [X| L3 ] ) : conc ( L1 , L2 , L3 ) .

Denidas as regras, pode-se realizar as seguintes consultas:


6 ? conc ( [ a , b ] , [ c ] , L ) .
L = [a, b, c] ;
No
7 ? conc ( [ a ] , [ b , c ] , L ) .
L = [a, b, c] ;
No

As regras denidas tambm podem ser usadas para decompor uma lista em suas
componentes. Para checar isso, basta realizar a seguinte consulta:
6 ?
L1 =
L1 =
L1 =
L1 =
No

6.3

conc ( L1 , L2 , [ a , b , c ] ) .
[ ] L2 = [ a , b , c ] ;
[ a ] L2 = [ b , c ] ;
[ a , b ] L2 = [ c ] ;
[ a , b , c ] L2 = [ ] ;

Adicionando elementos

A adio de um elemento uma lista pode ser denida de modo simples. Para isso, basta
inserir o elemento no incio da lista, esta relao denida atravs da seguinte regra:
i n s e r e (X, L , [X | L ] ) .

com isso, pode-se realizar as seguintes inseres:


7 ? i n s e r e ( a , [ b , c ] , L ) .
L = [a, b, c] ;
No
8 ? i n s e r e ( [ 1 , 2 ] , 3 , L ) .
L = [[1 , 2]|3] ;
No

6.4

Excluindo elementos

A excluso de um elemento pode ser implementada atravs das seguintes regras:


e x c l u i (X, [X | T a i l ] , T a i l ) .
e x c l u i (X, [Y | T a i l ] , [Y | T a i l 1 ] ) : e x c l u i (X, T a i l , T a i l 1 ) .

a primeira regra utilizada quando o elemento que se deseja excluir corresponde cabea
da lista. J a segunda regra exclui um elemento que pertence a cauda da lista. Vale

18

salientar que esta implementao no exclui todos os elementos existentes na lista que
correspondam ao elemento passado como argumento.
Denidas as regras podem ser realizadas as seguintes consultas:
9 ? e x c l u i ( a , [ a , b , c ] , L ) .
L = [b, c ] ;
No
10 ? e x c l u i ( b , [ a , b , c ] , L ) .
L = [a, c] ;
No
11 ? e x c l u i ( c , [ a , c , b , c ] , L ) .
L = [a, b, c] ;
L = [a, c , b] ;
No

Existem diversas outras operaes nativas de Prolog, um exerccio interessante seria


realizar a implementao de algumas operaes. Pode-se, por exemplo, criar uma operao
para checar se uma lista est contida em outra ou uma operao para realizar permutao
dos elementos.

Aritmtica

Geralmente, quando se escreve uma expresso matemtica a notao inxa utilizada, por
exemplo 2a+bc, onde 2, a, b e c so argumentos e + e so operadores. Em Prolog uma
expresso representada internamente como uma rvore, assim a expresso anterior seria
representada pela rvore da Figura 4. Uma maneira de representar em Prolog a expresso
em questo utiliza notao prexa, a expresso seria representada como +((2, a), (b, c)).
Porm, por ser mais usual a representao inxa tambm compreendida pela linguagem.

Figura 4: rvore para a expresso 2 a + b c


Prolog possui denidos operadores para as quatro operaes: +, , , /, para realizar
soma, subtrao, multiplicao e diviso, respectivamente. Para se obter o resultado de
uma operao necessrio utilizar o operador is, tal como ilustrado nas consultas abaixo:
3 ? X i s 2 + 3 .
X = 5 ;
No
4 ? X i s 4 1 .
X = 3 ;
No
5 ? X i s 2 5 .

19

X = 10 ;
No
6 ? X i s 9 / 2 .
X = 4.5 ;
No

Para o SWI-Prolog a operao / representa uma diviso real, para se obter uma
diviso inteira deve-se usar o operador //. A precedncia de operaes aritmticas em
Prolog a mesma precedncia adotada na matemtica, assim, quando necessrio devem ser
utilizados parnteses para descrever uma expresso corretamente. Alguns dos operadores
reconhecidos so:

mod - para obter o resto da diviso;


- para potenciao;
cos - funo cosseno;
sin - funo seno;
tan - funo tangente;
exp - exponencial;
ln - logaritmo natural;
log - logaritmo;
sqrt - raiz quadrada.
Existem tambm operaes de converso, algumas so automticas outras precisam
ser explicitamente solicitadas. Um exemplo de converso automtica ocorre quando um
nmero inteiro relacionado em uma expresso com nmeros de ponto utuante, automaticamente os inteiros so convertidos para nmeros nmeros de ponto utuante.
Algumas converses explcitas nativas so:

integer(X) - converte X para inteiro;


oat(X) - converte X para ponto utuante.
Prolog tambm possui operaes para comparao, os operadores so:

> - maior que;


< - menor que;
>= - maior ou igual;
=< - menor ou igual;
=:= - igual;
= / = - diferente.
20

importante explicitar a diferena entre os operadores = e =:=, o primeiro operador


verica se dois objetos so iguais, enquanto o segundo verica se o resultado da operao
igual. Isso ca mais claro atravs das consultas:
18 ?
No
19 ?
Yes
20 ?
A = 2
B = 1
No

1 + 2 = 2 + 1.
1 + 2 =:= 2 + 1 .
1 + A = B + 2.
;

Corte de uxo

A ordem das clusulas em um programa e a ordem de denio de uma regra podem


determinar o uxo de execuo de um programa. Esta seo apresenta um elemento para
controle do uxo denominado de corte, representado por !.
A principal funo do corte melhorar a ecincia de um programa. Como j foi
apresentado, Prolog utiliza encadeamento para trs sempre que necessrio para satisfazer
uma meta. Porm, muitas vezes, a utilizao de encadeamento para trs causa uma
busca desnecessria, levando a inecincia. Para estes casos o uso do mecanismo de corte
extremamente til.
Para apresentar o corte ser utilizado o seguinte exemplo: Sejam dados dois nmeros
X e Y , desejado saber qual o valor mximo destes.
As seguintes regras descrevem a relao maximo(x,y), signicando que x o mximo
valor se x maior ou igual a y, y o maior valor se y maior que x:
maximo (X, Y,X) : X >= Y.
maximo (X, Y,Y) : X < Y.

estas regras computam a relao de maneira correta, porm, elas so exclusivas, ou seja,
quando a primeira obtm sucesso a segunda ir falhar. Porm, Prolog sempre executa as
duas regras, utilizando encadeamento para trs, o que para esta relao resulta apenas
em inecincia.
A mesma relao pode ser obtida, porm, sem gerar processamento ineciente utilizando corte. Para isso, as regras seriam escritas como:
maximo (X, Y,X) : X >= Y, ! .
maximo (X, Y,Y) : X < Y.

com isso, caso a primeira regra obtenha sucesso a segunda regra no ser executada. A
execuo do programa com corte no altera o resultado deste, o corte apenas evita que
sejam realizadas buscas desnecessrias.
No entanto, o uso do corte exige muito mais ateno do programador. Isso ocorre pois
um programa sem cortes pode ter a ordem de suas clusulas e regras modicadas sem
alterar o signicado do mesmo. Por sua vez, um programa que possua cortes pode ter seu
signicado alterado caso suas clusulas sejam reordenadas. O seguinte exemplo ilustra
estas armaes. Sejam dadas as regras:
21

p : a , b .
p : c .

o signicado lgico das regras pode ser interpretado pela frmula: p (a b) c. Com
esta frmula podemos modicar a ordem das clusulas e seu signicado no ser alterado.
Porm, caso seja utilizado corte, tal como nas seguintes regras:
p : a , ! , b .
p : c .

o signicado lgico das regras pode ser interpretado pela frmula: p (a b) ( a c).
Com esta, caso a ordem das regras seja alterada para:
p : c .
p : a , ! , b .

o signicado lgico das regras pode ser pela frmula: p c (a b).


Assim, pode-se armar que o corte um mecanismo til, porm, deve ser utilizado
com cuidado.

Exemplos

Uma das melhores formas de se aprender uma nova linguagem de programao observando o cdigo de programas. Esta seo apresenta alguns programas escritos em Prolog,
o nvel de complexidade destes programas ser crescente, no que diz respeito aos conceitos utilizados. Uma boa atividade para o leitor seria realizar algumas modicaes ou
extenses sobre os programas apresentados.

Exemplo 9.1. Exemplo


Descrio: O exemplo clssico para determinar que se todo homem mortal e se
Scrates um homem, ento Scrates mortal. Essas armaes podem ser representadas
atravs das frmulas:

x(homem(x) mortal(x))
homem(socrates)
a partir destas pode-se concluir:

mortal(socrates)
O programa Prolog que descreve estas relaes pode ser representado como a seguir.
Cdigo:
m o r t a l (X) :
% Todos os homens so m o r t a i s
homem(X) ,
w r i t e f ( `%w%w%w ' , [ ` Sim , ' , X, ` m o r t a l ' ] ) .
homem( s o c r a t e s ) .
% S c r a t e s um homem

Consulta:
22

? m o r t a l ( s o c r a t e s ) .
Sim , s o c r a t e s m o r t a l
Yes

Exemplo 9.2. Exemplo


Descrio: Dado um conjunto de animais determinar a cadeia alimentar de um animal
qualquer.
O programa Prolog que descreve estas relaes pode ser representado como a seguir.
Cdigo:
anim al ( u r s o ) .
anim al ( p e i x e ) .
anim al ( p e i x i n h o ) .
anim al ( g u a x i n i m ) .
anim al ( r a p o s a ) .
anim al ( c o e l h o ) .
anim al ( veado ) .
anim al ( l i n c e ) .
planta ( alga ).
p l a n t a ( grama ) .
come ( urso , p e i x e ) .
come ( p e i x e , p e i x i n h o ) .
come ( p e i x i n h o , a l g a ) .
come ( guaxinim , p e i x e ) .
come ( urso , g u a x i n i m ) .
come ( urso , r a p o s a ) .
come ( raposa , c o e l h o ) .
come ( c o e l h o , grama ) .
come ( urso , veado ) .
come ( veado , grama ) .
come ( l i n c e , veado ) .
c a d e i a a l i m e n t a r (X, Z) :
come (X, Z ) .
c a d e i a a l i m e n t a r (X, Z) :
come (X, Y) ,
c a d e i a a l i m e n t a r (Y, Z ) .

Consulta:
? c a d e i a a l i m e n t a r ( urso , Y ) .
Y = peixe ;
Y = guaxinim ;
Y = raposa ;
Y = veado ;
Y = peixinho ;
Y = alga ;
Y = peixe ;
Y = peixinho ;

23

Y =
Y =
Y =
Y =
No

alga ;
coelho ;
grama ;
grama ;

A repetio de elementos ocorre, pois, um urso come um animal z diretamente e come


algum animal y que come z. Ento, a cada vez que um animal aparece na cadeia alimentar
de um urso ele ser exibido.

Exemplo 9.3. Exemplo


Descrio: Implementar um cdigo para solucionar o jogo Torre de Hanoi, com n
peas. O jogo formado por uma base contendo trs pinos, em um destes pinos esto
dispostos sete discos uns sobre os outros, em ordem crescente de dimetro, de cima para
baixo, tal como ilustrado na Figura 5(a). O problema consiste em passar todos os discos
de um pino para outro qualquer, usando um dos pinos como auxiliar, de maneira que um
disco maior nunca que em cima de outro menor em nenhuma situao. O nmero de
discos pode variar sendo que o mais simples contm apenas trs. A Figura 5(a) ilustra
um possvel estado inicial e a Figura 5(b) ilustra um possvel estado nal para o estado
inicial exibido.

(a) Estado inicial para o jogo torre de hanoi.

(b) Estado nal para o jogo torre de hanoi.

Figura 5: Jogo Torre de Hanoi

Um programa Prolog que fornece solues para o jogo descrito pode ser implementado
como a seguir.
Cdigo:
h a n o i (N) :
move (N, e s q u e r d o , c e n t r a l , d i r e i t o ) .
move ( 0 , _, _, _) : ! .
move (N, A, B, C) :
M i s N 1,
move (M, A, C, B) ,
i n f o r m (A, B) ,
move (M, C, B, A ) .
i n f o r m (X, Y) :
w r i t e f ( `%w%w%w%w ' , [ ` Mova o d i s c o do p i n o ' , X, ` para o p i n o ' , Y] ) ,
nl .

Consulta:
? h a n o i ( 3 ) .
Mova o d i s c o do p i n o e s q u e r d o para o p i n o c e n t r a l

24

Mova
Mova
Mova
Mova
Mova
Mova
Yes

o
o
o
o
o
o

disco
disco
disco
disco
disco
disco

do
do
do
do
do
do

pino
pino
pino
pino
pino
pino

e s q u e r d o para o p i n o d i r e i t o
c e n t r a l para o p i n o d i r e i t o
e s q u e r d o para o p i n o c e n t r a l
d i r e i t o para o p i n o e s q u e r d o
d i r e i t o para o p i n o c e n t r a l
e s q u e r d o para o p i n o c e n t r a l

Para visualizar a soluo procure uma verso do jogo na internet, porm, o cdigo
implementado considera que o estado inicial do jogo contm todos os discos no pino da
esquerda, enquanto alguns verses disponveis na internet aceitam outras conguraes.

Exemplo 9.4. Exemplo


Descrio: O bubble sort, o mais simples algoritmo de ordenao. O algoritmo consiste em percorrer um vetor vrias vezes, em cada iterao o menor ou o maior elemento
colocado em sua posio correta no vetor.
O programa Prolog que implementa este algoritmo o exibido a seguir.
Cdigo:
b u b b l e s o r t ( Lista_In , Lista_Out ) :
append ( L_Front , [ A, B | R e s t ] , L i s t a _ I n ) ,
B < A, ! ,
append ( L_Front , [ B, A| R e s t ] , L_Rest ) ,
b u b b l e s o r t ( L_Rest , Lista_Out ) .
b u b b l e s o r t ( Lista , Lista ) .

%
%
%
%
%

L i s t a _ I n = [A + B | R e s t ]
c h e c a s e B menor que A
L_Rest = [ B + A| R e s t ]
u t i l i z a e regra recursivamente
L i s t a j e s t ordenada

Consulta:
? b u b b l e s o r t ( [ 2 , 3 , 1 , 7 , 5 , 4 ] , L ) .
L = [1 , 2 , 3 , 4 , 5 , 7] ;
No

Exemplo 9.5. Exemplo


Descrio: Dada uma lista de elementos, determine se ela um palndromo ou no.
Um palndromo uma palavra ou nmero cuja leitura a mesma, quer se faa da esquerda
para a direita, quer se faa da direita para a esquerda;
Cdigo:
palindrome ( [ ] ) .
p a l i n d r o m e ( [_ ] ) .
p a l i n d r o m e ( [ F |R ] ) :
append ( S , [ F ] ,R) ,
palindrome (S ) .

Consulta:
? p a l i n d r o m e ( [m, a ,m] ) .
Yes
? p a l i n d r o m e ( [m, a , a ] ) .

25

No
? p a l i n d r o m e ( [ s , o , c , o , r , r , a ,m,m, e , e ,m,m, a , r , r , o , c , o , s ] ) .
Yes

Exemplo 9.6. Exemplo


Descrio: Mximo Divisor Comum (M.D.C.). Dados dois inteiros positivos A e B,
o eu mximo divisor comum, C, o maior nmero que divide A e B sem deixar resto.
Para encontrar o m.d.c de dois nmeros necessrio trabalhar com trs casos, so eles:

se A=B, ento, C=A ou B;


se A < B, ento, C igual ao maior divisor comum de A e B - A;
se A > B, ento, C igual ao maior divisor comum de B e A - B.
Um programa Prolog que que implementa m.d.c pode ser representado como a seguir.
Cdigo:
mdc (A, A, A ) . mdc (A, B, C) :
A < B,
Temp i s B A,
mdc (A, Temp , C ) .
mdc (A, B, C) :
A > B,
Temp i s A B,
mdc (Temp , B, C ) .

Consulta:
? mdc ( 1 2 , 18 , C ) .
C = 6 ;
No
? mdc ( 4 , 4 ,C ) .
C = 4 ;
No

Exemplo 9.7. Exemplo


Descrio: Clculo de fatorial. Implementar um programa Prolog que realize o clculo
do fatorial de um nmero.
Cdigo:
fatorial (0 ,1).
f a t o r i a l (N, F) :
N>0,
N1 i s N 1,
f a c t o r i a l (N1 , F1 ) ,
F i s N F1 .

26

Consulta:
? f a t o r i a l ( 3 ,W) .
W= 6 ;
No
? f a t o r i a l ( 4 , X ) .
X = 24 ;
No

Exemplo 9.8. Exemplo


Descrio: Implementar um programa que determina se um determinado dia faz parte
de um dia da semana ou nal de semana. Note que a determinao de uma categoria j
exclui a possibilidade de que o elemento pertena a outra categoria, ou seja, no existe
um dia que seja semana e nal de semana.
Cdigo:
semana ( s e g u n d a ) .
semana ( t e r c a ) .
semana ( q u a r t a ) .
semana ( q u i n t a ) .
semana ( s e x t a ) .
fimdesemana ( s a b a d o ) .
fimdesemana ( domingo ) .
c a t e g o r i a (X) :
fimdesemana (X) ,
w r i t e f ( `%w%w ' , [ X, ` um f i n a l de semana . ' ] ) ,
!.
c a t e g o r i a (X) :
semana (X) ,
w r i t e f ( `%w%w ' , [ X, ` um d i a de semana . ' ] ) ,
!.

Consulta:
? c a t e g o r i a ( s e g u n d a ) .
s e g u n d a um d i a de semana .
Yes .
? c a t e g o r i a ( domingo ) .
domingo um f i n a l de semana .
Yes .

10

Exerccios

As questes 10.1 at 10.4 so relacionadas ao programa Prolog apresentado a seguir:


g e n i t o r ( pam , bob ) .
g e n i t o r ( tom , bob ) .
g e n i t o r ( tom , l i z ) .

27

g e n i t o r ( bob , ann ) .
g e n i t o r ( bob , pat ) .
g e n i t o r ( pat , jim ) .
mulher (pam ) .
mulher ( l i z ) .
mulher ( pat ) .
mulher ( ann ) .
homem( tom ) .
homem( bob ) .
homem( jim ) .
p r o l e (Y,X) : g e n i t o r (X,Y ) .
mae (X,Y) : g e n i t o r (X,Y) , mulher (X ) .
avos (X, Z ) : g e n i t o r (X,Y) , g e n i t o r (Y, Z ) .
irma (X,Y) : g e n i t o r ( Z ,X) , g e n i t o r ( Z ,Y) , mulher (X) , not (X = Y ) .
d e s c e n d e n t e (X, Z ) : g e n i t o r (X, Z ) .
d e s c e n d e n t e (X, Z ) : g e n i t o r (X,Y) , d e s c e n d e n t e (Y, Z ) .

Exerccio 10.1. Quais as respostas para as seguintes consultas?


1. ?- genitor(X, jim).
2. ?- genitor(jim, X).
3. ?- genitor(pam, X), genitor(X, pat).
4. ?- genitor(pam, X), genitor(X, Y), genitor(Y, jim).

Exerccio 10.2. Formule consultas para descobrir:


1. Quem so os pais de Pat?
2. Liz possui lhos?
3. Quem o av de Pat?
4. Quem a me de Jim?
5. Quem o irmo de Bob?
6. Quem a irm de Pat?

Exerccio 10.3. Formule regras para as seguintes relaes:


1. tio(a);
2. irmo;
3. avs paternos;
4. avs maternos;
5. ascendente (o inverso de descendente);
6. primo(a), insira novos fatos para realizar consultas sobre esta relao.
28

Exerccio 10.4. Em quais das seguintes consultas Prolog utiliza encadeamento para trs?
1. ?- genitor(pam, bob).
2. ?- mae(pam, bob).
3. ?- avos(pam, ann).
4. ?- avos(bob, jim).

Exerccio 10.5. Considere as seguintes premissas:

Todos os animais tm pele. Peixe um tipo de animal, pssaros so outro tipo e


mamferos so um terceiro tipo. Normalmente, os peixes tm nadadeiras e podem nadar,
enquanto os pssaros tm asas e podem voar. Se por um lado os pssaros e os peixes pem
ovos, os mamferos no pem. Embora tubares sejam peixes, eles no pem ovos, seus
lhotes nascem j formados. Salmo um outro tipo de peixe, e considerado uma delcia.
O canrio um pssaro amarelo. Uma avestruz um tipo de pssaro grande que no voa,
apenas anda. Os mamferos normalmente andam para se mover, como por exemplo uma
vaca. As vacas do leite, mas tambm servem elas mesmas de comida (carne). Contudo,
nem todos os mamferos andam para se mover. Por exemplo, o morcego voa.
Considere ainda que existem os seguinte animais:
1. Piupiu, que um canrio.
2. Nemo, que um peixe.
3. Tutu, que um tubaro.
4. Mimosa, que uma vaca.
5. Vamp, que um morcego.
6. Xica, que uma avestruz.
7. Alfred, que um salmo.
Dena fatos e regras Prolog que representam as premissas acima, e formule consultas
Prolog para responder s seguintes perguntas:
1. O piupiu voa?
2. Qual a cor do piupiu?
3. A Xica voa?
4. A Xica tem asas?
5. O Vamp voa? Tem asas? Poem ovos?
6. Quais os nomes dos animais que pem ovos?
7. Quais os nomes dos animais que so comestveis?
29

8. Quais os nomes dos animais que se movem andando?


9. Quais os nomes dos animais que se movem nadando mas no pem ovos?
As questes 10.6 at 10.8 so relacionadas ao programa Prolog apresentado a seguir:
animal ( u r s o ) .
animal ( p e i x e ) .
animal ( p e i x i n h o ) .
animal ( guaxinim ) .
animal ( r a p o s a ) .
animal ( c o e l h o ) .
animal ( veado ) .
animal ( l i n c e ) .
planta ( alga ) .
p l a n t a ( grama ) .
come ( urso , p e i x e ) .
come ( p e i x e , p e i x i n h o ) .
come ( p e i x i n h o , a l g a ) .
come ( guaxinim , p e i x e ) .
come ( urso , guaxinim ) .
come ( urso , r a p o s a ) .
come ( raposa , c o e l h o ) .
come ( c o e l h o , grama ) .
come ( urso , veado ) .
come ( veado , grama ) .
come ( l i n c e , veado ) .
p r e s a (X) : come (_, X) , animal (X ) .

Exerccio 10.6. Quais as respostas para as seguintes consultas?


1. ?- come(urso, peixinho).
2. ?- come(raposa, coelho).
3. ?- come(guaxinim, X).
4. ?- come(X, grama).
5. ?- come(urso, X), come(X, coelho).
6. ?- presa(X), not(come(raposa, X)).

Exerccio 10.7. Formule regras para as seguintes relaes:


1. herbvoro;
2. carnvoro.

Exerccio 10.8. Utilizando a regra da questo anterior, elabore consultas para as seguintes
perguntas:

1. Quais animais so herbvoros?


30

2. Quais animais so carnvoros?


3. Quais animais herbvoros so presas de uma raposa?

Exerccio 10.9. Elabore um programa Prolog que fornea o nome da capital de qualquer

estado brasileiro.

Exerccio 10.10. Implemente um programa para determinar quais tipos sanguneos podem doar/receber sangue de quais tipos. A tabela seguinte fornece a informao necessria
para a implementao.

A
B
AB
O

Tabela 1: Tipos sanguneos.


A
B
AB
Doa/Recebe
Doa
Doa/Recebe
Doa
Recebe
Recebe
Doa/Recebe
Doa
Doa
Doa

O
Recebe
Recebe
Recebe
Doa/Recebe

Exerccio 10.11. Dena:


1. um predicado que fornea a interseco de duas listas;
2. um predicado que identique se um conjunto de elementos est contido em uma lista;
3. dois predicados que identiquem se uma lista possui tamanho par ou mpar;
4. um predicado que escreva uma lista em ordem inversa. Dica: utilize concatenao;
5. um predicado que retorne o maior valor contido em uma lista numrica;
6. um predicado para obter a soma dos N primeiros nmeros naturais.

Exerccio 10.12. Implemente um programa que retorne a N-sima potncia de um nmero.


Exerccio 10.13. As regras abaixo identicam se um nmero positivo, negativo ou zero.

Dena regras que realizem o mesmo procedimento, porm, de maneira mais eciente.
Dica: utilize cortes.
checagem (N, p o s i t i v o ) : N > 0 .
checagem ( 0 , z e r o ) .
checagem (N, n e g a t i v o ) : N < 0 .

Exerccio 10.14. Implemente um programa que classique se uma pessoa considerada:


criana (idade <= 12), adolescente (12 < idade <= 18 ), adulto (18 < idade <= 65) ou
idoso (65 < idade).
Obs.: Utilize cortes para melhorar a ecincia do programa.

Exerccio 10.15. Implemente um programa que fornea o signo de uma pessoa, mediante
a uma consulta do tipo dataNascimento(DD,MM, Signo).
Obs.: Utilize cortes para melhorar a ecincia do programa.

31

Exerccio 10.16. Um estudante acostumado a usar linguagens procedimentais est de-

senvolvendo um compilador em Prolog. Uma das tarefas consiste em traduzir um cdigo


de erro para uma pseudo-descrio em portugus. O cdigo por ele usado :
t r a d u z a ( Codigo , S i g n i f i c a d o ): Codigo =1, S i g n i f i c a d o=i n t e g e r _ o v e r f l o w .
t r a d u z a ( Codigo , S i g n i f i c a d o ): Codigo =2, S i g n i f i c a d o=d i v i s a o _ p o r _ z e r o .
t r a d u z a ( Codigo , S i g n i f i c a d o ): Codigo =3, S i g n i f i c a d o=i d _ d e s c o n h e c i d o .

O cdigo funciona, porm, pode ser implementado de outra maneira (mais descritiva e
menos procedimental). Melhore o cdigo.

32

Referncias
[1] Ivan Bratko. Prolog Programming for Articial Intelligence. Addison-Wesley, 1986.
[2] L. Sterling e E. Shapiro. The Art of Prolog. MIT Press, 1986.
[3] Marco Antnio Casanova, Fernando Giorno, and Antnio L. Furtado. Programao
em lgica e a linguagem Prolog. Edgar Blucher, 1987.
[4] Judith L. Gersting. Fundamentos matemticos para Cincia da Computao. LTC,
2001.
[5] Logic Programming Associates. Logic Programming Associates. www.lpa.co.uk/,
2006.
[6] Mike Brady. Open Prolog Home Page. www.cs.tcd.ie/open-prolog/, 2006.
[7] The Computational logic,
Languages,
Implementation,
and Parallelism Laboratory.
The Ciao Prolog Development System WWW Site.
www.clip.dia..upm.es/Software/Ciao, 2006.
[8] LIACC-Universidade do Porto and COPPE Sistemas-UFRJ. Yet Another Prolog.
www.ncc.up.pt/ vsc/Yap, 2006.
[9] Jan Wielemaker. What is SWI-Prolog? www.swi-prolog.org/, 2006.
[10] Swedish Institute of Computer Science. SICStus Prolog. www.sics.se/sicstus/, 2006.
[11] Amzi! Inc. AMZI! www.amzi.com/, 2006.
[12] Prolog Development Center. Visual Prolog. www.visual-prolog.com/, 2006.
[13] Daniel Diaz. The GNU Prolog web site. gnu-prolog.inria.fr, 2003.
[14] Stony Brook University. Welcome to the home of XSB! xsb.sourceforge.net/, 2006.
[15] TRINC. Trinc Prolog R3a. www.trinc-prolog.com, 2006.
[16] University of Amsterdam.
SWI-Prolog
gollem.science.uva.nl/SWI-Prolog/Manual/, 2006.

5.6.17

Reference

Manual.

33

Você também pode gostar