Aula 14
1 Predicado de alta ordem
Predicados que recebem outros predicados como argumentos
1.1 call
transforma uma estrutura em um query
?- P = pai(X,ana), call(P). P = pai(a, b), X = a.
1.2 univ =..
constroi uma estrutura de uma lista (ou quebra uma estrutura em seus componentes)
?- X =.. [a,4,5]. X = a(4, 5) ?- Y = pai(a,b), Y =.. Z. Z = [pai, a, b].
1.3 map
mapeia um predicado em 1 lista (map1) ou em duals listas (map2), etc
map1(,[]). map1(P,[X|R]) :- G=..[P,X], call(G), map1(P,R) map2(_,[],[]). map2(P,[X|RX],[Y|RY]) :- G =.. [P,X,Y], call(G), map2(P,RX,RY).
Na verdade é possível usar o mesmo nome map
pois o predicado so
unifica com um outro predicado de mesmo nome e mesmo numero de
argumentos.
map(,[]). map(P,[X|R]) :- G=..[P,X], call(G), map(P,R) map(_,[],[]). map(P,[X|RX],[Y|RY]) :- G =.. [P,X,Y], call(G), map(P,RX,RY).
se distingue as duas versões de map
por map/2
e map/3
O map
ja esta implementado em SWIProlog
apply em listas como maplist
1.4 filter
% filter(+Teste, +Lin, -Lout) filter(_,[],[]). filter(T,[X|R],Lout) :- G =.. [P,X], ( call(G) -> Lout = [X| RR] ; Lout = RR ), filter(T,R,RR).
ja implementado como include
no SWIProlog
1.5 foldl
foldl(+P, +Lista, + Val_inicial, -Val_final)
P
tem que ser um predicado de 3 argumentos
P( +Dado, +Acumulador, -NovoAcum)
foldl(_,[],V,V). foldl(P,[X|R],V0,V) :- G =.. [P,X,V0,V1], call(G), foldl(P,R,V1,v).
contaelementos(L,DIC) :- foldl(soma1,L,[],DIC).
2 Todas as soluções
pai(a,b). pai(a,c). pai(b,e). pai(c,f). ant(A,B) :- pai(A,B). ant(A,B) :- pai(A,C),ant(C,B).
findall
findall( padrao, query, lista-com-os-resultados)
findall(X,pai(a,X),L). L = [b, c].
todos filhos de a
?- findall(X,pai(e,X),L). L = [].
todos os filhos de e
findall(X, pai(Z,X), L). L = [b, c, e, f].
todos filhos de alguem
findall( [X,Y], pai(X,Y), L). L = [[a, b], [a, c], [b, e], [c, f]].
pares (lista de 2) de pais/filhos
findall(zz(X,Y), (ant(a,X),pai(Y,X)), L).
Há 2 outros predicados parecidos mas com comportamento diferente em
casos particulares bagof
e setof
3 Alterando o banco de dados
3.1 assertz
assertz
insere um fato no final do BD.
:- dynamic pai/2. ?- assertz(pai(f,h)). ?- listing(pai/2).
asserta
insere no inicio do BD.
3.2 retract
remove o 1o fato que unifica como o argumento do retract
?- retract(pai(a,Z)).
3.3 retractall
remove todos os fatos que unificam com o argumento.
?- retractall(pai(_,_)).
3.4 fatos como dicionários
:- dynamic c/2. c(a,4). c(b,5). c(c,10). get(CH,V) :- c(CH,V). set(CH,V) :- ( c(CH,_) -> retract(c(CH,_)), asserta(c(CH,V)) ; asserta(c(CH,V)) ). clear(CH) :- retractall(c(CH,_)). clearall() :- retractall(c(_,_)) soma1(CH) :- ( c(CH,V) -> retract(c(CH,V)), VV is V+1, asserta(c(CH,VV)) ; asserta(c(CH,1)) ).
4 Outros meta predicados
once
transforma um predicado em deterministico
once(G) :- call(G),!.
ignore
tenta rodar um predicado, mas dá certo de qq forma
ignore(G) :- call(G),!. ignore(_).
once e ignore permite isolar partes do projeto sem que o backtrack de uma parte volte para outras partes
once(ledados(D)), processa(D,SAIDA), ignore(imprime(SAIDA)).
5 remove de um ABB
arv(NO, AE, AD) ou vazio
remove(vazio,N,vazio) remove(arv(N,AE,vazio), N, AE). remove(arv(N,vazio,AD), N, AD). remove(arv(N,AE,AD), X, A) :- (X < N -> remove(AE,X,NAE), A=arv(N,NAE,AD) ; remove(AD,X,NAD), A=arv(N,AE,NAD) ) remove(arv(N,AE,AD),N,A) :- menor(AD,Men,NAD), A = arv(Men,AE,NAD) menor(arv(N,vazio,AD), N, AD). menor(arv(N,AE,AD), Men, A) :- menor(AE,Men, NAE),A=arv(N, NAE, AD).