You are on page 1of 99

c  

 

       

Rafael Rosario
rafael.rosario@sociesc.org.br
rafael.rosario@datasul.com.br
÷ROLOG (I)
Foi criada em meados de 1972 por Alain Colmerauer e
÷ ilippe Roussel, na Universidade de Marsel a.

O nome ÷ROLOG foi escol ido por ÷ ilippe Roussel


como uma abreviação de ͞ grammation en
ique͟.

÷ropósito da criação: criar programas para tradução de


linguagens faladas, como português ou inglês.
÷ROLOG (II)
Fundamentada na  ;

É uma linguagem declarativa: em vez de o programa


estipular a maneira de c egar à solução, passo a
passo, limita-se a fornecer uma descrição do
problema que se pretende computar.

Usa uma coleção de  e de relações lógicas (  )


que exprimem o domínio relacional do problema.
÷ROLOG(III)
Outro fato que o difere das outras linguagens é o fato
de não possuir estruturas de controle (if-else, do-
w ile, for, switc ). ÷ara isso utilizamos métodos
lógicos para declarar como o programa deverá atingir
o seu objetivo.

Um programa em ÷ROLOG pode rodar em um modo


interativo: o usuário poderá formular queries
utilizando fatos e regras para produzir a solução
através do mecanismo de unificação.
Fato (I)
Determina uma relação existente entre objetos
con ecidos. Expressa uma verdade sobre um
relacionamento:

omem(jose).
pai(jose,carina).

omem / pai ʹ ÷redicado ou Relação.


jose / jose,carina ʹ Argumento do ÷redicado ou
Objeto
Fato (II)
Os nomes dos predicados e dos objetos devem começar
com letra minúscula.

Os objetos são escritos dentro de parênteses.

Todo fato é terminado com um ponto final.

A ordem dos objetos é importante:


pai (jose, carina). Ã pai (carina, jose).
Fato (III)
Com fatos, podemos montar uma base de con ecimento:

pai(alfredo,moacyr).
pai(alfredo,romeu).
pai(moacyr,eduardo).
pai(moacyr,rafael).
pai(moacyr,vinicius).
pai(romeu,cezar).
pai(romeu,alfredin o).
Regra (I)
Expressa um relacionamento entre fatos. Um
relacionamento em uma regra é verdadeiro se os
outros relacionamentos nessa regra também o são:

luz(acesa) :- interruptor(ligado).

O ":-" significa "se"; ou seja, essa regra significa que


luz(acesa) é verdadeiro se interruptor(ligado) é
verdadeiro.
Regra (II)
Regras podem também fazer uso de variáveis:
avo(X,Z) :- pai(X,Y), pai(Y,Z).
Isso significa "se X é pai de Y e Y é pai de uma Z, então
X é avô de Z͞.

X, Y e Z são variáveis. No ÷ROLOG,uma variável não é


um contêiner cujo valor pode ser atribuído. Seu
comportamento é como de uma incógnita, cujo valor
é descon ecido a princípio e, após descoberto, não
sofre mais mudanças. Escritas sempre em Maiúsculo.
Consulta (I)
Quando de uma consulta, a máquina ÷ROLOG pesquisa
a base de dados procurando cláusulas que se
unifiquem com a consulta:

? ʹ pai(moacyr, rafael).

Responderá   se localizar um fato que se unifique


com a consulta; se o fato consultado não existir na
base de dados, responderá 

Consulta (II)
Quando uma consulta contém variáveis, é realizada
uma pesquisa em todas as cláusulas, localizado os
objetos que essas representam:
?- avo(alfredo,N).
N = eduardo ;
N = rafael ;
N = vinicius ;
N = cezar ;
N = alfredin o.
Regras Recursivas
Um predicado definido por uma regra recursiva deve
ter, no mínimo uma definição não recursiva. Se isto
não acontecer, a definição é logicamente mal-
formada e o programa ficaria em laço infinito.

