6. Backtracking e
Controle
Backtracking
Considere o seguinte programa
abstrato e a consulta ?-a. :
A ordem de visita dos nodos na
árvore de busca é dada abaixo:
a :- b.
a :- c.
a :- d.
b
b :- e.
b :- f.
f :- g.
f :- h.
f :- i.
d.
e
f
3
g
2
5
h
a
1
c
8
d
9
4
6
i
7
a, b, e, (b), f, g, (f), h, (f), i, (f), (b), (a), c, (a), d
Os parênteses indicam caminho em backtracking
Introdução à Programação Prolog
2
Backtracking
Considere o seguinte programa
com o predicado gosta/2:
gosta(joão, jazz).
gosta(joão, maria).
gosta(joão, lasanha).
gosta(maria, joão).
gosta(maria, lasanha).
E a consulta:
O sistema Prolog tenta satisfazer o primeiro objetivo, desencadeando a
seguinte execução top-down:
1. Encontra que joão gosta de jazz
2. Instancia X com "jazz"
3. Tenta determinar se “maria gosta de jazz"
4. Falha, porque não consegue determinar se maria gosta de jazz
5. Realiza um backtracking na repetição da tentativa de satisfazer
gosta(joão, X), esquecendo o valor "jazz"
6. Encontra que joão gosta de maria
7. Instancia X com “maria"
8. Tenta determinar se “maria gosta de maria"
9. Falha porque não consegue demonstrar que maria gosta de maria
?- gosta(joão, X), gosta(maria, X).
X = lasanha
yes
10. Realiza um backtracking, mais uma vez tentando satisfazer
gosta(joão, X), esquecendo o valor “maria"
11. Encontra que joão gosta de lasanha
12. Instancia X com "lasanha"
13. Encontra que “maria gosta de lasanha"
14. É bem-sucedido, com X instanciado com "lasanha"
Introdução à Programação Prolog
3
O Operador Cut (!)
•
Seu objetivo é eliminar backtracking inútil, removendo da árvore de
busca as ramificações que não tem interesse.
•
Sintaticamente é representado por um ponto de exclamação.
•
Em uma cláusula, é interpretado como um objetivo que sempre é bemsucedido quando é encontrado no sentido normal da execução.
•
Mas, quando é encontrado no backtracking, sempre falha, neste caso
produzindo ainda a falha de todas as demais cláusulas do predicado
em que se encontra.
•
Seu uso pode melhorar consideravelmente o desempenho de
programas Prolog, mas pode ocasionar a perda da interpretação
declarativa (lógica), devendo ser usado com cuidado e parcimônia.
Introdução à Programação Prolog
4
Exemplo
Considere o seguinte programa
abstrato:
a :- !, b, c, d.
b :- f, g.
c :- m, n, !, p, q.
c :- r.
d.
Introdução à Programação Prolog
•
a é verdadeiro se b, c, d são
todos verdadeiros.
•
b é verdadeiro se f e g são
verdadeiros.
•
c é verdadeiro (1) se m, n, p, q
são verdadeiros, ou (2) se r é
verdadeiro.
•
se b falhar, a sempre vai falhar.
•
se p falhar, c sempre irá falhar e r
não será tentado.
5
Outros Predicados de Controle
Backtracking e cut são utilizados em
conjunto com outros predicados de
controle:
fail: é um predicado que sempre falha.
true: é um predicado que sempre é
bem sucedido.
repeat: sempre é bem-sucedido, tanto
no sentido direto quanto no
backtracking. É usado em conjunto
com o fail na construção de loops.
Comporta-se como se fosse definido
por:
repeat.
repeat :- repeat.
Introdução à Programação Prolog
Prolog emprega uma forma de negação
denominada negação por falha finita que
se comporta como se fosse definida por:
not(X) :- X, !, fail; true.
ou ainda:
not(X) :- X, !, fail.
not(_).
Esta forma de negação baseia-se na
Hipótese do Mundo Fechado (Closed
World Assumption) que estabelece que:
“Toda a verdade está no programa e
nada mais é verdadeiro”.
6
Mais Predicados de Controle
Processar Y para todas as soluções de X:
for(X, Y) :- X, Y, fail.
for(_,_).
ou ainda:
for(X, Y) :- X, Y, fail; true.
O ifThenElse em Prolog fica:
ifThenElse(X, Y, _) :- X, !, Y.
ifThenElse(_. _, Z) :- Z.
Como fica usando o “ou” (;)?
Um loop em Prolog pode ser controlado
da seguinte maneira:
loop:repeat,
read(X),
(X=fim, !;
processa(X,Y),
write(Y), nl,
fail).
O funcionamento é similar a um
while not X = fim do...
Em SWI-Prolog há a forma abreviada:
X -> Y; Z.
Introdução à Programação Prolog
7
Download

Backtracking e Controle