Вы находитесь на странице: 1из 34

Hugo Pires @ Universidade Lusfona do Porto

Prolog

Aula #7

J vimos que os termos compostos em prolog podem servir


para representarem estruturas de dados
Aliado s noes de unificao (matching), retrocesso
(backtracking) e s operaes aritmticas temos uma
ferramenta de programao poderosa

Hugo Pires @ Universidade


Lusfona do Porto

Estruturas de Dados

Consideremos a seguinte estrutura para representar uma


famlia (Bratko, 1986)
Cada famlia tem um pai, uma me, e um conjunto de filhos
(representado por uma lista)
Cada pessoa pode ser visto como tendo: nome prprio,
apelido, data de nascimento e situao profissional
A situao profissional indica o empregador e o salrio ou se a
pessoa est desempregada

Hugo Pires @ Universidade


Lusfona do Porto

Estruturas de Dados

manel

pessoa

silva

01

data

01
1970

emprego

ulp
2000

pessoa
familia

silva

01

data

12

luis

1972
emprego

03

cmp

silva

03

1500

data

2000

pessoa
.

pessoa

desempr
egado
marta

05

silva

05

data
desempr
egado

2003

Hugo Pires @ Universidade


Lusfona do Porto

maria

Estruturas de Dados
Em prolog pode ser representado por

me
filhos

pessoa(maria,silva,data(01,12,1972),emprego(cmp,1500) ),
[ pessoa(luis,silva,data(03,03,2000),desempregado),
pessoa(marta,silva,data(05,05,2003),desempregado) ]
).

Hugo Pires @ Universidade


Lusfona do Porto

pai