ancestral(X,Y) :- mae(X,Y).
ancestral(X,Y) :- pai(X,Y).
ancestral(X,Y) :- mae(X,Z),ancestral(Z,Y).
ancestral(X,Y) :- pai(X,Z),ancestral(Z,Y).
÷rática 1
Crie a árvore genealógica da sua família, utilizando os
predicados pai e mae, e verifique o que retorna cada
consulta:
ß ancestral(fulano,ciclano).
ß ancestral(X,ciclano). /*clique n a cada valor*/
ß ancestral(fulado,Y). /*clique n a cada valor*/
ß ancestral(fulado,_). /*clique n a cada valor*/
ß mae(X,_). /*clique n a cada valor*/
ß ancestral(X,_),pai(X,Y),pai(Y,_)
÷rática 1 - exemplo
mae(zilda,moacyr).
mae(zilda,romeu).
mae(maria,eduardo).
mae(maria,rafael).
mae(maria,vinicius).
mae(norma,cezar).
mae(norma,alfredin o).

pai(alfredo,moacyr).
pai(alfredo,romeu).
pai(moacyr,rafael).
pai(moacyr,eduardo).
pai(moacyr,vinicius).
pai(romeu,cezar).
pai(romeu,alfredin o).
Outros conceitos (I)
h   : (͞E͟ Lógico) é feita colocando-se uma
vírgula entre os fatos:
avo(X,Z) :- pai(X,Y)  pai(Y,Z).

!!: é usado para a quantidade de objetos


que o argumento de um predicado possui.
gosta (maria, josé). /* aridade = 2 */
bebe (penélope, pinga, vodka, rum). /*4*/
Outros conceitos (II)
a : uma consulta é avaliada como falsa no caso
de não estar presente nen uma regra positiva ou
fato que dê suporte ao termo proposto. Em outras
palavras, se um fato não é con ecido ser verdadeiro
(ou falso), assume-se que ele é falso.
legal(X) :- "# ilegal(X).

$   % quando duas variáveis não podem ter o


mesmo valor:
vizin o(X,Y) :- rua(X,Z), rua(Y,Z), X "&& Y.
Outros conceitos (II)
$  % (OU lógico), quando se declara mais de uma
regra para determinar uma mesma relação:

vizin o(X,Y) :- rua(X,Z), rua(Y,Z), X \== Y' rua(X,Z), rua


(X,W), proximo(Z,W).
÷rática 2
A partir da árvore genealógica da sua família, crie as
funções para:

ß irmão;
ß meio-irmão;
ß primo;
Resposta - ÷rática 2 (I)
irmao(X,Y) :- pai(÷,X), pai(÷,Y),
mae(M,X),mae(M,Y), X \== Y.

meio-irmao(X,Y) :-
pai(÷,X), pai(÷,Y), X \== Y, \+ irmao(X,Y)'
mae(M,X),mae(M,Y), X \== Y, \+ irmao(X,Y).
Resposta - ÷rática 2 (II)
genitor(X,Y) :- pai(X,Y); mae(X,Y).

primo(X,Y) :- genitor(÷,X), genitor(T,Y),


÷ \== T,
genitor(V,÷), genitor(V,T).
Aplicações (I)
ß Lógica matemática, prova de teoremas e semântica;

ß Solução de equações simbólicas;

ß Bancos de dados relacionais;

ß Linguagem Natural;

ß Sistemas Especialistas;
Aplicações (II)
ß ÷lanejamento Automático de Atividades;

ß Aplicações de ͞General ÷roblem Solving͟, como jogos


(Xadrez, Damas, Jogo da Vel a, etc.);

ß Compiladores;

ß Análise Bioquímica e projetos de novas drogas.


Revisando ʹ 3 elementos ÷rolog (I)

ð:
gosta(rafael,cac orro).
valioso(ouro).
pai(moacyr,rafael).
Revisando ʹ 3 elementos ÷rolog (II)

 :
avo(X,Z) :- pai(X,Y), pai(Y,Z).
fil o(Y,X) :- pai(X,Y), omem(Y).
aluno(X,ia) :- estuda(X,prolog).
Revisando ʹ 3 elementos ÷rolog (III)

ß h  ( ):


? ʹ avo (alfredo, rafael).
? ʹ primo (cezar, X).
? ʹ pai (moacyr,_).
? ʹ pai (X, eduardo).
Operadores de Controle
O ÷rolog utiliza de alguns operadores de controle para
tratamento da recursividade:

