View
214
Download
0
Category
Preview:
Citation preview
Predicados extralógicos
Prof. Elaine Faria e Hiran NonatoProgramação Lógica
UFU 2012
Créditos
• O material a seguir consiste de adaptações e extensões dos originais gentilmente cedidos pelo Prof. Alexsandro Santos Soares
Introdução
• Todas as implementações Prolog oferecem um certo número de predicados prédefinidos orientados a execução de rotinas que
• são necessárias com muita freqüência• são de difícil programação • se destinam a um domínio particular realçado pela
implementação
Tipos de termos• Os termos Prolog podem assumir desde simples constantes até
estruturas complexas • Se um termo é uma variável, então esta pode ou não estar instanciada
em algum momento da execução do programa
• Exemplo: adicionar os valores de duas variáveis, X e Y, por meio deZ is X + Y
– Desejase verificar se as variáveis X e Y estão instanciados com valores inteiros
• Podese utilizar o predicado prédefinido integer(X), que é verdadeiro se X estiver instanciada com um valor inteiro
..., integer(X), integer(Y), Z is X + Y, ...
Tipos de termos
Luis, A. M. Palazzo, Introdução à Programação Prolog, Educat, 1997.
Tipos de termos
Tipos de termos
?X=1, classifica(X).Tipo Atômico:> Numero Inteiro
?X=[], classifica(X).Tipo Atômico:> Lista Vazia
?X=tio(josé), classifica(X).Termo Estruturado
Construção e decomposição de termos
• Há três predicados prédefinidos para a decomposição de termos e construção de novos termos: – functor/3 – arg/3 – =../2
Construção e decomposição de termos
• =../2 "univ“ (operador infixo)– O objetivo Termo =.. L é bemsucedido se L é uma lista contendo
como primeiro elemento o functor principal de Termo, seguido pelos seus argumentos.
?f(a, b) =.. L.L=[f, a, b]
?T =.. [retângulo, 3, 5].T=retângulo(3, 5)
?Z =.. [p, X, f(X, Y)].Z=p(X, f(X, Y))
Construção e decomposição de termos
• functor/3functor(Termo, Functor, Aridade)
é verdadeiro se Functor é o functor principal de Termo e Aridade é o seu número de argumentos
• arg/3arg(N, Termo, Argumento)
é verdadeiro se Argumento é o Nésimo argumento em Termo
Construção e decomposição de termos
• Exemplos?functor(teste(f(X), X, t), Functor, Aridade).
Functor=teste Aridade=3
?arg(2, teste(X, t(a), t(b)), Argumento).Argumento=t(a)
?functor(D, data, 3), arg(1, D, 5), arg(2, D, abril), arg(3, D, 1994).D=data(5, abril, 1994)
Programas ou Bases de Dados• Modelo relacional
– uma base de dados é a especificação de um conjunto de relações
• Um programa Prolog pode ser visto como uma base de dados – A especificação das relações é parcialmente implícita (regras) e
parcialmente explícita (fatos).
• Prolog possui cinco comandos básicos para a manipulação da base de dados:
– assert/1– asserta/1– assertz/1
– retract/1– retractall/1
Adicionar informação
Remover informação
Manipulação da base de dados
? listing.true
Inicie com uma base de dados vazia
Using assert/1
? assert(feliz(maria)).true
Using assert/1
feliz(maria). ? assert(feliz(maria)).true?
Using assert/1
feliz(maria). ? assert(feliz(maria)).true? listing. feliz(maria).?
feliz(maria). ? assert(feliz(maria)).true? listing. feliz(maria).? assert(feliz(vicente)), assert(feliz(marcelo)), assert(feliz(bruno)),
assert(feliz(vicente)).
Using assert/1
Using assert/1
feliz(maria).feliz(vicente).feliz(marcelo).feliz(bruno).feliz(vicente).
? assert(feliz(maria)).true? listing. feliz(maria).? assert(feliz(vicente)), assert(feliz(marcelo)), assert(feliz(bruno)),
assert(feliz(vicente)).true?
Alterando o significado de predicados
• As manipulações na base de dados alteraram o significado do predicado feliz/1
• Mais genericamente:– Os comandos de manipulação da base de dados
nos dão a habilidade de alterar o significado dos predicados em tempo de execução.
Predicados estáticos e dinâmicos
• Predicados cujo o significado se altera durante o tempo de execução são chamados de predicados dinâmicos– feliz/1 é um predicado dinâmico– Alguns interpretadores Prolog necessitam de uma
declaração de predicados dinâmicos.
• Predicados comuns são algumas vezes chamados de predicados estáticos.
Inserindo regras
feliz(maria).feliz(vicente).feliz(marcelo).feliz(bruno).feliz(vicente).
? assert( (ingenuo(X): feliz(X)).
feliz(maria).feliz(vicente).feliz(marcelo).feliz(bruno).feliz(vicente).
ingenuo(A): feliz(A).
? assert( (ingenuo(X): feliz(X)).true?
Inserindo regras
Removendo informação
• Agora sabemos como adicionar informação à base de dados do Prolog– Fazemos isto como o predicado assert/1
• Como nós removemos informação?
Removendo informação
• Agora sabemos como adicionar informação à base de dados do Prolog– Fazemos isto como o predicado assert/1
• Como nós removemos informação?– Fazemos isto como o predicado retract/1 que
removerá uma cláusula– Podemos remover muitas cláusulas
simultaneamente com o predicado retractall/1
Usando retract/1
feliz(maria).feliz(vicente).feliz(marcelo).feliz(bruno).feliz(vicente).
ingenuo(A): feliz(A).
? retract(feliz(marcelo)).
feliz(maria).feliz(vicente).feliz(bruno).feliz(vicente).
ingenuo(A): feliz(A).
? retract(feliz(marcelo)).true?
Usando retract/1
feliz(maria).feliz(vicente).feliz(bruno).feliz(vicente).
ingenuo(A): feliz(A).
? retract(feliz(marcelo)).true? retract(feliz(vicente)).
Usando retract/1
feliz(maria).feliz(bruno).feliz(vicente).
ingenuo(A): feliz(A).
? retract(feliz(marcelo)).true? retract(feliz(vicente)).true
Usando retract/1
feliz(maria).feliz(bruno).feliz(vicente).
ingenuo(A): feliz(A).
? retract(feliz(X)).
Usando retract/1
feliz(bruno).feliz(vicente).
ingenuo(A): feliz(A).
? retract(feliz(X)).X=maria;
Usando retract/1
feliz(vicente).
ingenuo(A): feliz(A).
? retract(feliz(X)).X=maria;X=bruno;
Usando retract/1
ingenuo(A): feliz(A).
? retract(feliz(X)).X=maria;X=bruno;X=vicente;
Usando retract/1
ingenuo(A): feliz(A).
? retract(feliz(X)).X=maria;X=bruno;X=vicente;false?
Usando retract/1
Programas ou Bases de Dados• Exemplo?crise.
false.?assert(crise).
true.?crise.
true.?retract(crise).
true.?crise.
false
Programas ou Bases de Dados
bom:sol, not(chuva).
instavel:sol, chuva.
deprimente:chuva, neblina.
chuva.neblina.
?bom.false.
?deprimente.true.
?retract(neblina).true.
?deprimente.false.
?assert(sol)true.
?instavel.true.
?retract(chuva).true.
?bom.true.
Programas ou Bases de Dados
• Podese especificar a posição na qual a cláusula deve ser inserida na base de dados
asserta(C)introduz a cláusula C no início da base de dados
assertz(C)adiciona a cláusula C no final da base de dados
Programas ou Bases de Dados
?assert(p(a)), assertz(p(b)), asserta(p(c)).true.
?p(X).X=c;X=a;X=b;false.
Programas ou Bases de Dados
• Relação entre consult/1 e assertz/1– para "consultar" um arquivo, ler cada um dos seus termos
(cláusulas) e inserilos no final da base de dados
consult(X) :open(X,read,A), read(A,C),transfere(A,C), close(A).
transfere(F,_) : at_end_of_stream(F),!.transfere(A,C) :
assertz(C), read(A,C1),transfere(A,C1).
Programas ou Bases de Dados
• Em algumas implementações Prolog asserta/1, assertz/1e retract/1 só funcionam em predicados que tenham sido declarados dinâmicos– Deve aparecer antes da definição ou uso do predicado dinâmico
: dynamic Nome/Aridade.– A intenção é evitar a alteração acidental da base de
conhecimento• Exemplo:
:dynamic gosta/2.
Programas ou Bases de Dados
• Uma aplicação útil do predicado asserta/1 é armazenar respostas já computadas para consultas formuladas ao programa
• Exemplo: predicado resolve(Problema, Solução)
?resolve(prob1,Sol), asserta(resolve(prob1, Sol)).Se o primeiro objetivo acima é bemsucedido, então a resposta(Solução) é armazenada e utilizada na resposta a questões futuras
Programas ou Bases de Dados• Adicionar a correspondente tabela de multiplicação à base
de dados
tabMult :L = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],membro(X, L), membro(Y, L),Z is X*Y, assert(produto(X, Y, Z)), fail.
tabMult.
? produto(A, B, 8).A=1 B=8; A=2 B=4; A=4 B=2; A=8 B=1; false.
Programas ou Bases de Dados
• Cuidado– O uso abusivo de assertretract pode obscurecer o
significado do programa e dificultar a compreensão do que é verdadeiro e o que não é num dado instante
– O comportamento resultante do programa pode se tornar difícil de entender, de explicar e de confiar
Recursos para o controle de programas
• call(P) – dispara um objetivo P. Será bemsucedido se e
somente se P também o for• repeat
– objetivo que sempre é bemsucedido. Sua principal propriedade é ser não determinístico
• toda vez que é alcançado por backtracking ele gera um caminho alternativo para a execução
repeat. repeat : repeat.
Recursos para o controle de programas
• Exemplos do uso do repeatquadrado :
repeat, read(X),(X=fim, !; Y is X*X, write(Y), fail).
executa :repeat, menu(X),(X=fim, !; exec(X), fail).
Bagof, Setof e Findall
• Podese gerar, através de backtracking, todos os objetos, um a um, que satisfazem algum objetivo
• Cada vez que uma nova solução é gerada, a anterior desaparece e não é mais acessível
• O que fazer quando desejase dispor de todos os objetos gerados?
Bagof, Setof e Findall
bagof(X, P, L)irá produzir uma lista L de todos os objetos X que satisfazem ao objetivo P
classe(a, vog).classe(b, con).classe(c, con).classe(d, con).classe(e, vog).. . .
?bagof(Letra, classe(Letra, con), Consoantes).Consoantes=[b, c, d, ..., z]
Bagof, Setof e Findall? bagof(Letra, classe(Letra, Classe), Letras).
Classe=vog, Letras=[a, e, i, o, u];Classe=con, Letras=[b, c, d, f, ..., z].
– Se não houver solução para P no objetivo bagof(X, P, L), então este falha
– Se algum objeto X é encontrado repetidamente, todas as suas ocorrências irão aparecer em L
• possibilidade de existência de elementos duplicados em L
Bagof, Setof e Findall
setof(X, P, L)irá produzir uma lista L dos objetos X que satisfazem a P, sendo que a lista L estará ordenada e itens duplicados serão eliminados
?setof(Classe/Letra, classe(Letra, Classe), Letras).Letras=[con/b, con/c, ..., con/z, vog/a, ..., vog/u]
Bagof, Setof e Findall
findall(X, P, L)produz a lista L de todos os objetos X que satisfazem P
• Diferença entre findall e o bagof – todos os objetos X são coletados sem considerar eventuais
soluções diferentes para as variáveis em P que não são compartilhadas com X
?findall(Letra, classe(Letra, Classe), Letras).Letras=[a, b, c, ..., z]
Bagof, Setof e Findallidade(pedro,7).idade(ana,5).idade(alice,8).idade(tomaz,5).
?findall(Crianca,idade(Crianca,Idade),L).L = [pedro,ana,alice,tomaz]
?findall(Crianca/Idade,idade(Crianca,Idade),L).L = [pedro/7, ana/5, alice/8, tomaz/5]
?findall(Crianca/Idade, (idade(Crianca,Idade),Idade>5),L).L = [pedro/7, alice/8]
Bagof, Setof e Findall
• Se não há nenhum objeto X que satisfaça P, então o predicado findall(X, P, L) resulta bemsucedido com L=[]
Referências
• Luis, A. M. Palazzo, Introdução à Programação Prolog, Educat, 1997.
• Slides da Profa Solange – ICMCUSP – Inteligência Artificial
Recommended