programação em lógicaeol/lp/1011/documents/praticas/...implementação em prolog…? números de...

92
Programação em Lógica Materiais de apoio às aulas TP 2009-10 Rui Gomes ([email protected])

Upload: others

Post on 25-Apr-2021

7 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Programação em Lógica

Materiais de apoio às aulas TP 2009-10

Rui Gomes ([email protected])

Page 2: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Grafos

Page 3: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Grafos

– connected(joao_deus, camara_gaia, amarela).

– connected(camara_gaia, general_torres, amarela).

– (…)

– connected(estadio_dragao, campanha, vermelha).

– connected(campanha, heroismo, vermelha).

– (…)

Page 4: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Grafos

– Consideram-se proximas duas estações se estiveremna mesma linha e existir no maximo uma estaçãoentre essas duas:• nearby(joao_deus, camara_gaia).

• nearby(camara_gaia, general_torres).

• nearby(joao_deus, general_torres).

• …

– Ou (bem) melhor .. ;)• nearby(X,Y):-connected(X,Y,L).

• nearby(X,Y):-connected(X,Z,L),connected(Z,Y,L).

Page 5: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Grafos

– Comparar:

• nearby(X,Y):-connected(X,Y,L).

• nearby(X,Y):-connected(X,Z,L),connected(Z,Y,L).

– Com:…

• not_too_far(X,Y):-connected(X,Y,L).

• not_too_far(X,Y):-connected(X,Z,L1),connected(Z,Y,L2).

– Pode ser re-escrito:

• not_too_far(X,Y):-connected(X,Y,_).

• not_too_far(X,Y):-connected(X,Z,_),connected(Z,Y,_).

Page 6: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Grafos - Recursividade

– É possível ir de uma estação a outra se estiverem namesma linha, ou com uma mudança de linha, ou duas, outrês, ou..:• reachable(X,Y):-connected(X,Y,L).

• reachable(X,Y):-connected(X,Z,L1),connected(Z,Y,L2).

• reachable(X,Y):-connected(X,Z1,L1),connected(Z1,Z2,L2),connected(Z2,Y,L3).

• (…)

– Ou BEM melhor!!...:• reachable(X,Y):-connected(X,Y,L).

• reachable(X,Y):-connected(X,Z,L),reachable(Z,Y).

Page 7: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Grafos – Listas

• path(X,Y,[]):-connected(X,Y,L).

• path(X,Y,[Z|R])):-connected(X,Z,L),path(Z,Y,R).

– ?-path(estadio_dragao,bolhao,R).

• R =[campanha, heroismo, 24_agosto]

.

campanha .

heroismo

24_agosto []

.

Podemos escrever esta lista de muitas maneiras:.(campanha,.(heroismo,.(24_agosto,[])))[campanha |[heroismo |[24_agosto |[]]]][campanha |[heroismo |[24_agosto]]][campanha |[heroismo, 24_agosto]][campanha, heroismo, 24_agosto][campanha, heroismo |[24_agosto]]…

Page 8: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Factorial

– Calcular o factorial de N• Computar o factorial de N-1 usando recursividade.

• Para quando o atingirmos o problema trivial que é..: o factorial ZERO = 1

fact_td(0,1).

fact_td(N,F):-N>0, N1 is N-1, fact_td(N1,F1), F is N*F1.

– Nota: a complexidade do procedimento acima é linear, ou seja, precisamos de N+1 chamadas a fact_td

Page 9: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Números de Fibonnaci

– Os Números de Fibonacci são uma sucessão definida como recursiva pela fórmula abaixo:

– Começando com 1, o próximo número de Fibonacci é encontrado somando os dois anteriores:

1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987,1597, 2584, 4181, 6765, 10946…

Implementação em Prolog…?

Page 10: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Números de Fibonnaci

– Solução:

fibonacci(0,1).

fibonacci(1,1).

fibonacci(N,F):-

N > 1,

N1 is N - 1,fibonacci(N1,F1),

N2 is N - 2, fibonacci(N2,F2),

F is F1 + F2.

Page 11: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Números Primos

Escreva um predicado e_primo(N) que determine se um dado número é primo

Page 12: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Números Primos

Escreva um predicado e_primo(N) que determine se um dado número é primo

– Solução:

e_primo(2).

e_primo(3).

e_primo(P) :- integer(P), P > 3, P mod 2 =\= 0, \+tem_factor(P,3).

tem_factor(N,L) :- N mod L =:= 0.

tem_factor(N,L) :- L * L < N, L2 is L + 2, tem_factor(N,L2).

Page 13: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Listas

Preveja os resultados das seguintes questões em Prolog:

a) ?- [a|[b,c,d]] = [a,b,c,d].

b) ?- [a|b,c,d] = [a,b,c,d].

c) ?- [H|T] = [apple, broccoli, refrigerator].

d) ?- [H|T] = [a, b, c, d, e].

e) ?- [H|T] = [apples, bananas].

f) ?- [H|T] = [a, [b,c,d]].

g) ?- [H|T] = [apples].

h) ?- [H|T] = [].

i) ?- [One, Two | T] = [apple, sprouts, fridge, milk].

Page 14: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Listas

