1

I have a very simple program in swipl

edge(X,Y) :- edge(X,Z),edge(Z,Y).
edge(a,b).
edge(a,f).
edge(b,c).
edge(c,d).
edge(g,c).
edge(f,g).
edge(f,c).
edge(f,e).
edge(c,e).
edge(e,d).

But when Ι make a query edge(a,c). Ι get a Out of local stack exception. The strange thing is that when I do the same query in windows the program works perfectly.

I tried to increase the local stack but simply the program takes longer to throw the exception.

false
  • 10,264
  • 13
  • 101
  • 209

2 Answers2

4

Your predicate defines a lovely infinite loop. It just sits there and calls itself and never even tries the facts since the predicate is first and is named the same as the facts.

What will help is: (1) assert the facts before the predicate, (2) don't define your predicate with the same name as the facts (technically, it doesn't mean the same thing so why should it have the same name?), and (3) in the recursive clause, check a pre-defined edge before the recursive call.

edge(a,b).
edge(a,f).
edge(b,c).
edge(c,d).
edge(g,c).
edge(f,g).
edge(f,c).
edge(f,e).
edge(c,e).
edge(e,d).

connected(X, Y) :-
    edge(X, Y).
connected(X, Y) :-
    edge(X, Z), connected(Z, Y).
lurker
  • 56,987
  • 9
  • 69
  • 103
  • Thanks, it works. But do you know why windows does not crash? – Geovany Gameros Mar 22 '17 at 19:28
  • @GeovanyGameros can you explain what you mean by "windows" not "crashing"? Are you saying that when you run your code in Windows, you don't get a stack overflow? And if you don't, what actually happens? The issue here is that the code goes into an infinite recursion. It's possible that, in Windows, it results in some other error condition before it sees the stack overflow and reports it as such. – lurker Mar 22 '17 at 19:45
  • I mean in Windows the code don't get a stack overflow. When i run my code i get "true". May be i got another swi-prolog version – Geovany Gameros Mar 22 '17 at 23:09
  • @GeovanyGameros are you sure you're running exactly the same code? Regardless, the answer I've provided is the solution to your original question. Why Windows gives a different result is a different question. :) – lurker Mar 23 '17 at 00:00
4

To actually see what is the problem consider the following :

edge(X,Y) :- edge(X,Z), false, edge(Z,Y).
edge(a,b) :- false.
edge(a,f) :- false.
edge(b,c) :- false.
edge(c,d) :- false.
edge(g,c) :- false.
edge(f,g) :- false.
edge(f,c) :- false.
edge(f,e) :- false.
edge(c,e) :- false.
edge(e,d) :- false.

If this fragment of your program does not terminate, then also your original program does not terminate. Look at what remained! A single recursion, where the arguments are either ignored (Y) or passed around (X). Thus, there is no way whatsoever that this program terminates. In other words: Your program terminates never.

false
  • 10,264
  • 13
  • 101
  • 209