ß Backtracking;
ß Cut;
ß Fail.
Backtracking (I)
* *  (  ): mecanismo usado pelo
÷rolog para encontrar fatos ou regras adicionais que
satisfaçam um objetivo;

Quando a questão possui muitas sub-metas, a fal a em


uma busca pode acontecer.

Neste momento, o ÷rolog precisa de uma maneira para


͞lembrar͟ os pontos de onde pode tentar procurar a
solução, para encontrar uma resposta certa.
Backtracking (II)
Considere a seguinte Base de Con ecimento:
gosta (maria, pizza).
gosta (maria, vin o).
gosta (joão, vin o).
gosta (joão, maria).

É realizada a questão:
? - gosta (maria, X), gosta (joão, X).
Backtracking (III)
? - gosta (maria, X)
X = pizza
? - gosta (joao, comida) ʹ fail..
Neste ponto, o ÷rolog precisa ignorar esse valor para X
e procurar de onde ele avia parado anteriormente:
? - gosta (maria, X).
X = vin o.
? - gosta (joao, vin o) ʹ  
Cut (I)
O corte (cut) é um usado para evitar o O  

O corte pode tornar um programa mais rápido, pois


evita que o ÷rolog explore alternativas que, sabe-se
de antemão, não irão contribuir para a solução do
problema, e ainda permite a economia de memória.
Cut (II)
f(X,0) :- X < 3.
f(X,2) :- X >= 3, X < 6.
f(X,4) :- X >= 6.

Se infomar um valor > 3 -> retorna 0


Se informar um valor entre 3 e 6 -> retorna 2
Se informar um valor > ou igual a 6 ->retorna 4
  % + , (-).
Cut (II)
O ÷rolog usando backtracking trata 2 regras que
sabemos que irão fal ar...

As 3 regras são mutuamente exclusivas: no momento


em que uma funciona, não faz sentido tratar as
outras 2.
÷ara isso usamos o Cut (!):
f(X,0) :- X < 3, !.
f(X,2) :- X >= 3, X < 6, !.
f(X,4) :- X >= 6.
÷rática 3
Utilizando o Cut (!), escreva uma regra para
validar se alguém tem um irmão, sem ter
pesquisar toda a árvore:

tem_irmao(X) :- +++
÷rática 3 - Resposta
Utilizando o Cut (!), escreva uma regra para
validar se alguém tem um irmão, sem ter
pesquisar toda a árvore:

/ (0) %,  (0/) 1.


Fail (I)
Inversamente ao comando cut, o predicado pré-
definido  sempre fal a.

O operador de corte (!) pode ser combinado com o


predicado fail para produzir uma fal a forçada:

gosta(maria,X) :- rato(X), !, fail.


gosta(maria,X) :- animal(X).
÷rática 4
÷odemos escrever a regra diferente de diversas formas:
diferente1(X,Y) :- \+ X = Y.
diferente2(X,Y) :- X\== Y.

Escreva utilizando o cut (!) e fail:


÷rática 4 - Resposta
÷odemos escrever a regra diferente de diversas formas:
diferente1(X,Y) :- \+ X = Y.
diferente2(X,Y) :- X\== Y.

Escreva utilizando o cut (!) e fail:

!   (00) %, 1 .
!   (0-).
Comando ͞Is͟ (I)
Avalia a expressão e unifica o resultado. Exemplos:

+  0  2 # 3
X = 12

+ .2  2 4 .2.
true
Comando ͞Is͟ (II)
Também pode ser usada para criar funções
matemáticas:

divisao(X,Y,Z) :- Z is X / Y.

? divisao (10, 3, N).


N = 3.33333
Fatorial
Fatorial usando comando ͞is͟:

fatorial (0,1).
fatorial (N,F) :- N1 is N - 1,
fatorial(N1,F1), F is N * F1.
fatorial(3,F) ʹ passo a passo (I)
fatorial (0,1).
fatorial (N,F) :- N1 is N ʹ 1, fatorial(N1,F1), F is N * F1.
-------------------------------------------------------
fatorial(0,1). fail
c5

