Aula de Prolog 06 - Recursão

19
Prolog – 06 Inteligência Artificial Fábio M. Pereira Baseado em Amzi! inc. – www.amzi.com

Transcript of Aula de Prolog 06 - Recursão

Page 1: Aula de Prolog 06 - Recursão

Prolog – 06

Inteligência ArtificialFábio M. Pereira

Baseado emAmzi! inc. – www.amzi.com

Page 2: Aula de Prolog 06 - Recursão

Aventura em Prolog 2

Aventura em Prolog Recursão Como a recursão funciona Pragmática Exercícios

Page 3: Aula de Prolog 06 - Recursão

Aventura em Prolog 3

Recursão É a habilidade de uma unidade de

código chamar a ela mesma, repetidamente, se necessário

É frequentemente uma maneira muito poderosa e conveniente de representar certos construtores de programação

Em Prolog, a recursão ocorre quando um predicado contém um objetivo que se refere a ele mesmo

Page 4: Aula de Prolog 06 - Recursão

Aventura em Prolog 4

Recursão Toda vez que uma regra é chamada,

Prolog usa o corpo da regra para criar uma nova consulta com novas variáveis

Uma vez que a consulta é uma nova cópia cada vez que é chamada, não faz diferença se uma regra chama outra regra ou a ela mesma

Page 5: Aula de Prolog 06 - Recursão

Aventura em Prolog 5

Recursão Uma definição recursiva sempre tem

pelo menos duas partes A condição limite (caso base): define um

caso simples que sabemos ser verdadeiro O caso recursivo: simplifica o problema

primeiro removendo uma camada de complexidade, e então chamando ela mesma

Em cada nível, a condição limite é testada, se verdadeira, a recursão pára, se não, a recursão continua

Page 6: Aula de Prolog 06 - Recursão

Aventura em Prolog 6

Exemplo – Nani Search Objetos próximos ou aninhados

O predicado local/2 nos diz que a lanterna está na escrivaninha e que a escrivaninha está no escritório, mas não nos indica que a lanterna está no escritório

?- local(lanterna,escritório).no

Usando recursão, iremos escrever um novo predicado esta_contido_em/2, o qual irá “cavar” através de camadas de objetos aninhados

Page 7: Aula de Prolog 06 - Recursão

Aventura em Prolog 7

Exemplo – Nani Search Para tornar o problema mais

interessante, primeiro iremos adicionar mais itens aninhados no jogo Iremos continuar usando o predicado local/2

para colocar objetos na escrivaninha, que por sua vez, podem conter outros objetos dentro deles

local(envelope, escrivaninha).local(selo, envelope).local(chave, envelope).

Page 8: Aula de Prolog 06 - Recursão

Aventura em Prolog 8

Exemplo – Nani Search Para listar todas as coisas no escritório:

Primeiro devemos listar os objetos que estão diretamente no escritório, como a escrivaninha

Depois devemos listar os objetos que estão na escrivaninha

A seguir objetos que estão dentro dos objetos que estão na escrivaninha

Page 9: Aula de Prolog 06 - Recursão

Aventura em Prolog 9

Exemplo – Nani Search A regra:

Um objeto, O1, está contido em outro objeto, O2, se O1 está diretamente localizado em O2 Esta é a condição limite

Um objeto, O1, está contido em outro objeto, O2, se algum objeto intermediário, X, está localizado em O2 e O1 está contido em X Aqui é onde nós simplificamos e fazemos a recursão

Page 10: Aula de Prolog 06 - Recursão

Aventura em Prolog 10

Exemplo – Nani Search Em Prolog:

Caso base:esta_contido_em(O1, O2):-

local(O1, O2). Caso recursivo:

esta_contido_em(O1, O2):-local(X, O2),esta_contido_em(O1, X).

Page 11: Aula de Prolog 06 - Recursão

Aventura em Prolog 11

Exemplo – Nani Search Testando...

