Estoy leyendo "Siete idiomas en siete semanas" atm, y estoy perplejo por alguna consulta Prolog a la que no entiendo la respuesta 'no'.Problema con ` +` en consultas de Prolog con variables
El archivo friends.pl
se parece a esto:
likes(wallace, cheese).
likes(grommit, cheese).
likes(wendolene, sheep).
friend(X, Y) :- \+(X = Y), likes(X, Z), likes(Y, Z).
Puedo hacer algunas preguntas triviales sobre el mismo, tales como:
| ?- ['friends'].
compiling /home/marc/btlang-code/code/prolog/friends.pl for byte code...
/home/marc/btlang-code/code/prolog/friends.pl compiled, 12 lines read - 994 bytes written, 8 ms
yes
| ?- friend(wallace,grommit).
yes
| ?- friend(wallace,wendolene).
no
Esto es todo como se esperaba. Ahora, quiero introducir una variable en la consulta. Mi intención es que Prolog me dé una lista de todos los amigos de Wallace. Estoy esperando X = grommit
, pero yo estoy no
:
| ?- trace.
The debugger will first creep -- showing everything (trace)
yes
{trace}
| ?- friend(wallace,X).
1 1 Call: friend(wallace,_16) ?
2 2 Call: \+wallace=_16 ?
3 3 Call: wallace=_16 ?
3 3 Exit: wallace=wallace ?
2 2 Fail: \+wallace=_16 ?
1 1 Fail: friend(wallace,_16) ?
no
{trace}
ni siquiera tratar de unificar X
(_16
) con grommit
. ¿Por qué?
OK, entendido. ¿Cómo reformularías 'friend/2' para que funcione con una consulta que contenga variables? –
A primera vista, habría usado el operador de igualdad '==/2' y lo reescribí como' amigo (X, Y): - \ + (X == Y), Me gusta (X, Z), Me gusta (Y , Z) .' pero esta versión tiene el defecto de incluirse dentro de sus amigos, por ejemplo 'friend (wallace, X)' listará 'wallace' como una solución. Así que es mejor, como sugiere Philip JF, incluso si todavía está utilizando el operador de unificación, poner el cheque al final: 'amigo (X, Y): - Me gusta (X, Z), me gusta (Y, Z), X \ == Y'. (Tenga en cuenta que '\ ==/2' es equivalente a negar' ==/2', pero más claro, solo más directo.) –