Search code examples
prologpredicatecyclic-graph

Write a predicate that works for cyclic graph to check if there exists a path between two nodes using prolog


I am trying to wrote a predicate isway(A, B) which should work for cyclic graphs. The expected outcome I am trying to get is, if there a path exists between 2 nodes or not. example: if I ask isway(a, f), expect it to answer either yes or no. below is my code but it never works and always gives me false as an output.

%given facts

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

edge2(d,a).
edge2(h,f).
edge2(X,Y) :- edge(X,Y).

%my implementation
isway(A,B) :- edge2(A,B,[]).

edge2(A,B,V) :- edge(A,X), not(member(X,V)), (B = X ; edge2(X,B,[A|V])).

%my output
?- isway(b,a). %I expect true for this one
false

?- isway(a,f). %False for this is ok but I am not confident about my logic
false.



Solution

  • You can use tabling for computing the transitive closure of the edge relation:

    edge(a,b).
    edge(a,c).
    edge(b,c).
    edge(c,d).
    edge(c,e).
    edge(d,e).
    edge(f,g).
    edge(g,h).
    
    edge(d,a). % acyclic
    edge(h,f). % acyclic
    
    :- table path/2.
    path(X, Y) :- edge(X, Y).
    path(X, Y) :- path(X, Z), path(Z, Y).
    

    Then, the queries work as you expect:

    ?- path(a, f).
    false.
    
    ?- path(b, a).
    true.