1
votes

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.

2
On windows this should also fail, since you create infinite recursion...Willem Van Onsem

2 Answers

4
votes

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).
4
votes

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.