Prolog/Comando Fail e a combinação Cut/Fail

Origem: Wikilivros, livros abertos por um mundo aberto.

fail é a instrução que força uma falha.

Ou seja, ao encontrar-se uma instrução fail, sempre é feito o backtracking.

fail, sozinho, raramente é usado, e seu uso principal é a combinação cut/fail.

Por exemplo:

% base de dados, com estrutura filho(Filho,Mae,Pai) ou filha(Filha,Mae,Pai):

filho(cleomenes_i,segunda_esposa,anaxandrides_ii).
filho(leonidas,primeira_esposa,anaxandrides_ii).
filho(cleombroto_regente,primeira_esposa,anaxandrides_ii).
filha(gorgo,esposa_cleomenes_i,cleomenes_i).
filho(plistarco,gorgo,leonidas).

pai(P, Filho) :- filho(Filho, _, P).
pai(P, Filha) :- filha(Filha, _, P).

mae(M, Filho) :- filho(Filho, M, _).
mae(M, Filha) :- filha(Filha, M, _).


% A é irmao de B quando:
% A não for B
% A for filho da mae de B
% A for filho do pai de B

irmao(A, A) :- !, fail.  % esta instrucao forca que uma pessoa nao seja irma dela mesma
irmao(A, B) :- filho(A, M, _), mae(M, B).
irmao(A, B) :- filho(A, _, P), pai(P, B).

Com os dados acima, é simples ver que o programa dá resultados verdadeiros (true) para as seis relações válidas de irmao(X, Y). Um problema, porém, é que a combinação cut-fail interrompe o backtracking sempre que encontra uma combinação irmao(X, X); ou seja, esta instrução, como escrita, não consegue descobrir todos pares de irmãos:

:- irmao(X, X).
% fail

Exercício: tente reescrever a instrução irmao(A, B) de forma a evitar este erro.