Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternative to express "Commutativity" in Prolog?

as a beginner to Prolog, I found the commutative expression in Prolog are quite not intuitive.

for example if I want to express X and Y are in one family, like:

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

I should also add the following to the definition, in order to make it "commutative":

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

But we use Prolog, because we want to write elegant code... so, I'd hope to add only one line(instead of the above three) to the original :

      family(Y,X).

Here is the POINT. it leads to untermination! why is prolog no so "logical"? and is there an alternative to this neat one line expression that doesn't lead to untermination?

Nice weekends! watt

like image 813
Matt Avatar asked Apr 21 '12 10:04

Matt


2 Answers

The problem with family(X,Y) :- family(Y,X). part of the rule is that it keeps unifying unconditionally with itself at each level, and keeps recursing down; there is no exit condition out of this recursion.

You should make the argument swap at the level above:

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

Alternatively, you could make underlying rules below symmetric where it makes sense:

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

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

You could now rewrite your family rule as follows:

family(X,Y) :-
    is_married(X,Y);
    is_relative(X,Y);
    father_son(X,Y);
    father_son(Y,X).
like image 188
Sergey Kalinichenko Avatar answered Oct 27 '22 08:10

Sergey Kalinichenko


How about:

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

family(X,Y) :-
  relatives(X,Y);
  relatives(Y,X).
like image 23
Eric Avatar answered Oct 27 '22 07:10

Eric