IA Prolog

18,637 views

Published on

Apresentação sobre linguagem Prolog, seu funcionamento, comandos e aplicações

Published in: Technology
3 Comments
6 Likes
Statistics
Notes
No Downloads
Views
Total views
18,637
On SlideShare
0
From Embeds
0
Number of Embeds
185
Actions
Shares
0
Downloads
749
Comments
3
Likes
6
Embeds 0
No embeds

No notes for slide
  • IA Prolog

    1. 1. Inteligência Artificial PROLOG – partes 1, 2 e 3 Rafael Rosario [email_address] [email_address]
    2. 2. PROLOG (I) <ul><li>Foi criada em meados de 1972 por Alain Colmerauer e Philippe Roussel, na Universidade de Marselha. </li></ul><ul><li>O nome PROLOG foi escolhido por Philippe Roussel como uma abreviação de “ PRO grammation en LOG ique”. </li></ul><ul><li>Propósito da criação: criar programas para tradução de linguagens faladas, como português ou inglês. </li></ul>
    3. 3. PROLOG (II) <ul><li>Fundamentada na lógica simbólica ; </li></ul><ul><li>É uma linguagem declarativa: em vez de o programa estipular a maneira de chegar à solução, passo a passo, limita-se a fornecer uma descrição do problema que se pretende computar. </li></ul><ul><li>Usa uma coleção de fatos e de relações lógicas ( regras ) que exprimem o domínio relacional do problema. </li></ul>
    4. 4. PROLOG(III) <ul><li>Outro fato que o difere das outras linguagens é o fato de não possuir estruturas de controle (if-else, do-while, for, switch). Para isso utilizamos métodos lógicos para declarar como o programa deverá atingir o seu objetivo. </li></ul><ul><li>Um programa em PROLOG pode rodar em um modo interativo: o usuário poderá formular queries utilizando fatos e regras para produzir a solução através do mecanismo de unificação. </li></ul>
    5. 5. Fato (I) <ul><li>Determina uma relação existente entre objetos conhecidos. Expressa uma verdade sobre um relacionamento: </li></ul><ul><ul><li>homem(jose). </li></ul></ul><ul><ul><li>pai(jose,carina). </li></ul></ul><ul><ul><li>homem / pai – Predicado ou Relação. </li></ul></ul><ul><ul><li>jose / jose,carina – Argumento do Predicado ou Objeto </li></ul></ul>
    6. 6. Fato (II) <ul><li>Os nomes dos predicados e dos objetos devem começar com letra minúscula. </li></ul><ul><li>Os objetos são escritos dentro de parênteses. </li></ul><ul><li>Todo fato é terminado com um ponto final. </li></ul><ul><li>A ordem dos objetos é importante: </li></ul><ul><ul><li>pai (jose, carina).  pai (carina, jose). </li></ul></ul>
    7. 7. Fato (III) <ul><li>Com fatos, podemos montar uma base de conhecimento: </li></ul><ul><ul><ul><li>pai(alfredo,moacyr). </li></ul></ul></ul><ul><ul><ul><li>pai(alfredo,romeu). </li></ul></ul></ul><ul><ul><ul><li>pai(moacyr,eduardo). </li></ul></ul></ul><ul><ul><ul><li>pai(moacyr,rafael). </li></ul></ul></ul><ul><ul><ul><li>pai(moacyr,vinicius). </li></ul></ul></ul><ul><ul><ul><li>pai(romeu,cezar). </li></ul></ul></ul><ul><ul><ul><li>pai(romeu,alfredinho). </li></ul></ul></ul>
    8. 8. Regra (I) <ul><li>Expressa um relacionamento entre fatos. Um relacionamento em uma regra é verdadeiro se os outros relacionamentos nessa regra também o são: </li></ul><ul><li>luz(acesa) :- interruptor(ligado). </li></ul><ul><li>O &quot;:-&quot; significa &quot;se&quot;; ou seja, essa regra significa que luz(acesa) é verdadeiro se interruptor(ligado) é verdadeiro. </li></ul>
    9. 9. Regra (II) <ul><li>Regras podem também fazer uso de variáveis: </li></ul><ul><li>avo(X,Z) :- pai(X,Y), pai(Y,Z). </li></ul><ul><li>Isso significa &quot;se X é pai de Y e Y é pai de uma Z, então X é avô de Z“. </li></ul><ul><li>X, Y e Z são variáveis. No PROLOG,uma variável não é um contêiner cujo valor pode ser atribuído. Seu comportamento é como de uma incógnita, cujo valor é desconhecido a princípio e, após descoberto, não sofre mais mudanças. Escritas sempre em Maiúsculo. </li></ul>
    10. 10. Consulta (I) <ul><li>Quando de uma consulta, a máquina PROLOG pesquisa a base de dados procurando cláusulas que se unifiquem com a consulta: </li></ul><ul><li>? – pai(moacyr, rafael). </li></ul><ul><li>Responderá true se localizar um fato que se unifique com a consulta; se o fato consultado não existir na base de dados, responderá fail . </li></ul>
    11. 11. Consulta (II) <ul><li>Quando uma consulta contém variáveis, é realizada uma pesquisa em todas as cláusulas, localizado os objetos que essas representam: </li></ul><ul><ul><ul><li>?- avo(alfredo,N). </li></ul></ul></ul><ul><ul><ul><li>N = eduardo ; </li></ul></ul></ul><ul><ul><ul><li>N = rafael ; </li></ul></ul></ul><ul><ul><ul><li>N = vinicius ; </li></ul></ul></ul><ul><ul><ul><li>N = cezar ; </li></ul></ul></ul><ul><ul><ul><li>N = alfredinho. </li></ul></ul></ul>
    12. 12. Regras Recursivas <ul><li>Um predicado definido por uma regra recursiva deve ter, no mínimo uma definição não recursiva. Se isto não acontecer, a definição é logicamente mal-formada e o programa ficaria em laço infinito. </li></ul><ul><ul><ul><ul><li>ancestral(X,Y) :- mae(X,Y). </li></ul></ul></ul></ul><ul><ul><ul><ul><li>ancestral(X,Y) :- pai(X,Y). </li></ul></ul></ul></ul><ul><ul><ul><ul><li>ancestral(X,Y) :- mae(X,Z),ancestral(Z,Y). </li></ul></ul></ul></ul><ul><ul><ul><ul><li>ancestral(X,Y) :- pai(X,Z),ancestral(Z,Y). </li></ul></ul></ul></ul>
    13. 13. Prática 1 <ul><li>Crie a árvore genealógica da sua família, utilizando os predicados pai e mae, e verifique o que retorna cada consulta: </li></ul><ul><ul><li>ancestral(fulano,ciclano). </li></ul></ul><ul><ul><li>ancestral(X,ciclano). /*clique n a cada valor*/ </li></ul></ul><ul><ul><li>ancestral(fulado,Y). /*clique n a cada valor*/ </li></ul></ul><ul><ul><li>ancestral(fulado,_). /*clique n a cada valor*/ </li></ul></ul><ul><ul><li>mae(X,_). /*clique n a cada valor*/ </li></ul></ul><ul><ul><li>ancestral(X,_),pai(X,Y),pai(Y,_) </li></ul></ul>
    14. 14. Prática 1 - exemplo <ul><li>mae(zilda,moacyr). </li></ul><ul><li>mae(zilda,romeu). </li></ul><ul><li>mae(maria,eduardo). </li></ul><ul><li>mae(maria,rafael). </li></ul><ul><li>mae(maria,vinicius). </li></ul><ul><li>mae(norma,cezar). </li></ul><ul><li>mae(norma,alfredinho). </li></ul><ul><li>pai(alfredo,moacyr). </li></ul><ul><li>pai(alfredo,romeu). </li></ul><ul><li>pai(moacyr,rafael). </li></ul><ul><li>pai(moacyr,eduardo). </li></ul><ul><li>pai(moacyr,vinicius). </li></ul><ul><li>pai(romeu,cezar). </li></ul><ul><li>pai(romeu,alfredinho). </li></ul>
    15. 15. Outros conceitos (I) <ul><li>Conjunção : (“E” Lógico) é feita colocando-se uma vírgula entre os fatos: </li></ul><ul><li> avo(X,Z) :- pai(X,Y) , pai(Y,Z). </li></ul><ul><li>Aridade : é usado para a quantidade de objetos que o argumento de um predicado possui. </li></ul><ul><li>gosta (maria, josé). /* aridade = 2 */ </li></ul><ul><li>bebe (penélope, pinga, vodka, rum). /*4*/ </li></ul>
    16. 16. Outros conceitos (II) <ul><li>Negação : uma consulta é avaliada como falsa no caso de não estar presente nenhuma regra positiva ou fato que dê suporte ao termo proposto. Em outras palavras, se um fato não é conhecido ser verdadeiro (ou falso), assume-se que ele é falso. </li></ul><ul><li>legal(X) :- + ilegal(X). </li></ul><ul><li>Diferente: quando duas variáveis não podem ter o mesmo valor: </li></ul><ul><li>vizinho(X,Y) :- rua(X,Z), rua(Y,Z), X == Y. </li></ul>
    17. 17. Outros conceitos (II) <ul><li>Disjunção: (OU lógico), quando se declara mais de uma regra para determinar uma mesma relação: </li></ul><ul><li>vizinho(X,Y) :- rua(X,Z), rua(Y,Z), X == Y ; rua(X,Z), rua (X,W), proximo(Z,W). </li></ul>
    18. 18. Prática 2 <ul><li>A partir da árvore genealógica da sua família, crie as funções para: </li></ul><ul><ul><li>irmão; </li></ul></ul><ul><ul><li>meio-irmão; </li></ul></ul><ul><ul><li>primo; </li></ul></ul>
    19. 19. Resposta - Prática 2 (I) <ul><li>irmao(X,Y) :- pai(P,X), pai(P,Y), mae(M,X),mae(M,Y), X == Y . </li></ul><ul><li>meio-irmao(X,Y) :- </li></ul><ul><li>pai(P,X), pai(P,Y), X == Y, + irmao(X,Y) ; </li></ul><ul><li>mae(M,X),mae(M,Y), X == Y, + irmao(X,Y). </li></ul>
    20. 20. Resposta - Prática 2 (II) <ul><li>genitor(X,Y) :- pai(X,Y); mae(X,Y). </li></ul><ul><li>primo(X,Y) :- genitor(P,X), genitor(T,Y), </li></ul><ul><li>P == T, </li></ul><ul><li>genitor(V,P), genitor(V,T). </li></ul>
    21. 21. Aplicações (I) <ul><li>Lógica matemática, prova de teoremas e semântica; </li></ul><ul><li>Solução de equações simbólicas; </li></ul><ul><li>Bancos de dados relacionais; </li></ul><ul><li>Linguagem Natural; </li></ul><ul><li>Sistemas Especialistas; </li></ul>
    22. 22. Aplicações (II) <ul><li>Planejamento Automático de Atividades; </li></ul><ul><li>Aplicações de “General Problem Solving”, como jogos (Xadrez, Damas, Jogo da Velha, etc.); </li></ul><ul><li>Compiladores; </li></ul><ul><li>Análise Bioquímica e projetos de novas drogas. </li></ul>
    23. 23. Revisando – 3 elementos Prolog (I) <ul><li>Fatos : </li></ul><ul><li>gosta(rafael,cachorro). </li></ul><ul><li>valioso(ouro). </li></ul><ul><li>pai(moacyr,rafael). </li></ul>
    24. 24. Revisando – 3 elementos Prolog (II) <ul><li>Regras : </li></ul><ul><li>avo(X,Z) :- pai(X,Y), pai(Y,Z). </li></ul><ul><li>filho(Y,X) :- pai(X,Y), homem(Y). aluno(X,ia) :- estuda(X,prolog). </li></ul>
    25. 25. Revisando – 3 elementos Prolog (III) <ul><li>Consultas (ou metas) : </li></ul><ul><li>? – avo (alfredo, rafael). </li></ul><ul><li>? – primo (cezar, X). </li></ul><ul><li>? – pai (moacyr,_). </li></ul><ul><li>? – pai (X, eduardo). </li></ul>
    26. 26. Operadores de Controle <ul><li>O Prolog utiliza de alguns operadores de controle para tratamento da recursividade: </li></ul><ul><ul><li>Backtracking; </li></ul></ul><ul><ul><li>Cut; </li></ul></ul><ul><ul><li>Fail. </li></ul></ul>
    27. 27. Backtracking (I) <ul><li>Backtracking (ou retrocesso) : mecanismo usado pelo Prolog para encontrar fatos ou regras adicionais que satisfaçam um objetivo; </li></ul><ul><li>Quando a questão possui muitas sub-metas, a falha em uma busca pode acontecer. </li></ul><ul><li>Neste momento, o Prolog precisa de uma maneira para “lembrar” os pontos de onde pode tentar procurar a solução, para encontrar uma resposta certa. </li></ul>
    28. 28. Backtracking (II) <ul><li>Considere a seguinte Base de Conhecimento: </li></ul><ul><li>gosta (maria, pizza). </li></ul><ul><li>gosta (maria, vinho). </li></ul><ul><li>gosta (joão, vinho). </li></ul><ul><li>gosta (joão, maria). </li></ul><ul><li>É realizada a questão: </li></ul><ul><li>? - gosta (maria, X), gosta (joão, X). </li></ul>
    29. 29. Backtracking (III) <ul><li>? - gosta (maria, X) </li></ul><ul><li>X = pizza </li></ul><ul><li>? - gosta (joao, comida) – fail.. </li></ul><ul><li>Neste ponto, o Prolog precisa ignorar esse valor para X e procurar de onde ele havia parado anteriormente: </li></ul><ul><li>? - gosta (maria, X). </li></ul><ul><li>X = vinho. </li></ul><ul><li>? - gosta (joao, vinho) – true </li></ul>
    30. 30. Cut (I) <ul><li>O corte (cut) é um usado para evitar o backtracking. </li></ul><ul><li>O corte pode tornar um programa mais rápido, pois evita que o Prolog explore alternativas que, sabe-se de antemão, não irão contribuir para a solução do problema, e ainda permite a economia de memória. </li></ul>
    31. 31. Cut (II) <ul><li>f(X,0) :- X < 3. </li></ul><ul><li>f(X,2) :- X >= 3, X < 6. </li></ul><ul><li>f(X,4) :- X >= 6. </li></ul><ul><li>  </li></ul><ul><li>Se infomar um valor > 3 -> retorna 0 </li></ul><ul><li>Se informar um valor entre 3 e 6 -> retorna 2 </li></ul><ul><li>Se informar um valor > ou igual a 6 ->retorna 4 </li></ul><ul><li>Perguntamos: ? - f(1,Y). </li></ul>
    32. 32. Cut (II) <ul><li>O Prolog usando backtracking trata 2 regras que sabemos que irão falhar... </li></ul><ul><li>As 3 regras são mutuamente exclusivas: no momento em que uma funciona, não faz sentido tratar as outras 2. </li></ul><ul><li>Para isso usamos o Cut (!): </li></ul><ul><li>f(X,0) :- X < 3, !. </li></ul><ul><li>f(X,2) :- X >= 3, X < 6, !. </li></ul><ul><li>f(X,4) :- X >= 6. </li></ul><ul><li>  </li></ul>
    33. 33. Prática 3 <ul><li>Utilizando o Cut (!), escreva uma regra para validar se alguém tem um irmão, sem ter pesquisar toda a árvore: </li></ul><ul><li>tem_irmao(X) :- ??? </li></ul>
    34. 34. Prática 3 - Resposta <ul><li>Utilizando o Cut (!), escreva uma regra para validar se alguém tem um irmão, sem ter pesquisar toda a árvore: </li></ul><ul><li>tem_irmao(X) :- irmao(X,_), !. </li></ul>
    35. 35. Fail (I) <ul><li>Inversamente ao comando cut, o predicado pré-definido fail sempre falha. </li></ul><ul><li>O operador de corte (!) pode ser combinado com o predicado fail para produzir uma falha forçada: </li></ul><ul><li>gosta(maria,X) :- rato(X), !, fail. </li></ul><ul><li>gosta(maria,X) :- animal(X). </li></ul>
    36. 36. Prática 4 <ul><li>Podemos escrever a regra diferente de diversas formas: </li></ul><ul><li>diferente1(X,Y) :- + X = Y. </li></ul><ul><li>diferente2(X,Y) :- X== Y. </li></ul><ul><li>Escreva utilizando o cut (!) e fail: </li></ul>
    37. 37. Prática 4 - Resposta <ul><li>Podemos escrever a regra diferente de diversas formas: </li></ul><ul><li>diferente1(X,Y) :- + X = Y. </li></ul><ul><li>diferente2(X,Y) :- X== Y. </li></ul><ul><li>Escreva utilizando o cut (!) e fail: </li></ul><ul><li>diferente1(X,X) :- !, fail. </li></ul><ul><li>diferente1(X,Y). </li></ul>
    38. 38. Comando “Is” (I) <ul><li>Avalia a expressão e unifica o resultado. Exemplos: </li></ul><ul><ul><ul><li>? – X is 5 + 7 </li></ul></ul></ul><ul><ul><ul><li>X = 12 </li></ul></ul></ul><ul><ul><ul><li>? 12.5 is 5 * 2.5. </li></ul></ul></ul><ul><ul><ul><li>true </li></ul></ul></ul>
    39. 39. Comando “Is” (II) <ul><li>Também pode ser usada para criar funções matemáticas: </li></ul><ul><ul><li>divisao (X,Y,Z) :- Z is X / Y. </li></ul></ul><ul><ul><li>? divisao (10, 3, N). </li></ul></ul><ul><ul><li>N = 3.33333 </li></ul></ul>
    40. 40. Fatorial <ul><li>Fatorial usando comando “is”: </li></ul><ul><li>fatorial (0,1). </li></ul><ul><li>fatorial (N,F) :- N1 is N - 1, </li></ul><ul><li> fatorial(N1,F1), F is N * F1. </li></ul>
    41. 41. fatorial(3,F) – passo a passo (I) <ul><li>fatorial (0,1). </li></ul><ul><li>fatorial (N,F) :- N1 is N – 1, fatorial(N1,F1), F is N * F1. </li></ul><ul><li>------------------------------------------------------- </li></ul><ul><li>fatorial(0,1). fail </li></ul><ul><li>fatorial (3,F) => N=3, N1 =2; </li></ul>PILHA F 3 * F1
    42. 42. <ul><li>fatorial (0,1). </li></ul><ul><li>fatorial (N,F) :- N1 is N – 1, fatorial(N1,F1), F is N * F1. </li></ul><ul><li>--------------------------------------------------------- </li></ul><ul><li>fatorial(0,1). fail </li></ul><ul><li>fatorial (3,F) => N=3, N1 =1; </li></ul><ul><li>fatorial (2,F) => N=2, N1 =1; </li></ul>fatorial(3,F) – passo a passo (II) PILHA F 2 * F1 F 3 * F1
    43. 43. fatorial(3,F) – passo a passo (III) <ul><li>fatorial (0,1). </li></ul><ul><li>fatorial (N,F) :- N1 is N – 1, fatorial(N1,F1), F is N * F1. </li></ul><ul><li>--------------------------------------------------------- </li></ul><ul><li>fatorial(0,1). fail </li></ul><ul><li>fatorial (3,F) => N=3, N1 =1; </li></ul><ul><li>fatorial (2,F) => N=2, N1 =1; </li></ul><ul><li>fatorial (1,F) => N=1, N1 =0; </li></ul>PILHA F 1 * F1 F 2 * F1 F 3 * F1
    44. 44. fatorial(3,F) – passo a passo (IV) <ul><li>fatorial (0,1). </li></ul><ul><li>fatorial (N,F) :- N1 is N – 1, fatorial(N1,F1), F is N * F1. </li></ul><ul><li>--------------------------------------------------------- </li></ul><ul><li>fatorial(0,1). true </li></ul><ul><li>fatorial (3,F) => N=3, N1 =1; </li></ul><ul><li>fatorial (2,F) => N=2, N1 =1; </li></ul><ul><li>fatorial (1,F) => N=1, N1 =0; </li></ul><ul><li>fatorial(0,F) => F = 1 </li></ul>PILHA F 1 F 1 * F1 F 2 * F1 F 3 * F1
    45. 45. fatorial(3,F) – passo a passo (V) <ul><li>fatorial (0,1). </li></ul><ul><li>fatorial (N,F) :- N1 is N – 1, fatorial(N1,F1), F is N * F1. </li></ul><ul><li>--------------------------------------------------------- </li></ul><ul><li>fatorial (3,F) => N=3, N1 =1; </li></ul><ul><li>fatorial (2,F) => N=2, N1 =1; </li></ul><ul><li>fatorial (1,1) => N=1, N1 =0; </li></ul>PILHA F = 1 1 * 1 F 2 * F1 F 3 * F1
    46. 46. fatorial(3,F) – passo a passo (VI) <ul><li>fatorial (0,1). </li></ul><ul><li>fatorial (N,F) :- N1 is N – 1, fatorial(N1,F1), F is N * F1. </li></ul><ul><li>--------------------------------------------------------- </li></ul><ul><li>fatorial (3,F) => N=3, N1 =1; </li></ul><ul><li>fatorial (2,2) => N=2, N1 =1; </li></ul>PILHA F = 2 2 * 1 F 3 * F1
    47. 47. fatorial(3,F) – passo a passo (VII) <ul><li>fatorial (0,1). </li></ul><ul><li>fatorial (N,F) :- N1 is N – 1, fatorial(N1,F1), F is N * F1. </li></ul><ul><li>--------------------------------------------------------- </li></ul><ul><li>fatorial (3,6) => N=3, N1 =1; </li></ul><ul><li>F = 6 </li></ul>PILHA F = 6 3 * 2
    48. 48. Prática 5 <ul><li>Teste o fatorial para outros números: </li></ul><ul><li>fatorial (0,1). </li></ul><ul><li>fatorial (N,F) :- N1 is N – 1, fatorial(N1,F1), F is N * F1. </li></ul><ul><li>? – fatorial (7,F). ? – fatorial (100,F). </li></ul><ul><li>E se mudarmos a seqüência das regras? </li></ul><ul><li>fatorial (N,F) :- N1 is N – 1, fatorial(N1,F1), F is N * F1. </li></ul><ul><li>fatorial (0,1). </li></ul>
    49. 49. Resposta - Prática 5 <ul><li>E se mudarmos a seqüência das regras? </li></ul><ul><li>fatorial (N,F) :- N1 is N – 1, fatorial(N1,F1), F is N * F1. </li></ul><ul><li>fatorial (0,1). </li></ul><ul><li> ERROR: Unhandled exception: Out of local stack </li></ul><ul><li>O Prolog entrou em loop e estourou a pilha (stack). Isso porque ele sempre executa as regras na ordem em que são colocadas. </li></ul>
    50. 50. Boas práticas (I) <ul><li>De uma forma geral, é uma boa idéia colocar fatos antes de regras sempre que possível: </li></ul><ul><ul><ul><ul><li>amigo(rafael,pedro). </li></ul></ul></ul></ul><ul><ul><ul><ul><li>amigo(pedro,fernando). </li></ul></ul></ul></ul><ul><ul><ul><ul><li>amigo(fernando,murilo). </li></ul></ul></ul></ul><ul><ul><ul><ul><li>amigo(X,Y):-amigo(Y,X). </li></ul></ul></ul></ul><ul><li>O que acontece se colocarmos a última cláusula por primeiro, e fizermos uma consulta: amigo (X,Y) ? </li></ul>
    51. 51. Boas práticas (II) <ul><li>Regras não recursivas normalmente devem ser colocadas antes de regras recursivas: </li></ul><ul><ul><ul><li>ancestral(X,Y) :- mae(X,Y). /*nao recursivo*/ </li></ul></ul></ul><ul><ul><ul><li>ancestral(X,Y) :- pai(X,Y). /*nao recursivo*/ </li></ul></ul></ul><ul><ul><ul><li>ancestral(X,Y) :- mae(X,Z),ancestral(Z,Y). </li></ul></ul></ul><ul><ul><ul><li>ancestral(X,Y) :- pai(X,Z),ancestral(Z,Y). </li></ul></ul></ul>
    52. 52. Boas práticas (III) <ul><li>Quando possível, usar validações que façam com que a ordem das regras não cause loop: </li></ul><ul><ul><ul><li>fatorial(N,F) :- N > 0 , N1 is N - 1, </li></ul></ul></ul><ul><ul><ul><li> fatorial(N1,F1), F is N * F1. </li></ul></ul></ul><ul><ul><ul><li>fatorial(0,1). </li></ul></ul></ul>
    53. 53. Prática 6 <ul><li>1. Implemente: </li></ul><ul><li> max(X, Y, Max) /*use max(4,5,Max) para testar*/ </li></ul><ul><li>2. A seguinte relação classifica números em três classes: positivo, nulo ou negativo. Defina este procedimento de forma mais eficiente usando cuts: </li></ul><ul><ul><li>classe(N, positivo) :- N > 0. </li></ul></ul><ul><ul><li>classe(0, nulo). </li></ul></ul><ul><ul><li>classe(N, negativo) :- N < 0. </li></ul></ul>
    54. 54. Prática 6 - Respostas <ul><li>Implemente: </li></ul><ul><li> max(X, Y, Max) </li></ul><ul><li> max(X, Y, X) :- X >= Y. </li></ul><ul><li> max(X, Y, Y) :- X < Y. </li></ul><ul><li> max(X, Y, X) :- X >= Y, !. </li></ul><ul><li> max(X, Y, Y). </li></ul>
    55. 55. Prática 6 - Respostas <ul><li>classe(N, positivo) :- N > 0, !. </li></ul><ul><li>classe(N, negativo) :- N < 0, !. </li></ul><ul><li>classe(0, nulo). </li></ul>
    56. 56. Operadores infixos (I) <ul><li>E se eu quisessemos realizar consultas utilizando uma linguagem mais próxima da nossa? </li></ul><ul><li>? - Quem tem carro. </li></ul><ul><li>? joana faz Oque? </li></ul>
    57. 57. Operadores infixos (II) <ul><li>O programador Prolog pode definir seus próprios operadores, como no exemplo: tem e faz . </li></ul><ul><li>A definição de novos operadores é realizada pela inserção de um tipo especial de cláusula chamada diretiva. </li></ul><ul><li>As diretivas devem aparecer antes de qualquer expressão que contenha o operador criado. </li></ul>
    58. 58. Diretivas (I) <ul><li>Exemplo de diretiva: </li></ul><ul><li>:- op (500, xfx, tem). </li></ul><ul><li>Onde: </li></ul><ul><ul><li>500 indica a prioridade do operador; </li></ul></ul><ul><ul><li>xfx indica que o operador (f) deve ser colocado entre dois argumentos (x); </li></ul></ul><ul><ul><li>tem indica o nome do operador. </li></ul></ul>
    59. 59. Diretivas (II) <ul><li>Tendo a diretiva, criamos a base de conhecimento: </li></ul><ul><ul><li>pedro tem carro. </li></ul></ul><ul><ul><li>joana tem dinheiro. </li></ul></ul><ul><ul><li>joao tem problemas. </li></ul></ul><ul><ul><li>joao tem dívidas. </li></ul></ul><ul><li>E fizemos as consultas: </li></ul><ul><li>?- Quem tem carro. </li></ul><ul><li> Quem = pedro. </li></ul>
    60. 60. Diretivas (III) <ul><li>Curiosidade : os “comandos” que usamos no Prolog, são diretivas pré-definidas na sua implementação: </li></ul><ul><li>:- op (1200, xfx, ‘:-’); </li></ul><ul><li>:- op (1200, fx [‘:-’, ‘?-]). </li></ul><ul><li>:- op (1100, xfx, ‘;’) </li></ul><ul><li>:- op (1000, xfx, ‘,’) /* etc...*/ </li></ul><ul><li>Note que alguns operadores (ex.: ‘ :- ’), possuem definição infixa (xfx) e prefixa (fx). </li></ul>
    61. 61. Prática 7 <ul><li>Crie duas diretivas novas com operador infixo, e uma base de conhecimento usando estas diretivas. </li></ul><ul><li>Em seguida crie consultas que se assemelhem a linguagem humana. Exemplos: </li></ul><ul><ul><ul><li>? - fulado conhece Quem. </li></ul></ul></ul><ul><ul><ul><li>? - ciclano mora Onde. </li></ul></ul></ul>
    62. 62. Operadores de Comparação <ul><li>Lista completa dos operadores de comparação: </li></ul>OPERADOR PRIORIDADE TIPO SIGNIFICADO > 700 xfx maior que < 700 xfx menor que >= 700 xfx maior ou igual a <= 700 xfx menor ou igual a =:= ou == 700 xfx valores iguais == ou == 700 xfx valores diferentes
    63. 63. Base de dados relacional (I) <ul><li>Como criar uma base de dados relacional em Prolog? </li></ul><ul><li>Como pesquisar resultados dentro dessa base? </li></ul><ul><ul><ul><li>nasceu(pedroBarnack,joinville,1978). </li></ul></ul></ul><ul><ul><ul><li>nasceu(muriloPereira,itajai,1980). </li></ul></ul></ul><ul><ul><ul><li>nasceu(rafaelRosario,joinville,1980). </li></ul></ul></ul><ul><ul><ul><li>nasceu(janineBoos,joinville,1985). </li></ul></ul></ul><ul><ul><ul><li>nasceu(douglasSouza,curitiba, 1970). </li></ul></ul></ul>
    64. 64. Base de dados relacional (II) <ul><li>Como perguntamos: </li></ul><ul><li> Nome e ano de nascimento dos curitibanos? </li></ul><ul><li> ?- nasceu(Quem,curitiba,Ano). </li></ul><ul><li>Quem nasceu em joinville a partir de 1980? </li></ul><ul><li>?- nasceu(Quem,joinville,Ano),Ano >= 1980. </li></ul><ul><li>Nome e ano de nascimento de quem nasceu antes de 1980 (sem trazer a cidade)? </li></ul><ul><li> ?- nasceu(Quem,_,Ano), Ano < 1980. </li></ul>
    65. 65. Prática 8 <ul><li>Crie um banco de dados que contenhas as seguintes informações: </li></ul><ul><ul><li>Nome do Professor e disciplina que leciona; </li></ul></ul><ul><ul><li>Disciplina e horário (dia da semana, aula: primeiro ou segundo horário); </li></ul></ul><ul><li>Construa as consultas para responder: </li></ul><ul><ul><li>Qual o horário do professor X (disciplina, dia e aula)? </li></ul></ul><ul><ul><li>Quais professores lecionam na terça-feira? </li></ul></ul><ul><ul><li>Quais matérias o professor X leciona no primeiro horário? </li></ul></ul>
    66. 66. Prática 8 - resposta <ul><li>horario_prof(P,D,S,A) :- leciona(P,D), horario(D,S,A). </li></ul><ul><li>? - horario_prof(rafael,Disc,DiaSemana,Aula) . </li></ul><ul><li>2. ?- leciona(X,Disciplina) , horario(Disciplina,3,Aula). </li></ul><ul><li>3. ?- leciona(eduardo,Disc), horario(Disc,_,aula1).*/ </li></ul><ul><li>Base de dados: </li></ul><ul><li>leciona(rafael,ia). </li></ul><ul><li>leciona(eduardo,redes). </li></ul><ul><li>horario(ia,2,aula1). </li></ul><ul><li>horario(ia,5,aula1). </li></ul><ul><li>horario(redes,3,aula1). </li></ul><ul><li>horario(redes,4,aula2). </li></ul>
    67. 67. Prática 8 – resposta 2 (I) <ul><li>:- op(500, xfx, leciona ). </li></ul><ul><li>:- op(450, xfx, eh_lecionada_na ). </li></ul><ul><li>:- op(400, xfx, no_horario ). </li></ul><ul><li>:- op(300, fx, qual_o_horario_do_professor ) </li></ul><ul><li>qual_o_horario_do_professor(Prof , Materia, DiaSemana, SeqAula) :- </li></ul><ul><li>Prof leciona Materia, Materia eh_lecionada_na DiaSemana no_horario SeqAula. </li></ul>
    68. 68. Prática 8 – resposta 2 (II) <ul><li>Base de dados: </li></ul><ul><li>rafael leciona ia. </li></ul><ul><li>eduardo leciona redes. </li></ul><ul><li>ia eh_lecionada_na segunda_feira no_horario primeira_aula. </li></ul><ul><li>ia eh_lecionada_na quinta_feira no_horario primeira_aula. </li></ul><ul><li>redes eh_lecionada_na terca_feira no_horario primeira_aula. </li></ul><ul><li>redes eh_lecionada_na quarta_feira no_horario segunda_aula. </li></ul>
    69. 69. Prática 8 – resposta 2 (III) <ul><li>1. ? - qual_o_horario_do_professor(eduardo , Materia, DiaSemana, SeqAula). </li></ul><ul><li>?- Professor leciona Materia, Materia eh_lecionada_na terca_feira no_horario Qualquer. </li></ul><ul><li>?- Professor leciona Materia, Materia eh_lecionada_na DiaSemana no_horario primeira_aula. /*ou _ no lugar de DiaSemana*/ </li></ul>
    70. 70. Listas <ul><li>Listas podem ser definidas e transformadas em Prolog de diversas maneiras diferentes. </li></ul><ul><li>Listas são representadas por []: </li></ul><ul><ul><li>[a,e,i,o,u]; </li></ul></ul><ul><ul><li>[1,2,3,5,7,11]; </li></ul></ul>
    71. 71. Composição de Lista <ul><li>Listas são compostas por uma cabeça e uma cauda: </li></ul><ul><ul><li>[H,T]; </li></ul></ul><ul><li>Na lista [1,2,3,5,7], podemos dizer que: </li></ul><ul><ul><li>1 é a cabeça da lista </li></ul></ul><ul><ul><li>[2,3,5,7] é a cauda da lista; </li></ul></ul><ul><ul><li>De maneira similar, 2 e [3,5,7] são respectivamente a cabeça e a cauda da sub-lista [2,3,5,7] ; </li></ul></ul>
    72. 72. Construindo uma Lista <ul><li>Um lista é construída a partir de seus elementos básicos - uma cabeça e um corpo (ou cauda): </li></ul><ul><li>cons(X, Y, [X | Y]). </li></ul><ul><li>?-cons(a, b, Z). </li></ul><ul><li>Z=[a | b] </li></ul>
    73. 73. Ocorrência de elementos na Lista (I) <ul><li>Para verificar se um elemento é membro de uma lista, precisamos construir uma regra. </li></ul><ul><li>Podemos definir que tal regra gere os resultados abaixo: </li></ul><ul><li>? - membro( a , [a,b,c,d]). true . </li></ul><ul><li>? - membro( c , [a,b,c,d]). true . </li></ul><ul><li>? - membro ( j , [a,b,c,d]). fail </li></ul>
    74. 74. Ocorrência de elementos na Lista (II) <ul><li>Ou seja, dada uma lista L, X é membro de L se: </li></ul><ul><ul><li>1. X é a cabeça de L; </li></ul></ul><ul><ul><li> ? - membro(a, [a,b,c,d]). </li></ul></ul><ul><ul><li>2. Ou X é membro do corpo de L. </li></ul></ul><ul><ul><li> ? - membro(c, [a,b,c,d]). </li></ul></ul>
    75. 75. Ocorrência de elementos na Lista (III) <ul><li>A regra membro (X,L) terá duas cláusulas: </li></ul><ul><li>A primeira, um fato, estabelece a primeira condição: X é membro de L, se X é a cabeça de L. </li></ul><ul><li>A segunda, é uma chamada recursiva que diz que X ainda pode ser membro de L, desde que seja membro do corpo de L: </li></ul><ul><li>membro(X, [X | C]). </li></ul><ul><li>membro(X, [Y | C]) :- membro(X, C). </li></ul>
    76. 76. Prática 9 <ul><li>Dada a variante de implementação da regra membro: </li></ul><ul><li>membro2(X, [H | T]) :- X == H. </li></ul><ul><li>membro2(X, [H | T]) :- membro2(X, T). </li></ul><ul><li>  </li></ul><ul><li>Habilite o Debug gráfico (menu Debug -> Graphical Debugger). Use o comando trace. Em seguida, execute membro(d,[a,b,c,d]) e veja passo a passo. </li></ul><ul><li>Execute membro(X,[a,b,c]) e membro2 (X,[a,b,c]). Qual das funções funciona? Por que? </li></ul>
    77. 77. Concatenação de listas (I) <ul><li>Para a concatenação de duas listas quaisquer, resultando em uma terceira, se definirá a relação: </li></ul><ul><li>conc(L1, L3, L3). </li></ul><ul><li>onde L1 e L2 são duas listas e L3 é a concatenação resultante. Por exemplo: </li></ul><ul><li>? - conc([a, b], [c, d], L3) </li></ul><ul><li>L3 = [a, b, c, d]. </li></ul>
    78. 78. Concatenação de listas (II) <ul><li>Novamente, dois casos devem ser considerados, dependendo do primeiro argumento L1: </li></ul><ul><ul><li>Se o primeiro argumento é uma lista vazia, então o segundo e o terceiro argumentos devem ser a mesma lista. </li></ul></ul><ul><ul><li>Chamando tal lista de L, essa situação pode ser representada pelo seguinte fato Prolog: </li></ul></ul><ul><li>conc([], L, L). </li></ul>
    79. 79. Concatenação de listas (III) <ul><li>Se o primeiro argumento for uma lista não-vazia, então é porque ela possui uma cabeça e um corpo, e pode ser denotada por [X|L1]. </li></ul><ul><li>A concatenação de [X|L1] com uma segunda lista L2, produzirá uma terceira lista, com a mesma cabeça X da primeira e um corpo (L3) que é a concatenação do corpo da primeira lista (L1), com toda a segunda (L2). Isso se representa em Prolog por meio da regra: </li></ul><ul><li>conc([X | L1], L2, [X | L3]) :- conc(L1, L2, L3). </li></ul>
    80. 80. Concatenação de listas (IV) <ul><li>conc([1,2],[3,4]). </li></ul><ul><li>conc([X | L1], L2, [X |L3]) :- conc (L1,L2,L3) será: </li></ul><ul><li>conc([1|[2]), [3,4], [1,L3]) :- conc ([2],[3,4], L3). </li></ul><ul><li> conc ([2],[3,4], L3). </li></ul><ul><li> conc(2, [], [3,4], [2,L3]) :- conc ([],[3,4], L3). </li></ul><ul><li>conc ([],[3,4], L3). </li></ul><ul><li>conc([],L,L). </li></ul><ul><li>conc([], [3,4], [3,4]) </li></ul>
    81. 81. Concatenação de listas (V) <ul><li>conc([1,2],[3,4]). </li></ul><ul><li>conc([X | L1], L2, [X |L3]) :- conc (L1,L2,L3) será: </li></ul><ul><li>conc([1|[2]), [3,4], [1,L3]) :- conc ([2],[3,4], L3). </li></ul><ul><li> conc ([2],[3,4], L3). </li></ul><ul><li> conc(2, [], [3,4], [2,L3]) :- conc ([],[3,4], L3). </li></ul><ul><li>conc ([],[3,4], L3). L3 = [3,4] </li></ul><ul><li>conc([],L,L). L = [3,4] </li></ul><ul><li>conc([], [3,4], [3,4]) </li></ul>
    82. 82. Concatenação de listas (VI) <ul><li>conc([1,2],[3,4]). </li></ul><ul><li>conc([X | L1], L2, [X |L3]) :- conc (L1,L2,L3) será: </li></ul><ul><li>conc([1|[2]), [3,4], [1,L3]) :- conc ([2],[3,4], L3). </li></ul><ul><li>conc ([2],[3,4], L3). </li></ul><ul><li>conc(2, [], [3,4], [2,L3]) :- conc ([],[3,4], L3). </li></ul><ul><li>L3 = [3,4] </li></ul><ul><li>[X,L3] = [2,3,4] </li></ul>
    83. 83. Concatenação de listas (VII) <ul><li>conc([1,2],[3,4]). </li></ul><ul><li>conc([X | L1], L2, [X |L3]) :- conc (L1,L2,L3) será: </li></ul><ul><li>conc([1|[2]), [3,4], [1,L3] :- conc ([2],[3,4], L3). </li></ul><ul><li> conc ([2],[3,4], L3). L3 = [2,3,4], [X,L3] = [1,2,3,4] </li></ul>
    84. 84. Prática 10 <ul><li>Utilize a regra conc/3 no sentido inverso ao que foi originalmente projetado, para decompor uma lista [a,b,c] em duas partes. </li></ul><ul><li>Podemos também usar o programa para procurar por um determinado padrão em uma lista. Encontre os meses antes e depois de um determinado mês: </li></ul><ul><li>? - M=[jan, fev, mar, abr, mai , jun, jul, ago, set, out, nov, dez], < cláusula usando conc/3 >. </li></ul><ul><li>Antes=[jan,fev,mar,abr] Depois=[jun,jul,ago,set,out,nov, dez] </li></ul>
    85. 85. Remover da lista (I) <ul><li>A remoção de um elemento X de uma lista L pode ser programada através da relação: </li></ul><ul><li>remover(X, L, L1). </li></ul><ul><li>onde L1 é a mesma lista L com o elemento X removido. </li></ul>
    86. 86. Remover da lista (II) <ul><li>A relação remover/3 é definida de maneira similar à relação de ocorrência. São dois casos a estudar: </li></ul><ul><li>Se X é a cabeça da lista L, então L1 será o seu corpo; </li></ul><ul><li>Se X está no corpo de L, então L1 é obtida removendo X desse corpo. </li></ul><ul><li>remover(X, [X | C], C). </li></ul><ul><li>remover(X, [Y | C], [Y | D]) :- remover(X, C, D). </li></ul>
    87. 87. Remover da lista (III) <ul><li>Se há diversas ocorrências de X em L, a relação remove/3 é capaz de retirar cada uma delas através do mecanismo de backtracking do Prolog. </li></ul><ul><li>Em cada execução do programa remove/3 retiramos somente uma das ocorrências de X, por exemplo: </li></ul><ul><li>?-remover(a, [a, b, a, a], L). </li></ul><ul><li>L=[b, a, a]; </li></ul><ul><li>L=[a, b, a]; </li></ul><ul><li>L=[a, b, a]; </li></ul>
    88. 88. Prática 11 <ul><li>Utilize a regra remove/3 no sentido inverso, para inserir um novo item em qualquer lugar da lista. </li></ul><ul><li>Crie uma nova cláusula para membro, utilizando a regra remover/3. </li></ul>
    89. 89. bagOf, setOf e findAll <ul><li>Podemos gerar, através de backtracking, todos os objetos, um a um, que satisfazem algum objetivo (next, next, next). </li></ul><ul><li>Porém, algumas vezes, deseja-se dispor de todas as respostas juntas, por exemplo, dentro de uma lista. </li></ul><ul><li>Os predicados bagof/3, setof/3 e findall/3 servem exatamente para tal propósito. </li></ul>
    90. 90. bagOf (I) <ul><li>bagof(X, P, L) </li></ul><ul><li>Irá produzir uma lista L de todos os objetos X que satisfazem ao objetivo P. </li></ul><ul><li>Exemplo - dada a base de conhecimento abaixo: </li></ul><ul><li>classe(a, vog). </li></ul><ul><li>classe(b, con). </li></ul><ul><li>classe(c, con). /* continua d, e, f… */ </li></ul>
    91. 91. bagOf (II) <ul><li>Podemos obter a lista de todas as consoantes nessa especificação através do objetivo: </li></ul><ul><li>?-bagof(Letra, classe(Letra, con), Consoantes). </li></ul><ul><li>Consoantes=[b, c, d, ..., z] </li></ul>
    92. 92. bagOf (III) <ul><li>Se a classe das letras não estivesse especificada, iríamos obter por meio de backtracking, duas listas, uma correspondendo às vogais e outra às consoantes: </li></ul><ul><li>?-bagof(Letra, classe(Letra, Classe), Letras). </li></ul><ul><li>Classe=vog Letras=[a, e, i, o, u]; </li></ul><ul><li>Classe=con Letras=[b, c, d, f, ..., z]. </li></ul>
    93. 93. bagOf – Outro Exemplo <ul><li>Dada a base de conhecimento: </li></ul><ul><li>leciona(rafael,progII). leciona(rafael,ia). </li></ul><ul><li>leciona(eduardo,redes). leciona(eduardo,progI). </li></ul><ul><li>Qual seria o retorno da consulta: </li></ul><ul><li>?- bagof(Disc,leciona(rafael,Disc),Disciplinas). </li></ul><ul><li>E ?- bagof(Disc,leciona(Prof,Disc),Disciplinas). </li></ul>
    94. 94. setOf (I) <ul><li>setof(X, P, L) </li></ul><ul><li>Irá novamente produzir uma lista L dos objetos X que satisfazem a P, só que desta vez a lista L estará ordenada e itens duplicados, se houver, serão eliminados. </li></ul>
    95. 95. setOf (II) <ul><li>Exemplo: </li></ul><ul><li>?- setof(Disc,eh_lecionada(Disc,Prof),Disciplinas). </li></ul><ul><li>Prof = rafael </li></ul><ul><li>Disciplinas = [ia, progII] </li></ul><ul><li>Prof = eduardo </li></ul><ul><li>Disciplinas = [progI, redes] </li></ul>
    96. 96. setOf (III) <ul><li>Não há restrição quanto ao tipo de objeto a ser coletado. Assim podemos, por exemplo, construir uma lista de pares da forma Classe/Letra de forma que as constantes apareçam em primeiro lugar na lista (&quot;con&quot; antecede alfabeticamente &quot;vog&quot;): </li></ul><ul><li>?-setof(Classe/Letra, classe(Letra, Classe), Letras). </li></ul><ul><li>Letras=[con/b, con/c, ..., con/z, vog/a, ..., vog/u] </li></ul>
    97. 97. findall (I) <ul><li>Teste no Prolog e descubra o que faz o findall/3 </li></ul>
    98. 98. What is next? <ul><li>Apostila completa: aluno@net </li></ul><ul><li>Próxima aula - DIA 14/04 – AVALIAÇÃO EM DUPLAS </li></ul>
    99. 99. Referências <ul><li>http://pt.wikipedia.org/wiki/Prolog </li></ul><ul><li>http://pt.wikipedia.org/wiki/Alain_Colmerauer </li></ul><ul><li>http://www.linhadecodigo.com.br/Artigo.aspx?id=1697 </li></ul><ul><li>http://en.wikipedia.org/wiki/Prolog </li></ul><ul><li>http://ccc.inaoep.mx/~emorales/Cursos/ProgSimb/node32.html </li></ul><ul><li>www.fei.edu.br/eletrica/r bianchi /ia/Apostila- Prolog .doc </li></ul><ul><li>http://www.swi-prolog.org/ </li></ul><ul><li>http://www.sics.se/isl/sicstuswww/site/index.html </li></ul><ul><li>http://gersonc.anahy.org/graduacao/paradigmas/prologsan.pdf </li></ul><ul><li>http://ia.ucpel.tche.br/~lpalazzo/Aulas/PDEC/ </li></ul><ul><li>http://gollem.science.uva.nl/SWI-Prolog/apps/view.html </li></ul><ul><li>http://www.fdi.ucm.es/profesor/fernan/des/ </li></ul>

    ×