fatorial (3,F) => N=3, N1 =2;

F 3 * F1
fatorial(3,F) ʹ passo a passo (II)
fatorial (0,1).
fatorial (N,F) :- N1 is N ʹ 1, fatorial(N1,F1), F is N * F1.
---------------------------------------------------------
fatorial(0,1). fail
c5

fatorial (3,F) => N=3, N1 =1;


fatorial (2,F) => N=2, N1 =1;
F 2 * F1
F 3 * F1
fatorial(3,F) ʹ passo a passo (III)
fatorial (0,1).
fatorial (N,F) :- N1 is N ʹ 1, fatorial(N1,F1), F is N * F1.
---------------------------------------------------------
fatorial(0,1). fail c5

fatorial (3,F) => N=3, N1 =1;


fatorial (2,F) => N=2, N1 =1; F 1 * F1
F 2 * F1
fatorial (1,F) => N=1, N1 =0;
F 3 * F1
fatorial(3,F) ʹ passo a passo (IV)
fatorial (0,1).
fatorial (N,F) :- N1 is N ʹ 1, fatorial(N1,F1), F is N * F1.
---------------------------------------------------------
fatorial(0,1).  
c5

fatorial (3,F) => N=3, N1 =1;


F 1
fatorial (2,F) => N=2, N1 =1; F 1 * F1
fatorial (1,F) => N=1, N1 =0; F 2 * F1
F 3 * F1
fatorial(0,F) => F = 1
fatorial(3,F) ʹ passo a passo (V)
fatorial (0,1).
fatorial (N,F) :- N1 is N ʹ 1, fatorial(N1,F1), F is N * F1.
---------------------------------------------------------
fatorial (3,F) => N=3, N1 =1;
c5

fatorial (2,F) => N=2, N1 =1;


fatorial (1,1) => N=1, N1 =0; F=1 1*1
F 2 * F1
F 3 * F1
fatorial(3,F) ʹ passo a passo (VI)
fatorial (0,1).
fatorial (N,F) :- N1 is N ʹ 1, fatorial(N1,F1), F is N * F1.
---------------------------------------------------------
fatorial (3,F) => N=3, N1 =1;
c5

fatorial (2,2) => N=2, N1 =1;

F=2 2*1
F 3 * F1
fatorial(3,F) ʹ passo a passo (VII)
fatorial (0,1).
fatorial (N,F) :- N1 is N ʹ 1, fatorial(N1,F1), F is N * F1.
---------------------------------------------------------
fatorial (3,6) => N=3, N1 =1;
c5

ð & 6

F=6 3*2
÷rática 5
•        7 %
fatorial (0,1).
fatorial (N,F) :- N1 is N ʹ 1, fatorial(N1,F1), F is N * F1.
+    (3ð). +    (88ð).

9  !   :;  !  +


fatorial (N,F) :- N1 is N ʹ 1, fatorial(N1,F1), F is N * F1.
fatorial (0,1).
Resposta - ÷rática 5
E se mudarmos a seqüência das regras?
fatorial (N,F) :- N1 is N ʹ 1, fatorial(N1,F1), F is N * F1.
fatorial (0,1).
ERROR: Un andled exception: Out of local stack

O ÷rolog entrou em loop e estourou a pil a (stack).


Isso porque ele sempre executa as regras na ordem
em que são colocadas.
Boas práticas (I)
De uma forma geral, é uma boa idéia colocar fatos
antes de regras sempre que possível:
amigo(rafael,pedro).
amigo(pedro,fernando).
amigo(fernando,murilo).
amigo(X,Y):-amigo(Y,X).
O que acontece se colocarmos a última cláusula por
primeiro, e fizermos uma consulta: amigo (X,Y) ?
Boas práticas (II)
Regras não recursivas normalmente devem ser
colocadas antes de regras recursivas:

ancestral(X,Y) :- mae(X,Y). /*nao recursivo*/