Preveja os resultados das seguintes questões em Prolog:(…)

– Solução:a) yesb) noc) H = appleT = [broccoli, refrigerator]d) H = aT = [b, c, d, e]e) H = applesT = [bananas]f) H = aT = [[b, c, d]]g) H = applesT = []h) noi) One = appleTwo = sproutsT = [fridge, milk]

Page 15: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Listas

Implemente o predicado membro(X,L) que sucede se X for um membro da lista L. (member).

Page 16: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Listas

Implemente o predicado membro(X,L) que sucede se X for um membro da lista L. (member).

– Solução:

member(X,[X|_]).

member(X,[_|Ys]) :- member(X,Ys).

Page 17: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Listas

Implemente o predicado append(L1,L2,L) em que L é constituída pela concatenação das listas L1 e L2.

Page 18: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Listas

Implemente o predicado append(L1,L2,L) em que L é constituída pela concatenação das listas L1 e L2.

– Solução:

append([],L,L).

append([X|L1],L2,[X|L3]):- append(L1,L2,L3).

Page 19: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Listas

Implemente o predicado duplicar(L,LL) em que LL é a lista L duplicada.

Page 20: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Listas

Implemente o predicado duplicar(L,LL) em que LL é a lista L duplicada.

– Solução:

duplicar([], []).

duplicar([X|R], [X,X|R2]) :- duplicar(R,R2).

Page 21: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Listas

Implemente o predicado substi(X,Y,L1,L2) em que L2 é L1 com todas as ocorrências de X substituídas por Y.

Page 22: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Listas

Implemente o predicado substi(X,Y,L1,L2) em que L2 é L1 com todas as ocorrências de X substituídas por Y.

– Solução:

substi(_,_,[],[]).

substi(X,Y,[X|R1],[Y|R2]) :- substi(X,Y,R1,R2).

substi(X,Y,[C|R1],[C|R2]) :- C \= X, substi(X,Y,R1,R2).

Page 23: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Listas

Implemente o predicado ordenada(Lista) que é verdadeiro se Lista é uma lista de inteiros ordenada.

Page 24: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Listas

Implemente o predicado ordenada(Lista) que é verdadeiro se Lista é uma lista de inteiros ordenada.

– Solução:

ordenada([N]).

ordenada([N1,N2]):- N1 =< N2.

ordenada([N1,N2|Resto]):-

N1 =< N2,

ordenada([N2|Resto]).

Page 25: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Listas

Implemente o predicado slice(L1,I,K,L2) em que L2 é a lista dos elementos de L1 entre os índices I e K (ambos incluídos).

Page 26: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Listas

Implemente o predicado slice(L1,I,K,L2) em que L2 é a lista dos elementos de L1 entre os índices I e K (ambos incluídos).

– Solução:slice([X|_],1,1,[X]).

slice([X|Xs],1,K,[X|Ys]) :- K > 1,

K1 is K - 1, slice(Xs,1,K1,Ys).

slice([_|Xs],I,K,Ys) :- I > 1,

I1 is I - 1,

K1 is K - 1,

slice(Xs,I1,K1,Ys).

Page 27: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Listas

Implemente o predicado inverte(List,Tsil) em que Tsil é List com a ordem dos elementos invertida.

Page 28: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Listas

Implemente o predicado inverte(List,Tsil) em que Tsil é List com a ordem dos elementos invertida.

– Solução:

inverte(L, Inv) :- inverte(L, [], Inv).

inverte([], Inv, Inv).

inverte([X|R], InvAux, Inv) :- inverte(R, [X|InvAux], Inv).

Page 29: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Factorial

– Calcular o factorial de N• Computar o factorial de N-1 usando recursividade.

• Para quando o atingirmos o problema trivial que é..: o factorial ZERO = 1

fact_td(0,1).

fact_td(N,F):-N>0, N1 is N-1, fact_td(N1,F1), F is N*F1.

– Nota: a complexidade do procedimento acima é linear, ou seja, precisamos de N+1 chamadas a fact_td

Page 30: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Factorial - iterativo

– Calcular o factorial de N

fact_it(N,F):-fact_it(N,1,F).fact_it(N,T,F):-N>0, T1 is T*N, N1 is N-1,fact_td(N1,T1F).Fact_it(0,F,F).

– Notas:• o acc é uma variável lógica: o valor é passado entre iterações,

não o endereço. • o mecanismo de write once leva a que uma variável nova seja

passada a cada iteração -> esta versão é mais eficiente em termos de espaço que a versão recursiva

Page 31: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Árvores de Pesquisa

– Árvore de pesquisa de um objectivo G relativamente a um programa P• raiz da árvore: G• nós: resolventes, com um objectivo seleccionado• arcos a sair de um nó: um por cada cláusula de P cuja cabeça unifica

com o objectivo seleccionado no nó• cada caminho na árvore, desde a raiz: computação de G por P• folhas: nós de sucesso, se corresponderem a resolventes vazias;• nós de falha se o objectivo seleccionado não puder ser reduzido

– Prolog pesquisa (daí o nome) a árvore primeiro em profundidade…• implementável por uma stack, onde se guardam os objectivos da

resolvente actual

Page 32: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Antes de avançar…

