Dinamismo – Programas que se Modificam

filósofo

Em Prolog, a base de dados é geralmente estática: os fatos e regras são definidos no arquivo e não mudam durante a execução. No entanto, muitas aplicações precisam de flexibilidade — adicionar novos dados, remover informações obsoletas ou modificar regras em tempo de execução. Para isso, o Prolog oferece uma base de dados dinâmica.

1. O Conceito de Base de Dados Dinâmica

Uma base de dados dinâmica permite que cláusulas (fatos e regras) sejam adicionadas ou removidas durante a execução do programa. Isso é útil para:

  • Sistemas interativos (ex: cadastro de usuários).
  • Bases de conhecimento que evoluem.
  • Algoritmos que constroem soluções incrementalmente.
  • Memorização de resultados (memoização).

2. A Diretiva :‑ dynamic

Para tornar um predicado dinâmico, usamos a diretiva :- dynamic seguida do nome e aridade do predicado.

Sem essa declaração, tentar modificar um predicado resultaria em erro.

3. Predicados de Manipulação

O Prolog fornece três predicados principais para manipular a base de dados dinâmica:

Predicado Descrição
asserta/1 Adiciona uma cláusula no início da base de dados (antes das existentes).
assertz/1 Adiciona uma cláusula no final da base de dados (depois das existentes).
retract/1 Remove a primeira cláusula que unifica com o argumento.
retractall/1 Remove todas as cláusulas que unificam com o argumento.

Além disso, listing/0 ou listing(predicado) exibe a base de dados atual.

4. Programa 6.1: Jogadores

Vamos começar com uma base de dados simples de jogadores e seus esportes:

Para ver a base atual, use listing(joga) ou listing/0.

5. Adicionando Novos Fatos com assertz/1

assertz/1 adiciona um fato no final da base.

Como resultado, a consulta joga(X, futebol) retorna os jogadores na ordem em que foram inseridos.

6. Adicionando com asserta/1

asserta/1 adiciona um fato no início da base.

Agora, joga(X, futebol) retorna robinho primeiro:

7. Removendo Fatos com retract/1

retract/1 remove a primeira cláusula que unifica com o argumento.

Também podemos remover usando variáveis:

Importante: O retract/1 remove apenas a primeira cláusula que unifica. Para remover todas, use retractall/1.

8. Exemplo Prático: Sistema de Agenda

Vamos construir um pequeno sistema de agenda telefônica usando base dinâmica:

9. Cuidados e Boas Práticas

O uso de base de dados dinâmica é poderoso, mas requer atenção:

  • Ordene com cuidado: A ordem dos fatos afeta a ordem das soluções e o backtracking.
  • Evite efeitos colaterais inesperados: Modificar a base durante uma consulta pode causar comportamentos imprevisíveis.
  • Use retract com unificação específica: Se usar variáveis, certifique-se de que elas estão instanciadas para evitar remoções indesejadas.
  • Organize o código: Declare todos os predicados dinâmicos no início do arquivo com :- dynamic.

10. Exercícios Propostos

  1. Sistema de Estoque: Crie um predicado dinâmico estoque(Produto, Quantidade) com funções para adicionar, remover e consultar produtos. Inclua verificação de quantidade negativa.
  2. Histórico de Operações: Implemente um sistema que registra todas as operações (adições e remoções) em um predicado log/2 com timestamp.
  3. Memoização: Implemente fib_memo(N, F) que calcula Fibonacci armazenando resultados já calculados para reutilização.
  4. Base de Alunos: Crie um sistema de cadastro de alunos com aluno(Nome, Nota) e funções para adicionar, remover, e calcular a média da turma.

11. Conclusão

A base de dados dinâmica é um recurso poderoso que estende a capacidade do Prolog para aplicações interativas e em evolução. Com asserta/1, assertz/1 e retract/1, podemos:

  • Construir sistemas que aprendem com novos dados.
  • Implementar caches e memoização para otimização.
  • Criar interfaces interativas com o usuário.
  • Manter bases de conhecimento atualizadas.

