SWI-prolog same generation - prolog

I have some facts and rules that I'm trying to use that when I pass a query it says if the two variables are of the same generation (either siblings or cousins).
%mother/father DB
mother(lisa, abe).
mother(lisa, sarah).
mother(nancy, john).
mother(mary, jill).
mother(sarah, susan).
mother(susan, jack).
mother(susan, phil).
father(tony, abe).
father(tony, sarah).
father(abe, john).
father(john, jill).
father(bill, susan).
father(rob, jack).
father(rob, phil).
father(jack, jim).
%Parent rule
parent(X,Y):-mother(X,Y).%Defines the parent rule
parent(X,Y):-father(X,Y).
%sibling rule true if X,Y share same parent
sibling(X,Y):-father(Z,X),father(Z,Y),
mother(M,X),mother(M,Y).
cousin(X,Y):-parent(P,X),parent(Q,Y),sibling(P,Q).
%returns true if X is an ancestor of Y
ancestor(X,Y):-parent(X,Y);parent(X,Z),ancestor(Z,Y).
same_generation(X,Y):-ancestor(Z,X),ancestor(A,Y),sibling(Z,A).
Unfortunately the problem I'm getting is that when I test the query for a child and parent ex.same_generation(Jack,Susan), I get true (that is incorrect)!
Any help would be great!
Here is the family tree:
enter image description here

Related

Creating a Knowledge Base and Querying in Prolog

