Your SlideShare is downloading. ×
Programacao logica
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Programacao logica

1,287

Published on

Published in: Education
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,287
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
47
Comments
0
Likes
1
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Linguagem de Programação Lógica ‐ PrologProf. Iális CavalcanteEngenharia da Computação – UFC/Sobral
  • 2. 0. Sumário Ambiente Iniciando um programa Fatos e Regras Operadores e Aritmética Estruturas Recursividade Listas
  • 3. Ambiente Recursos requeridos: ◦ Editor de texto (escrita de programas); ◦ Ambiente de desenvolvimento (SWI-Prolog - http://www.swi- prolog.org/); ◦ Controle dos diretórios e arquivos; Interpretador vs Compilador ◦ Um compilador transforma seu programa em um arquivo executável, cujo arquivo pode ser executado fora do ambiente de desenvolvimento. ◦ Um interpretador executa seu programa linha por linha dentro dos recursos do ambiente de desenvolvimento. ◦ Interpretador Prolog
  • 4. Iniciando um programa Escreva um programa com o código abaixo: gosta(maria,comida). gosta(maria,vinho). gosta(joao, vinho). gosta(joao, maria). ◦ Não coloque espaço após o ponto; ◦ Não escreva qualquer termo com letra maiúscula; ◦ Adicione uma linha em branco ao final de tudo; Salve como “intro.pl” Abra o arquivo no SWI-Prolog Verifique a compilação (há erros?) Entre com: [intro].
  • 5. Iniciando um programa Teste o comando listing. Execute algumas consultas: ◦ gosta(maria,comida). ◦ gosta(joao, vinho). ◦ gosta(joao, comida). Quando terminado pode sair de intro com o comando halt
  • 6. Fatos e Regras O programa criado anteriormente pode ser adicionado por mais fatos. Realize novos testes a cada modificação: ◦ gosta(joao,X). ◦ gosta(maria,X). ◦ gosta(Y, comida). ◦ gosta(Y, vinho). Para a formação de uma regra é necessário a estrutura condicional a partir de um operador: Operador Significado :- if , and ; or
  • 7. Fatos e Regras Exemplo de fatos: amiga(joana,maria). amiga(maria,joana). amiga(maria,clara). amiga(clara,maria). ama(joana,maria). ama(maria,joana). Exemplo de regra (amiga_intima): amiga_intima(Ela1,Ela2) :- amiga(Ela1,Ela2), amiga(Ela2,Ela1), ama(Ela1,Ela2), ama(Ela2,Ela1). ?- amiga_intima(maria,joana). yes ?- amiga_intima(maria,clara). no
  • 8. Fatos e Regras Exercícios: crie regras para expressar as seguintes frases... ◦ João gosta de qualquer coisa que Maria gosta. João gosta de alguma coisa se Maria gosta de alguma coisa. ◦ João gosta de qualquer um que gosta de vinho. João gosta de alguém se alguém gosta de vinho. ◦ João gosta de qualquer um que goste deles mesmos.
  • 9. Fatos e Regras James I Charles I ElizabethCatherine Charles II James II Sophia George I
  • 10. Fatos e Regras Defina os fatos presentes nessa árvore da família... % macho(P) é verdadeiro quando P é macho macho(james1). macho(charles1). macho(charles2). macho(james2). macho(george1). % femea(P) é verdadeiro quando P é fêmea femea(catherine). femea(elizabeth). femea(sophia).
  • 11. Fatos e Regras Continuando... % pai(C,P) é verdadeiro quando C tem um pai chamado P pai(charles1, james1). pai(elizabeth, james1). pai(charles2, charles1). pai(catherine, charles1). pai(james2, charles1). pai(sophia, elizabeth). pai(george1, sophia). Salve o programa como familia.pl e faça algumas buscas.
  • 12. Fatos e Regras ◦ George I é o pai de Charles I? ◦ Quem é o pai de Charles I? ◦ Quem são os filhos de Charles I? Tente adicionar as seguintes regras e verifique o resultado: ◦ M é a mãe de P se ela é um pai de P e é fêmea. ◦ F é o pai de P se ele é pai de P e é macho. ◦ X é irmã(o) de Y se ambos têm os mesmos pais.
  • 13. Operadores e Aritmética Aridade ◦ A aridade de um predicado é simplesmente o número de argumentos que ele possui. ◦ Prolog se referencia à aridade porque permite diferentes predicados com o mesmo nome mas com aridade diferente. O uso desse recurso não é recomendável: legibilidade... Uso de espaços ◦ Evitar ao máximo, principalmente na definição dos fatos.
  • 14. Operadores e Aritmética Comentários % - para uma linha simples /* Para mais de uma linha a ser comentada */ Entrada/Saída simples ◦ nl – move o cursor para uma nova linha na tela ◦ write(X) – escreve X na tela
  • 15. Operadores e Aritmética Operadores relacionais: <, >, >=, =<, =, etc. ◦ positive(N) :- N>0. ◦ non_zero(N) :- N<0 ; N>0. Operadores aritméticos: +, -, *, / ◦ Funções como sqrt, exp, cos,... Mas com comportamento diferente. ◦ “1+4”, “3+2” e “5*1” são trabalhados de formas diferentes. primo(2). primo(3). primo(5). ... ◦ As consultas “primo(1+1)” or “primo(5*1)” falharão! ◦ “X is 1+1, primo(X).” terá sucesso!
  • 16. Operadores e Aritmética Teste a expressão: ◦ X is sqrt(9),Y is 2 ** 4, Z is floor(3.14). Teste as expressões a seguir e entenda o funcionamento das relações em Prolog: ◦ N is 1+1. ◦ N is 1+1, P is N*2, Q is P+Q. ◦ N is X+1. ◦ I is I+1. ◦ I is 6, I is I+1. ◦ I is 6, J is I+1. Apenas duas consultas são válidas!
  • 17. Operadores e Aritmética Todas as operações em Prolog são tratadas como relações. Sendo uma função definida em C/C++ para calcular o valor mínimo entre dois números: int minimum(int x, int y) { if (x < y) return x; else return y; } Em Prolog, essa função será representada por uma relação.
  • 18. Operadores e Aritmética Em geral, uma função que tem k argumentos será representada em Prolog como uma relação com: ◦ k+1 argumentos; ◦ Sendo que o último é usado para carregar o resultado; Então em Prolog, escreve-se: % minimum(X,Y,Z) é verdadeiro se Z é o mínimo de X e Y minimum(X,Y,X) :- X<Y. minimum(X,Y,Y) :- X>=Y.
  • 19. Estruturas (Structure) Forma geral: estrutura-nome (atributo, ..., atributo ) Parece um predicado, mas aqui representam objeto. Não representam relações. Se diferenciam, porque estruturas sempre surgem como argumentos.
  • 20. Estruturas Supondo que queremos representar carros como os atributos: marca, anos de uso (idade), preço. Chamaremos uma estrutura carro de três lugares, por exemplo: carro(ford,3,5000) representando um carro Ford de 3 anos de uso com valor de venda R$ 5.000,00.% possui(P,C) é verdadeiro se P tem um carro que combina com Cpossui(joao, carro(ford,3,5000)).possui(joao, carro(opel,2,6000)).possui(gil, carro(toyota,5,1000)).possui(gil, carro(ford,2,2000)). E fazemos a pergunta: “Que tipo de Ford o Gil possui?" Consulta: possui(gil, carro(ford, Idade, Preco)) Resposta: Idade=2, Preco=2000
  • 21. EstruturasSe quiser somente recuperar a informação sobre alguns campos pode-seutilizar o marcador _ (underline) que retorna qualquer valor existente| ?- possui(Pessoa, carro(ford,_,_)).Pessoa = joao ? ;Pessoa = gilyes◦ O underscore "_" indica que não se quer saber qual fato se casa com os campos apresentados.◦ Se quiser saber qual marca de carro foi vendida abaixo de 5000, deve-se verificar:| ?- possui(_, carro(Marca,_,Preco)), Preco < 5000.Marca = toyotaPreco = 1000 ? ;Marca = fordPreco = 2000yes
  • 22. Recursividade Quando se usa a recursão deve-se conhecer três coisas: ◦ Algum conjunto (ou “estrutura de dados”) sobre a qual está sendo feita a recursão: exemplos comuns incluem números, arrays, árvores, etc. ◦ Uma definição de caso base, normalmente lida com uma estrutura vazia. ◦ Uma definição de caso recursivo, explicando como trabalhar um caso não-trivial em termos de algumas versões de valores menores que ele mesmo. Fatorial: por definição, o fatorial de algum número n, escrito n! é n*n-1*n-2*…*1. Nós podemos expressar em termos de recursão como segue: ◦ Estrutura de Dados: números naturais ◦ Caso Base: 0! = 1 ◦ Caso Recursivo: Para qualquer n>0, nós temos n! = n * (n-1)! ◦ Perceba que foi definido n! em termos de (n-1)!. Pode-se fazer isso a partir do momento que se conhece que (n-1) < n
  • 23. Listas O formato de uma lista segue uma seqüência de valores, correspondente a um vetor em C. Exemplo: [joao, maria, patricia] [‘string’, 6, maria, X] também é válida; Lista vazia: [ ] Lista não-vazia: contém cabeça (head) com o primeiro elemento e cauda (tail) contendo os outros elementos. Exemplo: [joao, maria, patricia] ◦ Cabeça: joao ◦ Cauda: [maria, patricia]
  • 24. Listas Notação específica para listas: [Hd | Tl] denota que a lista possui cabeça Hd e com cauda uma lista Tl. [joao, maria, patricia] -> [ joao | [maria, patricia] ] -> -> [joao | [maria | [patricia] ] ] -> [joao | [maria | [patricia | [ ] ] ] ] Processamento de listas utiliza regras de unificação: ◦ O único termo que unifica com [ ] é [ ]; ◦ [H1 | T1] unifica com [H2 | T2] se H1 unifica com H2 e T1 unifica com T2
  • 25. Listas Quase todos os predicados que utilizam listas são recursivos: ◦ Caso base: a lista vazia [ ]; ◦ Caso recursivo: para uma lista da forma [H | T], execute alguma ação na cabeça H e chame o predicado recursivamente usando a cauda T. Tamanho de uma lista: size(Lista,Tam). % size(List,N) is true if List has N elements size([],0). size([H|T],N) :- size(T,N1), N is N1+1. Definindo: ◦ O tamanho da lista vazia é 0; ◦ O tamanho da lista [H | T] é: 1+(tamanho de T).
  • 26. ListasSomando uma lista: supondo que seja formada apenas por números.% somaLista(List, N) é verdadeiro se os elementos de Lista somam para NsomaLista([],0).somaLista([H|T],N) :- somaLista (T,N1), N is N1+H.Verificação de elemento na lista:% contem(Elem, Lista) é verdadeiro se Lista contém Elemcontem(X,[X|_]).contem(X,[_|T]) :- contem(X,T).contem(2, [1,2,3])contem(E, [1,2,3])contem(E, [2,1,2])contem(E, [])
  • 27. Listas como Acumuladores% print_to(N) - prints out all the numbers down from N to 0print_to(0) :- write(0).print_to(N) :- N>0, write(N), nl, N1 is N-1, print_to(N1). print_to(5). Imprime todos os números entre N e 0, N ≥ 0. Como armazenar este resultado em um vetor? [H| T] collect_to(0,[]). collect_to(N,[N|T]) :- N>0, N1 is N-1, collect_to(N1,T).
  • 28. Listas como Acumuladores Unindo duas listas: ◦ O predicado join_list(L1,L2,L3) define “se quisermos juntar L1 e L2 conseguimos L3". Considerando as possibilidades para L1 ◦ L1 é uma lista vazia, neste caso L3 é L2 ◦ L1 está na forma[H1 | T1]. Se fixar L2 ao seu final, consegue-se uma lista em que a cabeça ainda é H1, mas cuja cauda é a junção de T1 e L2join_list(L1,L2,L3) :- L1=[], L3=L2.join_list(L1,L2,L3) :- L1=[H1|T1], join_list(T1,L2,T3), L3=[H1|T3]. Outras possibilidades?
  • 29. Listas como Acumuladoresjoin_list([], L2, L2).join_list([H1|T1], L2, [H1|L3]) :- join_list(T1,L2,L3).join_list([],L2,L3) :- L3=L2.join_list([H1|T1],L2,L3) :- join_list(T1,L2,T3), L3=[H1|T3].join_list([1,2],[6,7],X).join_list(X, [5,6], [3,5,6]).join_list([3,4],Y, [3,4,5,6]).join_list(X,Y,[1,2]).
  • 30. Listas como Acumuladores Invertendo uma lista (duas maneiras):% bad_reverse(L1,L2) - uma implementação ruim de inversão de listabad_reverse([],[]).bad_reverse([H|T], L2) :-bad_reverse(T,NT), append(NT,[H],L2).% myreverse(?List, ?Reversed)% é verdadeiro quando Reversed possui os mesmos elementos que List mas em ordem inversagood_reverse(List, Reversed) :- good_reverse(List, [], Reversed).good_reverse([], Reversed, Reversed).good_reverse([Head|Tail], SoFar, Reversed) :- good_reverse(Tail, [Head|SoFar], Reversed).
  • 31. Listas como Acumuladores Exercícios: ◦ Escreva predicados para os seguintes problemas: cutlast(L1,L2) que é verdadeiro se L2 é L1 com o último elemento removido. trim(L1,N,L2) que é verdadeiro se L2 contém somente os N primeiros elementos de L1 evens(L1,L2) que é verdadeiro se L2 contém somente aqueles elementos de L1 que são pares, e na mesma ordem.
  • 32. Backtracking e Cut Suponha um programa que avalie a necessidade de atendimento de um paciente de acordo com sua idade:grau(N, primeiro) :- N>=70.grau(N, segundo) :- N<70, N>=63.grau(N, terceiro) :- N<63, N>=55.grau(N, quarto) :- N<55, N>=50.grau(N, espera) :- N<50, N>=40.grau(N, falha) :- N<40. grau(75, G) -> G = primeiro Mas avalia ainda todas as outras condições!
  • 33. Backtracking e Cutint pri(int n) { return n>=70; }int seg(int n) { return n<70 && n>=63; } Avalia todos!// ... preenchendo o resto ...int fal(int n) { return n<40; }switch(n) { case(pri(n)): cout << “Primeiro"; break; case(seg(n)): cout << “Segundo"; break; case(ter(n)): cout << “Terceiro"; break; Avalia apenas o válido! case(qua(n)): cout << “Quarto"; break; case(esp(n)): cout << “Espera"; break; case(fal(n)): cout << “Falha";}
  • 34. Backtracking e Cut Para melhorar o desempenho pode-se usar o recurso: ! (cut). Funciona como o break em C;grau(N, primeiro) :- N>=70, !.grau(N, segundo) :- N>=63, !.grau(N, terceiro) :- N>=55, !.grau(N, quarto) :- N>=50, !.grau(N, espera) :- N>=40, !.grau(N, falha) :- N<40.

×