ancestral(X,Y) :- pai(X,Y). /*nao recursivo*/
ancestral(X,Y) :- mae(X,Z),ancestral(Z,Y).
ancestral(X,Y) :- pai(X,Z),ancestral(Z,Y).
Boas práticas (III)
Quando possível, usar validações que façam com que a
ordem das regras não cause loop:

fatorial(N,F) :- a < 8, N1 is N - 1,
fatorial(N1,F1), F is N * F1.
fatorial(0,1).
÷rática 6
1. Implemente:
max(X, Y, Max) /*use max(4,5,Max) para testar*/
2. A seguinte relação classifica números em três
classes: positivo, nulo ou negativo. Defina este
procedimento de forma mais eficiente usando cuts:
classe(N, positivo) :- N > 0.
classe(0, nulo).
classe(N, negativo) :- N < 0.
÷rática 6 - Respostas
Implemente:
max(X, Y, Max)
=(0 - 0) %, 0 <& -.
=(0 - -) %, 0 > -.

=(0 - 0) %, 0 <& - 1.
=(0 - -).
÷rática 6 - Respostas
(a ?) %, a < 8 1.
(a ?) %, a > 8 1.
(8 ).
Operadores infixos (I)
E se eu quisessemos realizar consultas utilizando
uma linguagem mais próxima da nossa?

? - Quem tem carro.


? joana faz Oque?
Operadores infixos (II)
O programador ÷rolog pode definir seus próprios
operadores, como no exemplo:  e @.

A definição de novos operadores é realizada pela


inserção de um tipo especial de cláusula c amada
! ?.

As diretivas devem aparecer antes de qualquer


expressão que conten a o operador criado.
Diretivas (I)
Exemplo de diretiva:
:- op (500, xfx, tem).

Onde:
288 indica a prioridade do operador;
= = indica que o operador (f) deve ser colocado
entre dois argumentos (x);
 indica o nome do operador.
Diretivas (II)
Tendo a diretiva, criamos a base de con ecimento:
pedro tem carro.
joana tem din eiro.
joao tem problemas.
joao tem dívidas.
E fizemos as consultas:
?- Quem tem carro.
Quem = pedro.
Diretivas (III)
h !!: os ͞comandos͟ que usamos no ÷rolog,
são diretivas pré-definidas na sua implementação:

:- op (1200, xfx, ͚:-͛);


:- op (1200, fx [͚:-͛, ͚?-]).
:- op (1100, xfx, ͚;͛)
:- op (1000, xfx, ͚,͛) /* etc...*/

Note que alguns operadores (ex.: ͚%,͛), possuem


definição infixa (xfx) e prefixa (fx).
÷rática 7
1. Crie duas diretivas novas com operador infixo, e
uma base de con ecimento usando estas diretivas.

2. Em seguida crie consultas que se assemel em a


linguagem umana. Exemplos:

? - fulado con ece Quem.


? - ciclano mora Onde.
Operadores de Comparação
Lista completa dos operadores de comparação:
 9
$ cc$
$9 •c  Acacðch
$
> 700 xfx maior que
< 700 xfx menor que
>= 700 xfx maior ou igual a
<= 700 xfx menor ou igual a
=:= ou == 700 xfx valores iguais
=\= ou \== 700 xfx valores diferentes
Base de dados relacional (I)
Como criar uma base de dados relacional em ÷rolog?
Como pesquisar resultados dentro dessa base?

nasceu(pedroBarnack,joinville,1978).
nasceu(murilo÷ereira,itajai,1980).
nasceu(rafaelRosario,joinville,1980).
nasceu(janineBoos,joinville,1985).
nasceu(douglasSouza,curitiba, 1970).
Base de dados relacional (II)
Como perguntamos:
Nome e ano de nascimento dos curitibanos?
?- nasceu(Quem,curitiba,Ano).
Quem nasceu em joinville a partir de 1980?
?- nasceu(Quem,joinville,Ano),Ano >= 1980.
Nome e ano de nascimento de quem nasceu antes
de 1980 (sem trazer a cidade)?
?- nasceu(Quem,_,Ano), Ano < 1980.
÷rática 8
Crie um banco de dados que conten as as seguintes
informações:
ß Nome do ÷rofessor e disciplina que leciona;
ß Disciplina e orário (dia da semana, aula: primeiro
ou segundo orário);
Construa as consultas para responder:
1. Qual o orário do professor X (disciplina, dia e aula)?
2. Quais professores lecionam na terça-feira?
3. Quais matérias o professor X leciona no primeiro orário?
÷rática 8 - resposta
1. orario_prof(÷,D,S,A) :- leciona(÷,D), orario(D,S,A).
? - orario_prof(rafael,Disc,DiaSemana,Aula) .