– Não terminação…• homem(mario).• homem(afonso).• homem(henrique).• homem(jorge).

• mulher(assuncao).• mulher(ana).• mulher(joana).• mulher(sofia).

– casou_com(X,Y) e… casou_com(Y,X) … como resolver?• casou_com(X,Y):-casou_com(Y,X) ???

Page 33: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Antes de avançar…

– casou_com(X,Y):-casou_com(Y,X).

– Trace de casou_com(mario, ana).• casou_com(mario, ana)

– casou_com(ana, mario)

» casou_com(mario, ana)

• casou_com(ana, mario)

• …

– Melhor solução: evitar recursividade à esquerda• sao_casados(X,Y):-casou_com(X,Y).

• sao_casados(X,Y):-casou_com(Y,X).

Page 34: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Grafos

Page 35: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Grafos

– connected(joao_deus, camara_gaia, amarela).

– connected(camara_gaia, general_torres, amarela).

– (…)

– connected(estadio_dragao, campanha, vermelha).

– connected(campanha, heroismo, vermelha).

– (…)

Page 36: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Grafos – pesquisa em profundidade

– É possível ir de uma estação a outra se estiverem na mesmalinha, ou com uma mudança de linha, ou duas, ou três, ou..:• reachable(X,Y):-connected(X,Y,L).

• reachable(X,Y):-connected(X,Z,L1),connected(Z,Y,L2).

• reachable(X,Y):-connected(X,Z1,L1),connected(Z1,Z2,L2),connected(Z2,Y,L3).

• (…)

– Ou BEM melhor!!...:• reachable(X,Y):-connected(X,Y,L).

• reachable(X,Y):-connected(X,Z,L),reachable(Z,Y).

– Quais as soluções para reachable(trindade,Y)…?

Page 37: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Grafos – pesquisa em profundidade

• Soluções para reachable(trindade,Y)– aliados– s_bento– jardim_morro– general_torres– camara_gaia– joao_deus

– faria_guimaraes– marques– combatentes– salgueiros– polo_universitario– ipo– hospital_s_joao

– bolhao– campo_24_agosto– heroismo– campanha– estadio_dragao

– lapa– carolina_michaelis– casa_musica– …

Page 38: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Grafos – pesquisa em profundidade

– E se trocássemos a ordem das regras fosse trocada…?

reachable(X,Y):-connected(X,Z,L),reachable(Z,Y).

reachable(X,Y):-connected(X,Y,L).

– Quais as soluções agora para reachable(trindade,Y)?

Page 39: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Grafos – pesquisa em profundidade

• Soluções para reachable(trindade,Y)– joao_deus– camara_gaia– general_torres– jardim_morro– s_bento– aliados

– hospital_s_joao– ipo– polo_universitario– salgueiros– combatentes– marques– faria_guimaraes

– estadio_dragao– campanha– heroismo– campo_24_agosto– bolhao

A ordem das regras não altera a a árvore de pesquisa, apenas a ordem com que as soluções são encontradas. A ordem dos golos altera a árvore de pesquisa.

Page 40: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Grafos – pesquisa em profundidade

– É possível ir de uma estação a outra se estiverem na mesmalinha, ou com uma mudança de linha, ou duas, ou três, ou..:• reachable(X,Y):-connected(X,Y,L).

• reachable(X,Y):-connected(X,Z,L1),connected(Z,Y,L2).

• reachable(X,Y):-connected(X,Z1,L1),connected(Z1,Z2,L2),connected(Z2,Y,L3).

• (…)

– Ou BEM melhor!!...:• reachable(X,Y):-connected(X,Y,L).

• reachable(X,Y):-connected(X,Z,L),reachable(Z,Y).

– Quais as soluções para reachable(trindade,Y)…?

Page 41: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Pensando bem…reachable(X,Y):-connected(X,Y,L).

reachable(X,Y):-connected(X,Z,L),reachable(Z,Y).

Funciona?...

Grafos – pesquisa em profundidade

Page 42: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Pensando bem…reachable(X,Y):-connected(X,Y,L).

reachable(X,Y):-connected(X,Z,L),reachable(Z,Y).

Funciona?...

reachable(X,Y):-reachable(X,Y, [X]).

reachable(A,A,Visitados).

reachable(A,B,Visitados):-connected(A,N,L), not member(N,Visitados), reachable(N,B,[N|Visitados]).

Grafos – pesquisa em profundidade

Page 43: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Pesquisa– Considere que um grafo não dirigido é representado por um conjunto de cláusulas

unitárias da forma ligacao(No1, No2).

• Escreva um predicado caminho(+NoInicio, +NoFim, -Lista), que dados dois nós do grafo, calcule um possível caminho (não necessariamente o mais curto) entre esses nós, supondo que a dimensão máxima do caminho é 5

– Nota: faça uso dos utilitários de manipulação de Listas

membro(X, [X|_]):- !.

membro(X, [_|Y]):- membro(X,Y).

» e

concatena([], L, L).

concatena([X|Y], L, [X|Lista]):- concatena(Y, L, Lista).

Exemplo:

?- caminho(2, 3, Lista).

Lista = [2,4,3] ; Lista = [2,4,6,3] ; Lista = [2,1,3] ; no

