In Prolog alone, you would write:
path(X,X).
path(X,Y) :- false, edge(X,Y).
path(X,Y) :- edge(X,Z), path(Z,Y).
or somewhat shorter and more terminating using closure0/3
.
path(X,Y) :-
closure0(edge, X,Y).
In (many definitions of) Datalog as a subset of Prolog, facts like path(X,X).
are not permitted, since they admit an infinite set of solutions.
So you need to restrict that fact to a finite set of nodes. However, since you do not have an explicit definition of nodes, you need to make up one based on the edges you have:
node(X) :-
edge(X,_).
node(Y) :_
edge(_,Y).
which now leads to:
path(X,X) :-
node(X).
path(X,Y) :-
edge(X,Z),
path(Z,Y).