2. ?- leciona(X,Disciplina) , orario(Disciplina,3,Aula).

3. ?- leciona(eduardo,Disc), orario(Disc,_,aula1).*/

 ! !!%
leciona(rafael,ia).
leciona(eduardo,redes).
orario(ia,2,aula1).
orario(ia,5,aula1).
orario(redes,3,aula1).
orario(redes,4,aula2).
÷rática 8 ʹ resposta 2 (I)
:- op(500, xfx, leciona).
:- op(450, xfx, e _lecionada_na).
:- op(400, xfx, no_ orario).
:- op(300, fx, qual_o_ orario_do_professor)

qual_o_ orario_do_professor(÷rof, Materia,


DiaSemana, SeqAula) :-
÷rof leciona Materia, Materia e _lecionada_na
DiaSemana no_ orario SeqAula.
÷rática 8 ʹ resposta 2 (II)
 ! !!%
rafael leciona ia.
eduardo leciona redes.
ia e _lecionada_na segunda_feira no_ orario primeira_aula.
ia e _lecionada_na quinta_feira no_ orario primeira_aula.
redes e _lecionada_na terca_feira no_ orario primeira_aula.
redes e _lecionada_na quarta_feira no_ orario segunda_aula.
÷rática 8 ʹ resposta 2 (III)
1. ? - qual_o_ orario_do_professor(eduardo, Materia,
DiaSemana, SeqAula).

2. ?- ÷rofessor leciona Materia, Materia


e _lecionada_na terca_feira no_ orario Qualquer.

3. ?- ÷rofessor leciona Materia, Materia


e _lecionada_na DiaSemana no_ orario
primeira_aula. /*ou _ no lugar de DiaSemana*/
Listas
Listas podem ser definidas e transformadas em ÷rolog
de diversas maneiras diferentes.

Listas são representadas por []:


[a,e,i,o,u];
[1,2,3,5,7,11];
Composição de Lista
Listas são compostas por uma cabeça e uma cauda:
ß [H,T];

Na lista [1,2,3,5,7], podemos dizer que:


ß  é a cabeça da lista
ß È23B é a cauda da lista;
ß De maneira similar,  e È23B são
respectivamente a cabeça e a cauda da sub-lista
È23B ;
Construindo uma Lista
Um lista é construída a partir de seus elementos
básicos - uma  e um   (ou cauda):

cons(X, Y, [X | Y]).
?-cons(a, b, Z).
Z=[a | b]
Ocorrência de elementos na Lista (I)

÷ara verificar se um elemento é membro de uma lista,


precisamos construir uma regra.
÷odemos definir que tal regra gere os resultados
abaixo:

? - membro(, [a,b,c,d]).  .


? - membro(, [a,b,c,d]).  .
? - membro (, [a,b,c,d]). 
Ocorrência de elementos na Lista (II)

Ou seja, dada uma lista L, X é membro de L se:


1. X é a cabeça de L;
+ ,  ( È!B).

2. Ou X é membro do corpo de L.
+ ,  ( È!B).
Ocorrência de elementos na Lista (III)

A regra membro (X,L) terá duas cláusulas:

ß A primeira, um fato, estabelece a primeira condição:


X é membro de L, se X é a cabeça de L.
ß A segunda, é uma c amada recursiva que diz que X
ainda pode ser membro de L, desde que seja
membro do corpo de L:
 (0 È0 C hB).
 (0 È- C hB) %,  (0 h).
÷rática 9
Dada a variante de implementação da regra membro:
membro2(X, [H | T]) :- X == H.
membro2(X, [H | T]) :- membro2(X, T).