Page 44: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Pesquisa – Solução (sem cut…)

ligacao(1, 2).

ligacao(1, 3).

ligacao(2, 4).

ligacao(3, 4).

ligacao(3,6).

ligacao(4, 6).

ligacao(5,6).

ligacao2(X,Y):- ligacao(X,Y) ; ligacao(Y,X).

caminho(NoInicio, NoFim, Lista):-

caminho(NoInicio, NoFim, [NoInicio], Lista, 5).

caminho(NoInicio, NoFim, Lista, ListaFim,_):-

ligacao2(NoInicio, NoFim),

append(Lista, [NoFim], ListaFim).

caminho(NoInicio, NoFim, Lista, ListaFim, N):-

N>0,

ligacao2(NoInicio, NoInterm),

NoInterm \= NoFim,

\+(member(NoInterm, Lista)),

append(Lista, [NoInterm], Lista2),

N2 is N-1,

caminho(NoInterm, NoFim, Lista2, ListaFim, N2).

Page 45: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Efeitos do cut

– Implicações:

• O golo p unificado com uma clausula que contem um cut e que sucede, não gera soluções usando clausulas que ocorrem abaixo dessa clausula

• O cut poda todas as soluções alternativas para o conjunção de golos à esquerda da sua ocorrência na clausula

• O cut não afecta os golos à sua direita, podendo produzir mais soluções no caso de backctracking

Page 46: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Efeitos do cut%merge(Xs,Ys,Zs) :- Zs é uma lista de inteiros ordenada obtida a partir da

fusao das listas de inteiros ordenadas Xs e Ys

merge([X|Xs],[Y|Ys],[X|Zs]) :-

X < Y, merge(Xs,[Y|Ys],Zs).

merge([X|Xs],[Y|Ys],[X,Y|Zs]) :-

X =:= Y, merge(Xs,Ys,Zs).

merge([X|Xs],[Y|Ys],[Y|Zs]) :-

X > Y, merge([X|Xs],Ys,Zs).

merge(Xs,[],Xs).

merge([],Xs,Xs).

Com cutsmerge([X|Xs],[Y|Ys],[X|Zs]) :-

X < Y, !, merge(Xs,[Y|Ys],Zs).

merge([X|Xs],[Y|Ys],[X,Y|Zs]) :-

X =:= Y, !, merge(Xs,Ys,Zs).

merge([X|Xs],[Y|Ys],[Y|Zs]) :-

X > Y, !, merge([X|Xs],Ys,Zs).

merge(Xs,[],Xs) :- !.

merge([],Xs,Xs) :- !.

merge([1,2,3],[3,5], Zs).

Page 47: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Efeitos do cut

O cut assim definido permite encurtar o caminho percorrido pelo Prolog, tornando a computação mais eficiente em termos de tempo e, especialmente, em termos de espaço. Neste exemplo, o uso de cut não altera o significado da computação (soluções obtidas) – é um cut verde ( ≠ cut vermelho…)

Page 48: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Cut verde e vermelho– Considere que um grafo não dirigido é representado por um conjunto de cláusulas

unitárias da forma ligacao(No1, No2).

• Escreva um predicado caminho(+NoInicio, +NoFim, -Lista), que dados dois nós do grafo, calcule um possível caminho (não necessariamente o mais curto) entre esses nós, supondo que a dimensão máxima do caminho é 5

– Nota: faça uso dos utilitários de manipulação de Listas

membro(X, [X|_]):- !.

membro(X, [_|Y]):- membro(X,Y).

» e

concatena([], L, L).

concatena([X|Y], L, [X|Lista]):- concatena(Y, L, Lista).

Exemplo:

?- caminho(2, 3, Lista).

Lista = [2,4,3] ; Lista = [2,4,6,3] ; Lista = [2,1,3] ; no

Page 49: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Cut verde e vermelho

• cut vermelhomembro(X, [X|_]).

membro(X, [_|Y]):- membro(X,Y).

» e

membro(X, [X|_]):- !.

membro(X, [_|Y]):- membro(X,Y).

Os programas apresentam o mesmo comportamento?– member(X,[1,2,3])

» …

Uma técnica habitual em Prolog é a omissão de condiçõesexplicitas. É muito útil por vezes, especialmente no caso condiçõesexplicitas de negação, que são mais rebuscadas de escrever. noentanto susceptível a erros.

Page 50: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Negação por falha

• O cut pode ser utilizado para implementar negação por falha/*

not X :- X não sucessede.

*/

not X :- X, !, fail.

not X.

Relembrar caminho:

caminho(NoInicio, NoFim, Lista, ListaFim, N):-

(…)

NoInterm \= NoFim,

\+(member(NoInterm, Lista)),

append(Lista, [NoInterm], Lista2),

(…)

not do Prolog não implementa verdadeira negação lógica.. A negação por falha não é garantido que funcione para termos não-fechados.

Page 51: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

If-Then-Else

• Implementação usando cut

/*

if_then_else(P,Q,R) :- OU P E Q, OU nao P E R.

*/

if_then_else(P,Q,R) :- P, !, Q.

if_then_else(P,Q,R) :- R.

Page 52: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

cut

• Considere a seguinte base de dados:p(1).

