Using multiple clauses - Prolog - prolog

I have a prolog program that contains details on course modules, students, and the modules they are attending. The program is as follows:
module(42, mod_details('Vocal Skills', 'Dawn Upshaw')).
module(53, mod_details('Physics', 'Dave Jones')).
module(64, mod_details('Maths', 'John Richards')).
module(75, mod_details('History', 'El Capitan')).
student('Bruce Wayne', student_det('100', '2')).
student('Clarke Kent', student_det('200', '3')).
student('Scott Summers', student_det('300', '1')).
student('Richard Kimble', student_det('400', '2')).
attends(100, 42).
attends(300, 42).
attends(400, 42).
attends(200, 53).
attends(300, 53).
attends(300, 64).
attends(100, 75).
attends(200, 75).
attends(300, 75).
attends(400, 75).
print_studentnos_for_modno(ModNo):-
attends(SNo, ModNo),
write(SNo).
print_studentnos_for_modtitle(ModTitle):-
module(ModNo, mod_details(ModTitle, Lect)),
attends(SNo, ModNo),
write(SNo).
is_a_student(StudentName):-
student(StudentName, student_det(SNo, Year)).
print_students_lectured_by(Lect):-
module(ModNo, mod_details(ModTitle, Lect)),
attends(SNo, ModNo),
student(StudentName, student_det(SNo, Year)),
write(StudentName), write(' '),
write(SNo).
The last clause, print_students_lectured_by(Lect), is supposed to print out the names of the students followed by their student number. However, it only gives a false answer.
I am extremely new at this so would appreciate any advice on how to amend my clause.
Many Thanks
Andy

student('Bruce Wayne', student_det('100', '2'))
should be
student('Bruce Wayne', student_det(100, 2))
and similarly for the rest of the students.
NOTE: Haven't tried this out myself

Related

Prolog Tube map Same Line

I am new to prolog and i am very confused about how to go about doing this, your help will help me understand what i have to do for further tasks as well.
I have to check if two stations are on the same line and which line that is,
Here are the Locations:
% Locations %
%Central Line
location(nh,central).
location(lg,central).
location(oc,central).
location(tc,central).
location(cl,central).
location(ls,central).
location(bg,central).
% victoria
location(br,victoria).
location(vi,victoria).
location(oc,victoria).
location(ws,victoria).
location(kx,victoria).
location(fp,victoria).
% Northern
location(eu,northern).
location(ws,northern).
location(tc,northern).
location(em,northern).
location(ke,northern).
% Metropolitan
location(fr,metropolitan).
location(bs,metropolitan).
location(kx,metropolitan).
location(ls,metropolitan).
location(al,metropolitan).
% Bakerloo
location(wa,bakerloo).
location(pa,bakerloo).
location(oc,bakerloo).
location(em,bakerloo).
location(ec,bakerloo).
so i need to make a sameLine() rule to check if the two station are on the same line and what line it is. I was thinking of doing :
sameLine(location1,location2,line) :-
location(location1,line),
location(location2,line).
Does that check if the two stations are on the same line? and how how would i show what line it is?

Prolog Tube Line Task

i have an assignment to make a simplified metro tube map in prolog, one part is asking to make a rule to check if two stations are on the same line, ive got a rule but it doesnt seem to work this is what i have so far:
adjacent(nh,lg,central,4).
adjacent(lg,oc,central,4).
adjacent(oc,tc,central,4).
adjacent(tc,cl,central,4).
adjacent(cl,ls,central,4).
adjacent(ls,bg,central,4).
adjacent(br,vi,victoria,4).
adjacent(vi,oc,victoria,4).
adjacent(oc,ws,victoria,4).
adjacent(ws,kx,victoria,4).
adjacent(kx,fp,victoria,4).
adjacent(ke,em,northern,4).
adjacent(em,tc,northern,4).
adjacent(tc,ws,northern,4).
adjacent(ws,eu,northern,4).
adjacent(al,ls,metropolitan,4).
adjacent(ls,kx,metropolitan,4).
adjacent(kx,bs,metropolitan,4).
adjacent(bs,fr,metropolitan,4).
adjacent(ec,em,bakerloo,4).
adjacent(em,oc,bakerloo,4).
adjacent(oc,pa,bakerloo,4).
adjacent(pa,wa,bakerloo,4).
next(X,Y,L):-adjacent(X,Y,L,_).
next(X,Y,L):-adjacent(Y,X,L,_).
direct_connect(X,Y,L,S,F):-
next(X,Z,L),
not(member(Z,S)),
direct_connect(Z,Y,L,[Z|S],F).
direct_connect(X,Y,L,S,[Y|S]):- next(X,Y,L).
one_change(X,Y,L,F):-
direct_connect(X,Z,L,[X],F1),
direct_connect(Z,Y,L2,[Z|F1],F),
L\=L2.
exist(X):-next(X,_,_).
member(X,[X|_]).
member(X,[_|T]):-member(X,T).
route(X,Y,F):-exist(X),exist(Y),
direct_connect(X,Y,_,[X],F),
write('Direct Connection'),nl,
revwrite(F).
route(X,Y,F):-exist(X),exist(Y),
one_change(X,Y,_,F),
write('One change required'),nl,
revwrite(F).
revwrite([X]):-write(X).
revwrite([H|T]):-revwrite(T), write('->'),write(H).
and the rule;
sameLine(Stat1, Stat2, Line) :-
station(Stat1, Line),
station(Stat2, Line),
Stat1 \= Stat2.
sorry for the unclear and no code propey posted, posting from phone :/

Prolog uniq value check false

