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:
|
1 2 3 4 5 6 7 8 9 10 11 |
% ponto(X, Y) - representa um ponto no plano cartesiano ponto(X, Y). % linha(P1, P2) - representa uma linha definida por dois pontos linha(P1, P2). % triangulo(P1, P2, P3) - representa um triângulo com três vértices triangulo(P1, P2, P3). |
Essas estruturas podem ser aninhadas. Por exemplo, uma linha é definida por dois pontos:
|
1 2 3 4 5 6 7 |
% Uma linha vertical de (1,1) a (1,3) linha(ponto(1,1), ponto(1,3)) % Um triângulo com vértices em (0,0), (2,0) e (1,2) triangulo(ponto(0,0), ponto(2,0), ponto(1,2)) |
2. Diagrama dos Objetos Geométricos
Visualize os objetos no plano cartesiano:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
Plano Cartesiano: y | 4 | ponto(1,4) | 3 | ponto(1,3) ── linha vertical | 2 | ponto(1,2) | 1 | ponto(1,1) | 0 ─────────────────────────── x 0 1 2 3 4 Triângulo: y | 3 | ponto(1,3) | / \ | / \ | / \ | / \ | / \ | / \ | / \ |/ \ 0 ─────────────────────────── x 0 1 2 3 4 ponto(0,0) ─────────── ponto(3,0) |
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:
|
1 2 3 4 5 6 7 8 9 10 11 |
% vertical(L) - L é uma linha vertical % Uma linha é vertical se as coordenadas X de seus dois pontos são iguais vertical(linha(ponto(X, _), ponto(X, _))). % horizontal(L) - L é uma linha horizontal % Uma linha é horizontal se as coordenadas Y de seus dois pontos são iguais horizontal(linha(ponto(_, Y), ponto(_, Y))). |
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
|
1 2 |
?- vertical(linha(ponto(1,1), ponto(1,2))). true. |
A unificação verifica que X=1 em ambos os pontos → linha vertical.
Teste 2: Linha Não Vertical
|
1 2 |
?- vertical(linha(ponto(1,1), ponto(2,2))). false. |
X é diferente (1 ≠ 2) → não é vertical.
Teste 3: Linha Horizontal com Variável
|
1 2 |
?- horizontal(linha(ponto(1,1), ponto(2,Y))). Y = 1. |
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)?”
|
1 2 |
?- vertical(linha(ponto(2,3), P)). P = ponto(2, _). |
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?”
|
1 2 3 4 5 6 7 8 9 10 11 12 |
?- vertical(L), horizontal(L). Para L = linha(ponto(X,Y1), ponto(X,Y2)) (vertical) Para L = linha(ponto(X1,Y), ponto(X2,Y)) (horizontal) Unificando: ponto(X,Y1) = ponto(X1,Y) → X = X1, Y = Y1 ponto(X,Y2) = ponto(X2,Y) → X = X2, Y = Y2 Portanto: X1 = X2 = X, Y1 = Y2 = Y A linha seria linha(ponto(X,Y), ponto(X,Y)) - um segmento de comprimento zero! Resposta: L = linha(ponto(X, Y), ponto(X, Y)). |
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:
|
1 2 3 4 5 6 7 8 9 |
% retangulo(R) - R é um retângulo com lados verticais e horizontais % R é representado por uma lista de 4 pontos no sentido horário retangulo([P1, P2, P3, P4]) :- vertical(linha(P1, P2)), horizontal(linha(P2, P3)), vertical(linha(P3, P4)), horizontal(linha(P4, P1)). |
Exercício: Definir quadrado/1
Um quadrado é um retângulo com lados iguais. Podemos estender a definição:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
% quadrado(Q) - Q é um quadrado % Q é uma lista de 4 pontos no sentido horário quadrado([P1, P2, P3, P4]) :- retangulo([P1, P2, P3, P4]), distancia(P1, P2, D1), distancia(P2, P3, D2), D1 =:= D2. % distancia(P1, P2, D) - D é a distância entre P1 e P2 distancia(ponto(X1, Y1), ponto(X2, Y2), D) :- DX is X2 - X1, DY is Y2 - Y1, D is sqrt(DX*DX + DY*DY). |
Testando as Definições
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
% Um retângulo com vértices (0,0), (2,0), (2,1), (0,1) ?- retangulo([ponto(0,0), ponto(2,0), ponto(2,1), ponto(0,1)]). true. % Um quadrado com vértices (0,0), (2,0), (2,2), (0,2) ?- quadrado([ponto(0,0), ponto(2,0), ponto(2,2), ponto(0,2)]). true. % Um retângulo que não é quadrado ?- quadrado([ponto(0,0), ponto(2,0), ponto(2,1), ponto(0,1)]). false. |
7. O Poder da Unificação com Estruturas
A magia por trás dessas definições é a unificação. Observe:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
% vertical(linha(ponto(X, _), ponto(X, _))). Quando consultamos: ?- vertical(linha(ponto(2,3), P)). O Prolog unifica: linha(ponto(X, _), ponto(X, _)) = linha(ponto(2,3), P) Isso resulta em: X = 2 ponto(2, _) = P Portanto, P = ponto(2, _) — uma resposta genérica! |
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:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Retângulo (largura 2, altura 1): (0,1) ─────────── (2,1) │ │ │ │ ← altura = 1 │ │ (0,0) ─────────── (2,0) ← largura = 2 → Quadrado (lado 2): (0,2) ─────────── (2,2) │ │ │ │ ← lado = 2 │ │ (0,0) ─────────── (2,0) ← lado = 2 → |
9. Exercícios Adicionais
-
Paralelogramo: Defina
paralelogramo/1para uma lista de 4 pontos onde lados opostos são paralelos. -
Losango: Defina
losango/1como um paralelogramo com todos os lados iguais. -
Ponto médio: Defina
ponto_medio(P1, P2, M)onde M é o ponto médio entre P1 e P2. -
Comprimento: Defina
comprimento(linha(P1,P2), C)que calcula o comprimento da linha. -
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.