While @WouterBeek already pinpointed your problems, Wouter's statement
Without running this code you can already observe that the second clause will always fail, since a list of length 2 cannot be unified with a list of length 1
merits some elaboration. For an experienced Prolog programmer it is easy to spot such problems. But what can beginners do? They can apply the following technique: Generalize your program and if the generalized program is still too specialized, there must be an error in the remaining part.
Generalizing a pure Prolog program
There are several ways to generalize a pure Prolog program: Either remove goals, or remove subterms in arguments of the head or a goal. To remove goals, I will add a *
in front of a goal, using:
:- op(950,fy, *).
*_.
path(Node1, Node2, X) :-
* edge(Node1, Node2),
append([Node1], [Node2], X).
path(Node1, Node2, X) :-
* edge(Node1, SomeNode),
append([Node1], [SomeNode], X),
* path(SomeNode, Node2, X),
append([], [Node2], X).
Now we can ask the most general query of this new predicate:
?- path(N1, N2, P).
P = [N1,N2]
; false.
Therefore: Although this definition is now an (over-) generalization, it still admits only paths of length 2. The problem is completely independent of the definition of edge/3
, only the remaining part is responsible. So look at the remaining part to fix the problem!