210 likes | 398 Vues
Exemplos de Prolog. Automática I. Exemplo 1. Regra: Todos que possuem livros podem emprestá-lo à maria Fato: João possui um livro. Questão: O João pode emprestar um livro à maria? empresta(X,maria,livro(P)):-dono(X,livro(P)). dono(joao,livro(exodo)).
E N D
Exemplos de Prolog Automática I
Exemplo 1 • Regra: Todos que possuem livros podem emprestá-lo à maria • Fato: João possui um livro. • Questão: O João pode emprestar um livro à maria? • empresta(X,maria,livro(P)):-dono(X,livro(P)). • dono(joao,livro(exodo)). • Questão: ?- empresta(joao,maria,livro(X)).
Solução vista pelo PROLOG -1 • ?- empresta(joao,maria,livro(X)). • empresta(X,maria,livro(P)):-dono(X,livro(P)). • dono(joao,livro(exodo)). • X = joao e P = exodo • X da pergunta equivale ao P da regra • empresta(joao,maria,livro(exodo)) • X = exodo
Exemplo 2 • Regra: Todos que respeitam a si mesmo são respeitados pelos outros • Fato: Carol respeita a si mesma. • Pergunta: Quem é respeitado(a) por José? • respeitado_por(_,X):- respeita_a_si_mesmo(X). • respeita_a_si_mesmo(carol). • Questão: respeitado_por(jose,X).
Solução vista pelo PROLOG - 2 • REGRAS: • respeitado_por(_,X):- respeita_a_si_mesmo(X). • respeita_a_si_mesmo(carol). • Questão:?- respeitado_por(jose,X). • respeitado_por(_,X):- respeita_a_si_mesmo(X). • _ = qualquer valor ; verifica então quem respeita_a_si_mesmo • respeita_a_si_mesmo(carol). então • respeitado_por(jose,carol):- respeita_a_si_mesmo(carol). • Logo X = carol!
Exemplo 3 – Torre de Hanoi • (nl – new-line) (vírgula = and) • mover(1,X,Y,_) :- escrever('Mova o disco do topo da '), escrever(X), escrever(' para a '), escrever(Y), nl. • mover(N,X,Y,Z) :- N>1, M is N-1, mover(M,X,Z,Y), mover(1,X,Y,_), mover(M,Z,Y,X).
REGRAS: • mover(1,X,Y,_) :- escrever('Mova o disco do topo da '), escrever(X), escrever(' para a '), escrever(Y), nl. • mover(N,X,Y,Z) :- N>1, M is N-1, mover(M,X,Z,Y), mover(1,X,Y,_), mover(M,Z,Y,X). • mover(3,1,2,3) • Lembrar: nl = nova linha, “,” = and (operador e) _ = null (qqer parametro torna verdadeiro) • SOLUÇÃO:
Exemplo 4 • Como deletar um membro de uma lista? • Resposta: • del(X,L1,L2) somente tem sucesso se X é um membro de L1 e L2 é a lista original (L1) sem X. • Se X é o cabeça de L1, então a lista correta é o resto de L1. • Se X está no resto de L1, então a lista correta é a cabeça de L1 mais o resto sem o X. • del(X,[X|R],R). • del(X,[H|R1],[H|R2]):-del(X,R1,R2). • Questão: ?- del(3,[1,2,3],X).
Solução : • Regras: • del(X,[X|R],R). • del(X,[H|R1],[H|R2]):-del(X,R1,R2). • Questão: ?- del(3,[1,2,3],X). X = [1,2] • del(3, [1|[2,3],[1|R2]):-del(3,[2,3],R2). R2 = [2] • del(3, [2] | [3], [2 | R2]):-del(3,[3],R2). R2 = [] • del(3, [3 | [] ], []) -> R = []
Exemplo 5 • Como concatenar duas listas? • Resposta: • concatena(X,Y,Z) é verdadeiro se a lista Z é o resultado da concatenação das listas X e Y. • Se X é lista vazia ([]) então Z=Y. • Se X não é lista vazia, então a cabeça de Z é a cabeça de X e o resto de Z é igual à concatenação do resto de X com a lista Y. • concatena([],L2,L2). • concatena([H1|T1],L2,[H1|T3]):-concatena(T1,L2,T3). • Questão: ?- concatena([a,b,c],[d,e,f],L)
Solução • Regras: • concatena([],L2,L2). • concatena([H1|T1],L2,[H1|T3]):-concatena(T1,L2,T3). • Questão: Concatena([a,b,c] , [d,e,f],L) L = [a,b,c,d,e,f] • concatena([a|[b,c]] , [d,e,f] , [a|T3]):-concatena([b,c],[d,e,f],T3) • concatena([b|c] , [d,e,f] , [b|T3]):-concatena(c , [d,e,f] , T3) • concatena([c|[]] , [d,e,f] , [c|T3]):-concatena([] , [d,e,f] , T3) • concatena([] , [d,e,f] , T3) T3 = [d,e,f] T3 = [b,c,d,e,f] T3 = [c,d,e,f] T3 = [d,e,f]
Exemplo 6 • Como inverter uma lista? • Resposta: • inverte(L1,L2) é verdadeiro se a lista L2 é o inverso de L1. • A inversão de uma lista vazia é a própria lista vazia (saída da recursão). • A iversão de uma lista não vazia é uma lista obtida da concatenação (exemplo 4) do reverso do resto com uma lista que é apenas a cabeça da lista original. • inverte([],[]). • inverte([H|T],L):-inverte(T,L0),concatena(L0,[H],L). • Questão: ?- inverte([a,b,c],L).
Solução : • Regras: • inverte([],[]). • inverte([H|T],L):-inverte(T,L0),concatena(L0,[H],L). • Questão: • ?- inverte([a,b,c],L). L = [c,b,a] • inverte([a|[b,c]],L):-inverte([b,c],L0),concatena(L0,[a],L). L0= [a] L = [c,b,a] • inverte([b|c],L):-inverte(c,L0),concatena(L0,[b],L). L0 = [c] L = [c,b] • inverte([c|[]],L):-inverte([],L0),concatena(L0,[c],L). L0 = [] L = [c] • inverte([],L0). L0 = []. !
Exemplo 7 • Como calcular o tamanho de uma lista? • Resposta: • tamanho([],0). • tamanho([_|R],Tam):-tamanho(R,TamResto),Tam is TamResto+1. • Questão: ?- tamanho([1,r,t,5],T).
Solução: • Regras: • tamanho([],0). • tamanho([_|R],Tam):-tamanho(R,TamResto),Tam is TamResto+1. • Questão: ?- tamanho([1,r,t,5],T).T = 4 • tamanho([1|[r,t,5]],T):-tamanho([r,t,5],TamResto),Tam is TamResto+1. Tam = 4 • tamanho([r|[t,5]],T):-tamanho([t,5],TamResto),Tam is TamResto+1 Tam = 3 • tamanho([t|[5]],T):-tamanho([5],TamResto),Tam is TamResto+1 Tam = 2 • tamanho([5|[]],T):-tamanho([],TamResto),Tam is TamResto+1 Tam = 1 • tamanho([],TamResto). TamResto = 0
Cut (!) • ! é chamado de cute sempre obtém sucesso. Mas há um porém: as metas à direita do ! podem ser re-satisfeitas em um backtracking, mas as metas à esquerda não! Note também que cláusulas alternativas no mesmo banco de dados não serão mais consideradas se uma meta deste tipo for encontrada. • É usado para: • Informar ao sistema que a regra correta foi encontrada e nenhuma outra alternativa pode ser considerada; • Usando !,fail: Informar ao sistema que a meta falhou e nenhuma outra pode ser tentada. • Informar ao sistema para buscar apenas uma solução descartando soluções alternativas.
Exemplo 8 • Somar os inteiros de 1 a n. • soma(1,1):-!. • soma(N,Res):-N0 is N-1,soma(N0,Res0),Res is Res0+N. • Questão: ?- soma(3,X). X = 6 • soma(3,X):-2 is 3-1,soma(2,Res0),Res is Res0+3. Res = 6 • soma(2,Res0):-1 is 2-1,soma(1,Res0’),Res is Res0’+2. Res = 3 • soma(1,Res0’):-!. Res0’ = 1
Exemplo 9 • Calcular M elevado na N recursivamente. • exp(0,1,1). • exp(M,N,Res):-N>0,N0 is N-1,exp(M,N0,Res0),Res is Res0*M. • Questão: ?- exp(3,4,Res). Res = 81 • exp(3,4,Res):-4>0, 3 is 4-1,exp(3,3,Res0),Res is Res0*3 Res = 81 • exp(3,3,Res):-3>0, 2 is 3-1,exp(3,2,Res0),Res is Res0*3 Res = 27 • exp(3,2,Res):-2>0, 1 is 2-1,exp(3,1,Res0),Res is Res0*3 Res = 9 • exp(3,2,Res):-2>0, 1 is 2-1,exp(3,0,Res0),Res is Res0*3 Res = 3 • exp(0,1,1). Não dá! Acho que era pra ser : exp(_,0,1). • exp(_,0,Res0). Daí Res0 = 1