2012-04-21 29 views
5

como principiante en Prolog, encontré que la expresión conmutativa en Prolog no es muy intuitiva.¿Alternativa para expresar "conmutatividad" en Prolog?

por ejemplo si quiero expresar X e Y son de una misma familia, como:

family(X,Y) :- 
     married(X,Y); 
     relative(X,Y); 
     father_son(X,Y). 

También me gustaría añadir lo siguiente a la definición, con el fin de que sea "conmutativa":

 married(Y,X); 
     relative(Y,X); 
     father_son(Y,X). 

Pero usamos Prolog, porque queremos escribir código elegante ... así que, yo espero que añadir una sola línea (en lugar de los tres anteriores) a la original:

 family(Y,X). 

Aquí está el PUNTO. ¡conduce a la falta de determinación! ¿Por qué el prólogo no es tan "lógico"? y ¿hay una alternativa a esta expresión limpia de una línea que no conduzca a la falta de determinación?

¡Buenos fines de semana! vatios

Respuesta

7

El problema con family(X,Y) :- family(Y,X). parte de la regla es que mantiene la unificación incondicionalmente con ella misma en cada nivel, y mantiene de manera recursiva hacia abajo; no hay una condición de salida de esta recursión.

usted debe hacer el canje argumento a nivel anterior:

family(X,Y) :- 
    is_family(X,Y); 
    is_family(Y,X). 

is_family(X,Y) :- 
    married(X,Y); 
    relative(X,Y); 
    father_son(X,Y). 

Como alternativa, puede hacer que las reglas subyacentes continuación simétrica donde tiene sentido:

is_married(X,Y) :- 
    married(X,Y); 
    married(Y,X). 

is_relative(X,Y) :- 
    relative(X,Y); 
    relative(Y,X). 

Ahora puede reescriba su regla family de la siguiente manera:

family(X,Y) :- 
    is_married(X,Y); 
    is_relative(X,Y); 
    father_son(X,Y); 
    father_son(Y,X). 
+0

Veo, y también está claro por qué no termina. ¡Gracias! – Matt

+0

también sugeriría usar hechos separados en lugar de; –

+0

@AlexanderSerebrenik Absolutamente - Quería estar cerca del estilo del original. Sin embargo, en mis días de Prolog, preferí varias reglas sobre ';' para facilitar la lectura y la depuración. – dasblinkenlight

1

¿Qué tal:

relatives(X,Y) :- 
    married(X,Y); 
    relative(X,Y); 
    father_son(X,Y). 

family(X,Y) :- 
    relatives(X,Y); 
    relatives(Y,X).