2
votes

I am new to Prolog and trying to learn it. I want to achieve something like a>b and b>c then a>c which is Transitive relation.

I have a set of following rules.

bigger(elephant,horse).
bigger(horse,ant).
bigger(ant, bacteria).
bigger(bacteria,virus).

We know that elephant is bigger than virus. What I want to achieve is that when I use smaller(ant,elephant) it should return true. The rule smaller(X,Y) I tried to use is

smaller(Y,X) :-
    bigger(X,Z),
   (bigger(Z,Y);
    Z=Y).
1
See transitive-closure, and specifically the definition. - mat
@lurker that is working because it's the second rule and doesn't work for smaller(virus,elephant) - Harwee
As @mat points out, you need transitive closure. So if you break it into two clauses, you'd have: smaller(X, Y) :- bigger(Y, X). and smaller(X, Y) :- bigger(Z, X), smaller(Z, Y). - lurker
The first result true means it succeeded in the query for the first result. The subsequent false means it didn't find any more solutions (there was a choice point). - lurker
Several good books. The Art of Prolog by Sterling & Shapiro, The Craft of Prolog by O'Keefe, Programming in Prolog by Clocksin & Mellish. There are some online tutorials which are fairly basic, but you can learn some things from them. Just Google "Prolog tutorial". - lurker

1 Answers

2
votes

You can perhaps use big_fact/2 to describe the database:

big_fact(elephant,horse).
big_fact(horse,ant).
big_fact(ant, bacteria).
big_fact(bacteria,virus).

Then you can use bigger/2 as a transitive closure:

bigger(X,Y) :-
    big_fact(X,Y).
bigger(X,Z) :-
    big_fact(X,Y),
    bigger(Y,Z).

If you run this in , it generates:

?- bigger(X,Y).
X = elephant,
Y = horse ;
X = horse,
Y = ant ;
X = ant,
Y = bacteria ;
X = bacteria,
Y = virus ;
X = elephant,
Y = ant ;
X = elephant,
Y = bacteria ;
X = elephant,
Y = virus ;
X = horse,
Y = bacteria ;
X = horse,
Y = virus ;
X = ant,
Y = virus ;
false.

?- bigger(virus,Y).
false.

?- bigger(ant,Y).
Y = bacteria ;
Y = virus ;
false.

?- bigger(X,horse).
X = elephant ;
false.

?- bigger(X,bacteria).
X = ant ;
X = elephant ;
X = horse ;
false.

?- bigger(elephant,bacteria).
true ;
false.

So it is a transitive closure.

You can then define smaller/2 by means of bigger/2:

smaller(X,Y) :-
    bigger(Y,X).