Prolog: unificação e busca
Unificação
Ao responder a uma consulta, o interpretador Prolog pode precisar instanciar variáveis, isto é, atribuir valor às variáveis.
Dizemos que dois termos podem ser unificados se eles são iguais ou se contêm variáveis que podem ser instanciadas de forma a tornar os termos idênticos.
Definindo mais formalmente, pode-se dizer que dois termos podem ser unificados se, e somente se uma das condições for verdadeira:
- os dois termos são constantes (i.e., átomos ou números) e iguais
- ex.:
1
e1
,casa
e'casa'
- ex.:
- um dos termos é uma variável
- ex.:
X
e 1,X
emasc(harry)
,X
eY
- nesse caso, a variável é instanciada com o termo
- ex.:
- ambos são termos complexos com o mesmo nome e mesmo número de argumentos, e os termos correspondentes podem ser unificados.
- ex.:
pai(james, harry)
epai(X, harry)
(note quejames
pode ser unificado comX
).
- ex.:
O predicado =
pode ser usado para determinar se dois termos podem ser unificados. Exemplos:
=(casa, casa).
oucasa = casa.
(operador infixo)X = casa.
(o escopo de X é a cláusula)X = casa, Y = X
X = Y.
- Negação:
\=
.\=(X, Y)
é equivalente anot(=(X, Y))
Exercício
Exercício 2.1 do livro Learn Prolog Now!, página 31.
Quais das seguintes consultas resultam em uma unificação bem sucedida, e qual a instanciação de variáveis leva a essa unificação?
bread = bread
’Bread’ = bread
’bread’ = bread
Bread = bread
bread = sausage
food(bread) = bread
food(bread) = X
food(X) = food(bread)
food(bread,X) = food(Y,sausage)
food(bread,X,beer) = food(Y,sausage,X)
food(bread,X,beer) = food(Y,kahuna_burger)
food(X) = X
meal(food(bread),drink(beer)) = meal(X,Y)
meal(food(bread),X) = meal(X,drink(beer))
Busca
- Ao receber uma consulta, o Prolog tenta unificá-la com cada um dos fatos e com a cabeça das regras que estão na base de conhecimento.
- Lembrete: regra =
cabeça :- corpo.
- Lembrete: regra =
- Se unificar com um fato, retorna as instâncias das variáveis.
- Se unificar com a cabeça de uma regra, consulta o corpo da regra (recursivamente).
- Ver exemplos.
- Use
trace.
/notrace.
para ativar/desativar o rastreamento das consultas. - A busca pode ser construída como uma árvore
Exemplo
Exemplos 2, 3 e 4: http://cs.union.edu/~striegnk/courses/esslli04prolog/slides/0.day2.pdf#p9
Exemplo
Considere a seguinte base de conhecimento:
progenitor(paul, petunia).
progenitor(paul, lili).
tem_mesmo_progenitor_que(X, Y) :-
progenitor(P, X), progenitor(P, Y).
eh_irma_de(X, Y) :-
X \= Y, tem_mesmo_progenitor_que(X, Y).
Qual o retorno da consulta eh_irma_de(petunia, X).
?
O retorno é false.
, pois X = Y
, tornando a primeira meta de eh_irma_de
falsa; em uma conjunção lógica, basta uma parte ser falsa para a expressão toda ser falsa.
O problema é que as variáveis X
e Y
ainda não estão instanciadas quando o interpretador Prolog vai tentar provar a meta X \= Y
. Para resolver esse problema, deve-se mover o termo X \= Y
para o final da cláusula, pois nesse momento as variáveis X
e Y
já terão sido instanciadas por causa da meta tem_mesmo_progenitor_que(X, Y)
.
Exercício
Quais das próximas operações de unificação serão bem sucedidas e quais irão falhar? Para as que forem bem sucedidas, quais são as instanciações de variáveis resultantes?
ponto(A, B) = ponto(1, 2)
ponto(A, B) = ponto(X, Y, Z)
mais(2, 2) = 4
+(2, D) = +(E, 2)
t(p(-1,0), P2, P3) = t(P1, p(1, 0), p(0, Y))