p(2):-!.

p(3).

– Indique todas as respostas dadas pelo interpretador às questões:

a) ?- p(X).

b) ?- p(X), p(Y).

c) ?- p(X), !, p(Y).

Page 53: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

cut

• Considere a seguinte base de dados:p(1).

p(2):-!.

p(3).

– Indique todas as respostas dadas pelo interpretador às questões:

a) ?- p(X).

b) ?- p(X), p(Y).

c) ?- p(X), !, p(Y).

Solução:

a) X=1 ; X=2

b) X=1 Y=1 ; X=1 Y=2 ; X=2 Y=1 ; X=2 Y=2

c) X=1 Y=1 ; X=1 Y=2

Page 54: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

cut• Suponha a seguinte base de factos em Prolog

dados(um).

dados(dois).

dados(tres).

• a) Qual o resultado da seguinte pergunta?

cut_teste_a(X) :- dados(X).cut_teste_a('ultima_clausula').

• ?- cut_teste_a(X), write(X), nl, fail.

• a) Qual o resultado do seguinte programa com um cut no final da primeira clausula?cut_teste_b(X):-

dados(X), !.

cut_teste_b('ultima_clausula').

• ?- cut_teste_b(X), write(X), nl, fail.

• c) Qual o resultado do seguinte programa com um Cut no meio dos dois objectivos?cut_teste_c(X,Y) :-

dados(X),!,dados(Y).

cut_teste_c('ultima_clausula').

• ?- cut_teste_c(X,Y), write(X-Y), nl, fail.

Page 55: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

cutSolução:

a) um

dois

tres

ultima_clausula

no

b) um

no

c) um - um

um - dois

um - tres

no

Page 56: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Unificação– Defina o predicado unificavel(L1, Termo, L2) em que L2 é uma lista com todos os

elementos de L1 que são unificáveis com Termo. Os elementos de L2 não são no entanto unificados com Termo. Exemplo:

?- unificavel([X,b,t(Y)],t(a),L).

L=[X,t(Y)]

– Note que se Termo1=Termo2 resulta então not(Termo1=Termo2) falha e a instanciação resultante de Termo1=Termo2 é anulada.

Page 57: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Unificação– Solução

%unificavel(LIn, T, Lout)

unificavel([], _, []).

unificavel([T1|RIn], T, ROut) :-

T1 \= T,

!,

unificavel(RIn, T, ROut).

unificavel([T1|RIn], T, [T1|ROut]) :-

unificavel(RIn, T, ROut).

Page 58: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Operadores

• Forma standard de ler e escrever os termos é com o functor seguido dos respectivos argumentos entre parênteses, ex: casado_com(X,Y)

• Certas expressões ficam mais legíveis usando operadores (Ex: as expressões matemáticas com: 2*a + b*c)

• comando: op( Precedencia, Tipo, Op )– Precedência de 1 a 1200

• ',' tem precedência 1000; logo, operadores que possam aparecer como argumentos devem ter precedência inferior a 1000 ou ficar entre parênteses, que corresponde a precedência 0

– Tipo pretende desambiguar expressões definindo o tipo de associatividade e a posição (infixo: xfx, xfy, yfx; prefixo: fx, fy; posfixo: xf, yf)

• x argumento com precedência INFERIOR ao do operador

• y argumento com precedência IGUAL OU SUPERIOR ao do operador

– Ex: Manuel joga futeboljoga(Manuel, futebol)

op(600, xfx, joga)

Page 59: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Operadores– Suponha que temos definidos os seguintes operadores :

:- op(500,xfx,na).

:- op(500,xfy,ad).

:- op(500,yfx,ae).

Mostre como seriam representadas em PROLOG as seguintes expressões se não tivéssemos as directivas acima (indique os casos em que o PROLOG assinalaria um erro sintáctico):

– a) a na b ae c.

– b) a na b ad c.

– c) a ad b na c.

– d) a na b na c.

– e) a ad b ad c.

– f) a ae b ae c.

– g) a ad b ad c na d ae e ae f.

Page 60: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Operadores

– Solução:

– a) ae(na(a,b),c).

– b) Erro.

– c) ad(a,na(b,c)).

– d) Erro.

– e) ad(a,ad(b,c)).

– f) ae(ae(a,b),c).

– g) ad(a,ad(b,ae(ae(na(c,d),e),f))).

Page 61: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Operadores– Crie as directivas que tornam termos abaixo sintacticamente válidos :

a) se X entao Y senao Z.

b) Y gostaria_de X se X fosse bom e X fosse inteligente.

Page 62: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Operadores

– Solução:

a)

:-op(500, xfx, entao).

:-op(400, fx, se).

:-op(400, xfx, senao).

b)

:-op(800, xfx, se).

:-op(600, xfx, gostaria_de).

:-op(500, xfy, e).

:-op(400, xfx, fosse).

Page 63: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Tipos de termos

• Predicados var, nonvar, atom, integer, atomic– Inteiros

– Termos

– Variáveis podem estar ou não instanciadas• Atómico

• Estrutura

• …

– …

– Saber qual o tipo em determinada altura

Z is X + Y

…integer(X), integer(Y), Z is X + Y,…

