2012-04-21 16 views
5

come principiante di Prolog, ho trovato l'espressione commutativa in Prolog non del tutto intuitiva.Alternativa per esprimere "commutatività" in Prolog?

per esempio se voglio esprimere X e Y sono in una famiglia, come:

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

Vorrei anche aggiungere quanto segue alla definizione, al fine di renderlo "commutativa":

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

Ma usiamo Prolog, perché vogliamo scrivere codice elegante ... così, mi auguro di aggiungere una sola linea (al posto di quanto sopra tre) a quella originale:

 family(Y,X). 

Ecco il punto. porta al disastro! perché il prologo non è così "logico"? e c'è un'alternativa a questa espressione di una sola linea che non porta al disastro?

Fine settimana piacevoli! watt

risposta

7

Il problema con family(X,Y) :- family(Y,X). parte della regola è che mantiene unificando incondizionatamente con se stesso ad ogni livello, e tiene recursing verso il basso; non ci sono condizioni di uscita fuori da questa ricorsione.

Si dovrebbe fare lo swap argomento a livello sopra:

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). 

In alternativa, si potrebbe fare le regole sottostanti sotto simmetrica in cui ha senso:

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

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

Si potrebbe ora riscrivi la tua regola family nel modo seguente:

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

Vedo, ed è anche chiaro il motivo per cui si stacca. Grazie! – Matt

+0

vorrei anche suggerire di utilizzare fatti separati anziché; –

+0

@AlexanderSerebrenik Assolutamente - Volevo stare vicino allo stile dell'originale. Tuttavia, nei giorni Prolog ho preferito più regole su ';' per la leggibilità e la facilità del debugging. – dasblinkenlight

1

ne dite:

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

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