?- esta_contido_em(X, escritório).X = escrivaninha ;X = computador ;X = lanterna ;X = envelope ;X = selo ;X = chave ;no?- esta_contido_em(envelope, escritório).yes?- esta_contido_em(maçã, escritório).no

Page 12: Aula de Prolog 06 - Recursão

Aventura em Prolog 12

Como a Recursão Funciona Como em todas as chamadas a regras,

as variáveis em uma regra são únicas, ou o escopo delas é a regra

Em um caso recursivo, isto significa que cada chamada à regra, em cada nível, possui seu próprio conjunto único de variáveis Assim, os valores de X, O1 e O2 no primeiro

nível da recursão são diferentes daqueles dos segundo nível

Page 13: Aula de Prolog 06 - Recursão

Aventura em Prolog 13

Como a Recursão Funciona Porém, a unificação entre um objetivo e

a cabeça de uma cláusula obrigue um relacionamento entre as variáveis de diferentes níveis

Acompanhe a execução da consulta a seguir...?- esta_contido_em(XQ, escritório).

Page 14: Aula de Prolog 06 - Recursão

Aventura em Prolog 14

esta_contido_em(XQ, escritório).

No primeiro nível de recursão:esta_contido_em(O11, O21) :- local(X1, O21), esta_contido_em(O11, X1).

XQ = _01 O11 = _01 O21 = escritório X1 = _02

Reescrita:esta_contido_em(_01, escritório) :- local(_02, escritório), esta_contido_em(_01, _02).

local/2 satisfeito com _02 = escrivaninhaesta_contido_em(_01, escrivaninha)

Este objetivo unifica com a cabeça de uma nova cópiada cláusula, no próximo nível de recursão. Após a unificação, as variáveis são:XQ = _01 O11 = _01 O12 = _01 O21 = escritório O22 = escrivaninha

X1 = escrivaninha X2 = _03

Page 15: Aula de Prolog 06 - Recursão

Aventura em Prolog 15

Como a Recursão Funciona Quando a recursão encontra uma solução,

como em ‘envelope’, todos os O1s e X0 imediatamente assumem um valor – utilize o modo de debug para acompanhar a execução

Ao escrever um predicado recursivo, é essencial garantir que a condição limite seja checada em cada nível, em outro caso, o programa poderá entrar em loop infinito A maneira mais simples de fazer isso, é sempre

definir a condição limite primeiro, garantindo que ela sempre será tentada antes do caso recursivo

Page 16: Aula de Prolog 06 - Recursão

Aventura em Prolog 16

Pragmática Considere que o objetivo local(X,Y) será

satisfeito por todas as cláusulas de local/2

Por outro lado, os objetivos local(X, escritório) e local(envelope, X) serão satisfeitos por poucas cláusulas

Observe no slide a seguir duas versões para a regra esta_contido_em/2...

Page 17: Aula de Prolog 06 - Recursão

Aventura em Prolog 17

Pragmática

Ambos darão respostas corretas, mas a performance de cada um irá depender da consulta: A consulta esta_contido_em(X, escritório) irá

executar mais rápido na primeira versão O2 é linkada fazendo com que a busca por local(X,

O2) seja mais fácil do que a busca por duas variáveis não linkadas

Por razões similares, a consulta esta_contido_em (chave, X) seja mais rapidamente executada na segunda versão

esta_contido_em(O1, O2):- local(X, O2), esta_contido_em(O1, X).

esta_contido_em(O1, O2):- local(O1, X), esta_contido_em(X, O2).

Page 18: Aula de Prolog 06 - Recursão

Aventura em Prolog 18

Exercícios Banco de dados genealógico

Utilize recursão para escrever o predicado ancestral/2

Utilize ancestral/2 para encontrar todos os ancestrais e todos os descendentes de uma pessoa

Escreva um predicado descendente/2 que seja otimizado para descendentes, oposto a ancestral/2, que deve ser otimizado para ancestrais

Page 19: Aula de Prolog 06 - Recursão

Aventura em Prolog 19

O que vem a seguir?

Estruturas de Dados Unificação ...