Page 64: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

• Predicados var, nonvar, atom, integer, atomic– var(X) (Predicados de tipo meta-lógicos)

– nonvar(X) (Predicados de tipo meta-lógicos)

– atom(X)

– integer(X)

– atomic(X)

Tipos de termos

Page 65: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Tipos de termos

• Predicados var, nonvar, atom, integer, atomic– var(X)

• ?-var(Z), Z=2.

• ?-Z=2,var(Z).

– nonvar(X)

– atom(X)• ?atom(22).

– integer(X)

– atomic(X)• ?atomic(22).

Page 66: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Tipos de termos

• Ex:– Count(A,L,N)

• ?-var(Z), Z=2.

• ?-Z=2,var(Z).

– nonvar(X)

– atom(X)• ?atom(22).

– integer(X)

– atomic(X)• ?atomic(22).

Page 67: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Tipos de termos

• Ex:– Count(A,L,N)

count(_,[],0).

count(A,[A|L],N):-!,

count(A,L,N1),

N is N1+1.

count(A,[_,L],N):-count(A,L,N).

Funciona?

?-count(a,[a,b,a,a],N).

N=3

?-count(a,[a,b,X,Y],Na).

Na=3

?-count(b,[a,b,X,Y],Nb).

Nb=3

?-L=[a,b,X,Y], count(a,[a,b,X,Y],Na), count(b,[a,b,X,Y],Nb).

…?

Page 68: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Tipos de termos

• Ex:– Count(A,L,N)

count(_,[],0).

count(A,[A|L],N):-!,

count(A,L,N1),

N is N1+1.

count(A,[_,L],N):-count(A,L,N).

Funciona?

?-L=[a,b,X,Y], count(a,[a,b,X,Y],Na), count(b,[a,b,X,Y],Nb).

Na=3

Nb=1

Isto é o número de termos que unificam com o atomo e não o real número de ocorrências do átomo conforme pretendíamos…

Page 69: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Tipos de termos

• Ex:– Count(A,L,N)

count(_,[],0).

count(A,[B|L],N):-

atom(B),A=B,!,

count(A,L,N1),

N is N1+1

;

count(A,L,N).

Funciona?

Page 70: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

• Predicados bagof, setof, findall– bagof( Termo, Objectivo, Lista )¬ Lista é o multiconjunto de todas as

instâncias de Termo para as quais o Objectivo é satisfeito (inclui repetidos)

– setof( Termo, Objectivo, Lista ) ¬ semelhante, mas sem valores repetidos e ordenado

– findall(X,P,L) - todos os objectos de X sem ligar a diferenças em variáveis de P

• Sucede mesmo se Res=[ ]

– Ex:

classifica(a, vog).

classifica(b, con).

classifica(c, con).

classifica(d, con).

classifica(e, vog).

classifica(f, con).

Predicados de conjuntos

Page 71: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

• Predicados bagof, setof, findall– Ex:

classifica(a, vog).

classifica(b, con).

classifica(c, con).

classifica(d, con).

classifica(e, vog).

classifica(f, con).

?-bagof(Letra, classifica(Letra,com), Letras).

? - setof(Class/Letra, classifica(Letra,Class), Res).

?-findall(Letra, classifica(Letra, Class), Letras).

Predicados de conjuntos

Page 72: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

• Predicados bagof, setof, findallclassifica(a, vog).

classifica(b, con).

classifica(c, con).

classifica(d, con).

classifica(e, vog).

classifica(f, con).

?-bagof(Letra, classifica(Letra,com), Letras).

Letras=[b,c,d]

? - setof(Class/Letra, classifica(Letra,Class), Res).

Res = [con/b, con/c, con/d, con/f, vog/a, vog/e]]

? - findall(Letra, classifica(Letra, Class), Letras).

Letras = [a, b, c, d, e, f]

Predicados de conjuntos

Page 73: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

• Predicados functor, arg, =..

– O golo Termo=..L é verdadeiro se L é uma lista cuja cabeça é o principal functor de Termo e a cauda são os seus argumentos

– functor( Termo, Functor, Aridade )¬ o functor principal de Termo é Functorcom aridade Aridade

– arg( N, Termo, Arg ) ¬ Arg é o Nésimo argumento de Termo

Predicados de manipulação da estrutura de termos

Page 74: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

• Predicados functor, arg, =..

– O golo Termo=..L é verdadeiro se L é uma lista cuja cabeça é o principal functor de Termo e a cauda são os seus argumentos

?- f(a,b) =.. L

L= [f,a,b]

?- T =.. [rectangulo, 3, 5]

T=rectangulo(3,5)

?- Z=.. [p, X, f(X,Y)]

Z = p(X, f(X,Y))

Predicados de manipulação da estrutura de termos

Page 75: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

• Predicados functor, arg, =..

– functor( Termo, Functor, Aridade )¬ o functor principal de Termo é Functorcom aridade Aridade

?- functor(likes(mary, pizza), Functor, Arity).

Functor = likes

Arity = 2

?- functor(likes(X, Y), Functor, Arity).

X = _G180

Y = _G181

Functor = likes

Arity = 2

Predicados de manipulação da estrutura de termos

Page 76: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

• Predicados functor, arg, =..

– arg( N, Termo, Arg ) ¬ Arg é o Nésimo argumento de Termo

?- arg(2, buys(john, beer), Arg).

Arg = beer

?- X = likes(mary, Y), arg(2, X, pizza).

X = likes(mary, pizza)

Y = pizza

Predicados de manipulação da estrutura de termos

Page 77: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Decomposição de termos

– É frequente desejarmos realizar uma dada transformação em todos os elementos de uma lista. Para o efeito vamos recorrer a um predicado de aridade 2. A esta transformação chama-se também mapeamento duma lista. Construa um predicado de mapeamento utilizando o operador =.. na sua definição.• Exemplo1:

– Tendo

f(X,Y):-Y is X*X.

– vem

?-map([2,4,8],f,L).

L=[4,16,64]

• Exemplo2:– Tendo

duplica(X,Y) :- Y is 2*X.

– vem

?-map([1,2,3],duplica,L).

L=[2,4,6]

Page 78: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Decomposição de termos• Exemplo1:

– Tendo

f(X,Y):-Y is X*X.

vem

?-map([2,4,8],f,L).

L=[4,16,64]

• Exemplo2:– Tendo

duplica(X,Y) :- Y is 2*X.

vem

?-map([1,2,3],duplica,L).

L=[2,4,6]

– Solução:map([],_,[]).

map([C|R],Transfor,[TC|CR]):-

aplica(Transfor, [C,TC]),

map(R,Transfor,CR).

aplica(P,LArgs) :- G =.. [P|LArgs], G.

Page 79: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Decomposição de termos

– Definição de functor(Term,F,N) e arg(N,Term,Arg) em termos do operador =..

• a) Defina o predicado functor2(Term,F,Arity) que é verdadeiro se Term é um termo cujo functor principal tem o nome F e a aridade Arity.

• b) Defina o predicado arg(N,Term,Arg) que é verdadeiro se Arg é o N-ésimo argumento do termo Term.

Page 80: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

Decomposição de termos

• a) Defina o predicado functor2(Term,F,Arity) que é verdadeiro se Term é um termo cujo functor principal tem o nome F e a aridade Arity.

Solução:functor_(Term,F,N):- Term=..[F|Args], length(Args,N).

• b) Defina o predicado arg(N,Term,Arg) que é verdadeiro se Arg é o N-ésimo argumento do termo Term.

Solução:arg_(N,Term,Arg):- Term=..[F|Args], position(N,Args,Arg).

position(1,[X|_],X).

position(N,[_|Xs],Y):-N>1, N1 is N-1, position(N1,Xs,Y).

Page 81: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

PLR – exercícios

– Fechadura:A combinação de uma fechadura é composta por três números com valores entre 1 e 50. O segundo número é o dobro do primeiro. O terceiro número é igual ao segundo mais 10. A soma dos dois primeiros números é maior que 10. O primeiro número tem um dígito par e um ímpar. O segundo número ou tem ambos os dígitos pares ou ambos os dígitos ímpares.

Construa um predicado puzzle(-Lista), capaz de calcular possíveis combinações da fechadura obedecendo às restrições mencionadas utilizando o paradigma da Programação em Lógica com Restrições.

– Exemplo:

?- Puzzle(Lista).

Lista = [10, 20, 30] ; Lista = [12, 24, 34] ; Lista = [14, 28, 38] ; no

Page 82: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

PLR – exercícios - solução

:-use_module(library(clpfd)).

puzzle([A,B,C]):-

domain([A,B,C],1,50),

domain([A1,B1],0,5),

domain([A2,B2],0,9),

A #= A1*10+A2,

B #= B1*10+B2,

B #= 2*A,

C #= 10+B,

A+B #> 10,

A1 mod 2 #\= A2 mod 2,

B1 mod 2 #= B2 mod 2,

labeling([ff],[A,B,C]).

Page 83: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

PLR – exercícios

– SolveDígitos:Construa um programa solveDigitos(A,B), utilizando PLR para encontrar os dois números (A e B) de três dígitos que obedecem às seguintes condições:

• Os seis dígitos que compõe os números A e B são todos distintos e nenhum deles é o 0.

• O primeiro dígito de B é igual a metade do último digito de A.

• Em ambos os números os dígitos encontram-se ordenados por ordem crescente.

• A soma dos dígitos de A é igual à soma dos dígitos de B.

• A multiplicação dos dígitos de A adicionado a 12 é igual à multiplicação dos dígitos de B.

- Exemplo: ?- solveDigitos(A,B).

A = 378, B = 459

Page 84: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

PLR – exercícios - solução

:-use_module(library(clpfd)).

resolveDigitos(A,B):-

Vars = [A1,A2,A3,B1,B2,B3],

domain(Vars, 1, 9),

A #= A1*100+A2*10+A3,

B #= B1*100+B2*10+B3,

all_distinct(Vars),

B1*2 #= A3,

A1 #< A2, A2 #< A3, B1 #< B2, B2 #< B3,

A1+A2+A3 #= B1+B2+B3,

A1*A2*A3+12 #= B1*B2*B3,

labeling([],Vars).

Page 85: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

PLR – exercícios

– Adega:

