How to create family relation logic?

2019-06-10 10:23发布

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.

3条回答
做个烂人
2楼-- · 2019-06-10 10:53

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.

查看更多
做自己的国王
3楼-- · 2019-06-10 10:56

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).

查看更多
Rolldiameter
4楼-- · 2019-06-10 11:01

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' ;
查看更多
登录 后发表回答