I have a list of user facts defined as:
user(@michael).
user(@ana).
user(@bob).
user(@george).
user(@john).
and so on. Furthermore, I have a set of facts as:
follows(@michael,@ana).
follows(@ana,@bob).
follows(@bob,@michael).
I am trying to write a relation indirect(user1,user1) which will tell me if user1 indirectly follows user2. However, I am not able to do away with cyclic relations.
Like in the given example, michael -> ana -> bob -> michael will cause a cycle.
What is the best way to eliminate these cycles from the result of indirect(user1,user2)?
You can make a rule that passes an extra list of users that you have "seen" so far, and ignore follows originating from these users:
follows(A, B, Seen).To do that, define a "follow transitive" rule that wraps the actual rule, like this:
Now you can define
follows/3rule this way:The base clause says that if there is a fact about
AfollowingB, we consider the predicate proven as long as we have not seenBbefore.Otherwise, we find someone who follows
A, check that we have not seen that user yet by checkingnot_member/2, and finally see if that user followsB, directly or indirectly.Finally, here is how you can define
not_member:Demo.