You are on page 1of 14

Manipulação em memória

:- dynamic(progenitor/2).
:- dynamic(masc/1).
:- dynamic(fem/1).

masc(ze). masc(lipe). masc(tel). fem(min). fem(jo).


fem(gil). fem(fe).

progenitor(lipe,tel). progenitor(lipe,gil).
progenitor(jo,ze). progenitor(jo,fe).
progenitor(min,jo). progenitor(min,lipe).

listprog :- listing(progenitor).
listindiv :- listing(masc), listing(fem).

add(X,SX) :- SX == m, assert(masc(X)), listindiv.


add(X,SX) :- SX == f, assert(fem(X)), listindiv.

addprog(X,Y) :- assert(progenitor(X,Y)), listprog.

remprog(X) :- retract(progenitor(X,_)), fail.


remprog(X) :- listprog.
Árvores binárias

• Indutivamente, cada nó é um termo:

no(a, ESQ, DIR)


ESQ = no(b, ESQ1, [])
DIR = no(c, ESQ2, DIR2)

ESQ1 = no(d, [], [])

arvore(no(a, no(b, no(d,[],[]),[]),


no(c, no(e,[],no(g,[],[])),
no(f,[],[])) )).
Percurso
preOrdem([]).
preOrdem(no(Info,E,D)): write(Info), preOrdem(E),
preOrdem(D).

?- arvore(A), preOrdem(A), nl.

abdcegf
A=no(a, no(b, no(d,[],[]),[]),
no(c, no(e,no(g,[],[]),[]),
no(f,[],[])) ))
Yes

3
Desenho
?-arvore(A), printArv(0,A), nl.
f
c
e
g
a
b
d

printArv(_,[]).
printArv(N,no(I,E,D)):- N1 is N+2, printArv(N1,D),
tab(N),write(I),nl,
printArv(N1,E).

(in-ordem da direita para esquerda)


Árvore de busca

• Filhos à esquerda têm valor menor que raiz


• Filhos à direita têm valor maior que raiz
• Por consequência, percurso in-ordem retorna?
– Lista ordenada crescente de valores (índices)
• Operações típicas: busca, inserção e remoção
...
5
Busca...
• ...por um valor X em um conjunto de nós do tipo no(I,E,D).
• se X=I, então retorna sucesso;
• se X<I, então busca na sub´arvore da esquerda;
• se X>I, então busca na sub´arvore da direita.

busca(X,no(I,E,D)):- X=I, !.
busca(X,no(I,E,D)):- X<I, !, busca(X,E).
busca(X,no(I,E,D)):- X>I, !, busca(X,D).
Inserção
• Similar à busca
• Parâmetros adicionais:
– Árvore de entrada
– Árvore resultante
• Casos:
– para árvores vazias, retorna-se um nó com o
valor e dois filhos vazios
– Para árvores não vazias, X=I é ignorado, X<I
insere-se na esquerda, X>I insere-se na
direita
ins(X,[],no(X,[],[])):-!.
ins(X,no(I,E,D),no(I,E,D)):- X==I,!.
ins(X,no(I,E,D),no(I,E1,D)):-X<I,!,ins(X,E,E1).
ins(X,no(I,E,D),no(I,E,D1)):-X>I,!,ins(X,D,D1).

insL([X|Xs],A,Ao):-!,ins(X,A,A1),insL(Xs,A1,Ao).
insL([],A,A):-!.

arvore1(A):-insL([7,5,12,3,6],[],A).
arvore2(A):-insL([7,5,12,3,6,11,9,10,15,13,17,14],
[],A).
arvore3(A):-insL([3,4,4,5,6],[],A).

?- arvore2(A), busca(9,A).
A = no(7, no(5, … ))))
Yes
Remoção

26
23 28

Caso 1: nó-folha
Caso 2: nó com um único filho
Caso 3: nó com dois filhos
Considerações sobre desempenho

Ordenação por inserção...


insOrd(X,[Y|L],[X,Y|L]) :- X =< Y,!.
insOrd(X,[Y|L],[Y |Io]) :- X > Y,!, insOrd(X,L,Io).
insOrd(X,[],[X]).

insDir([C|Ls],So) :- insDir(Ls,Si),insOrd(C,Si,So).
insDir([],[]).

?-insDir([7,4,8,3,8],S)
S=[3,4,7,8,8]

?- insOrd(4, [2,3,5,7],L).
L=[2,3,4,5,7]
Medindo performance de programas
Predicado time/1 retorna o tempo gasto para execução de um
predicado, bem como o número de inferências lógicas que
foram executadas pela máquina abstrata do Prolog
lista_rand( [],V,N):- N<1,!.
lista_rand([R|L],V,N):- N1 is N-1,
R is random(V), lista_rand(L,V,N1).

lista100r(L):- lista_rand(L,50,100).
repeatN(0,_):-!.
repeatN(N,Call):- call(Call),
N1 is N-1,
repeatN(N1,Call).

teste1 :- lista100r(L),write(’ins_dir:’),
time(repeatN(100,insDir(L,S))).

?- teste1.
% ins_dir:
% 912,313 inferences, 0.19 CPU in 0.17 seconds
(108% CPU, 4873436 Lips)
Práticas
• P18 – Defina uma representação alternativa
para árvores, baseada em listas, em que o nó
no(I,E,D) é representado como [I,E,D]. Refaça o
predicado preOrdem e implemente os
predicados inOrdem e posOrdem.

• P19 – Implemente a remoção em árvores


binárias de busca
Práticas
• P20 – Implemente os algoritmos de ordenação
BubleSort e SelectionSort

• P21 – Implemente os algoritmos de ordenação


QuickSort e MergeSort

• P22 – Realize testes de eficiência entre suas


implementações e implementações depositadas
por seus colegas.

You might also like