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
















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          To learn more, see our tips on writing great answers.




          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







          這個網誌中的熱門文章

          Barbados

          How to read a connectionString WITH PROVIDER in .NET Core?

          Node.js Script on GitHub Pages or Amazon S3