Três freiras herdaram a adega do tio. A primeira teve direito a 5/12 das garrafas, a segunda a 30% e a terceira às 187 garrafas restantes. Construa um programa em PLR para descobrir quantas garrafas estavam na adega.

Page 86: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

PLR – exercícios - solução

:-use_module(library(clpfd)).

garrafas(Num):-

Num in 187..10000,

Num #= A + B + 187,

A*12 #= 5*Num,

B*10 #= 3*Num,

labeling([],[Num]).

Page 87: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

PLR – exercícios

– Doze automóveis:Doze automóveis estão parados, em fila indiana, num cruzamento com semáforos. Sabe-se que:

• Os automóveis têm a seguinte distribuição de cores: 4 amarelos, 2 verdes, 3 vermelhos e 3 azuis;

• O primeiro e o último automóvel são da mesma cor;

• O segundo e o penúltimo são da mesma cor;

• O quinto automóvel é azul;

• Todos os conjuntos de três automóveis consecutivos têm três cores distintas;

• Partindo do primeiro automóvel para o último automóvel, é possível visualizar a sequência: amarelo-verde-vermelho-azul uma única vez.

Construa um programa em PLR para determinar a cor de cada um dos automóveis

Page 88: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

PLR – exercícios - solução:-use_module(library(clpfd)).

carros(Lista):-

length(Lista,12),

domain(Lista,1,4), %1-y, 2-g, 3-r, 4-b

global_cardinality(Lista, [1-4, 2-2, 3-3, 4-3]),

Lista=[A1,A2,_,_,A5,_,_,_,_,_,A11,A12],

A1 #= A12, A2 #= A11, A5 #= 4,

trios(Lista),

quad(Lista,ListVal),

sum(ListVal, #=, 1), !,

labeling([ff],Lista).

trios([_,_]).

trios([A,B,C|Resto]):-

all_different([A,B,C]),

trios([B,C|Resto]).

quad([_,_,_], []).

quad([A,B,C,D|Resto], [Val|ResVal]):-

A#<B #/\ B#<C #/\ C#<D #<=> Val,

quad([B,C,D|Resto], ResVal).

Page 89: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

PLR – exercícios

– Escalonamento simples:O Sr. Paulino nunca acorda antes das 6h da manhã mas necessita de acordar uma hora antes de apanhar o autocarro para o trabalho. A viagem de autocarro demora pelo menos uma hora. O Sr. Paulino não sai do trabalho antes de trabalhar pelo menos 8 horas, após o que demora pelo mais de uma hora a chegar a casa e poder ligar a sua televisão. No entanto o Sr. Paulino não resiste a ver pelo menos 3 horas de televisão antes de se deitar.

Utilize as variáveis: WakeUp, TakeBus1, StartWork, TakeBus2, TurnTVOn, FallASleep e construa um escalonador para o dia do Sr. Paulino. As variáveis devem estar nos limites 1..24.

Page 90: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

PLR – exercícios - solução:-use_module(library(clpfd)).

schedule(Times) :-

Times = [WakeUp,TakeBus1,StartWork,TakeBus2,TurnTVOn,FallASleep],

domain(Times,1,24),

WakeUp #>= 6,

WakeUp #< TakeBus1 - 1,

TakeBus1 #< StartWork - 1,

StartWork #< TakeBus2 - 8,

TakeBus2 #< TurnTVOn - 1,

TurnTVOn #< FallASleep - 3.

% Test 1 :

% schedule(Day).

% Test 2 :

% WU::7..9,FAS::20..22,schedule([WU,TB1,SW,TB2,TV,FAS])

% e com o labeling…?

% e mudando:

%StartWork #< TakeBus2 - 7,

%TurnTVOn #< FallASleep - 2.

Page 91: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

PLR – exercícios

– Cumulative:Considere 7 tarefas, cada qual com uma duração e quantidade de recursos utilizados fixos::

O obejctivo é encontrar o escalonamento com o mínimo tempo de conclusão não excedendo a capacidade do recurso - que é 13..

Tarefa Duração Recursos

T1 16 2

T2 6 9

T3 13 3

T4 7 7

T5 5 10

T6 18 1

T7 4 11

Page 92: Programação em Lógicaeol/LP/1011/documents/Praticas/...Implementação em Prolog…? Números de Fibonnaci –Solução: fibonacci(0,1). fibonacci(1,1). fibonacci(N,F):-N > 1, N1

PLR – exercícios - solução:-use_module(library(clpfd)).

schedule(Ss, End) :-

Ss = [S1,S2,S3,S4,S5,S6,S7],

Es = [E1,E2,E3,E4,E5,E6,E7],

Tasks = [task(S1,16,E1, 2, 1),

task(S2, 6,E2, 9, 2),

task(S3,13,E3, 3, 3),

task(S4, 7,E4, 7, 4),

task(S5, 5,E5,10, 5),

task(S6,18,E6, 1, 6),

task(S7, 4,E7,11, 7)],

domain(Ss, 1, 30),

domain(Es, 1, 50),

domain([End], 1, 50),

maximum(End, Es),

cumulative(Tasks, [limit(13)]),

append(Ss, [End], Vars),

labeling([minimize(End)], Vars).