Relacionando Tabelas em Prolog

filósofo

 

Consultas relacionais no estilo SQL, mas com a alma lógica

Assim como em SQL, frequentemente precisamos relacionar informações que estão em tabelas diferentes.
Em Prolog, fazemos isso de forma natural usando variáveis compartilhadas — que atuam como
“chaves estrangeiras”. Neste artigo, vamos construir um pequeno sistema de funcionários e dependentes,
e aprender a fazer joins, consultas com condições e até encontrar registros sem correspondência.

1. O problema: funcionários e dependentes

Imagine que temos duas tabelas em um banco de dados relacional:

  • Funcionários — com código, nome e salário.
  • Dependentes — com código do funcionário a quem estão vinculados e seu nome.

O campo código em funcionários é a chave primária; em dependentes,
é uma chave estrangeira que referencia o funcionário.

2. Modelando em Prolog

Em Prolog, cada “tabela” vira um conjunto de fatos com uma aridade fixa:


 

🔑 Chave de relacionamento: O campo Código é o elo entre as duas tabelas.
Em dep/2, o primeiro argumento é o código do funcionário, que deve existir em func/3.

3. O campo Código como chave relacional

Assim como em SQL, a integridade referencial é implícita: se um dependente tem código 2,
esperamos que exista func(2, ...). O Prolog não valida isso automaticamente, mas nossas
consultas vão explorar essa relação.

4. “Joins” com variáveis compartilhadas

Para fazer um join entre as duas tabelas, usamos a mesma variável no lugar
do código em ambas as chamadas. O Prolog unifica as ocorrências e encontra as combinações que satisfazem
todos os fatos.

Exemplo: “Quem são os dependentes do Ivo?”

Sabemos que Ivo tem código 2. Queremos os nomes dos dependentes associados a esse código.


 

Se não soubéssemos o código, poderíamos deixar o Prolog descobrir:

 

🔎 Leitura: “Encontre um código C tal que C seja funcionário
chamado Ivo, e depois encontre um dependente com esse mesmo C.”

Exemplo: “De quem o Ary é dependente?”

Agora partimos do dependente para o funcionário.


 

Na base, ary aparece como funcionário (código 4), mas não como dependente. A consulta retorna
false porque não há nenhum dependente chamado ary.

5. Consultas com condições adicionais

Podemos filtrar usando comparações numéricas, como em SQL com WHERE.

“Quem depende de funcionário com salário < 950?”

Funcionários com salário menor que 950: Eva (800).


 

Isso retorna o funcionário eva e seu dependente Nino.

6. Negação por falha: “Funcionários sem dependentes”

Em SQL, usaríamos LEFT JOIN ... WHERE dep.codigo IS NULL. Em Prolog, usamos
negação por falha com o predicado not (ou \+).


 

O Prolog tenta provar dep(C, _); se falha, a negação é bem-sucedida. O resultado mostra
que Lia (código 3) não tem dependentes.

⚠️ Cuidado com a instanciação! Para que not funcione corretamente,
a variável C deve estar instanciada no momento em que not
é chamado. Por isso, colocamos func(C, N, _) antes de not(dep(C, _)).
Se trocássemos a ordem, o Prolog poderia não encontrar soluções ou gerar erro.

8. Comparação com SQL

O mesmo “join” em SQL seria:


 

Em Prolog, a consulta equivalente é:


 

Abaixo, um resumo das principais correspondências:

SQL Prolog
FROM func JOIN dep ON func.codigo = dep.codigo func(C, ...), dep(C, ...)
WHERE salario > 1000 func(_, _, S), S > 1000
IS NULL (left join) not(dep(C, _))
SELECT nome Variável no lugar do campo (ex: N)

✅ O Prolog oferece uma maneira elegante e declarativa de relacionar dados, sem necessidade de sintaxe
especial para joins. Basta compartilhar variáveis e deixar o mecanismo de unificação fazer o trabalho
pesado. Combine isso com comparações e negação, e você terá todo o poder de um SGBD relacional —
com a flexibilidade da programação lógica.

Aritmética e Comparações em Prolog

filósofo
Lidando com números de forma declarativa — e sem sustos

