%% Here we define a function, father, taking two objects as an argument. There is no typing system here.
%% so father(x, y) is true when man(x) is true and parent(x, y) is also true.
father(Father, Child) :- man(Father), parent(Father, Child).
mother(Mother, Child) :- woman(Mother), parent(Mother, Child).
child(Child, Mother, Father) :-
woman(Mother),
man(Father),
parent(Mother, Child),
parent(Father, Child).
%% Here we define man(x) as not woman(x). So an object cannot be both male + female.
man(Man) :- \+ woman(Man).
woman(Woman) :- \+ man(Woman).
%% The _ operator means match any, so is_father is true iff father(x, *) is true. ie. there is some child which x is a father of.
is_father(Father) :- father(Father, _).
is_mother(Mother) :- mother(Mother, _).
is_child(Child) :- child(Child, _, _).
are_siblings(Child, Child2) :- parent(Father, Child),
parent(Father, Child2),
parent(Mother, Child),
parent(Mother, Child2).
are_brothers(Child, Child2) :- are_siblings(Child, Child2),
man(Child),
man(Child2).
are_sisters(Child, Child2) :- are_siblings(Child, Child2),
woman(Child),
woman(Child2).
uncle(Uncle, Child) :- man(Uncle), are_siblings(Parent, Uncle), parent(Parent, Child).
%% Here we actually assign some properties to variables. jon is a man!
man(jon).
man(stew).
woman(jess).
%% Mum is a woman and she is also a parent to jess, stew, dan + dylan.
woman(mum).
parent(mum, jess).
parent(mum, stew).
parent(mum, dan).
parent(mum, dylan).
%% dad is also a parent to these children.
man(dad).
parent(dad, jess).
parent(dad, stew).
parent(dad, dan).
parent(dad, dyland).
man(grandad).
parent(grandad, dad).
parent(grandad, neil).
woman(grandma).
parent(grandma, dad).
parent(grandma, neil).
man(neil).
%% dad's parents are grandma + grandad who also have a child called neil. At this point we can evaluate neil to an uncle of stew because
%% he is a sibling with the father of stew! :D