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.










share|improve this question


























    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.










    share|improve this question
























      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.










      share|improve this question













      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






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 11 at 6:44









      cb7

      202




      202
























          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.






          share|improve this answer























          • 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











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














           

          draft saved


          draft discarded


















          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

























          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.






          share|improve this answer























          • 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















          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.






          share|improve this answer























          • 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













          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.






          share|improve this answer














          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.







          share|improve this answer














          share|improve this answer



          share|improve this answer








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


















          • 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
















          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


















           

          draft saved


          draft discarded



















































           


          draft saved


          draft discarded














          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





















































          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







          Popular posts from this blog

          Xamarin.iOS Cant Deploy on Iphone

          Glorious Revolution

          Dulmage-Mendelsohn matrix decomposition in Python