Prolog Tube Line Task - prolog

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 :/

Related

Prolog output message understanding

This is a really quick one, I don't know the correct way to google it!
Say we have an output such it gives:
X = [4|_1218]
what generally has to be changed to get the output just to say 4?
member1(Head, [Head|_]):-!.
member1(Item, [_|Tail]):-
member1(Item, Tail).
findnotin([Head|_], RuledOut, [Head|_]):-
not(member1(Head, RuledOut)).
Edit Completedish program:
find_not_in([], _, _).
find_not_in([Head|Candidates], RuleOut, [Head|Legal]):-
not(member1(Head, RuleOut)),
find_not_in(Candidates, RuleOut, Legal).
find_not_in([_|Candidates], RuleOut, Legal):-
find_not_in(Candidates, RuleOut, Legal).

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?

A*(Star) Prolog

I have an A*(Star) Algorithm in prolog, and I need receive a list of destinations instead a single destination, and it should past for every element of the list and then back to the start.
NOTE: It can pass in the same place twice.
I tried it, but Swi-prolog returns false everytime, can I get any help?
The code above receive a single destination, and it works, but as I said I need a list of destinations, and pass through them all.
Example: astar(1,[2,2,4,6,8,9,10,13,15],C,P).
/*area(Number,PosX,PosY).*/
area(1,20,80).
area(2,50,30).
area(3,100,100).
area(4,90,70).
area(5,70,50).
area(6,110,50).
area(7,150,90).
area(8,200,90).
area(9,140,60).
area(10,160,20).
area(11,180,60).
area(12,190,20).
area(13,230,70).
area(14,240,30).
area(15,240,20).
/*street(CityA,CityB,Distance).*/
street(1,2,50).
street(1,3,100).
street(1,4,75).
street(1,5,65).
street(2,5,30).
street(3,4,40).
street(3,7,50).
street(4,5,25).
street(4,6,30).
street(4,9,65).
street(4,7,70).
street(5,6,30).
street(6,9,35).
street(6,10,60).
street(7,8,35).
street(7,9,30).
street(8,9,70).
street(8,11,40).
street(8,13,50).
street(9,10,50).
street(9,11,30).
street(10,11,50).
street(10,12,40).
street(11,12,40).
street(11,13,50).
street(11,14,60).
street(12,14,50).
street(13,14,50).
astar(Start,Final,_,Tp):-
estimation(Start,Final,E),
astar1([(E,E,0,[Start])],Final,_,Tp).
astar1([(_,_,Tp,[Final|R])|_],Final,[Final|R],Tp):- reverse([Final|R],L3),write('Path = '),write(L3).
astar1([(_,_,P,[X|R1])|R2],Final,C,Tp):-
findall((NewSum,E1,NP,[Z,X|R1]),(street(X,Z,V),
not(member(Z,R1)),
NP is P+V,
estimation(Z,Final,E1),
NewSum is E1+NP),L),
append(R2,L,R3),
sort(R3,R4),
astar1(R4,Final,C,Tp).
estimation(C1,C2,Est):- area(C1,X1,Y1),area(C2,X2,Y2), DX is X1-X2,DY is Y1-Y2,
Est is sqrt(DX*DX+DY*DY).

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

Using multiple clauses - 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

Resources