Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prolog Recursion - Satisfying Both Directions (Simple)

I am very new to Prolog and I was given this assignment.

My code is as follows:

relatives(cindy,tanya).
relatives(tanya,alan).
relatives(alan,mike).
relatives(kerry,jay).
relatives(jay,alan).

isRelated(X,Y):-
    relatives(X,Y).
isRelated(X,Y):-
    relatives(X,Z),
    isRelated(Z,Y).

Simple enough. This shows that if:

?- isRelated(cindy,mike).

Prolog will return true. Now, I'm stuck on how to make it return true if:

?- isRelated(mike,cindy).

I've been trying to come up with ideas like if isRelated(Z,Y) returns false, then switch X and Y, and run isRelated again. But I'm not sure if Prolog even allows such an idea. Any hints or advice would be greatly appreciated. Thanks!

UPDATE:************************************

So I added:

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

That will satisfy "direct" relationships, but simply enough I found out that it doesn't satisfy indirect relationships.

I really want to do something like, if the initial query:

isRelated(mike,cindy)

fails, then try and see if the reverse is true by switching X and Y:

isRelated(cindy,mike)

That will definitely return true. I just don't know how to do this syntactically in Prolog.

like image 220
cYn Avatar asked Dec 20 '25 18:12

cYn


2 Answers

Further hint to those in the comments, as I can't leave comments yet: With your original set of rules and facts, isRelated(cindy,tanya) is true, but isRelated(tanya,cindy) is not, so you need to make isRelated(X,Y) symmetric; what simple addition to isRelated would achieve that?

Also, you could try drawing a graph of the relation relatives(X,Y), with an arrow from X to Y for all your base facts, and see if that helps you think about how the Prolog interpreter is going to attempt to satisfy a query.

like image 51
Jason Ozolins Avatar answered Dec 22 '25 11:12

Jason Ozolins


So to answer your last question, you don't switch the values of X and Y in Prolog, like you would call swap(x,y) in C, say. The value held by a logic variable can not be changed explicitly, only back-tracked over. But you can easily use Y where you would use X, and vice versa:

somePred(X,Y):- is_it(X,Y).
somePred(X,Y):- is_it(Y,X).

This defines somePred predicate as a logical disjunction, an "OR". It can be written explicitly too, like

somePred(X,Y):- is_it(X,Y) ; is_it(Y,X).

Note the semicolon there. A comma , between predicates OTOH defines a conjunction, an "AND" (a comma inside a compound term just serves to delimit the term's "arguments").

like image 27
Will Ness Avatar answered Dec 22 '25 11:12

Will Ness



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!