Search code examples
prologtransitive-closurefailure-slice

In prolog, why doesn't adding "edge(X, Y) :- edge(Y, X)." alone work for converting a directed graph definition to an undirected graph


I'm just learning Prolog, and I'm reviewing lecture notes and all the notes say is that:

given the following definition for directed graphs:

path(X, Y) :- edge(X, Y).
path(X, Y) :- edge(X, Z), path(Z, Y).

If we wanted to make this an undirected graph, defining edge(X, Y) :- edge(Y, X). alone doesn't work, and I can't figure out why. X to Y has an edge if Y to X has an edge. Seems to make sense to me.

The notes don't really clarify why not, but it does define that the proper solution would be:

edge1(X, Y) :- edge(X, Y).
edge1(X, Y) :- edge(Y, X). 

to what we already had.

Can anyone explain this to me, please and thanks? <3


Solution

  • Because rules don't work the same as facts, and you are spiraling off into an infinite loop if you use the same predicate.

    Let's take the example ?-edge(5,2). We will end up calling --

    edge(5,2) :- edge(2,5).
    

    Ok, what happens when we call edge(2,5)?

    edge(2,5) :- edge(5,2).
    

    ... Uh oh. Logic circle.

    When using edge1, you are simply creating a wrapper for your predicate to escape the recursive definition.