Prolog Tube map Same Line - prolog

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?

Related

Line fitting python

I have these two arrays x and y (pink scatter points), and I want to fit a line as shown in the figure (blue line). However, I have not been able to find the proper fit or a proper equation. I have tried exponentials, polyfits and nothing. Maybe someone here has an idea. Original x and y data are here.
x=[50.56457351, -25.94178241, 10.20492002, -4.42553174,
-27.33151148, -29.9721279 , 36.06962759, 7.56321785,
52.94172778, 1.99279668, 70.60954309, -41.28236289,
-28.56116707, -43.98117436, 19.52197933, -13.99493533,
-35.4383463 , -44.3050207 , -3.96679614, 14.88981502]
y=[-3.39506291, 5.07105136, 21.0870528 , 17.67702032, 0.03026157,
6.45900452, -0.19873009, 7.50795551, -1.82804242, -3.65200329,
-2.93492827, -5.86174941, -2.50507783, -3.43619693, -2.66194664,
-3.59860008, -0.19628881, -2.94505151, -2.3179664 , -2.29120004]

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 logical task

There is a logical problem:
four friends: Ivan, Petr, Mikhail, Sergey spent their time in different ways: two were playing chess, one read books, one watched TV. Find who does what if Sergey does not play chess and Petr did not watch TV.
Here is my solution:
PREDICATES
question(string,string,string,string)
friend(string)
readBook(string)
watchTV(string)
playsChess(string, string)
CLAUSES
friend(ivan).
friend(petr).
friend(mikhail).
friend(sergey).
readBook(X):-
friend(X).
watchTV(X):-
friend(X),
X<>"petr".
playsChess(X,Y):-
friend(X),
friend(Y),
X<>Y,
X<>"sergey",
Y<>"sergey".
question(A,B,C,D):-
friend(A),
friend(B),
friend(C),
friend(D),
playsChess(A,B),
readBook(C),
watchTV(D),
A<>B, A<>C, A<>D,
B<>C, B<>D,
C<>D.
GOAL
question(A,B,C,D).
I have the following solution:
A=ivan, B=petr, C=mikhail, D=sergey (1)
A=ivan, B=petr, C=sergey, D=mikhail (2)
A=ivan, B=mikhail, C=petr, D=sergey (3)
A=petr, B=ivan, C=mikhail, D=sergey (4)
A=petr, B=ivan, C=sergey, D=mikhail (5)
A=petr, B=mikhail, C=ivan, D=sergey (6)
A=petr, B=mikhail, C=sergey, D=ivan (7)
A=mikhail, B=ivan, C=petr, D=sergey (8)
A=mikhail, B=petr, C=ivan, D=sergey (9)
A=mikhail, B=petr, C=sergey, D=ivan (10)
10 Solutions
But some lines are redundant since they are combined A and B. For example lines (1) and (4) (A=ivan, B=petr and A=petr, B=ivan).
I tried to use ! here:
playsChess(X,Y):-!,
friend(X),
friend(Y),
X<>Y,
X<>"sergey",
Y<>"sergey".
but it has no effect.
So the question is: how can I get rid of excess solution results?
Consider using the variable you introduce for each friend to directly represent the activity corresponding to that person:
friends([ivan=Ivan,petr=Petr,mikhail=Mikhail,sergey=Sergey]) :-
Fs0 = [Ivan,Petr,Mikhail,Sergey],
dif(Sergey, chess),
dif(Petr, tv),
select(books, Fs0, Fs1),
select(tv, Fs1, [chess,chess]).
Example query and its result:
?- friends(Fs).
Fs = [ivan=books, petr=chess, mikhail=chess, sergey=tv] ;
Fs = [ivan=chess, petr=books, mikhail=chess, sergey=tv] ;
Fs = [ivan=chess, petr=chess, mikhail=books, sergey=tv] ;
Fs = [ivan=tv, petr=chess, mikhail=chess, sergey=books] ;
Fs = [ivan=chess, petr=chess, mikhail=tv, sergey=books] ;
false.
The simplest way to solve the problem would be to constrain A and B further and force one to be "greater" than the other. I'm not sure exactly if this is the syntax in Visual Prolog, but try this. Note the use of A > B instead of A <> B.
question(A,B,C,D):-
friend(A),
friend(B),
friend(C),
friend(D),
playsChess(A,B),
readBook(C),
watchTV(D),
A > B, A<>C, A<>D,
B<>C, B<>D,
C<>D.
By constraining with > instead of <> you will ensure that you won't have symmetrical cases. For example, a > b is false, but a < b is true. However, both a <> b and b <> a are true, so the <> gives both a, b and b, a.
Your cut (!) did nothing because when you use it on a predicate that has only one clause like this:
my_predicate(...) :- !, subqueries ...
It just tells Prolog not to backtrack beyond the beginning of the first subquery. Since there are no other my_predicate clauses to backtrack to anyway, it has no effect.

