Prolog not finding all solutions
up vote
1
down vote
favorite
Modelling the stops of an underground tube line like so:
stop(line1, 1, station1).
stop(line1, 2, station2).
stop(line1, 3, station3).
stop(line1, 4, station4).
stop(line1, 5, station5).
stop(line2, 1, station2).
stop(line2, 2, station4).
where stop(L, N, S)
means S
is the N
'th stop on line L
, I'm trying to define path(S1, S2, P)
that calculates possible paths between S1
and S2
.
Here a path is a list of "segments", a segment being a journey along the same line, i.e. segment(L,S1,S2)
represents the continuous journey from S1
to S2
along line L
. So a possible solution to path(a,d,P)
is P=[segment(line1, a, b), segment(line2, b, d)]
, i.e. go from a
to b
on line1
, then go from b
to d
on line2
.
An additional constraint is that a path should not include the same line more than once.
I've got the following:
segment(L, S1, S2) :- stop(L, N1, S1), stop(L, N2, S2), N2>N1.
line_present_in_path(_, ) :- false.
line_present_in_path(L, [H|_]) :- segment(L, _, _) = H.
line_present_in_path(L, [_|T]) :- line_present_in_path(L, T).
path(S1, S2, [H]) :- segment(_, S1, S2) = H, H.
path(S1, S2, [H|T]) :- segment(L, S1, X) = H, H, +line_present_in_path(L, T), path(X, S2, T).
but something peculiar happens. If I explicitly specify all the parameters myself, it recognises it as a correct path:
?- path(station1, station4, [segment(line1, station1, station2),segment(line2, station2, station4)]).
true ;
false.
However, if I ask it to calculate all paths, it only finds one path, different to the path it just verified as correct:
?- path(station1, station4, P).
P = [segment(line1, station1, station4)] ;
false.
I must admit I'm new to Prolog so I might be missing something basic. But, I really can't understand why it can verify a given path as correct, but it doesn't find that path when trying to find all paths.
prolog
add a comment |
up vote
1
down vote
favorite
Modelling the stops of an underground tube line like so:
stop(line1, 1, station1).
stop(line1, 2, station2).
stop(line1, 3, station3).
stop(line1, 4, station4).
stop(line1, 5, station5).
stop(line2, 1, station2).
stop(line2, 2, station4).
where stop(L, N, S)
means S
is the N
'th stop on line L
, I'm trying to define path(S1, S2, P)
that calculates possible paths between S1
and S2
.
Here a path is a list of "segments", a segment being a journey along the same line, i.e. segment(L,S1,S2)
represents the continuous journey from S1
to S2
along line L
. So a possible solution to path(a,d,P)
is P=[segment(line1, a, b), segment(line2, b, d)]
, i.e. go from a
to b
on line1
, then go from b
to d
on line2
.
An additional constraint is that a path should not include the same line more than once.
I've got the following:
segment(L, S1, S2) :- stop(L, N1, S1), stop(L, N2, S2), N2>N1.
line_present_in_path(_, ) :- false.
line_present_in_path(L, [H|_]) :- segment(L, _, _) = H.
line_present_in_path(L, [_|T]) :- line_present_in_path(L, T).
path(S1, S2, [H]) :- segment(_, S1, S2) = H, H.
path(S1, S2, [H|T]) :- segment(L, S1, X) = H, H, +line_present_in_path(L, T), path(X, S2, T).
but something peculiar happens. If I explicitly specify all the parameters myself, it recognises it as a correct path:
?- path(station1, station4, [segment(line1, station1, station2),segment(line2, station2, station4)]).
true ;
false.
However, if I ask it to calculate all paths, it only finds one path, different to the path it just verified as correct:
?- path(station1, station4, P).
P = [segment(line1, station1, station4)] ;
false.
I must admit I'm new to Prolog so I might be missing something basic. But, I really can't understand why it can verify a given path as correct, but it doesn't find that path when trying to find all paths.
prolog
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
Modelling the stops of an underground tube line like so:
stop(line1, 1, station1).
stop(line1, 2, station2).
stop(line1, 3, station3).
stop(line1, 4, station4).
stop(line1, 5, station5).
stop(line2, 1, station2).
stop(line2, 2, station4).
where stop(L, N, S)
means S
is the N
'th stop on line L
, I'm trying to define path(S1, S2, P)
that calculates possible paths between S1
and S2
.
Here a path is a list of "segments", a segment being a journey along the same line, i.e. segment(L,S1,S2)
represents the continuous journey from S1
to S2
along line L
. So a possible solution to path(a,d,P)
is P=[segment(line1, a, b), segment(line2, b, d)]
, i.e. go from a
to b
on line1
, then go from b
to d
on line2
.
An additional constraint is that a path should not include the same line more than once.
I've got the following:
segment(L, S1, S2) :- stop(L, N1, S1), stop(L, N2, S2), N2>N1.
line_present_in_path(_, ) :- false.
line_present_in_path(L, [H|_]) :- segment(L, _, _) = H.
line_present_in_path(L, [_|T]) :- line_present_in_path(L, T).
path(S1, S2, [H]) :- segment(_, S1, S2) = H, H.
path(S1, S2, [H|T]) :- segment(L, S1, X) = H, H, +line_present_in_path(L, T), path(X, S2, T).
but something peculiar happens. If I explicitly specify all the parameters myself, it recognises it as a correct path:
?- path(station1, station4, [segment(line1, station1, station2),segment(line2, station2, station4)]).
true ;
false.
However, if I ask it to calculate all paths, it only finds one path, different to the path it just verified as correct:
?- path(station1, station4, P).
P = [segment(line1, station1, station4)] ;
false.
I must admit I'm new to Prolog so I might be missing something basic. But, I really can't understand why it can verify a given path as correct, but it doesn't find that path when trying to find all paths.
prolog
Modelling the stops of an underground tube line like so:
stop(line1, 1, station1).
stop(line1, 2, station2).
stop(line1, 3, station3).
stop(line1, 4, station4).
stop(line1, 5, station5).
stop(line2, 1, station2).
stop(line2, 2, station4).
where stop(L, N, S)
means S
is the N
'th stop on line L
, I'm trying to define path(S1, S2, P)
that calculates possible paths between S1
and S2
.
Here a path is a list of "segments", a segment being a journey along the same line, i.e. segment(L,S1,S2)
represents the continuous journey from S1
to S2
along line L
. So a possible solution to path(a,d,P)
is P=[segment(line1, a, b), segment(line2, b, d)]
, i.e. go from a
to b
on line1
, then go from b
to d
on line2
.
An additional constraint is that a path should not include the same line more than once.
I've got the following:
segment(L, S1, S2) :- stop(L, N1, S1), stop(L, N2, S2), N2>N1.
line_present_in_path(_, ) :- false.
line_present_in_path(L, [H|_]) :- segment(L, _, _) = H.
line_present_in_path(L, [_|T]) :- line_present_in_path(L, T).
path(S1, S2, [H]) :- segment(_, S1, S2) = H, H.
path(S1, S2, [H|T]) :- segment(L, S1, X) = H, H, +line_present_in_path(L, T), path(X, S2, T).
but something peculiar happens. If I explicitly specify all the parameters myself, it recognises it as a correct path:
?- path(station1, station4, [segment(line1, station1, station2),segment(line2, station2, station4)]).
true ;
false.
However, if I ask it to calculate all paths, it only finds one path, different to the path it just verified as correct:
?- path(station1, station4, P).
P = [segment(line1, station1, station4)] ;
false.
I must admit I'm new to Prolog so I might be missing something basic. But, I really can't understand why it can verify a given path as correct, but it doesn't find that path when trying to find all paths.
prolog
prolog
asked Nov 11 at 6:44
cb7
202
202
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
1
down vote
The bug is in the second clause for the path/3
predicate. Rewriting it for clarity:
path(S1, S2, [segment(L, S1, X)|T]) :-
+ line_present_in_path(L, T),
path(X, S2, T).
With a goal such as path(station1, station4, P)
, you call the line_present_in_path/2
predicate with a variable in the second argument. That call always succeeds and thus its negation always fails. In general, you should be cautious of only using +/1
with a sufficiently instantiated argument.
Hint: to solve the bug, use an additional argument to the path predicate to hold the stations found so far. E.g.
path(S1, S2, Path) :-
path(S1, S2, Path, ).
path(S1, S2, Path, Visited) :-
...
You can use the de facto standard member/2
predicate to check if a station is already in the path and add it to the visited list otherwise. Path finding is a common question and you will find several related answers here in StackOverflow. But try first to solve it on your own.
Thanks for the answer. I understand why mine is failing now but regretfully I've been staring and thinking for hours now and still can't heed your advice. Could you please expand a bit? Should I do away withline_present_in_path
entirely or does your solution complement that?
– cb7
Nov 11 at 20:47
Expanded the answer a bit as you asked.
– Paulo Moura
Nov 12 at 11:49
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
The bug is in the second clause for the path/3
predicate. Rewriting it for clarity:
path(S1, S2, [segment(L, S1, X)|T]) :-
+ line_present_in_path(L, T),
path(X, S2, T).
With a goal such as path(station1, station4, P)
, you call the line_present_in_path/2
predicate with a variable in the second argument. That call always succeeds and thus its negation always fails. In general, you should be cautious of only using +/1
with a sufficiently instantiated argument.
Hint: to solve the bug, use an additional argument to the path predicate to hold the stations found so far. E.g.
path(S1, S2, Path) :-
path(S1, S2, Path, ).
path(S1, S2, Path, Visited) :-
...
You can use the de facto standard member/2
predicate to check if a station is already in the path and add it to the visited list otherwise. Path finding is a common question and you will find several related answers here in StackOverflow. But try first to solve it on your own.
Thanks for the answer. I understand why mine is failing now but regretfully I've been staring and thinking for hours now and still can't heed your advice. Could you please expand a bit? Should I do away withline_present_in_path
entirely or does your solution complement that?
– cb7
Nov 11 at 20:47
Expanded the answer a bit as you asked.
– Paulo Moura
Nov 12 at 11:49
add a comment |
up vote
1
down vote
The bug is in the second clause for the path/3
predicate. Rewriting it for clarity:
path(S1, S2, [segment(L, S1, X)|T]) :-
+ line_present_in_path(L, T),
path(X, S2, T).
With a goal such as path(station1, station4, P)
, you call the line_present_in_path/2
predicate with a variable in the second argument. That call always succeeds and thus its negation always fails. In general, you should be cautious of only using +/1
with a sufficiently instantiated argument.
Hint: to solve the bug, use an additional argument to the path predicate to hold the stations found so far. E.g.
path(S1, S2, Path) :-
path(S1, S2, Path, ).
path(S1, S2, Path, Visited) :-
...
You can use the de facto standard member/2
predicate to check if a station is already in the path and add it to the visited list otherwise. Path finding is a common question and you will find several related answers here in StackOverflow. But try first to solve it on your own.
Thanks for the answer. I understand why mine is failing now but regretfully I've been staring and thinking for hours now and still can't heed your advice. Could you please expand a bit? Should I do away withline_present_in_path
entirely or does your solution complement that?
– cb7
Nov 11 at 20:47
Expanded the answer a bit as you asked.
– Paulo Moura
Nov 12 at 11:49
add a comment |
up vote
1
down vote
up vote
1
down vote
The bug is in the second clause for the path/3
predicate. Rewriting it for clarity:
path(S1, S2, [segment(L, S1, X)|T]) :-
+ line_present_in_path(L, T),
path(X, S2, T).
With a goal such as path(station1, station4, P)
, you call the line_present_in_path/2
predicate with a variable in the second argument. That call always succeeds and thus its negation always fails. In general, you should be cautious of only using +/1
with a sufficiently instantiated argument.
Hint: to solve the bug, use an additional argument to the path predicate to hold the stations found so far. E.g.
path(S1, S2, Path) :-
path(S1, S2, Path, ).
path(S1, S2, Path, Visited) :-
...
You can use the de facto standard member/2
predicate to check if a station is already in the path and add it to the visited list otherwise. Path finding is a common question and you will find several related answers here in StackOverflow. But try first to solve it on your own.
The bug is in the second clause for the path/3
predicate. Rewriting it for clarity:
path(S1, S2, [segment(L, S1, X)|T]) :-
+ line_present_in_path(L, T),
path(X, S2, T).
With a goal such as path(station1, station4, P)
, you call the line_present_in_path/2
predicate with a variable in the second argument. That call always succeeds and thus its negation always fails. In general, you should be cautious of only using +/1
with a sufficiently instantiated argument.
Hint: to solve the bug, use an additional argument to the path predicate to hold the stations found so far. E.g.
path(S1, S2, Path) :-
path(S1, S2, Path, ).
path(S1, S2, Path, Visited) :-
...
You can use the de facto standard member/2
predicate to check if a station is already in the path and add it to the visited list otherwise. Path finding is a common question and you will find several related answers here in StackOverflow. But try first to solve it on your own.
edited Nov 12 at 11:49
answered Nov 11 at 10:12
Paulo Moura
10.8k21325
10.8k21325
Thanks for the answer. I understand why mine is failing now but regretfully I've been staring and thinking for hours now and still can't heed your advice. Could you please expand a bit? Should I do away withline_present_in_path
entirely or does your solution complement that?
– cb7
Nov 11 at 20:47
Expanded the answer a bit as you asked.
– Paulo Moura
Nov 12 at 11:49
add a comment |
Thanks for the answer. I understand why mine is failing now but regretfully I've been staring and thinking for hours now and still can't heed your advice. Could you please expand a bit? Should I do away withline_present_in_path
entirely or does your solution complement that?
– cb7
Nov 11 at 20:47
Expanded the answer a bit as you asked.
– Paulo Moura
Nov 12 at 11:49
Thanks for the answer. I understand why mine is failing now but regretfully I've been staring and thinking for hours now and still can't heed your advice. Could you please expand a bit? Should I do away with
line_present_in_path
entirely or does your solution complement that?– cb7
Nov 11 at 20:47
Thanks for the answer. I understand why mine is failing now but regretfully I've been staring and thinking for hours now and still can't heed your advice. Could you please expand a bit? Should I do away with
line_present_in_path
entirely or does your solution complement that?– cb7
Nov 11 at 20:47
Expanded the answer a bit as you asked.
– Paulo Moura
Nov 12 at 11:49
Expanded the answer a bit as you asked.
– Paulo Moura
Nov 12 at 11:49
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53246463%2fprolog-not-finding-all-solutions%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown