Prévia do material em texto
Paradigmas de Linguagem de Programação Resolução da Lista de Exercícios Sobre Prolog 1. Suponha que a base de conhecimento denominada labirinto.pl (enviada como anexo) descreve uma espécie de labirinto. Os fatos desta base determinam quais pontos estão conectados, ou seja, de qual ponto do labirinto pode-se ir diretamente a outro ponto em uma única etapa (ou seja, sem passar por pontos intermediários). Além disso, suponha que todos os caminhos são ruas de mão única, só se pode andar por elas em um único sentido. Assim, pode-se ir do ponto 1 ao ponto 2, mas não no sentido contrário. Escreva um predicado que informa de quais pontos do labirinto pode-se chegar a quais outros pontos quando se encadeia conexões expressas na base de conhecimento. Esse predicado deve poder responder questões como essas: Pode-se ir do ponto 5 ao ponto 10? Quais pontos se pode alcançar quando se começa no ponto 1? A partir de quais pontos se pode alcançar o ponto 13? Resposta: .?-connected(5,10). .?-connected(1,X). .?-connected(X,13). 2. Dada a base de conhecimento denominada viagem.pl (enviada como anexo), na qual o predicado byCar indica que a viagem é feita de carro; byTrain indica viagem de trem; e byPlane indica viagem de avião, escreva um programa travel que informa se é possível viajar de um ponto a outro encadeando trajetos de trem, carro e avião. Exemplo: o programa deve responder True à consulta travel(valmont,raglan). Resposta: travel(A,B):- byCar(A,B);byTrain(A,B);byPlane(A,B). travel(A,B):- ( byCar(A,C);byTrain(A,C);byPlane(A,C)),travel(C,Y). 3. Escreva um predicado de três parâmetros denominado combine1 que recebe duas listas com mesmo número de elementos como argumentos e combina os elementos das duas primeiras listas à terceira lista, conforme os exemplos a seguir: .?- combine1([a,b,c],[1,2,3],X). X = [a,1,b,2,c,3] .?- combine1([f,b,yip,yup],[glu,gla,gli,glo],Result). Result = [f,glu,b,gla,yip,gli,yup,glo] Resposta: combine1([X], [Y], [X,Y]). combine1([X|L1], [Y|L2], [X,Y|L3]):-combine1(L1, L2, L3). 4. Escreva agora um predicado de três parâmetros denominado combine2 que recebe duas listas com mesmo número de elementos como argumentos e combina os elementos das duas primeiras listas à terceira lista, conforme os exemplos a seguir: ?- combine2([a,b,c],[1,2,3],X). X = [[a,1],[b,2],[c,3]] ?-combine2([f,b,yip,yup],[glu,gla,gli,glo],Result). Result = [[f,glu],[b,gla],[yip,gli],[yup,glo]] Resposta: combine2([X], [Y], [[X,Y]]). combine2([X|L1], [Y|L2], [[X,Y]|L3]):-combine2(L1, L2, L3). 5. Escreva agora um predicado de três parâmetros denominado combine3 que recebe três listas como argumentos e combina os elementos das duas primeiras listas à terceira lista, conforme os exemplos a seguir: ?- combine3([a,b,c],[1,2,3],X). X = [j(a,1),j(b,2),j(c,3)] ?- combine3([f,b,yip,yup],[glu,gla,gli,glo],R). R = [j(f,glu),j(b,gla),j(yip,gli),j(yup,glo)] Resposta: combine3([X], [Y], [j(X,Y)]). combine3([X|L1], [Y|L2], [j(X,Y)|L3]):-combine3(L1, L2, L3). 6. Escreva um predicado retorna o último elemento de uma lista Resposta: Base de conhecimento: ultimo_elem([Y], Y). ultimo_elem([_|Xs], Y):-ultimo_elem(Xs, Y). Executar: ultimo_elem([a,b,c,d,e] , R) 7. Escreva um predicado que retorna o penúltimo elemento de uma lista Resposta: Base de conhecimento: penultimo([P, _],P). penultimo([Ca|Resto], R) :- penultimo(Resto,R). Executar: penultimo([a,b,c,d,e], R) 8. Escreva um predicado Prolog que cria uma lista contendo os inteiros numa dada faixa de valores. Exemplo: ?- range(4,9,L). L = [4,5,6,7,8,9] Resposta: listanum(Inicio, Fim, Lista):- listaux(Inicio, Fim, [], Lista). listaux(Inicio, Fim, Aux, Aux):- Fim < Inicio. listaux(Inicio, Fim,Aux,Lista):- Fim >= Inicio, DecFim is Fim - 1, listaux(Inicio, DecFim, [Fim|Aux], Lista). Executar: listanum(5, 15, Lista). 9. Define-se uma lista como duplicada se ela é formada por dois blocos de elementos que são exatamente os mesmos. A lista [a,b,c,a,b,c], por exemplo, é duplicada, pois é formada de [a,b,c] seguida de [a,b,c]. Já a lista [a,b,c,c,b,c] não é duplicada. Escreva um predicado Prolog duplicada(Lista), que retorna true se a lista é duplicada. Resposta: duplicada(Lista) :- append(X, X, Lista). 10. Escreva um predicado remove(X,L,K,R) que remove o k-ésimo elemento da lista L e retorna esse elemento no primeiro parâmetro (X) e retorna a lista sem o elemento (R). Exemplo: ?- remove(X,[a,b,c,d],2,R). X = b R = [a,c,d] Resposta: remove(L1,[L1|L2],1,L2). remove(X,[H|L1],N,[H|S]):- N1 is N-1 , remove(X,L1,N1,S). 11. Escreva um predicado Prolog que elimina duplicatas consecutivas de uma lista Prolog. Se uma lista contém elementos repetidos, eles devem ser substituídos por uma única cópia do elemento. A ordem dos elementos não deve ser alterada. Exemplo: ?. comprimir([z,z,z,z,y,x,x,z,z,w,v,v,v,v],X). X = [z,y,x,z,w,v] Resposta: comprimir([X],[X]). comprimir([X,Y|Zs],Ls):-X = Y,comprimir([Y|Zs],Ls). comprimir([X,Y|Zs],[X|Ls]):-X \= Y,comprimir([Y|Zs],Ls). 12. Escreva um predicado Prolog que extrai uma fatia de uma lista. Exemplo: ?- fatia([a,b,c,d,e,f,g,h,i,k],3,7,L). X = [c,d,e,f,g] Resposta: fatia([X|_],1,1,[X]). fatia([X|Xs],1,T,[X|Ys]) :- T > 1, T1 is T - 1, fatia(Xs,1,T1,Ys). fatia([_|Xs],J,T,Ys) :- J > 1, J1 is J - 1, T1 is T - 1, fatia(Xs,J1,T1,Ys).