0

I'm trying to make this but for a different language. In this language there are different kinds of names for uncles and aunts. We call paternal aunt something else and maternal aunt something else.

I came across a graph database 'neo4j'. I created 5 members. I got this approach to work just like I want. But the problem in this is that I've to create n * (n-1) relationships. I'm create a full tree here and not just 5 members of a family.

Also, this is more like brute force. I'm creating all the possibilities. enter image description here

I'm looking for a smarter way to do this. Creating rules like for example Father's sister = paternal-aunt and Mother's sister = maternal-aunt I also want queries Father's wife's sister but don't want to define them separately.

Guy Coder
  • 24,501
  • 8
  • 71
  • 136
Pranav
  • 447
  • 5
  • 18

3 Answers3

1

You can create functions that establish the rules, e.g.:

def is_maternal_aunt(individual, member):
    return member in individual.mother.sister

These can be arbitrary complex:

def is_maternal_aunt(individual, member):
    return is_sister(individual.mother, member)

def is_sister(individual, member):
    return individual.mother == member.mother

It will be a matter of design for which you consider are primary relationships and which are derived. You can probably derive everything from parent child relationships (and marriage).

AChampion
  • 29,683
  • 4
  • 59
  • 75
  • My input will be anything like for eg. "father wife sister". Which should return maternal aunt. What should be the class structure of individual and member? – Pranav Sep 22 '15 at 17:37
1

You don't have to create the bidirectional relationships, and you also don't have to create short-cut-relationships, you can just infer the information in the other direction or across multiple steps.

MATCH path = allShortestPaths((p1:Person {name:"Jane"})-[*]-(p2:Person {name:"John"}))
RETURN [r in relationships(path) | type(r)] as rels

which would then return ["husband","father"] e.g. for an Father-in-Law or ["mother","sister"] for an maternal aunt.

You can then map those tuples either still in cypher (with case) or in your python program.

Michael Hunger
  • 41,339
  • 3
  • 57
  • 80
  • What do you mean by bidirectional relationships and short-cut relationships? I'm not very clear. Can you please explain or link me to something? Thanks! – Pranav Sep 24 '15 at 04:25
1

Prolog is a reasonable choice... For instance I have this small library to draw 'genealogy trees' like this

enter image description here

from this definition (genre definitions are used only to change node' color)

:- module(elizabeth, [elizabeth/0]).
:- use_module(genealogy).

elizabeth :- genealogy(elizabeth, 'Elizabeth II Family').

female('Elizabeth II').
female('Lady Elizabeth Bowes-Lyon').
female('Princess Mary of Teck').
female('Cecilia Cavendish-Bentinck').

parent_child('George VI', 'Elizabeth II').
parent_child('Lady Elizabeth Bowes-Lyon','Elizabeth II').

parent_child('George V', 'George VI').
parent_child('Princess Mary of Teck', 'George VI').

parent_child('Cecilia Cavendish-Bentinck','Lady Elizabeth Bowes-Lyon').
parent_child('Claude Bowes-Lyon', 'Lady Elizabeth Bowes-Lyon').

It requires SWI-Prolog and Graphviz.

edit adding some facts

female('Rose Bowes-Lyon').
parent_child('Cecilia Cavendish-Bentinck','Rose Bowes-Lyon').
parent_child('Claude Bowes-Lyon', 'Rose Bowes-Lyon').

and the rule

is_maternal_aunt(Person, Aunt) :-
    parent_child(Parent, Person),
    female(Parent),
    parent_child(GranParent, Parent),
    parent_child(GranParent, Aunt),
    Aunt \= Parent.

we get

?- is_maternal_aunt(X,Y).
X = 'Elizabeth II',
Y = 'Rose Bowes-Lyon' ;
CapelliC
  • 59,646
  • 5
  • 47
  • 90
  • How can I query something like what's my relation to 'father's father's daughter'? – Pranav Sep 24 '15 at 11:15
  • The main relation is parent_child/2. I introduced female/1 facts, so we *could* introduce a rule `male(X) :- \+ female(X).`. Then, every other relation can be computed. i.e. `father(Father,Child) :- parent_child(Father,Child), male(Father).` Using negation to define facts has some consequence about computability... – CapelliC Sep 24 '15 at 11:40
  • Thanks for replying. Appreciate it. But I'm not asking how to define relationship for father. Input of my program can be anything like 'sister's brother's father's father' which should return grandfather. How to compute that? – Pranav Sep 24 '15 at 11:51
  • Prolog has a relational data model... just write down the join, it becomes a rule. Such join would require adding sister/2, brother/2, and, of course, father/2 – CapelliC Sep 24 '15 at 12:12
  • Ok, I'll look into it. Do you think for replicating [this](http://www.wolframalpha.com/input/?i=father%27s%20sister%27s%20grandfather&dataset=&equal=Submit) prolog is a good idea? A user can input anything and it returns a relation. – Pranav Sep 24 '15 at 12:17
  • I don't know Wolfram Alpha, so I cannot be sure... Prolog it's for *computing logic*, and of course this doesn't comprises *anything*. Knowledge representation and computability have strong and complex relationships... Usually, we go thru 'googling' for answers, isn't true ? and then we apply *our* knowledge about the world... – CapelliC Sep 24 '15 at 12:53
  • Can you take a look at [this](http://stackoverflow.com/questions/32764537/another-relationship-as-argument-to-a-relationship-in-prolog)? – Pranav Sep 24 '15 at 17:59
  • @RaghavSharma: the answer you got there it's fine... relational calculus is applied. As I said above, its data model is relational, with only limited support - for instance - arithmetic, that is cumbersome when expressed in pure relational form – CapelliC Sep 24 '15 at 18:28
  • All right thanks, man! I've bothered you enough. I'll take it from here. – Pranav Sep 24 '15 at 18:49