2012-04-21 18 views
5

jako początkujący Prolog, stwierdziłem, że wyrażenia przemienne w Prologu nie są intuicyjne.Alternatywa ekspresji "Commutativity" w Prologu?

na przykład jeśli chcę wyrazić X i Y są w jednej rodzinie, jak:

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

Należy również dodać następujące definicji, w celu uczynienia go „przemienne”:

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

Ale używamy Prolog, ponieważ chcemy pisać elegancki kod ... tak, to mam nadzieję dodać tylko jedną linię (zamiast powyżej trzech) do oryginału:

 family(Y,X). 

Oto PUNKT. prowadzi do oznaczenia! dlaczego prolog nie jest tak "logiczny"? i czy istnieje alternatywa dla tego zgrabnego, jednorzędowego wyrażenia, które nie prowadzi do unieważnienia?

Przyjemne weekendy! wat

Odpowiedz

7

Problem z family(X,Y) :- family(Y,X). część reguły jest to, że utrzymuje ujednolicenie bezwarunkowo ze sobą na każdym poziomie i utrzymuje recursing w dół; nie ma warunków wyjścia z tej rekursji.

Powinieneś zrobić swap argumentów na poziomie powyżej:

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

Alternatywnie, można zrobić zasady leżące u poniżej symetryczne, gdzie ma to sens:

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

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

mógłbyś teraz przepisz regułę family w następujący sposób:

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

Rozumiem, i to jest również jasne, dlaczego to nieodwracalne. Dzięki! – Matt

+0

Proponuję także użycie osobnych faktów zamiast; –

+0

@AlexanderSerebrenik Absolutnie - chciałem pozostać blisko stylu oryginału. Jednak w czasach prologu wolałem kilka reguł od ';' dla czytelności i łatwości debugowania. – dasblinkenlight

1

Jak o:

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

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