How to correctly write grandparent rule - prolog

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.

Related

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

I'm new to Prolog and I don't know where I'm going wrong

Current predicate: wings/1
Warning: Use :- discontiguous size/1. to suppress this message
Warning: Clauses of bill/1 are not together in the source-file
Warning: Current predicate: size/1
Warning: Use :- discontiguous bill/1. to suppress this message
Warning: Clauses of live/1 are not together in the source-file
Warning: Current predicate: bill/1
Warning: Use :- discontiguous live/1. to suppress this message
Warning: Clauses of nostrils/1 are not together in the source-file
Warning: Current predicate: live/1
This is the code I'm using.
:-dynamic known/3.
top_goal(X):-bird(X).
bird(laysan_albatross):-
family(albatross),
color(white).
bird(black_footed_albatross):-
family(albatross),
color(dark).
bird(whistling_swan):-
family(swan),
voice(muffled_musical_whistle).
bird(trumpeter_swan):-
family(swan),
voice(loud_trumpeting).
order(tubenose):-
nostrils(external_tubular),
live(at_sea),
bill(hooked).
order(waterfowl):-
feet(webbed),
bill(flat).
family(albatross):-
order(tubenose),
size(large),
wings(long_narrow).
family(swan):-
order(waterfowl),
neck(long),
color(white),
flight(ponderous).
nostrils(external_tubular).
live(at_sea).
bill(hooked).
size(large).
wings(long_narrow).
color(dark).
color(X):-ask(color,X).
wings(X):-ask(wings,X).
size(X):-ask(size,X).
bill(X):-ask(bill,X).
live(X):-ask(live,X).
nostrils(X):-ask(nostrils,X).
voice(X):-ask(voice,X).
flight(X):-ask(flight,X).
feet(X):-ask(feet,X).
neck(X):-ask(neck,X).
ask(A, V):-
known(yes, A, V),
!.
ask(A, V):-
known(_, A, V),
!,fail.
ask(A, V):-
write(A:V),
write('? : '),
read(Y),
asserta(known(Y, A, V)),
Y==yes.
solve:-
retractall(known(_,_,_)),
top_goal(X),
write('The bird is'),write(X),nl.
solve:-
write('This is an unknown bird.'),nl.
You are putting a full stop character where you should be using a comma in the swan family:
family(swan):-
order(waterfowl),
neck(long),
color(white),
flight(ponderous). %Should be ',' instead of '.'
nostrils(external_tubular). %idem
live(at_sea). bill(hooked). size(large). %idem
wings(long_narrow). %idem
color(dark). %This full stop is ok
These characters are very different in purpose !
As per your code, you are defining bill/1 or live/1 after the swan family code, and again when you ask the user. So prolog sees that as two separate definitions of the same predicate, which it flagged as "discontinous" error.

How to allow program to proceed?

How to make the program proceed to menu1/0 after false appear
mylist([a,b,c]).
myprog(X) :- mylist(L), member(X, L).
go :- start_message,menu1.
start_message :-
write('This is a program.'),nl,
write('Below are a list:'),nl,
myprog(X),
write(X),nl,
fail.
menu1 :-
nl,write('Select operation:'),nl,
write('1. Input time'),nl,
write('2. Exit program'),nl.
Below is what I am stuck with:
go.
This is a program.
Below are a list:
a
b
c
false
You can do like this
start_message :-
write('This is a program.'),nl,
write('Below are a list:'),nl,
( myprog(X),
write(X),nl,
fail
; true ).
Now when myprog/1 cannot succeed anymore, control goes to true/0 and start_message/0 succeeds.
Remove the fail statement in the last line of start_message.

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.

SWI-prolog same generation

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

Resources