1. Habilite o Debug gráfico (menu Debug -> Grap ical


Debugger). Use o comando trace. Em seguida,
execute membro(d,[a,b,c,d]) e veja passo a passo.
2. Execute membro(X,[a,b,c]) e membro2 (X,[a,b,c]).
Qual das funções funciona? ÷or que?
Concatenação de listas (I)
÷ara a concatenação de duas listas quaisquer,
resultando em uma terceira, se definirá a relação:
 (  ).

onde L1 e L2 são duas listas e L3 é a concatenação


resultante. ÷or exemplo:
+ ,  (È B È !B )
 & È   !B.
Concatenação de listas (II)
Novamente, dois casos devem ser considerados,
dependendo do primeiro argumento L1:

Se o primeiro argumento é uma lista vazia, então o


segundo e o terceiro argumentos devem ser a
mesma lista.
C amando tal lista de L, essa situação pode ser
representada pelo seguinte fato ÷rolog:
 (ÈB  ).
Concatenação de listas (III)
Se o primeiro argumento for uma lista não-vazia, então
é porque ela possui uma cabeça e um corpo, e pode
ser denotada por [X|L1].

A concatenação de [X|L1] com uma segunda lista L2,


produzirá uma terceira lista, com a mesma cabeça X
da primeira e um corpo (L3) que é a concatenação do
corpo da primeira lista (L1), com toda a segunda (L2).
Isso se representa em ÷rolog por meio da regra:
 (È0 C B  È0 C B) %,  (  ).
Concatenação de listas (IV)
conc([1,2],[3,4]).

conc([X | L1], L2, [X |L3]) :- conc (L1,L2,L3) será:


conc([1|[2]), [3,4], [1,L3]) :- conc ([2],[3,4], L3).
conc ([2],[3,4], L3).
conc(2, [], [3,4], [2,L3]) :- conc ([],[3,4], L3).
conc ([],[3,4], L3).
conc([],L,L).
conc([], [3,4], [3,4])
Concatenação de listas (V)
conc([1,2],[3,4]).

conc([X | L1], L2, [X |L3]) :- conc (L1,L2,L3) será:


conc([1|[2]), [3,4], [1,L3]) :- conc ([2],[3,4], L3).
conc ([2],[3,4], L3).
conc(2, [], [3,4], [2,L3]) :- conc ([],[3,4], L3).
conc ([],[3,4], L3).  & ÈDB
conc([],L,L).  & ÈDB
conc([], [3,4], [3,4])
Concatenação de listas (VI)
conc([1,2],[3,4]).

conc([X | L1], L2, [X |L3]) :- conc (L1,L2,L3) será:


conc([1|[2]), [3,4], [1,L3]) :- conc ([2],[3,4], L3).
conc ([2],[3,4], L3).
conc(2, [], [3,4], [2,L3]) :- conc ([],[3,4], L3).
L3 = [3,4]
[X,L3] = [2,3,4]
Concatenação de listas (VII)
conc([1,2],[3,4]).

conc([X | L1], L2, [X |L3]) :- conc (L1,L2,L3) será:


conc([1|[2]), [3,4], [1,L3] :- conc ([2],[3,4], L3).
conc ([2],[3,4], L3).  & ÈDB È0B & ÈDB
÷rática 10
1) Utilize a regra conc/3 no sentido inverso ao que foi
originalmente projetado, para decompor uma lista
[a,b,c] em duas partes.
2) ÷odemos também usar o programa para procurar
por um determinado padrão em uma lista. Encontre
os meses antes e depois de um determinado mês:
? - M=[jan, fev, mar, abr, , jun, jul, ago, set, out,
nov, dez], <E  !  F>.
Antes=[jan,fev,mar,abr]
Depois=[jun,jul,ago,set,out,nov, dez]
Remover da lista (I)
A remoção de um elemento X de uma lista L pode ser
programada através da relação:

? (0  ).

onde L1 é a mesma lista L com o elemento X


removido.
Remover da lista (II)
A relação remover/3 é definida de maneira similar à
relação de ocorrência. São dois casos a estudar:

ß Se X é a cabeça da lista L, então L1 será o seu corpo;

ß Se X está no corpo de L, então L1 é obtida


