0. Revisão: variáveis em consultas
Como vimos no artigo anterior, variáveis em Prolog começam com letra maiúscula (ex: X, Pessoa, Filho) e representam valores desconhecidos que o sistema tenta descobrir através da unificação.
Atualise o arquivo familia.pl
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
% Fatos sobre pais% pai(adão, cain). pai(adão, abel). pai(adão, seth). pai(seth, enos). % Fatos sobre maes% mae(eva, cain). mae(eva, abel). mae(eva, seth). |
Como atualizar:
- 1. Edite familia.pl (Em SWI opção Edit)
- 2. Salve as alterações (No arquivo pl opção Save buffer)
- 3. Em SWI-Prolog dê “Reload modified files”
- 4. Agora suas alterações serão percebidas no SWI
|
1 2 |
?- pai(X, abel). % X é uma variável X = adão. % O sistema unifica X com adão |
Mas o que acontece quando usamos a mesma variável em diferentes partes da consulta? E como podemos “ignorar” um valor que não nos interessa? É exatamente isso que vamos explorar agora!
1. Variáveis Compartilhadas: conectando objetivos
Uma variável compartilhada é uma variável que aparece em múltiplos objetivos (subconsultas) dentro de uma mesma consulta. Quando a mesma variável aparece em lugares diferentes, o Prolog exige que ela tenha o mesmo valor em todos os lugares.
Exemplo clássico: “Quem é o avô de Enos?”
Para descobrir o avô de Enos, precisamos encontrar alguém que seja pai do pai de Enos. Em Prolog, isso se traduz em dois objetivos com uma variável compartilhada:
|
1 |
?- pai(Y, enos), pai(X, Y). |
Aqui, a variável Y é compartilhada entre os dois objetivos. Ela representa o “pai de Enos” no primeiro objetivo e o “filho de X” no segundo. O Prolog precisa encontrar um valor para Y que satisfaça ambas as condições.
2. Como o Prolog resolve essa consulta (passo a passo)
pai(Y, enos). Ele procura na base de fatos por um pai cujo segundo argumento seja enos.
|
1 2 3 |
% Encontra: pai(seth, enos) % Então Y = seth |
Y = seth, o Prolog agora tenta resolver o segundo objetivo: pai(X, seth). Ele procura por alguém que seja pai de Seth.
|
1 2 3 |
% Encontra: pai(adão, seth) % Então X = adão |
X = adão e apresenta a resposta.
|
1 2 3 |
?- pai(Y, enos), pai(X, Y). Y = seth, X = adão. % Adão é o avô de Enos! |
pai(X, Y), pai(Y, enos), o Prolog começaria procurando um pai X de Y (qualquer um), depois verificaria se Y é pai de Enos. O resultado seria o mesmo, mas a ordem pode afetar a eficiência.
3. Por que variáveis compartilhadas são importantes?
Variáveis compartilhadas são a base para construir consultas multi-objetivo em Prolog. Elas permitem:
- Encadear relações: avô, bisavô, irmão, tio, etc.
- Filtrar resultados: encontrar pessoas que satisfazem múltiplas condições.
- Comparar valores: verificar se duas variáveis têm o mesmo valor.
- Expressar restrições: “X é pai de Y E Y é pai de Z” → X é avô de Z.
Sem variáveis compartilhadas, cada objetivo seria independente e não poderíamos expressar relações entre eles.
4. A Variável Anônima (_): quando o valor não importa
Às vezes, queremos fazer uma pergunta onde um dos valores não nos interessa. Por exemplo: “Quem já foi pai (de alguém)?” — não importa quem é o filho, só queremos saber os pais.
Para isso, usamos a variável anônima, representada por um underscore (_). Ela diz ao Prolog: “Ignore este valor; não me importa qual é.”
- Começa com
_(ex:_,_Algo). - Cada ocorrência de
_é independente — duas ocorrências de_não são compartilhadas. - Não gera respostas (o Prolog não mostra seu valor).
- Não unifica com outras variáveis (cada
_é único).
Exemplo: “Quem já procriou?” (quem é pai de alguém)
|
1 2 3 4 5 6 7 8 9 10 11 12 |
?- pai(X, _). % Quem é pai de alguém? (não importa de quem) X = adão ; % Adão é pai de Caim, Abel e Seth X = adão ; X = adão ; X = seth ; X = enos ; X = cainã ; X = malalel ; X = jarede ; X = enoque ; X = metusael ; X = lameque. |
O Prolog encontra todas as pessoas que aparecem como primeiro argumento de pai/2, independentemente de quem é o filho. O _ simplesmente “engole” o segundo argumento.
_ é independente. Em pai(_, _), a primeira ocorrência ignora o pai e a segunda ignora o filho — a consulta pergunta “existe alguma relação pai/2?” e sempre retorna true.
5. Variável Anônima vs. Variável Nomeada: qual a diferença?
| Característica | Variável Nomeada (X, Y) | Variável Anônima (_) |
|---|---|---|
| Sintaxe | Começa com maiúscula | Começa com _ |
| Compartilhamento | O mesmo nome = mesma variável (compartilhada) | Cada _ é independente |
| Aparece na resposta | Sim, o valor é mostrado | Não, o valor é ignorado |
| Quando usar | Quando o valor é importante ou precisa ser compartilhado | Quando o valor não importa ou você quer evitar respostas desnecessárias |
| Exemplo | pai(X, abel) → mostra quem é o pai | pai(_, abel) → pergunta “Abel tem pai?” (true/false) |
Exemplo comparativo
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
% Com variável nomeada: mostra quem é o pai de Abel ?- pai(X, abel). X = adão. % Com variável anônima: só pergunta se Abel tem pai (true/false) ?- pai(_, abel). true. % Com variável anônima: quantas relações pai/2 existem? ?- findall(_, pai(_, _), Lista). Lista = [_, _, _, _, _, _, _, _, _, _, _]. % 11 relações |
6. Variável anônima com nome: _Algo
Você pode usar _ seguido de um nome (ex: _Filho) para indicar que o valor não importa, mas quer dar um nome descritivo para melhor legibilidade. O comportamento é o mesmo: a variável é anônima e não gera respostas.
|
1 2 3 4 5 6 |
% Quem é pai de alguém? (versão mais legível) ?- pai(Pai, _Filho). Pai = adão ; Pai = adão ; ... (continua) |
Neste caso, _Filho é anônima (começa com _), mas o nome ajuda a entender que se trata do filho. O Prolog não mostrará o valor de _Filho.
7 Quando usar cada tipo de variável?
Use variável nomeada (compartilhada) quando:
- Você precisa conectar diferentes partes da consulta.
- O valor da variável é importante e você quer vê-lo na resposta.
- Você quer comparar valores entre diferentes objetivos.
Use variável anônima (_) quando:
- O valor não é relevante para a resposta (ex: “quem é pai de alguém?”).
- Você quer evitar poluir a resposta com valores desnecessários.
- Você está fazendo uma consulta de “existência” (true/false).
- Quer melhorar a legibilidade sem gerar respostas extras.
Resumo:
- Variáveis compartilhadas (mesmo nome em múltiplos objetivos) permitem encadear relações e expressar consultas complexas.
- Variáveis anônimas (
_) ignoram valores que não nos interessam, tornando as consultas mais limpas e eficientes. - Escolher o tipo certo de variável torna suas consultas mais expressivas e fáceis de entender.