6.4. Reversibilidade das Relações
Permite que o sistema não diferencie entre argumentos de entrada e saída de um predicado, podendo um determinado argumento ser ora parâmetro de entrada, ora de saída . Ou seja, a execução pode ocorrer em qualquer sentido, dependendo do contexto. Um exemplo simples de reversibilidade é quando definimos a relação pai, e a partir desta podemos fazer tanto consultas para descobrir quem são os filhos de um pai, como quem é o pai de um filho.
Para o programa ilustrado no Exemplo 55, por exemplo, a consulta ?- pai(paulo,Y) retornará joana, e a consulta ?- pai(X, joana) retornará paulo. Note que para o mesmo predicado, na primeira consulta o primeiro parâmetro era o parâmetro de entrada e o segundo de saída, enquanto que, na segunda consulta o primeiro parâmetro foi o de saída e o segundo o de entrada.
Exemplo 55:
pai(paulo, joana).
Um caso prático de utilidade dessa propriedade do paradigma lógico pode ser encontrado no processamento de listas. Imagine que precisamos definir um predicado que concatena duas listas para formar uma terceira. A consulta ?- concat([1,2],[3,4,5],X). no programa ilustrado no Exemplo 56 retornará X = [1,2,3,4,5].
Exemplo 56:
concat([],Ys,Ys).
concat([X|Xs],Ys,[X|Z]) :- concat(Xs,Ys,Z).
A partir de concat, podemos definir outros dois predicados: prefix e suffix, que verificam se uma lista Xs está presente no começo de uma lista Zs e se uma lista Ys está presente no fim de uma lista Zs, respectivamente. Executar a consulta: ?- prefix([1,2,3],[1,2,3,4,5,6,7]) no programa ilustrado no Exemplo 57, retornaria yes.
Exemplo 57:
prefix(Xs, Zs) :- concat(Xs,Ys,Zs).
suffix(Ys, Zs) :- concat(Xs,Ys,Zs).