# Handling Cycles with Tabling

By adding `arc(k, e).` we alter the previous example in TransitiveClosures to this:

Unless guarded against, this will cause `tc(a, X).` to never escape looping between *k* and *e*. Thanks to a relatively recent addition to SWI Prolog Tabled execution, all that's needed to avoid this is adding one line of code `:- table tc/2.` to that previously shown in TransitiveClosures.

:- table tc/2. arc(a, b). arc(a, c). arc(a, d). arc(b, e). arc(b, f). arc(c, g). arc(c, h). arc(c, i). arc(d, j). arc(e, k). arc(f, l). arc(f, m). arc(h, n). arc(i, o). arc(i, p). arc(j, q). arc(j, r). arc(j, s). arc(k, e). arc(m, t). tc(X, Y) :- arc(X, Y). tc(X, Z) :- arc(X, Y), tc(Y, Z).

Tabling changes the order of traversal returned by `tc(a, X)`to this:

X = h X = e X = q X = j X = l X = f X = o X = c X = i X = r X = b X = t X = g X = n X = s X = d X = m X = k X = p

Those familiar with transitive closures, but not Prolog, tend to wonder why we don't just have our *arc* facts and one rule:

arc(X, Z) :- arc(X, Y), arc(Y, Z).

Tabling allows us to rewrite our code as follows to dispense with *tc* rules:

:- table arc/2. arc(a, b). arc(a, c). arc(a, d). arc(b, e). arc(b, f). arc(c, g). arc(c, h). arc(c, i). arc(d, j). arc(e, k). arc(f, l). arc(f, m). arc(h, n). arc(i, o). arc(i, p). arc(j, q). arc(j, r). arc(j, s). arc(k, e). arc(m, t). arc(X, Z) :- arc(X, Y), arc(Y, Z).

Transitive closures with tabling are great assuming we aren't dealing with *dynamic* data, as for instance in PuzzleSolving when the graph has to be built from a starting point with provided rules, so arcs can't simply be looked up for PathFinding. In BreadthDepthFirst we'll look at how to *listify* graphs and then traverse them breadth or depth first.