Se você vem de linguagens como Python, Java ou C, pode estranhar o comportamento do Prolog com números.
Prolog não avalia expressões aritméticas automaticamente.
Ao contrário do que acontece em 2 + 3 em Python (que já retorna 5),
em Prolog a expressão 2 + 3 é apenas uma estrutura simbólica — a não ser
que você peça explicitamente para avaliá-la.

Neste artigo, vamos explorar como fazer cálculos, comparar valores numéricos e extrair informações
de uma base de dados de países. Tudo com exemplos práticos e explicações passo a passo.

1. Prolog não avalia automaticamente

Em Prolog, termos como 2 + 3 são vistos como uma estrutura com um operador functor +
e dois argumentos. Se você perguntar X = 2 + 3, o Prolog unificará X com a
estrutura +(2,3), e não com o número 5. Para efetivamente calcular, precisamos
de um predicado especial: is/2.

🧠 Lembre-se: is/2 é um predicado que avalia a expressão
aritmética do lado direito e unifica o resultado com o lado esquerdo (que deve ser uma variável ou um número).

2. O predicado is/2 — o avaliador

O uso clássico é: X is 2 + 3. Isso faz o Prolog calcular 2 + 3 e unificar
X com 5.

?- X is 2 + 3.
X = 5.

is/2 só funciona se o lado direito for uma expressão aritmética totalmente instanciada
(sem variáveis). Caso contrário, ocorrerá um erro.

3. Operadores aritméticos no Prolog

O Prolog oferece os operadores que você espera, com algumas particularidades:

  • + adição
  • - subtração
  • * multiplicação
  • / divisão real (resultado em ponto flutuante)
  • // divisão inteira (trunca para inteiro)
  • mod resto da divisão inteira
  • ^ exponenciação (potência)

 

4. Base de dados: países (área, população)

Vamos trabalhar com uma base de fatos no estilo país(nome, área, população),
onde área está em milhões de km² e população em milhões de habitantes.


 

5. Calculando densidade demográfica

A densidade populacional é D = P / A (população / área). Vamos criar uma regra
que calcula a densidade de um país.


 

Consultando:


 

🔎 Interpretação: O Brasil tem cerca de 25 habitantes por milhão de km² (na verdade,
usando milhões, a unidade fica coerente).

6. Predicados de comparação

Para comparar valores numéricos, usamos os seguintes operadores (todos avaliados aritmeticamente):

  • =:= igualdade aritmética (ex: 2 + 3 =:= 5 é verdadeiro)
  • =\= diferente aritmético
  • > maior que
  • < menor que
  • >= maior ou igual
  • =< menor ou igual (atenção: não é <= !)

 

7. “A área do Brasil é igual à área dos EUA?”

Para comparar áreas, podemos consultar diretamente:

?- país(brasil, A1, _), país(eua, A2, _), A1 =:= A2.
false.

O resultado é false, pois as áreas são diferentes (8.516 vs 9.834).

Se quiséssemos países com a mesma área (o que não ocorre nessa base), poderíamos usar
=:= na condição.

8. Selecionando dados: “Países com população > 500 milhões?”

Podemos usar comparações dentro de regras ou consultas para filtrar países.


 

Também podemos criar uma regra:


 

Consultando: ?- populoso(X). retorna X = india.

📊 Outras perguntas:
• Países com área maior que 5 milhões de km²? ?- país(N, A, _), A > 5. → Brasil, EUA.
• Densidade maior que 100? ?- país(N, A, P), D is P/A, D > 100. → Índia (≈426), Portugal (≈112).

9. Atenção: = (unificação) vs =:= (igualdade aritmética)

Essa é uma das maiores fontes de confusão para quem está aprendendo Prolog:

  • = é o operador de unificação. Ele tenta tornar dois termos
    sintaticamente idênticos, sem avaliar expressões aritméticas.
  • =:= é um predicado que avalia ambas as expressões
    aritméticas e compara os resultados numéricos.

 

⚠️ Importante: Use =:= e =\= para comparar valores numéricos.
Use = para unificar termos (inclusive variáveis). Para diferença sintática, use \=.


✅ A aritmética em Prolog é poderosa, mas exige precisão: use is/2 para calcular,
=:= para comparar valores e lembre-se que = é unificação, não igualdade numérica.
Pratique com a base de países e explore outras métricas como densidade, crescimento ou PIB per capita.