I want to create the Knowledge base equivalent to the statements as below in Prolog.
John likes all kind of food.
Apple and vegetable are food
Anything anyone eats and not killed is food.
Anil eats peanuts and still alive
Harry eats everything that Anil eats.
So this one of the version borrowed from here
Once this file is created I want to find the answer for the query "John likes peanuts." saying likes(john, peanut).
Attempt to write rules in Prolog from my side is as below
alive(anil).
eats(anil,peanut).
food(apple).
food(vegitables).
food(X):-likes(john,X).
eats(X,Y),not(killed(X)):-food(Y).
eats(anil,X):-eats(harry,X).
killed(X):-not(alive(X)).
alive(X):-not(killed(X)).
But I am getting the errors and warnings as below;
ERROR: No permission to modify static procedure `(',')/2'
Warning: Clauses of eats/2 are not together in the source-file
Warning: Current predicate: food/1
Warning: Use ':- discontiguous eats/2.' to suppress this message
Warning: Clauses of alive/1 are not together in the source-file
Warning: Current predicate: killed/1
Warning: Use ':- discontiguous alive/1.' to suppress this message
"John likes all kind of food."
likes(john,X) :- food(X).
"Apple and vegetable are food."
food(apple).
food(X) :- vegetable(X).
"Anything anyone eats and not killed is food."
food(X) :- eats(P,X), alive(P).
"Anil eats peanuts and still alive."
eats(anil,peanuts).
alive(anil).
"Harry eats everything that Anil eats."
eats(harry,X) :- eats(anil,X).
Asking
?- likes(john,X).
produces (in SWI Prolog)
70 ?- likes(john,X).
X = apple ;
ERROR: food/1: Undefined procedure: vegetable/1
Exception: (9) vegetable(_G19387424) ? fail
Exception: (8) food(_G19387424) ? fail
71 ?-
Fixing it with
:- dynamic(vegetable/1).
we get
75 ?- likes(john,X).
X = apple ;
X = peanuts ;
false.
and so, of course,
101 ?- likes(john,peanuts).
true .

I wrote a prolog code for my family tree. What's the problem with this code?

/*facts*/
female(Sufia).
female(Bilkis).
female(Nasima).
female(Rabeya).
female(NWife).
female(Eva).
female(Rekha).
female(Shammi).
female(Shanta).
female(TWife).
female(NSWife).
female(Jui).
female(SHWife).
female(TSWife).
male(Anowar).
male(Shahidul).
male(Khazal).
male(Shafik).
male(Nahid).
male(Jahorul).
male(Naim).
male(Tanim).
male(Raiyan).
male(NSon).
male(JHusband).
male(Jubayer).
male(Shoddo).
male(TSon).
male(NSSon).
male(JSon).
male(SHSon).
male(TSSon).
parent(Anowar,Shahidul).
parent(Anowar,Nasima).
parent(Anowar,Shafik).
parent(Shahidul,Nahid).
parent(Shahidul,Eva).
parent(Nasima,Rekha).
parent(Nasima,Shammi).
parent(Nasima,Shanta).
parent(Shafik,Tanim).
parent(Shafik,Raiyan).
parent(Nahid,NSon).
parent(Rekha,Jui).
parent(Rekha,Jubayer).
parent(Shammi,Shoddo).
parent(Tanim,TSon).
parent(NSon,NSSon).
parent(Jui,JSon).
parent(Shoddo,SHSon).
parent(TSon,TSSon).
/*rules*/
mother(X,Y):-parent(X,Y),female(X).
father(X,Y):-parent(X,Y),male(X).
son(X,Y):-parent(X,Y),male(X).
daughter(X,Y) :- female(X),parent(X,Y).
sister(X,Y) :- female(Y),parent(Par,X),parent(Par,Y), X \= Y.
child(X, Y) :-parent(Y, X).
sibling(X,Y):-parent(Z,X),parent(Z,Y),X\=Y.
grandparent(X,Z):-parent(X,Y),parent(Y,Z).
firstCousin(X,Y):-grandparent(Z,X),grandparent(Z,Y),X\=Y.
secondCousin(X,Y):-grandparent(A,X),grandparent(B,Y),sibling(A,B),A\=B.
firstcousinOnceRemoved(X,Y):-child(X,Z),cousin(Z,Y).
firstcousinTwiceRemoved(X,Y):-grandparent(X,Z),cousin(Z,Y).
You need to quote every name, otherwise these symbols are variables, not atoms.
Otherwise, just lowercase the first letter. To illustrate this last option, using my pet project, here is the graph:
as obtained from this source
:- module(answer_so, [answer_so/0]).
:- use_module(genealogy).
answer_so :- genealogy(answer_so, 'Answer SO').
parent_child(P,C) :- parent(P,C).
female(sufia).
female(bilkis).
female(nasima).
female(rabeya).
female(nwife).
female(eva).
female(rekha).
female(shammi).
female(shanta).
female(twife).
female(nswife).
female(jui).
female(shwife).
female(tswife).
male(anowar).
male(shahidul).
male(khazal).
male(shafik).
male(nahid).
male(jahorul).
male(naim).
male(tanim).
male(raiyan).
male(nson).
male(jhusband).
male(jubayer).
male(shoddo).
male(tson).
male(nsson).
male(json).
male(shson).
male(tsson).
parent(anowar,shahidul).
parent(anowar,nasima).
parent(anowar,shafik).
parent(shahidul,nahid).
parent(shahidul,eva).
parent(nasima,rekha).
parent(nasima,shammi).
parent(nasima,shanta).
parent(shafik,tanim).
parent(shafik,raiyan).
parent(nahid,nson).
parent(rekha,jui).
parent(rekha,jubayer).
parent(shammi,shoddo).
parent(tanim,tson).
parent(nson,nsson).
parent(jui,json).
parent(shoddo,shson).
parent(tson,tsson).
Seems there are no marriages...

Prolog Procedure si(A) Does not Exist

This is the code
verificar(S) :-
(si(S)
->
true ;
(no(S)
->
fail ;
preguntar(S))).
preguntar(Pregunta) :-
write('Tiene los siguientes sintomas: '),
write(Pregunta),
write('?'),
read(Respuesta),
nl,
( (Respuesta == si)
->
assert(si(Pregunta));
assert(no(Pregunta)), fail).
and the problem is
procedure `si(A)' does not exist
Reachable from:
verificar(A)
resfriado
hipotesis(A)
evaluar
The problem is for the first run, the program does not know what you mean with si(A) since there is no predicate or rule defined. Quickfix: Add dummy data like
si(nothing).
no(nothing).
which can be removed after the first "valid" entry in your knowledge base.
You have not written the predicate for si(). This is why you are getting the error:-
procedure `si(A)' does not exist

How to correctly write grandparent rule

This is my first homework assignment using prolog, I thought I knew what I was doing but when I write a query it says
"procedure `parent(A,B)' does not exist
Reachable from:
grandparent(A,B)".
female(jane).
female(mary).
female(clare).
female(vivian).
female(alice).
female(sarah).
female(rachel).
male(floyd).
male(tom).
male(richard).
male(calvin).
male(john).
male(andrew).
parent_of(tom, richard).
parent_of(tom, jane).
parent_of(mary, calvin).
parent_of(mary, alice).
parent_of(clare, john).
parent_of(clare, tom).
parent_of(john, alice).
parent_of(john, calvin).
parent_of(richard, vivian).
parent_of(richard, floyd).
parent_of(jane, sarah).
parent_of(jane, rachel).
parent_of(jane, andrew).
grandparent(X,Z):-parent(X,Y),parent(Y,Z).
sister_of(X,Y):-parent(Z,X),parent(Z,Y),female(X),X\==Y.
brother_of(X, Y):-parent(Z,X),parent(Z,Y),male(X),X\==Y.
You declared your predicates as
parent_of/2
Look at your code again
parent_of(tom, richard).
parent_of(tom, jane).
parent_of(mary, calvin).
parent_of(mary, alice).
parent_of(clare, john).
parent_of(clare, tom).
[...]
therefore you also have to use parent_of in your grandparent predicate like following:
grandparent(X,Z):-parent_of(X,Y),parent_of(Y,Z).
please note, that you have to change the following predicates aswell (sister_of and brother_of):
sister_of(X,Y):-parent_of(Z,X),parent_of(Z,Y),female(X),X\==Y.
brother_of(X, Y):-parent_of(Z,X),parent_of(Z,Y),male(X),X\==Y.

Write a predicate same_name(Person1,Person2) that returns true if Person 1 and Person 2 have same family name

parent(albert, jim).
parent(albert, peter).
parent(jim, brian).
parent(john, darren).
parent(peter, lee).
parent(peter, sandra).
parent(peter, james).
parent(peter, kate).
parent(peter, kyle).
parent(brian, jenny).
parent(irene, jim).
parent(irene, peter).
parent(pat, brian).
parent(pat, darren).
parent(amanda, jenny).
female(irene).
female(pat).
female(lee).
female(sandra).
female(jenny).
female(amanda).
female(kate).
male(albert).
male(jim).
male(peter).
male(brian).
male(john).
male(darren).
male(james).
male(kyle).
We assume that each person will have the same family name as their father, but that married women retain their original birth name.
Example :
?- same_name(pat, brian).
false.
?- same_name(jenny, jim).
true
I wrote conditions to check if they have same father or one of them is grandfather :
check_grandfather(A,B) :-
parent(A,X),
parent(X,B).
check_siblings(A,b) :-
parent(X,A),
parent(X,B),
A \== B.
but I can not understand how can I use conditions to check same_name.
I am thinking something like,
same_name(P1,P2) :-
check_siblings(P1,P2),
check_grandfather(P1,P2).
But it doesn't seem to work. I am very new to prolog so any help would be appreciated.

Resources