ia prolog
Post on 28-Jan-2015
118 Views
Preview:
DESCRIPTION
TRANSCRIPT
Inteligência Artificial
PROLOG – partes 1, 2 e 3
Rafael Rosariorafael.rosario@sociesc.org.br
rafael.rosario@datasul.com.br
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 “PROgrammation en LOGique”.
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 - exemplomae(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 0Se informar um valor entre 3 e 6 -> retorna 2Se 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 + 7X = 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). failfatorial (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). failfatorial (3,F) => N=3, N1 =1;fatorial (2,F) => N=2, N1 =1;
fatorial(3,F) – passo a passo (II)
PILHA
F 2 * F1F 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). failfatorial (3,F) => N=3, N1 =1;fatorial (2,F) => N=2, N1 =1;fatorial (1,F) => N=1, N1 =0;
PILHA
F 1 * F1F 2 * F1F 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). truefatorial (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
PILHAF 1F 1 * F1F 2 * F1F 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 * 1F 2 * F1F 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 * 1F 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 = 6PILHA
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
1. Crie duas diretivas novas com operador infixo, e uma base de conhecimento usando estas diretivas.
2. 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:
1. Qual o horário do professor X (disciplina, dia e aula)?2. Quais professores lecionam na terça-feira?3. Quais matérias o professor X leciona no primeiro horário?
Prática 8 - resposta
1. 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).
2. ?- Professor leciona Materia, Materia eh_lecionada_na terca_feira no_horario Qualquer.
3. ?- 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).
1. 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.
2. 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
1) Utilize a regra conc/3 no sentido inverso ao que foi originalmente projetado, para decompor uma lista [a,b,c] em duas partes.
2) 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
1) Utilize a regra remove/3 no sentido inverso, para inserir um novo item em qualquer lugar da lista.
2) 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 = rafaelDisciplinas = [ia, progII]Prof = eduardoDisciplinas = [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 ("con" antecede alfabeticamente "vog"):
?-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/rbianchi/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/
top related