I want to detect a cycle in an nondirected graph and return true or false. My node is a pair of (X, Y) coordinates on a table.
I have a game which plays on a tic-tac-toe grid. The predicate quantum(pos(X, Y), pos(Z, T), Color) resembles a piece on my grid. It can be put on two cells on my 3x3 table. I can have two quantum positions from different pieces into the same cell, and sometimes they can form a cycle and I want to detect it.
Since my nodes are cells (tuple of X, Y coordinates), my quantum piece acts like an edge between two nodes. I thought of getting all my quantum pieces from the state and form a list (DirectedEdges) of pairs of cells, made by the first findall. My graph is nondirected, so I made ReverseEdges and combined them both to get my list of nondirected edges.
My cycle function doesn't work on my nondirected graph and I don't get it why. I don't think I needed to add that much context to ask my question.
The parameters of cycle are: Node is the starting point (the first parameter), Next iterates through the Graph (the second parameter), Visited is the list of visited nodes (third parameter) and Edges is the list which contains all the edges of my Graph (forth parameter).
EDIT: State is a list of pieces on my board, it can have more pieces or less pieces.
State = [quantum(pos(1, 1), pos(3, 1), white), quantum(pos(1, 2), pos(3, 2), black), quantum(pos(1, 1), pos(3, 2), white)]
State = [quantum(pos(1, 1), pos(3, 1), white), quantum(pos(1, 2), pos(3, 2), black), quantum(pos(1, 1), pos(3, 2), white), quantum(pos(1, 2), pos(3, 1), black)].
For the first State I want has_cycle(State) to return false, because it doesn't have a cycle, and true for the second State. The color does not interfere with the cycle.
cycle(Node, Node, _, _) :- !, true.
cycle(_, Node, Visited, _) :- member(Node, Visited), !, fail.
cycle(Node, Next, Visited, Edges) :- member((Next, NextNext), Edges), cycle(Node, NextNext, [Next|Visited], Edges).
has_cycle(State) :-
findall((pos(X, Y), pos(Z, T)), member(quantum(pos(X, Y), pos(Z, T), _), State), DirectedEdges),
findall((pos(X, Y), pos(Z, T)), member((pos(Z, T), pos(X, Y)), DirectedEdges), ReverseEdges),
append(DirectedEdges, ReverseEdges, Edges),
member((Node, Next), Edges),
cycle(Node, Next, [Next], Edges).