Introdução à Linguagem
Prolog
Prof. Fabrício Enembreck
PPGIA – Programa de Pós Graduação
em Informática Aplicada
Predicados Dinâmicos e Alocação
de Memória
• Visualizando cláusulas na memória
?- listing(p/2). (mostra todas as declarações referentes ao
predicado p/2)
• Adicionando programas da memória
:- dynamic p/2. (declara um predicado como dinâmico)
:- multifile p/2. (permite que cláusulas de um ou mais predicados
sejam declaradas em arquivos diferentes)
?- assert(p(a,a)). (insere como último fato)
?- asserta(p(b,b)). (insere como primeiro fato)
Predicados Dinâmicos e Alocação
de Memória (cont.)
• Removendo programas da memória
?- abolish(p/2). (remove todas as declarações relativas ao
predicado p/2)
?- abolish(p,2).
?- retract(p(_,_)). (remove a primeira cláusula – fato ou regra
- que “casa” como o parâmetro fornecido)
?- retractall(p(_,_)). (remove todas as cláusulas – fatos ou
regras - que “casam” como o parâmetro fornecido)
Predicados Dinâmicos e Alocação
de Memória (cont)
• Consultando arquivos:
?- consult(‘c:\\temp\\arquivo.pl’).
Exercícios
1)
Utilizando os predicados assert, asserta, retract, etc,
crie a seguinte base de fatos:
venda(‘joao da silva’, data(15,1,2005), 3, bola, 12.50).
venda(claudia, data(18,1,2005), 1, tenis, 89.45).
venda(‘joao claudio’, data(22,1,2005), 4, sabao, 1.35).
2) Altere o segundo fato na memória para:
venda(claudia, data(18,1,2005), 1, tenis, 109.45).
3) Crie arquivos que contém cláusulas de predicados
venda/5
4) Escreva um predicado no seu código-fonte que carrega
todos os fatos de todos os arquivos na memória
5) Escreva um predicado que soma o valor de todas as
vendas (vc deve utilizar um predicado dinâmico
cont/1)
Exercícios
6) Escreva um predicado que recebe como
entrada um determinado mês e calcula a soma
realizada naquele mês
Conteúdo do Curso
• Introdução à Lógica e à Programação
Lógica
• Introdução ao Prolog e ao SWI-Prolog
• Matching e Backtraking
• Listas e predicados recursivos
• Múltiplas soluções
Listas e predicados recursivos
• Listas são estruturas heterogêneas de
dados
• Exemplos de Listas
– [a]
– [o, homem, [gosta,pescar]]
– [a,V1,b,[X,Y], b(c)]
– []
Listas e predicados recursivos
• “[ ]” : Lista vazia
• Estrutura de uma Lista não vazia
[X | Y]
Cabeça
(é um elemento)
Corpo
(é uma lista)
Barra Vertical
Matching com Listas
• ?- [a,b,c] = [X|Y].
X=a
Y = [b,c]
• ?- [casa,carro,[corsa,golf]] = [X|Y].
X = casa
Y = [carro,[corsa,golf]]
• ?- [[a,b,c],e,f,g] = [X|Y].
X = [a,b,c]
Y = [e, f, g]
• ?- [[a,b,c],e,f,g] = [X,Y|Z].
X = [a,b,c]
Y = e Z = [f,g]
• ?- [[a,b,c],e,f,g] = [X,Y,Z|W].
X = [a,b,c]
Y=e
Z=f
• ?- [[a,b,c],e,f,g] = [X].
no
W =[g]
Predicados Recursivos com Listas
• Pertence
– Construir um predicado “pertence” que verifica se um
elemento existe dentro da lista
• Ex.: ?- pertence(2,[a,5,f(a), 2,casa]).
yes
Existem duas situações:
• O elemento desejado está na cabeça da lista
pertence(X,[X|_]).
• O elemento não está na cabeça da lista mas pode estar no
corpo da lista
pertence(X,[_|Y]) :pertence(X,Y).
3a. Chamada
Solução
Debugando
o “pertence”
• ?- pertence(c, [a,b,c]).
pertence(X,[X|_]).
pertence(X,[_|Y]) :pertence(X,Y).
X= c Y = [c]
2a. Chamada
Fail
pertence(X,[X|_]).
pertence(X,[_|Y]) :pertence(X,Y).
X= c Y = [c]
1a. Chamada
Fail
pertence(X,[X|_]).
pertence(X,[_|Y]) :pertence(X,Y).
X= c Y = [b,c]
Yes
Pesquisando elementos de uma
lista
• Construa um predicado Prolog que
encontre os elementos pares de uma lista
de inteiros
?- pares([2,45,21,12,8], L).
L = [2, 12, 8]
Pesquisando elementos de uma
lista
• Um procedimento recursivo sempre tem
um CRITÉRIO DE PARADA. Na maioria
das vezes esse critério é o de lista vazia
pares([], []). % Os pares de uma
% lista vazia resulta em outra lista vazia
pares([X|Y], [X|Z]) :- % se a cabeça é um elemento
par(X),
% par então o armazenamos e
pares(Y,Z).
% chamamos o pred. sobre o corpo
pares([_|Y], Z) :pares(Y,Z).
% se a cabeça não é um elemento
% par então o ignoramos e
% chamamos o pred. sobre o corpo
Exercícios
• Implemente os seguintes programas Prolog:
• ?- potencia(Base, Expo, V) % calcula a potência
• ?- n_elementos([a,b,c], X). % calcula o tamanho da lista
X=3
• ?- n_esimo(2, [a,b,c], X). % encontra o n-ésimo elem.
X=b
• ?- merge([1, 4, 12, 28], [6,7,10], X). % faz o merge
X = [1,4,6,7,10,12,28]
• ?- insere(a, 2, [1,2,3], L). % insere um elemento na posição
L = [1,a,2,3]
Exercícios
• ?- concatena([a,b,c],[1,2,3], L). % une duas listas
L = [a,b,c,1,2,3]
• ?- inverte([a,b,c], X).
X = [c,b,a]
• ?- ultimo([a,b,c],X).
% inverte uma lista
% encontra o último elem. da lista
Encontrando Múltiplas Soluções
• bagoff : retorna uma lista não ordenada de soluções. Se
não houver solução então falha
objeto(bola,azul).
objeto(bola,amarela).
objeto(carro,vermelho).
?- bagof(A,objeto(X,A),Lista).
A=_,
X = bola ,
Lista = [azul,amarela] ;
A=_,
X = carro ,
Lista = [vermelho] ;
no
?- bagof(A,X^objeto(X,A),Lista).
A=_,
X=_,
Lista = [azul,amarela,vermelho]
Encontrando Múltiplas Soluções
• setof : retorna uma lista ordenada de soluções. Se não
houver solução então falha
objeto(bola,azul).
objeto(bola,amarela).
objeto(carro,vermelho).
?- setof(A,objeto(X,A),Lista).
A=_,
X = bola ,
Lista = [amarela, azul] ;
A=_,
X = carro ,
Lista = [vermelho] ;
no
?- bagof(A,X^objeto(X,A),Lista).
A=_,
X=_,
Lista = [amarela, azul,vermelho]
Encontrando Múltiplas Soluções
• findall : retorna uma lista única não ordenada de
soluções. Se não houver solução então retorna lista
vazia.
objeto(bola,azul).
objeto(bola,amarela).
objeto(carro,vermelho).
?- findall(A,objeto(X,A),Lista).
A=_,
X = bola ,
Lista = [azul, amarela, vermelho]
Download

Introdução à Programação Lógica-Aula4