I'm working on an expert system using PyDatalog
to model and infer various family relations.
This is the data used (loaded from a CSV file):
name father_name mother_name gender
0 Ahmad Bachar Rafah Male
1 Amjad Bachar Rafah Male
2 Danah Bachar Rafah Female
3 Yazan Hassan Ghalia Male
4 Leen Hassan Ghalia Female
5 Dema Faiaz Sahar Female
6 Dania Faiaz Sahar Female
7 Tareq Faiaz Sahar Male
8 Asmaa Waleed Hanan Female
9 Alaa Waleed Hanan Female
10 Tasneem Waleed Hanan Female
11 Firas Waleed Hanan Male
12 Farouk Shareef Sameah Male
13 Usaema Saeed Adebeh Female
14 Bachar Farouk Usaema Male
15 Hassan Farouk Usaema Male
16 Rafah Zuhair Rukaieh Female
17 Zoukaa Zuhair Rukaieh Female
18 Lujain Adnan Zoukaa Female
19 Mohammad Adnan Zoukaa Male
First I added the terms:
pyDatalog.create_terms('X,Y,Z,W, parent, male, female, father_of, mother_of,
son, daughter, aunt, uncle, cousin, niece, nephew, sibling, brother, sister')
And this is how I am defining the rules son, male, daughter, female, father_of, mother_of
:
for index, row in data.iterrows():
name, father_name, mother_name, gender = row['name'], row['father_name'], row['mother_name'], row['gender']
if gender == 'Male':
+son(name, father_name)
+son(name, mother_name)
+male(name)
else:
+daughter(name, father_name)
+daughter(name, mother_name)
+female(name)
+father_of(father_name, name)
+mother_of(mother_name, name)
Testing the rules gave the right answers:
print(son(X, "Bachar"))
print(son(X, "Sahar"))
# Output:
X
-----
Amjad
Ahmad
X
-----
Tareq
This is for the parent, brother, sister, sibling
also: (Won't include the results to avoid making the question long but tested and worked well 100%)
parent(X, Y) <= father_of(X, Y)
parent(X, Y) <= mother_of(X, Y)
brother(X, Y) <= (parent(Z, X) & parent(Z, Y) & male(X) & (X != Y))
sister(X, Y) <= (parent(Z, X) & parent(Z, Y) & (X != Y) & female(X))
sibling(X,Y) <= parent(Z, X) & parent(Z, Y) & (X != Y)
The issue and purpose of the question is defining the uncle
and aunt
:
I wrote this:
uncle(X, Y) <= brother(X, Z) & parent(Z, Y) & male(X)
aunt(X, Y) <= sister(X, Z) & parent(Z, Y) & female(X)
cousin(X, Y) <= parent(Z, X) & (sister(X, Z) & parent(Z, Y))
Testing it with the "Yazan" and "Ahmad" is OK but with "Asmaa" it outputs an empty list, if you go to the data above the output should be "Bachar, Hassan". The same in the aunt
and cousin
rules also output wrong answers. Is there something I'm missing here or needs to be corrected?
I went down to the PyDatalog
Docs and checked the code written using their interactive tutorial, one issue I found was related to Google Colab itself and I had to terminate the session and start a new one.
Fixing the problem required additional data to be included, so according to PyDatalog
an empty list []
is also could be an indcatior to an error in the logic or the Facts and rules
declartion which in return would not be resolved or detcted easily.
What I did to solve that?
The simple answer is changing the logic how reltives family relationships
are definded and adding an information about cousin's parents like i.e. Grandparents and siblings.