removendo X desse corpo.

? (0 È0 C hB h).


? (0 È- C hB È- C $B) %, ? (0 h $).
Remover da lista (III)
Se á diversas ocorrências de X em L, a relação
remove/3 é capaz de retirar cada uma delas através
do mecanismo de backtracking do ÷rolog.
Em cada execução do programa remove/3 retiramos
somente uma das ocorrências de X, por exemplo:
+, ? ( È   B ).
&È  B'
&È  B'
&È  B'
÷rática 11
1) Utilize a regra remove/3 no sentido inverso, para
   um novo item em qualquer lugar da lista.

2) Crie uma nova cláusula para membro, utilizando a


regra remover/3.
bagOf, setOf e findAll
÷odemos gerar, através de backtracking, todos os
objetos, um a um, que satisfazem algum objetivo
(next, next, next).

÷orém, algumas vezes, deseja-se dispor de todas as


respostas juntas, por exemplo, dentro de uma lista.

Os predicados  F  F   !F servem


exatamente para tal propósito.
bagOf (I)
 (0  )
Irá produzir uma lista L de todos os objetos X que
satisfazem ao objetivo ÷.
Exemplo - dada a base de con ecimento abaixo:

( ?).
(  ).
(  ). F4    !  G 4F
bagOf (II)
÷odemos obter a lista de todas as consoantes nessa
especificação através do objetivo:

+, (  (   ) h  ).


h  &È  ! ... @B
bagOf (III)
Se a classe das letras não estivesse especificada,
iríamos obter por meio de backtracking, duas listas,
uma correspondendo às vogais e outra às
consoantes:

+, (  (  h)  ).


h&?  &È    B'
h&  &È  !  ... @B.
bagOf ʹ Outro Exemplo
Dada a base de con ecimento:
leciona(rafael,progII). leciona(rafael,ia).
leciona(eduardo,redes). leciona(eduardo,progI).

Qual seria o retorno da consulta:


?- bagof(Disc,leciona(rafael,Disc),Disciplinas).

E ?- bagof(Disc,leciona(÷rof,Disc),Disciplinas).
setOf (I)
 (0  )
Irá novamente produzir uma lista L dos objetos X que
satisfazem a ÷, só que desta vez a lista L estará
ordenada e itens duplicados, se ouver, serão
eliminados.
setOf (II)
Exemplo:

?- setof(Disc,e _lecionada(Disc,÷rof),Disciplinas).

÷rof = rafael
Disciplinas = [ia, progII]
÷rof = eduardo
Disciplinas = [progI, redes]
setOf (III)
Não á restrição quanto ao tipo de objeto a ser
coletado. Assim podemos, por exemplo, construir
uma lista de pares da forma Classe/Letra de forma
que as constantes apareçam em primeiro lugar na
lista ("con" antecede alfabeticamente "vog"):

?-setof(Classe/Letra, classe(Letra, Classe), Letras).


 &È F  F ...  F@ ?F ... ?FB
findall (I)
Teste no ÷rolog e descubra o que faz o findall/3
W at is next?

 %  H 

=  , $c
DF8D 
I
c
JK 9L $M 
A
Referências
ß ttp://pt.wikipedia.org/wiki/÷rolog
ß ttp://pt.wikipedia.org/wiki/Alain_Colmerauer
ß ttp://www.lin adecodigo.com.br/Artigo.aspx?id=1697
ß ttp://en.wikipedia.org/wiki/÷rolog
ß ttp://ccc.inaoep.mx/~emorales/Cursos/÷rogSimb/node32. tml
ß www.fei.edu.br/eletrica/r N/ia/Apostila- .doc
ß ttp://www.swi-prolog.org/
ß ttp://www.sics.se/isl/sicstuswww/site/index. tml
ß ttp://gersonc.ana y.org/graduacao/paradigmas/prologsan.pdf
ß ttp://ia.ucpel.tc e.br/~lpalazzo/Aulas/÷DEC/
ß ttp://gollem.science.uva.nl/SWI-÷rolog/apps/view. tml
ß ttp://www.fdi.ucm.es/profesor/fernan/des/