familia(
pessoa(manel,silva,data(01,01,1970),emprego(ulp,2000) ),

Estruturas de Dados

Em prolog podemos referir facilmente um objecto sem termos


de especificar particularmente todos os outros
Basta descrever a estrutura!

Hugo Pires @ Universidade


Lusfona do Porto

Desta forma podemos representar todas as famlias


E como obter a informao desta BC?
Muito simples!...

Estruturas de Dados
Exemplo:

E famlias com 3 filhos?


familia( _ , _ , [ _ , _ , _ ] ).
E o nome de todas as mulheres com 2 filhos?
familia( _ , pessoa( Nome, Apelido, _ , _ ) , [ _ , _ ]).

Hugo Pires @ Universidade


Lusfona do Porto

Como que nos podemos referir as famlias Silva?


familia( pessoa( _ , silva, _ , _ ), _ , _ ).

Estruturas de Dados
marido(X) :- familia( X, _ , _ ).
mulher(X) :- familia( _ , X, _ ).
filho(X) :- familia( _ , _ , Filhos), membro(X, Filhos).
existe(Pessoa) :- marido(Pessoa); mulher(Pessoa);
filho(Pessoa).
dataNascimento( pessoa( _ , _ , Data, _ ), Data).
salario( pessoa( _ , _ , _ , emprego( _, S) ), S).
salario( pessoa( _ , _ , _ , desempregado ), 0).

Hugo Pires @ Universidade


Lusfona do Porto

Assim podemos facilmente definir predicados para obter


informao:

Estruturas de Dados
E a partir deles colocar questes mais complexas

Todos os desempregados que nasceram antes de 1970


?- existe( pessoa( Nome, Apelido, data( _ , _ , Ano), desempregado),
Ano < 1970.
Pessoas nascidas antes de 1950 com salario superior a 5000
?- existe(Pessoa), dataNascimento(Pessoa, data( _ , _ , Ano) ),

Hugo Pires @ Universidade


Lusfona do Porto

O nome de todas as pessoas


?- existe( pessoa( Nome, Apelido, _ , _ ) ).

Ano < 1950, salario( Pessoa, Salario), Salario > 5000.


9

Estruturas de Dados
Exerccio

Hugo Pires @ Universidade


Lusfona do Porto

Definir o predicado que calcula o total dos rendimentos de uma lista


de pessoas
total( Lista_Pessoas, Total_Rendimentos).

10

Estruturas de Dados
Podemos criar um nvel superior de abstraco que torne
transparente a forma como a informao est representada
Para tal podemos definir selectores da forma

A utilizao de selectores facilita a alterao da estrutura que


representa a informao

Hugo Pires @ Universidade


Lusfona do Porto

selectorRelacao( Objecto, ComponenteSeleccionado)

11

Estruturas de Dados
marido( familia( Marido, _, _), Marido).
mulher( familia( _ , Mulher, _), Mulher).
filhos( familia( _, _, ListaFilhos), ListaFilhos).
primFilho( Familia, Prim) :- filhos( Familia, [ Prim | _ ] ).
segFilho(Familia, Segundo) :- filhos( Familia, [ _, Segundo| _ ] ).

Hugo Pires @ Universidade


Lusfona do Porto

Exemplo

12

Suponhamos que cada casal poderia ter inmeros filhos


A representao dos filhos (conjuntos) ineficiente em
termos de procura quando temos um elevado nmero de
elementos
Nestes casos podemos optar pela representao dos dados
numa rvore
As estruturas em rvore so frequentes para armazenar
informao e representar problemas
Vamos generalizar a sua representao e definir alguns
predicados

Hugo Pires @ Universidade


Lusfona do Porto

Estruturas de Dados

13

Estruturas de Dados

nodo(a,
nodo(b,vazio,vazio),
nodo(c,
nodo(d,vazio,vazio),
nodo(e,vazio,vazio)
)
).

a
b

c
d

Hugo Pires @ Universidade


Lusfona do Porto

Podemos representar a rvore como

14

Estruturas de Dados

Pr-ordem: escreve o nodo, e depois visita a rvore esquerda e


depois a direita.
In-ordem: visita a rvore esquerda, escreve o nodo e depois visita
a rvore direita.
Ps-ordem: visita a rvore esquerda, depois a direita e depois
escreve o nodo.

Hugo Pires @ Universidade


Lusfona do Porto

Vamos ento definir um predicado que percorre a rvore a


imprime o seu contedo
Qual a ordem:

15

Estruturas de Dados
Pr-Ordem
write(N), escreveArv( E ), escreveArv( D ).

Podemos tornar a impresso mais legvel


escreveArv( A ) :- escreveArv1( 0 , A ).
escreveArv1( _ , vazio ).
escreveArv1( NEsp , nodo( N, E, D ) ) :-

Hugo Pires @ Universidade


Lusfona do Porto

escreveArv( vazio ).
escreveArv( nodo( N, E, D ) ):-

tab( NEsp ), write(N), nl, N1 is NEsp+1,


escreveArv1( N1, E ), escreveArv1( N1, D ).

16

Estruturas de Dados
guardaArv( vazio, [ ] ).
guardaArv( nodo( N, E, D), [ N | EDs ] ) :guardaArv( E, Es ), guardaArv( D, Ds ),
append( Es, Ds, EDs ).

E se fossem s os nodos folhas


guardaArv( vazio, [ ] ) :- !.
guardaArv( nodo( N, vazio, vazio), [ N ] ) :- !.
guardaArv( nodo( _, E, D), EDs ) :guardaArv( E, Es ), guardaArv( D, Ds ),
append( Es, Ds, EDs ).

Hugo Pires @ Universidade


Lusfona do Porto

Vamos agora guardar numa lista os nodos da rvore

17

Estruturas de Dados
Grafos

Os grafos so estruturas de dados tpicas para a representao


de mltiplos problemas

Hugo Pires @ Universidade


Lusfona do Porto

Os grafos so generalizaes de rvores


Um grafo definido por um conjunto de nodos e um conjunto de
ligaes entre nodos.

18

Consideremos o problema de procurar um caminho entre


duas cidades
A informao relativa ligao entre as cidades pode ser vista
como um grafo em que cada nodo uma cidade e a existncia
de uma estrada entre elas define uma ligao

Hugo Pires @ Universidade


Lusfona do Porto

Estruturas de Dados

19

Estruturas de Dados
Exemplo
Viana
Braga

Porto

Hugo Pires @ Universidade


Lusfona do Porto

estrada(viana,porto).
estrada(viana,braga).
estrada(porto,braga).
estrada(porto,aveiro).

Aveiro

20

Estruturas de Dados
Exemplo
Viana
Braga

Porto

Hugo Pires @ Universidade


Lusfona do Porto

estrada(viana,porto).
estrada(viana,braga).
estrada(porto,braga).
estrada(porto,aveiro).
ligacao(A,B) :- estrada(A,B).
ligacao(A,B) :- estrada(B,A).

Aveiro

21

H caminho entre a cidade A e a cidade B?


A cidade inicial pode ser vista como o estado inicial dum
problema e a cidade destino como o estado final
Existe a possibilidade de transitarmos de um estado para o
seguinte at atingirmos o estado final?
A soluo obtida atravs da pesquisa nos possveis estados
do sistema

Hugo Pires @ Universidade


Lusfona do Porto

Estruturas de Dados

22

Estruturas de Dados

caminho(A,B) :- ligacao(A,B),!.
caminho(A,B) :ligacao(A,X), caminho(X,B).
PROBLEMAS:
1. No verifica se temos ciclos!
2. Quanto existe ligao direta ignora
restantes ligaes

Viana

Braga

Porto

Aveiro

Hugo Pires @ Universidade


Lusfona do Porto

H caminho entre viana e


aveiro?

23

Estruturas de Dados
Como evitar ciclos?
Temos que registar os nodos visitados

Viana

caminho( A, B ) :- caminho( A, B, [ A ] ).
caminho( A, B, _ ) :- ligacao( A, B ),!.
caminho( A, B, C ) :ligacao( A, X ),
\+ member( X, C ),
caminho( X, B, [ X | C ] ).

Porto

Aveiro

Hugo Pires @ Universidade


Lusfona do Porto

Braga

24

Estruturas de Dados
Viana

Reformular a procura

caminho( A, B ) :- caminho( A, B, [ A ] ).
caminho( B, B, _ ) :- !.
caminho( A, B, C ) :ligacao( A, X ),
\+ member( X, C ),
caminho( X, B, [ X | C ] ).

Braga

Porto

Aveiro

Hugo Pires @ Universidade


Lusfona do Porto

Como considerar todas as


solues?

25

Estruturas de Dados
Exerccio
Braga

Porto

Aveiro

Hugo Pires @ Universidade


Lusfona do Porto

Alterar o predicado para


retornar o caminho
percorrido

Viana

26

Estruturas de Dados
Exerccio

caminho( A, B, R ) :- caminho( A, B, [A], R ).


caminho( B, B, CPerc, CPerc ) :- !.
caminho( A, B, CPerc, R ) :ligacao( A, X ),
\+ member( X, CPerc ),
cam( X, B, [ X | CPerc ], R ).

Viana

Braga

Porto

Aveiro

Hugo Pires @ Universidade


Lusfona do Porto

Alterar o predicado para retornar


o caminho percorrido
(aproveitamos a lista j utilizada)

27

Estruturas de Dados
Exerccio

caminho( A, B, R ) :- caminho( A, B, [A], R ).


caminho( B, B, _, [B] ) :- !.
caminho( A, B, CPerc, [A|R] ) :ligacao( A, X ),
\+ member( X, CPerc ),
caminho( X, B, [ X | CPerc ], R ).

Viana

Braga

Porto

Aveiro

Hugo Pires @ Universidade


Lusfona do Porto

Alterar o predicado para retornar


o caminho percorrido (construindo
o percurso de novo)

28

Estruturas de Dados

findall
bagof
setof

Viana

Braga

Porto

Aveiro

Hugo Pires @ Universidade


Lusfona do Porto

Podemos obter todos


os percursos numa s
lista utilizando os
seguintes predicados
pr-definidos do
prolog:

29

Estruturas de Dados
?- caminho(aveiro,braga,C).
C = [aveiro, porto, viana, braga] ;
C = [aveiro, porto, braga] ;
false.
?-findall(C,caminho(aveiro,braga,C),R).
R = [[aveiro, porto, viana, braga], [aveiro,
porto, braga]].

Viana

Braga

Porto

Aveiro

Hugo Pires @ Universidade


Lusfona do Porto

Exemplo

30

Estruturas de Dados
30

Viana

Braga

70

50

Porto

50
Aveiro

Hugo Pires @ Universidade


Lusfona do Porto

Em aplicaes com
grafos
comum associamos a
cada ligao um
determinado custo que,
no nosso caso, poder
ser visto como a
distncia ou o custo da
viagem

31

Estruturas de Dados

custo(viana,porto,70).
custo(viana,braga,30).
custo(porto,braga,50).
custo(porto,aveiro,50).
ligacao(A,B,Custo) :custo(A,B,Custo).
ligacao(A,B,Custo) :custo(B,A,Custo).

30

Viana

Braga

70

50

Porto

50
Aveiro

Hugo Pires @ Universidade


Lusfona do Porto

Essa informao teria de ser


parte integrante da BC

32

Estruturas de Dados

caminho( A, B, R, V ) :caminho( A, B, [A], R, V ).


caminho( B, B, _, [B], 0 ) :- !.
caminho( A, B, CPerc, [A|R], V ) :ligacao( A, X, Vd ),
\+ member( X, CPerc ),
caminho( X, B, [ X | CPerc ], R, Vc ),
V is Vc + Vd.

30

Viana

Braga

70

50

Porto

50
Aveiro

Hugo Pires @ Universidade


Lusfona do Porto

Vamos agora reescrever o predicado


caminho com vista a calcularmos o custo
de cada viagem

33

Estruturas de Dados
30

Viana

Braga

70

caminho( A, B, R, V, Max ) :caminho( A, B, [A], R, V, Max ).


caminho( B, B, _, [B], V , _ ) :- !.
caminho( A, B, CPerc, [A|R], V , NMax ) :ligacao( A, X, Vd ),
NMax is Max Vd,
Max >= 0,
\+ member( X, CPerc ),
caminho( X, B, [ X | CPerc ], R, V , NMax
).

50

Porto

50
Aveiro

Hugo Pires @ Universidade


Lusfona do Porto

Escreva agora o predicado que limita as


solues a custos inferiores a um
determinado valor

34

Вам также может понравиться