i have 4 persons that makes an order and i want everyone of them take a different beverage and a different dessert. but uniq of beverage does not working and i can not find why?
person(X):- X=steve; X=sam; X=sue; X=sara.
desert(X):- X=fruit; X=pie; X=ice_cream; X=cake.
beverage(X):- X=water; X=coffee, X=milk; X=tea.
uniq(X,Y,Z,W):- dif(X,Y), dif(X,Z), dif(X,W), dif(Y,Z), dif(Y,W), dif(Z,W).
order_all(Person1,D1,B1,Person2,D2,B2,Person3,D3,B3,Person4,D4,B4):-
uniq(Person1,Person2,Person3,Person4) ,
person(Person1),
person(Person2),
person(Person3),
person(Person4),
uniq(D1,D2,D3,D4),
desert(D1),
desert(D2),
desert(D3),
desert(D4).
order_b(B1,B2,B3,B4):-
uniq(B1,B2,B3,B4),
beverage(B1),
beverage(B2),
beverage(B3),
beverage(B4).
You have a typo:
beverage(X):- X=water; X=coffee, X=milk; X=tea.
^
Right here
Replace the colon with semicolon.

Is the PROLOG knowledge base created suitable for the following statements exercise?

The exercise was as follows:
Represent the following in Prolog:
Butch is a killer.
Mia and Marsellus are married.
Zed is dead.
Marsellus kills everyone who gives Mia a footmassage.
Mia loves everyone who is a good dancer.
Jules eats anything that is nutritious or tasty.
The knowledge base code I wrote was:
killer(Butch).
married(Mia,Marsellus).
dead(Zed).
kills(Marsellus, Y):- getsfootmassagefrom(Mia, Y).
loves(Mia, X):- goodDancer(X).
eats(Jules, X):- nutritious(X); tasty(X).
Is this correct or have any made any errors whilst writing the rules?
Thanks
Is this more like it?
killer(butch).
killer(marcellus).
adult(mia).
adult(marcellus).
adult(jules).
loves(marcellus,mia).
loves(mia,marcellus)
loves(zed,butch).
married(X,Y):-
loves(X,Y),
adult(X).
'good dancer'(butch).
'good dancer'(zed).
'mia loves'(X):-
'good dancer'(X).
'mia footmassager'(zed).
'mia footmassager'(jules).
'mia footmassager'(butch).
'marcellus kills'(X):-
'mia footmassager'(X).
nutritious('cod liver oil').
nutritious(hummus).
tasty(hummus).
tasty(chocolate).
'jules eats'(X):-
nutritious(X),
tasty(X).

Prolog Query Exercise - Beginner

I'm a begginer at Prolog and I need some help with this exercise, this is the knowledge base provided:
album(‘R. Stevie Moore’, ‘Manuscription’).
album(‘Lane Steinberg’, ‘Manuscription’).
album(‘R. Stevie Moore’, ‘The Yung & Moore Show’).
album(‘Yukio Yung’, ‘The Yung & Moore Show’).
album(‘Jessie Evans’, ‘Autonervous’).
album(‘Bettina Koster’, ‘Autonervous’).
album(‘Lucia Pamela’, ‘Walkin on the moon’).
album(‘Shooby Taylor’, ‘The Human Horn’).
album(‘Tiny Tim’, ‘God Bless Tiny Tim’).
album(‘The Legendary Stardust Cowboy’, ‘Rock-It to Stardom’).
vinil(‘Rock-It to Stardom’).
vinil(‘Walking on the Moon’).
cd( ‘God Bless Tiny Tim’).
cd(‘Walking on the Moon’).
cd(‘Autonervous’).
cd(‘Manuscription’).
cassette(‘The Human Horn’).
cassette(‘The Yung & Moore Show’).
mp3(‘Walkin on the Moon’).
I need to make a query that will return to me all the albums that were made by only one musician.
Thanks for your help :)
In the comments you have provided your code album(X,B),album(Y,C), B \= C. Actually, this is not too far away from a correct solution.
A correct solution could be:
one_musician_album(X) :-
album(A, X),
\+ (album(B, X), A \= B).
The meaning of the predicate is: an album X is a "one-musician album" if this album is authored by some musician A and it's not possible to find a different musician B authored the album X.
Test run:
?- one_musician_album(X).
X = 'Walkin on the moon' ;
X = 'The Human Horn' ;
X = 'God Bless Tiny Tim' ;
X = 'Rock-It to Stardom'.
To get all answers you have to type ';' after each answer.
Maybe this is not needed for you, but it's possible to get all answers in a list with findall:
?- findall(X, one_musician_album(X), Albums).
Albums = ['Walkin on the moon', 'The Human Horn', 'God Bless Tiny Tim', 'Rock-It to Stardom'].
Here is a generalization, based on 'all solutions' builtin bagof/3.
Note that
?- bagof(A, album(A,T), As).
T = 'Autonervous',
As = ['Jessie Evans', 'Bettina Koster'] ;
T = 'God Bless Tiny Tim',
As = ['Tiny Tim']
....
then, restricting the authors (As) to be a list of a single element, we get albums with a single author
?- bagof(A, album(A,T), [A]).
A = 'Tiny Tim',
T = 'God Bless Tiny Tim' ;
...
then, we could use findall/3, as in the good answer by Sergey, or, again, bagof/3, with explicit quantification:
?- bagof(T, A^bagof(A, album(A, T), [A]), Ts).
Ts = ['God Bless Tiny Tim', 'Rock-It to Stardom', 'The Human Horn', 'Walkin on the moon'].

Resources