Use com responsabilidade: base dinâmica é uma ferramenta poderosa, mas seu uso indevido pode tornar o programa difícil de depurar. Sempre documente os predicados dinâmicos e planeje a estratégia de modificação da base.

Aplicação Prática com Estrutura

filósofo

Uma das aplicações mais elegantes das estruturas em Prolog é a modelagem de objetos geométricos. Usando functors aninhados, podemos representar pontos, linhas, triângulos e outras figuras, e então verificar propriedades através de unificação e casamento de padrões. Vamos explorar essa aplicação passo a passo.

1. Modelagem Geométrica

Primeiro, definimos as estruturas básicas:

Essas estruturas podem ser aninhadas. Por exemplo, uma linha é definida por dois pontos:

2. Diagrama dos Objetos Geométricos

Visualize os objetos no plano cartesiano:

3. Programa 5.6: Vertical e Horizontal

Vamos definir predicados para identificar linhas verticais e horizontais usando apenas casamento de padrões e unificação:

Observe a elegância dessas definições:

  • Não há loops, comparações ou cálculos.
  • Apenas casamento de padrões com a estrutura linha(ponto(X,_), ponto(X,_)).
  • O Prolog unifica automaticamente as coordenadas X.

4. Consultas com Vertical e Horizontal

Teste 1: Linha Vertical

A unificação verifica que X=1 em ambos os pontos → linha vertical.

Teste 2: Linha Não Vertical

X é diferente (1 ≠ 2) → não é vertical.

Teste 3: Linha Horizontal com Variável

O Prolog descobre que Y deve ser 1 para que a linha seja horizontal.

5. Consultas Mais Complexas

“Existe uma linha vertical com extremo em (2,3)?”

O Prolog responde com uma solução genérica: o segundo ponto deve ter a mesma coordenada X=2, mas Y pode ser qualquer valor (_ é uma variável não instanciada).

“Existe uma linha que seja vertical e horizontal ao mesmo tempo?”

6. Exercícios do PDF: Retângulos e Quadrados

Exercício: Definir regular/1

Um retângulo regular tem lados verticais e horizontais. Podemos definir:

Exercício: Definir quadrado/1

Um quadrado é um retângulo com lados iguais. Podemos estender a definição:

Testando as Definições

7. O Poder da Unificação com Estruturas

A magia por trás dessas definições é a unificação. Observe:

Essa capacidade de gerar respostas parciais (com variáveis) é uma das características mais poderosas do Prolog. Ela permite que o sistema derive propriedades sem que precisemos especificar todos os detalhes.

8. Diagrama: Retângulo e Quadrado

Visualize as definições:

9. Exercícios Adicionais

  1. Paralelogramo: Defina paralelogramo/1 para uma lista de 4 pontos onde lados opostos são paralelos.
  2. Losango: Defina losango/1 como um paralelogramo com todos os lados iguais.
  3. Ponto médio: Defina ponto_medio(P1, P2, M) onde M é o ponto médio entre P1 e P2.
  4. Comprimento: Defina comprimento(linha(P1,P2), C) que calcula o comprimento da linha.
  5. Circunferência: Defina uma estrutura circulo(Centro, Raio) e predicados para verificar se um ponto pertence à circunferência.

10. Conclusão

Este exemplo mostra como estruturas + padrões criam uma base poderosa para programação declarativa:

  • Estruturas modelam dados complexos (pontos, linhas, figuras).
  • Padrões (casamento de estruturas) permitem verificar propriedades.
  • Unificação gera respostas genéricas e parciais.
  • Recursão permite explorar figuras mais complexas.

Essa abordagem elimina a necessidade de loops, índices ou estruturas de controle complexas. O código é legível, conciso e expressivo — exatamente como a programação lógica deve ser.