Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Refactoring tangled, circular rules in Prolog

Tags:

Right up front: This is not a homework exercise. I’m trying to learn Prolog and this is just a problem that happens to need solving and for which Prolog is a perfect fit.

I have a bunch of family relations which comprise my facts:

male/1
female/1
husband/2
wife/2
father/2
mother/2
grandfather/2
grandmother/2
son/2
daughter/2
brother/2
sister/2
uncle/2
aunt/2
nephew/2
niece/2
cousin/2

The data that I have are incomplete, many links of the family mesh are missing. My facts come from an external source, I can only supply the rules. For a given person, I might have male, brother and cousin, for another mother and wife. In the worst case, I barely know cousin, but have enough other facts to be able to infer who is, say, the uncle, therefore that the person might be that brother mentioned elsewhere, hence is male. And so forth.

There’s no way in which I can influence which facts there will be. That’s the whole point of the problem: If the facts were complete, I wouldn’t need to do this. I could do the guesswork by hand, but that’s what a computer is for, if I can find a way of expressing it. The goal is therefore to fill the missing links as good as possible, especially with regard to the ‘indirect’ relations around uncle, aunt, nephew, niece and especially cousin, which are notoriously incomplete.

I could write my rules naïvely like this:

male(Who) :-
   brother(Who, _); father(Who, _); uncle(Who, _); …
brother(Who, Whose) :-
   sibling(Who, Ofwhom), male(Who).
sibling(Who, Whose) :-
   brother(Who, Whose) ; brother(Whose, Who).
motherly_cousin(Cousin, Whose) :-
   cousin(Cousin, Whose),
   sibling(Mother, Uncle_or_Aunt),
   parent(Uncle_or_Aunt, Cousin).

I am rather sure that I am trying to solve the problem in a fundamentally wrong way, as I see no way of breaking the circular reasoning. And without breaking the circles, any Prolog program that I’ll devise for this will degenerate into endless recursions.

So what could I do to break this tangle down into something that can be solved?