IA Prolog
Upcoming SlideShare
Loading in...5
×
 

IA Prolog

on

  • 20,509 views

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

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

Statistics

Views

Total Views
20,509
Views on SlideShare
20,339
Embed Views
170

Actions

Likes
5
Downloads
640
Comments
3

2 Embeds 170

http://www.slideshare.net 169
http://webcache.googleusercontent.com 1

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

IA Prolog IA Prolog Presentation Transcript

  • Inteligência Artificial PROLOG – partes 1, 2 e 3 Rafael Rosario [email_address] [email_address]
  • PROLOG (I)
    • Foi criada em meados de 1972 por Alain Colmerauer e Philippe Roussel, na Universidade de Marselha.
    • O nome PROLOG foi escolhido por Philippe Roussel como uma abreviação de “ PRO grammation en LOG ique”.
    • Propósito da criação: criar programas para tradução de linguagens faladas, como português ou inglês.
  • PROLOG (II)
    • Fundamentada na lógica simbólica ;
    • É 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.
    • Usa uma coleção de fatos e de relações lógicas ( regras ) que exprimem o domínio relacional do problema.
  • PROLOG(III)
    • 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.
    • 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.
  • Fato (I)
    • Determina uma relação existente entre objetos conhecidos. Expressa uma verdade sobre um relacionamento:
      • homem(jose).
      • pai(jose,carina).
      • homem / pai – Predicado ou Relação.
      • jose / jose,carina – Argumento do Predicado ou Objeto
  • Fato (II)
    • Os nomes dos predicados e dos objetos devem começar com letra minúscula.
    • Os objetos são escritos dentro de parênteses.
    • Todo fato é terminado com um ponto final.
    • A ordem dos objetos é importante:
      • pai (jose, carina).  pai (carina, jose).
  • Fato (III)
    • Com fatos, podemos montar uma base de conhecimento:
        • pai(alfredo,moacyr).
        • pai(alfredo,romeu).
        • pai(moacyr,eduardo).
        • pai(moacyr,rafael).
        • pai(moacyr,vinicius).
        • pai(romeu,cezar).
        • pai(romeu,alfredinho).
  • Regra (I)
    • Expressa um relacionamento entre fatos. Um relacionamento em uma regra é verdadeiro se os outros relacionamentos nessa regra também o são:
    • luz(acesa) :- interruptor(ligado).
    • O ":-" significa "se"; ou seja, essa regra significa que luz(acesa) é verdadeiro se interruptor(ligado) é verdadeiro.
  • Regra (II)
    • Regras podem também fazer uso de variáveis:
    • avo(X,Z) :- pai(X,Y), pai(Y,Z).
    • Isso significa "se X é pai de Y e Y é pai de uma Z, então X é avô de Z“.
    • 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.
  • Consulta (I)
    • Quando de uma consulta, a máquina PROLOG pesquisa a base de dados procurando cláusulas que se unifiquem com a consulta:
    • ? – pai(moacyr, rafael).
    • 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 .
  • Consulta (II)
    • Quando uma consulta contém variáveis, é realizada uma pesquisa em todas as cláusulas, localizado os objetos que essas representam:
        • ?- avo(alfredo,N).
        • N = eduardo ;
        • N = rafael ;
        • N = vinicius ;
        • N = cezar ;
        • N = alfredinho.
  • Regras Recursivas
    • 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.
          • ancestral(X,Y) :- mae(X,Y).
          • ancestral(X,Y) :- pai(X,Y).
          • ancestral(X,Y) :- mae(X,Z),ancestral(Z,Y).
          • ancestral(X,Y) :- pai(X,Z),ancestral(Z,Y).
  • Prática 1
    • Crie a árvore genealógica da sua família, utilizando os predicados pai e mae, e verifique o que retorna cada consulta:
      • ancestral(fulano,ciclano).
      • ancestral(X,ciclano). /*clique n a cada valor*/
      • ancestral(fulado,Y). /*clique n a cada valor*/
      • ancestral(fulado,_). /*clique n a cada valor*/
      • mae(X,_). /*clique n a cada valor*/
      • ancestral(X,_),pai(X,Y),pai(Y,_)
  • Prática 1 - exemplo
    • mae(zilda,moacyr).
    • mae(zilda,romeu).
    • mae(maria,eduardo).
    • mae(maria,rafael).
    • mae(maria,vinicius).
    • mae(norma,cezar).
    • mae(norma,alfredinho).
    • pai(alfredo,moacyr).
    • pai(alfredo,romeu).
    • pai(moacyr,rafael).
    • pai(moacyr,eduardo).
    • pai(moacyr,vinicius).
    • pai(romeu,cezar).
    • pai(romeu,alfredinho).
  • Outros conceitos (I)
    • Conjunção : (“E” Lógico) é feita colocando-se uma vírgula entre os fatos:
    • avo(X,Z) :- pai(X,Y) , pai(Y,Z).
    • Aridade : é usado para a quantidade de objetos que o argumento de um predicado possui.
    • gosta (maria, josé). /* aridade = 2 */
    • bebe (penélope, pinga, vodka, rum). /*4*/
  • Outros conceitos (II)
    • 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.
    • legal(X) :- + ilegal(X).
    • Diferente: quando duas variáveis não podem ter o mesmo valor:
    • vizinho(X,Y) :- rua(X,Z), rua(Y,Z), X == Y.
  • Outros conceitos (II)
    • Disjunção: (OU lógico), quando se declara mais de uma regra para determinar uma mesma relação:
    • vizinho(X,Y) :- rua(X,Z), rua(Y,Z), X == Y ; rua(X,Z), rua (X,W), proximo(Z,W).
  • Prática 2
    • A partir da árvore genealógica da sua família, crie as funções para:
      • irmão;
      • meio-irmão;
      • primo;
  • Resposta - Prática 2 (I)
    • irmao(X,Y) :- pai(P,X), pai(P,Y), mae(M,X),mae(M,Y), X == Y .
    • meio-irmao(X,Y) :-
    • pai(P,X), pai(P,Y), X == Y, + irmao(X,Y) ;
    • mae(M,X),mae(M,Y), X == Y, + irmao(X,Y).
  • Resposta - Prática 2 (II)
    • genitor(X,Y) :- pai(X,Y); mae(X,Y).
    • primo(X,Y) :- genitor(P,X), genitor(T,Y),
    • P == T,
    • genitor(V,P), genitor(V,T).
  • Aplicações (I)
    • Lógica matemática, prova de teoremas e semântica;
    • Solução de equações simbólicas;
    • Bancos de dados relacionais;
    • Linguagem Natural;
    • Sistemas Especialistas;
  • Aplicações (II)
    • Planejamento Automático de Atividades;
    • Aplicações de “General Problem Solving”, como jogos (Xadrez, Damas, Jogo da Velha, etc.);
    • Compiladores;
    • Análise Bioquímica e projetos de novas drogas.
  • Revisando – 3 elementos Prolog (I)
    • Fatos :
    • gosta(rafael,cachorro).
    • valioso(ouro).
    • pai(moacyr,rafael).
  • Revisando – 3 elementos Prolog (II)
    • Regras :
    • avo(X,Z) :- pai(X,Y), pai(Y,Z).
    • filho(Y,X) :- pai(X,Y), homem(Y). aluno(X,ia) :- estuda(X,prolog).
  • Revisando – 3 elementos Prolog (III)
    • Consultas (ou metas) :
    • ? – avo (alfredo, rafael).
    • ? – primo (cezar, X).
    • ? – pai (moacyr,_).
    • ? – pai (X, eduardo).
  • Operadores de Controle
    • O Prolog utiliza de alguns operadores de controle para tratamento da recursividade:
      • Backtracking;
      • Cut;
      • Fail.
  • Backtracking (I)
    • Backtracking (ou retrocesso) : mecanismo usado pelo Prolog para encontrar fatos ou regras adicionais que satisfaçam um objetivo;
    • Quando a questão possui muitas sub-metas, a falha em uma busca pode acontecer.
    • 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.
  • Backtracking (II)
    • Considere a seguinte Base de Conhecimento:
    • gosta (maria, pizza).
    • gosta (maria, vinho).
    • gosta (joão, vinho).
    • gosta (joão, maria).
    • É realizada a questão:
    • ? - gosta (maria, X), gosta (joão, X).
  • Backtracking (III)
    • ? - gosta (maria, X)
    • X = pizza
    • ? - gosta (joao, comida) – fail..
    • Neste ponto, o Prolog precisa ignorar esse valor para X e procurar de onde ele havia parado anteriormente:
    • ? - gosta (maria, X).
    • X = vinho.
    • ? - gosta (joao, vinho) – true
  • Cut (I)
    • O corte (cut) é um usado para evitar o backtracking.
    • 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.
  • Cut (II)
    • f(X,0) :- X < 3.
    • f(X,2) :- X >= 3, X < 6.
    • f(X,4) :- X >= 6.
    •  
    • Se infomar um valor > 3 -> retorna 0
    • Se informar um valor entre 3 e 6 -> retorna 2
    • Se informar um valor > ou igual a 6 ->retorna 4
    • Perguntamos: ? - f(1,Y).
  • Cut (II)
    • O Prolog usando backtracking trata 2 regras que sabemos que irão falhar...
    • As 3 regras são mutuamente exclusivas: no momento em que uma funciona, não faz sentido tratar as outras 2.
    • Para isso usamos o Cut (!):
    • f(X,0) :- X < 3, !.
    • f(X,2) :- X >= 3, X < 6, !.
    • f(X,4) :- X >= 6.
    •  
  • Prática 3
    • Utilizando o Cut (!), escreva uma regra para validar se alguém tem um irmão, sem ter pesquisar toda a árvore:
    • tem_irmao(X) :- ???
  • Prática 3 - Resposta
    • Utilizando o Cut (!), escreva uma regra para validar se alguém tem um irmão, sem ter pesquisar toda a árvore:
    • tem_irmao(X) :- irmao(X,_), !.
  • Fail (I)
    • Inversamente ao comando cut, o predicado pré-definido fail sempre falha.
    • O operador de corte (!) pode ser combinado com o predicado fail para produzir uma falha forçada:
    • gosta(maria,X) :- rato(X), !, fail.
    • gosta(maria,X) :- animal(X).
  • Prática 4
    • Podemos escrever a regra diferente de diversas formas:
    • diferente1(X,Y) :- + X = Y.
    • diferente2(X,Y) :- X== Y.
    • Escreva utilizando o cut (!) e fail:
  • Prática 4 - Resposta
    • Podemos escrever a regra diferente de diversas formas:
    • diferente1(X,Y) :- + X = Y.
    • diferente2(X,Y) :- X== Y.
    • Escreva utilizando o cut (!) e fail:
    • diferente1(X,X) :- !, fail.
    • diferente1(X,Y).
  • Comando “Is” (I)
    • Avalia a expressão e unifica o resultado. Exemplos:
        • ? – X is 5 + 7
        • X = 12
        • ? 12.5 is 5 * 2.5.
        • true
  • Comando “Is” (II)
    • Também pode ser usada para criar funções matemáticas:
      • divisao (X,Y,Z) :- Z is X / Y.
      • ? divisao (10, 3, N).
      • N = 3.33333
  • Fatorial
    • Fatorial usando comando “is”:
    • fatorial (0,1).
    • fatorial (N,F) :- N1 is N - 1,
    • fatorial(N1,F1), F is N * F1.
  • fatorial(3,F) – passo a passo (I)
    • fatorial (0,1).
    • fatorial (N,F) :- N1 is N – 1, fatorial(N1,F1), F is N * F1.
    • -------------------------------------------------------
    • fatorial(0,1). fail
    • fatorial (3,F) => N=3, N1 =2;
    PILHA F 3 * F1
    • fatorial (0,1).
    • fatorial (N,F) :- N1 is N – 1, fatorial(N1,F1), F is N * F1.
    • ---------------------------------------------------------
    • fatorial(0,1). fail
    • fatorial (3,F) => N=3, N1 =1;
    • fatorial (2,F) => N=2, N1 =1;
    fatorial(3,F) – passo a passo (II) PILHA F 2 * F1 F 3 * F1
  • fatorial(3,F) – passo a passo (III)
    • fatorial (0,1).
    • fatorial (N,F) :- N1 is N – 1, fatorial(N1,F1), F is N * F1.
    • ---------------------------------------------------------
    • fatorial(0,1). fail
    • fatorial (3,F) => N=3, N1 =1;
    • fatorial (2,F) => N=2, N1 =1;
    • fatorial (1,F) => N=1, N1 =0;
    PILHA F 1 * F1 F 2 * F1 F 3 * F1
  • fatorial(3,F) – passo a passo (IV)
    • fatorial (0,1).
    • fatorial (N,F) :- N1 is N – 1, fatorial(N1,F1), F is N * F1.
    • ---------------------------------------------------------
    • fatorial(0,1). true
    • fatorial (3,F) => N=3, N1 =1;
    • fatorial (2,F) => N=2, N1 =1;
    • fatorial (1,F) => N=1, N1 =0;
    • fatorial(0,F) => F = 1
    PILHA F 1 F 1 * F1 F 2 * F1 F 3 * F1
  • fatorial(3,F) – passo a passo (V)
    • fatorial (0,1).
    • fatorial (N,F) :- N1 is N – 1, fatorial(N1,F1), F is N * F1.
    • ---------------------------------------------------------
    • fatorial (3,F) => N=3, N1 =1;
    • fatorial (2,F) => N=2, N1 =1;
    • fatorial (1,1) => N=1, N1 =0;
    PILHA F = 1 1 * 1 F 2 * F1 F 3 * F1
  • fatorial(3,F) – passo a passo (VI)
    • fatorial (0,1).
    • fatorial (N,F) :- N1 is N – 1, fatorial(N1,F1), F is N * F1.
    • ---------------------------------------------------------
    • fatorial (3,F) => N=3, N1 =1;
    • fatorial (2,2) => N=2, N1 =1;
    PILHA F = 2 2 * 1 F 3 * F1
  • fatorial(3,F) – passo a passo (VII)
    • fatorial (0,1).
    • fatorial (N,F) :- N1 is N – 1, fatorial(N1,F1), F is N * F1.
    • ---------------------------------------------------------
    • fatorial (3,6) => N=3, N1 =1;
    • F = 6
    PILHA F = 6 3 * 2
  • Prática 5
    • Teste o fatorial para outros números:
    • fatorial (0,1).
    • fatorial (N,F) :- N1 is N – 1, fatorial(N1,F1), F is N * F1.
    • ? – fatorial (7,F). ? – fatorial (100,F).
    • E se mudarmos a seqüência das regras?
    • fatorial (N,F) :- N1 is N – 1, fatorial(N1,F1), F is N * F1.
    • fatorial (0,1).
  • Resposta - Prática 5
    • E se mudarmos a seqüência das regras?
    • fatorial (N,F) :- N1 is N – 1, fatorial(N1,F1), F is N * F1.
    • fatorial (0,1).
    • ERROR: Unhandled exception: Out of local stack
    • O Prolog entrou em loop e estourou a pilha (stack). Isso porque ele sempre executa as regras na ordem em que são colocadas.
  • Boas práticas (I)
    • De uma forma geral, é uma boa idéia colocar fatos antes de regras sempre que possível:
          • amigo(rafael,pedro).
          • amigo(pedro,fernando).
          • amigo(fernando,murilo).
          • amigo(X,Y):-amigo(Y,X).
    • O que acontece se colocarmos a última cláusula por primeiro, e fizermos uma consulta: amigo (X,Y) ?
  • Boas práticas (II)
    • Regras não recursivas normalmente devem ser colocadas antes de regras recursivas:
        • ancestral(X,Y) :- mae(X,Y). /*nao recursivo*/
        • ancestral(X,Y) :- pai(X,Y). /*nao recursivo*/
        • ancestral(X,Y) :- mae(X,Z),ancestral(Z,Y).
        • ancestral(X,Y) :- pai(X,Z),ancestral(Z,Y).
  • Boas práticas (III)
    • Quando possível, usar validações que façam com que a ordem das regras não cause loop:
        • fatorial(N,F) :- N > 0 , N1 is N - 1,
        • fatorial(N1,F1), F is N * F1.
        • fatorial(0,1).
  • Prática 6
    • 1. Implemente:
    • max(X, Y, Max) /*use max(4,5,Max) para testar*/
    • 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:
      • classe(N, positivo) :- N > 0.
      • classe(0, nulo).
      • classe(N, negativo) :- N < 0.
  • Prática 6 - Respostas
    • Implemente:
    • max(X, Y, Max)
    • max(X, Y, X) :- X >= Y.
    • max(X, Y, Y) :- X < Y.
    • max(X, Y, X) :- X >= Y, !.
    • max(X, Y, Y).
  • Prática 6 - Respostas
    • classe(N, positivo) :- N > 0, !.
    • classe(N, negativo) :- N < 0, !.
    • classe(0, nulo).
  • Operadores infixos (I)
    • E se eu quisessemos realizar consultas utilizando uma linguagem mais próxima da nossa?
    • ? - Quem tem carro.
    • ? joana faz Oque?
  • Operadores infixos (II)
    • O programador Prolog pode definir seus próprios operadores, como no exemplo: tem e faz .
    • A definição de novos operadores é realizada pela inserção de um tipo especial de cláusula chamada diretiva.
    • As diretivas devem aparecer antes de qualquer expressão que contenha o operador criado.
  • Diretivas (I)
    • Exemplo de diretiva:
    • :- op (500, xfx, tem).
    • Onde:
      • 500 indica a prioridade do operador;
      • xfx indica que o operador (f) deve ser colocado entre dois argumentos (x);
      • tem indica o nome do operador.
  • Diretivas (II)
    • Tendo a diretiva, criamos a base de conhecimento:
      • pedro tem carro.
      • joana tem dinheiro.
      • joao tem problemas.
      • joao tem dívidas.
    • E fizemos as consultas:
    • ?- Quem tem carro.
    • Quem = pedro.
  • Diretivas (III)
    • Curiosidade : os “comandos” que usamos no Prolog, são diretivas pré-definidas na sua implementação:
    • :- op (1200, xfx, ‘:-’);
    • :- op (1200, fx [‘:-’, ‘?-]).
    • :- op (1100, xfx, ‘;’)
    • :- op (1000, xfx, ‘,’) /* etc...*/
    • Note que alguns operadores (ex.: ‘ :- ’), possuem definição infixa (xfx) e prefixa (fx).
  • Prática 7
    • Crie duas diretivas novas com operador infixo, e uma base de conhecimento usando estas diretivas.
    • Em seguida crie consultas que se assemelhem a linguagem humana. Exemplos:
        • ? - fulado conhece Quem.
        • ? - ciclano mora Onde.
  • Operadores de Comparação
    • Lista completa dos operadores de comparação:
    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
  • Base de dados relacional (I)
    • Como criar uma base de dados relacional em Prolog?
    • Como pesquisar resultados dentro dessa base?
        • nasceu(pedroBarnack,joinville,1978).
        • nasceu(muriloPereira,itajai,1980).
        • nasceu(rafaelRosario,joinville,1980).
        • nasceu(janineBoos,joinville,1985).
        • nasceu(douglasSouza,curitiba, 1970).
  • Base de dados relacional (II)
    • Como perguntamos:
    • Nome e ano de nascimento dos curitibanos?
    • ?- nasceu(Quem,curitiba,Ano).
    • Quem nasceu em joinville a partir de 1980?
    • ?- nasceu(Quem,joinville,Ano),Ano >= 1980.
    • Nome e ano de nascimento de quem nasceu antes de 1980 (sem trazer a cidade)?
    • ?- nasceu(Quem,_,Ano), Ano < 1980.
  • Prática 8
    • Crie um banco de dados que contenhas as seguintes informações:
      • Nome do Professor e disciplina que leciona;
      • Disciplina e horário (dia da semana, aula: primeiro ou segundo horário);
    • Construa as consultas para responder:
      • Qual o horário do professor X (disciplina, dia e aula)?
      • Quais professores lecionam na terça-feira?
      • Quais matérias o professor X leciona no primeiro horário?
  • Prática 8 - resposta
    • horario_prof(P,D,S,A) :- leciona(P,D), horario(D,S,A).
    • ? - horario_prof(rafael,Disc,DiaSemana,Aula) .
    • 2. ?- leciona(X,Disciplina) , horario(Disciplina,3,Aula).
    • 3. ?- leciona(eduardo,Disc), horario(Disc,_,aula1).*/
    • Base de dados:
    • leciona(rafael,ia).
    • leciona(eduardo,redes).
    • horario(ia,2,aula1).
    • horario(ia,5,aula1).
    • horario(redes,3,aula1).
    • horario(redes,4,aula2).
  • Prática 8 – resposta 2 (I)
    • :- op(500, xfx, leciona ).
    • :- op(450, xfx, eh_lecionada_na ).
    • :- op(400, xfx, no_horario ).
    • :- op(300, fx, qual_o_horario_do_professor )
    • qual_o_horario_do_professor(Prof , Materia, DiaSemana, SeqAula) :-
    • Prof leciona Materia, Materia eh_lecionada_na DiaSemana no_horario SeqAula.
  • Prática 8 – resposta 2 (II)
    • Base de dados:
    • rafael leciona ia.
    • eduardo leciona redes.
    • ia eh_lecionada_na segunda_feira no_horario primeira_aula.
    • ia eh_lecionada_na quinta_feira no_horario primeira_aula.
    • redes eh_lecionada_na terca_feira no_horario primeira_aula.
    • redes eh_lecionada_na quarta_feira no_horario segunda_aula.
  • Prática 8 – resposta 2 (III)
    • 1. ? - qual_o_horario_do_professor(eduardo , Materia, DiaSemana, SeqAula).
    • ?- Professor leciona Materia, Materia eh_lecionada_na terca_feira no_horario Qualquer.
    • ?- Professor leciona Materia, Materia eh_lecionada_na DiaSemana no_horario primeira_aula. /*ou _ no lugar de DiaSemana*/
  • Listas
    • Listas podem ser definidas e transformadas em Prolog de diversas maneiras diferentes.
    • Listas são representadas por []:
      • [a,e,i,o,u];
      • [1,2,3,5,7,11];
  • Composição de Lista
    • Listas são compostas por uma cabeça e uma cauda:
      • [H,T];
    • Na lista [1,2,3,5,7], podemos dizer que:
      • 1 é a cabeça da lista
      • [2,3,5,7] é a cauda da lista;
      • De maneira similar, 2 e [3,5,7] são respectivamente a cabeça e a cauda da sub-lista [2,3,5,7] ;
  • Construindo uma Lista
    • Um lista é construída a partir de seus elementos básicos - uma cabeça e um corpo (ou cauda):
    • cons(X, Y, [X | Y]).
    • ?-cons(a, b, Z).
    • Z=[a | b]
  • Ocorrência de elementos na Lista (I)
    • Para verificar se um elemento é membro de uma lista, precisamos construir uma regra.
    • Podemos definir que tal regra gere os resultados abaixo:
    • ? - membro( a , [a,b,c,d]). true .
    • ? - membro( c , [a,b,c,d]). true .
    • ? - membro ( j , [a,b,c,d]). fail
  • Ocorrência de elementos na Lista (II)
    • Ou seja, dada uma lista L, X é membro de L se:
      • 1. X é a cabeça de L;
      • ? - membro(a, [a,b,c,d]).
      • 2. Ou X é membro do corpo de L.
      • ? - membro(c, [a,b,c,d]).
  • Ocorrência de elementos na Lista (III)
    • A regra membro (X,L) terá duas cláusulas:
    • A primeira, um fato, estabelece a primeira condição: X é membro de L, se X é a cabeça de L.
    • A segunda, é uma chamada recursiva que diz que X ainda pode ser membro de L, desde que seja membro do corpo de L:
    • membro(X, [X | C]).
    • membro(X, [Y | C]) :- membro(X, C).
  • Prática 9
    • Dada a variante de implementação da regra membro:
    • membro2(X, [H | T]) :- X == H.
    • membro2(X, [H | T]) :- membro2(X, T).
    •  
    • 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.
    • Execute membro(X,[a,b,c]) e membro2 (X,[a,b,c]). Qual das funções funciona? Por que?
  • Concatenação de listas (I)
    • Para a concatenação de duas listas quaisquer, resultando em uma terceira, se definirá a relação:
    • conc(L1, L3, L3).
    • onde L1 e L2 são duas listas e L3 é a concatenação resultante. Por exemplo:
    • ? - conc([a, b], [c, d], L3)
    • L3 = [a, b, c, d].
  • Concatenação de listas (II)
    • Novamente, dois casos devem ser considerados, dependendo do primeiro argumento L1:
      • Se o primeiro argumento é uma lista vazia, então o segundo e o terceiro argumentos devem ser a mesma lista.
      • Chamando tal lista de L, essa situação pode ser representada pelo seguinte fato Prolog:
    • conc([], L, L).
  • Concatenação de listas (III)
    • 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].
    • 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:
    • conc([X | L1], L2, [X | L3]) :- conc(L1, L2, L3).
  • Concatenação de listas (IV)
    • conc([1,2],[3,4]).
    • conc([X | L1], L2, [X |L3]) :- conc (L1,L2,L3) será:
    • conc([1|[2]), [3,4], [1,L3]) :- conc ([2],[3,4], L3).
    • conc ([2],[3,4], L3).
    • conc(2, [], [3,4], [2,L3]) :- conc ([],[3,4], L3).
    • conc ([],[3,4], L3).
    • conc([],L,L).
    • conc([], [3,4], [3,4])
  • Concatenação de listas (V)
    • conc([1,2],[3,4]).
    • conc([X | L1], L2, [X |L3]) :- conc (L1,L2,L3) será:
    • conc([1|[2]), [3,4], [1,L3]) :- conc ([2],[3,4], L3).
    • conc ([2],[3,4], L3).
    • conc(2, [], [3,4], [2,L3]) :- conc ([],[3,4], L3).
    • conc ([],[3,4], L3). L3 = [3,4]
    • conc([],L,L). L = [3,4]
    • conc([], [3,4], [3,4])
  • Concatenação de listas (VI)
    • conc([1,2],[3,4]).
    • conc([X | L1], L2, [X |L3]) :- conc (L1,L2,L3) será:
    • conc([1|[2]), [3,4], [1,L3]) :- conc ([2],[3,4], L3).
    • conc ([2],[3,4], L3).
    • conc(2, [], [3,4], [2,L3]) :- conc ([],[3,4], L3).
    • L3 = [3,4]
    • [X,L3] = [2,3,4]
  • Concatenação de listas (VII)
    • conc([1,2],[3,4]).
    • conc([X | L1], L2, [X |L3]) :- conc (L1,L2,L3) será:
    • conc([1|[2]), [3,4], [1,L3] :- conc ([2],[3,4], L3).
    • conc ([2],[3,4], L3). L3 = [2,3,4], [X,L3] = [1,2,3,4]
  • Prática 10
    • Utilize a regra conc/3 no sentido inverso ao que foi originalmente projetado, para decompor uma lista [a,b,c] em duas partes.
    • 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:
    • ? - M=[jan, fev, mar, abr, mai , jun, jul, ago, set, out, nov, dez], < cláusula usando conc/3 >.
    • Antes=[jan,fev,mar,abr] Depois=[jun,jul,ago,set,out,nov, dez]
  • Remover da lista (I)
    • A remoção de um elemento X de uma lista L pode ser programada através da relação:
    • remover(X, L, L1).
    • onde L1 é a mesma lista L com o elemento X removido.
  • Remover da lista (II)
    • A relação remover/3 é definida de maneira similar à relação de ocorrência. São dois casos a estudar:
    • Se X é a cabeça da lista L, então L1 será o seu corpo;
    • Se X está no corpo de L, então L1 é obtida removendo X desse corpo.
    • remover(X, [X | C], C).
    • remover(X, [Y | C], [Y | D]) :- remover(X, C, D).
  • Remover da lista (III)
    • 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.
    • Em cada execução do programa remove/3 retiramos somente uma das ocorrências de X, por exemplo:
    • ?-remover(a, [a, b, a, a], L).
    • L=[b, a, a];
    • L=[a, b, a];
    • L=[a, b, a];
  • Prática 11
    • Utilize a regra remove/3 no sentido inverso, para inserir um novo item em qualquer lugar da lista.
    • Crie uma nova cláusula para membro, utilizando a regra remover/3.
  • bagOf, setOf e findAll
    • Podemos gerar, através de backtracking, todos os objetos, um a um, que satisfazem algum objetivo (next, next, next).
    • Porém, algumas vezes, deseja-se dispor de todas as respostas juntas, por exemplo, dentro de uma lista.
    • Os predicados bagof/3, setof/3 e findall/3 servem exatamente para tal propósito.
  • bagOf (I)
    • bagof(X, P, L)
    • Irá produzir uma lista L de todos os objetos X que satisfazem ao objetivo P.
    • Exemplo - dada a base de conhecimento abaixo:
    • classe(a, vog).
    • classe(b, con).
    • classe(c, con). /* continua d, e, f… */
  • bagOf (II)
    • Podemos obter a lista de todas as consoantes nessa especificação através do objetivo:
    • ?-bagof(Letra, classe(Letra, con), Consoantes).
    • Consoantes=[b, c, d, ..., z]
  • bagOf (III)
    • 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:
    • ?-bagof(Letra, classe(Letra, Classe), Letras).
    • Classe=vog Letras=[a, e, i, o, u];
    • Classe=con Letras=[b, c, d, f, ..., z].
  • bagOf – Outro Exemplo
    • Dada a base de conhecimento:
    • leciona(rafael,progII). leciona(rafael,ia).
    • leciona(eduardo,redes). leciona(eduardo,progI).
    • Qual seria o retorno da consulta:
    • ?- bagof(Disc,leciona(rafael,Disc),Disciplinas).
    • E ?- bagof(Disc,leciona(Prof,Disc),Disciplinas).
  • setOf (I)
    • setof(X, P, L)
    • 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.
  • setOf (II)
    • Exemplo:
    • ?- setof(Disc,eh_lecionada(Disc,Prof),Disciplinas).
    • Prof = rafael
    • Disciplinas = [ia, progII]
    • Prof = eduardo
    • Disciplinas = [progI, redes]
  • setOf (III)
    • 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;):
    • ?-setof(Classe/Letra, classe(Letra, Classe), Letras).
    • Letras=[con/b, con/c, ..., con/z, vog/a, ..., vog/u]
  • findall (I)
    • Teste no Prolog e descubra o que faz o findall/3
  • What is next?
    • Apostila completa: aluno@net
    • Próxima aula - DIA 14/04 – AVALIAÇÃO EM DUPLAS
  • Referências
    • http://pt.wikipedia.org/wiki/Prolog
    • http://pt.wikipedia.org/wiki/Alain_Colmerauer
    • http://www.linhadecodigo.com.br/Artigo.aspx?id=1697
    • http://en.wikipedia.org/wiki/Prolog
    • http://ccc.inaoep.mx/~emorales/Cursos/ProgSimb/node32.html
    • www.fei.edu.br/eletrica/r bianchi /ia/Apostila- Prolog .doc
    • http://www.swi-prolog.org/
    • http://www.sics.se/isl/sicstuswww/site/index.html
    • http://gersonc.anahy.org/graduacao/paradigmas/prologsan.pdf
    • http://ia.ucpel.tche.br/~lpalazzo/Aulas/PDEC/
    • http://gollem.science.uva.nl/SWI-Prolog/apps/view.html
    • http://www.fdi.ucm.es/profesor/fernan/des/