问题
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.
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.
回答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).
回答2:
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:
Prolog is a reasonable choice... For instance I have this small library to draw 'genealogy trees' like this
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' ;
来源:https://stackoverflow.com/questions/32699313/how-to-create-family-relation-logic