Successors is a collection of N elements, describing a directed graph with N nodes (with the nodes numbered 1..N). Each node has a successor, and the i'th element of Successors indicates the successor to node i: Successors[I] = J means that there is an edge from I to J.
The constraint enforces Successors to form a Hamiltonian circuit, i.e. a path through every node, visiting each node once and forming a single circuit.
If only a Hamiltonian path (rather than circuit) is required, add an extra source/sink node and apply the constraint to the extended graph (see example).
This constraint already implies ic:alldifferent(Successors). Depending on the application, it may be advantageous to post a redundant constraint ic_global:alldifferent(Successors) in order to strengthen propagation.
?- circuit([1, 2, 3]). No (0.00s cpu) ?- circuit([2, 3, 1]). Yes (0.00s cpu) ?- circuit([A, B, C]). A = A{[2, 3]} B = B{[1, 3]} C = C{[1, 2]} There are 6 delayed goals. Yes (0.00s cpu) ?- dim(S, [3]), circuit(S), labeling(S). S = [](2, 3, 1) Yes (0.00s cpu, solution 1, maybe more) S = [](3, 1, 2) Yes (0.00s cpu, solution 2) ham_path(Succ, Start) :- array_concat(Succ, [](Start), Succ1), circuit(Succ1). ?- dim(S, [3]), ham_path(S, 1), labeling(S). S = [](2, 3, 4) Yes (0.00s cpu, solution 1, maybe more) S = [](3, 4, 2) Yes (0.00s cpu, solution 2)