1

I'm interested in implementing a simple Prolog program that performs path finding queries on maze structures.

/* i_ -> intersections  */
i_(c,b). /* horizontal adjacencies */
i_(g,h).
i_(h,i).
i_(i,g).
i_(a,d). /* vertical adjacencies */
i_(d,g).
i_(c,f).
i_(f,i).

/* symmetric interface */
i(X,Y) :- i_(X,Y);i_(Y,X).

/* path, the rule in question*/
path(X,Y) :- i(X,Y) ; i(X,Z), path(Z,Y).

Bug: My Prolog interpreter (SWI) is thrown into a state of infinite recursion when path is used with input nodes >= 5 steps away. However, the rule works fine with fewer than 5 nodes step in path. Curiously,omitting the rule of symmetry (simply declaring each adjacency, backwards and forwards), reduces the call limit of path to fewer than 3 nodes difference. Overriding the default stack allocation again increases the span of path before stack overflow.

Obviously, an accumulator is in order. I suspect that my program crashes at run time because the interpreter continues to revisit nodes already traversed in the path.

I modified path to include an additional requirement of legal, which serves as an accumulator:

/* path --> recursive path check */
legal(Z,[]).
legal(Z,[H|T]):- Z\==H, legal(Z,T). 
path(X,Y,T) :- i(X,Y) ; i(X,Z), legal(Z,T), path(Z,Y,[Z|T]).

However, I'm now facing an issue with the var Z as a 'singleton'.

Any suggestions as to how I can properly implement a accumulator so as to avoid excessive stack calls?

false
  • 10,264
  • 13
  • 101
  • 209
David Shaked
  • 3,171
  • 3
  • 20
  • 31
  • 3
    `path(X,Y) :- closure0(i,X,Y).` See the definition of [`closure0/3`](http://stackoverflow.com/q/26946133). – false Mar 10 '16 at 22:10
  • Using SWI-Prolog, the following error occurred: ?- path(a,b). ERROR: path/2: Undefined procedure: closure0/3 Exception: (7) closure0(i, a, b) ? Unknown option (h for help) Exception: (7) closure0(i, a, b) ? creep – David Shaked Mar 10 '16 at 22:49
  • 2
    @DavidShaked the definition of `closure0/3` is given in the link that false shows. It's not in the SWI library. – lurker Mar 11 '16 at 01:34
  • 1
    Hi, David! I believe we talked about this briefly the other night at the N-Languages meetup. The `Singleton variables` warning is only alerting you to the fact that, in the clause `legal(Z,[]).`, the variable `Z` appears only once. This warning helps catch a lot of bugs caused by typos (where one variable ends up slightly misnamed). Usually, when you don't need a variable again in the same clause, you leave it anonymous: `legal(_,[]).`, then you won't receive that (harmless) warning. – Shon Mar 11 '16 at 04:22
  • 1
    @ShonFeder Not really that harmless, or rather, in this case harmless, but you explain yourself why it should definitely not be ignored. –  Mar 11 '16 at 06:01
  • @ShonFeder Great to hear from you! I put your anon var suggestion to use in place of Z and compiled without a problem. I'll run more tests when I get a chance to ensure the program is behaving as expected. Thanks for the pointer! – David Shaked Mar 12 '16 at 21:54

0 Answers0