alphanumeric sort in VIM

Suppose I have a list in a text file which is as follows -
TaskB_115
TaskB_19
TaskB_105
TaskB_13
TaskB_10
TaskB_0_A_1
TaskB_17
TaskB_114
TaskB_110
TaskB_0_A_5
TaskB_16
TaskB_12
TaskB_113
TaskB_15
TaskB_103
TaskB_2
TaskB_18
TaskB_106
TaskB_11
TaskB_14
TaskB_104
TaskB_112
TaskB_107
TaskB_0_A_4
TaskB_102
TaskB_100
TaskB_109
TaskB_101
TaskB_0_A_2
TaskB_0_A_3
TaskB_116
TaskB_1_A_0
TaskB_111
TaskB_108
If I sort in vim with command %sort, it gives me output as -
TaskB_0_A_1
TaskB_0_A_2
TaskB_0_A_3
TaskB_0_A_4
TaskB_0_A_5
TaskB_10
TaskB_100
TaskB_101
TaskB_102
TaskB_103
TaskB_104
TaskB_105
TaskB_106
TaskB_107
TaskB_108
TaskB_109
TaskB_11
TaskB_110
TaskB_111
TaskB_112
TaskB_113
TaskB_114
TaskB_115
TaskB_116
TaskB_12
TaskB_13
TaskB_14
TaskB_15
TaskB_16
TaskB_17
TaskB_18
TaskB_19
TaskB_1_A_0
TaskB_2
But I would like to have the output as follows -
TaskB_0_A_1
TaskB_0_A_2
TaskB_0_A_3
TaskB_0_A_4
TaskB_0_A_5
TaskB_1_A_0
TaskB_2
TaskB_10
TaskB_11
TaskB_12
TaskB_13
TaskB_14
TaskB_15
TaskB_16
TaskB_17
TaskB_18
TaskB_19
TaskB_100
TaskB_101
TaskB_102
TaskB_103
TaskB_104
TaskB_105
TaskB_106
TaskB_107
TaskB_108
TaskB_109
TaskB_110
TaskB_111
TaskB_112
TaskB_113
TaskB_114
TaskB_115
TaskB_116
Note I just wrote this list to demonstrate the problem. I could generate the list in VIM. But I want to do it for other things as well in VIM.
With [n] sorting is done on the first decimal number
in the line (after or inside a {pattern} match).
One leading '-' is included in the number.
try this command:
sor n
and you don't need the %, sort sorts all lines if no range was given.
EDIT
as commented by OP, if you have:
TaskB_0_A_1
TaskB_0_A_2
TaskB_0_A_4
TaskB_0_A_3
TaskB_0_A_5
TaskB_1_A_0
you could try:
sor n /.*_\ze\d*/
or
sor nr /\d*$/
EDIT2
for newly edited question, this line may give you expected output based on your example data:
sor nr /\d*$/|sor n

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