This is a simplified version of a problem I’m working on. There exists a solution without tabling, but it would be more elegant if I could use tabling instead.
Here’s a modified version of the code in Example 2: avoiding non-termination that also returns the path between two points [Note: the original post was missing one clause; I’ve edited this to including the missing code]:
:- table connection/3. connection(X, Y, Path) :- connection(X, Z, Path1), connection(Z, Y, Path2), append(Path1, Path2, Path). connection(X, Y, [X->Y]) :- % <=== This clause was missing connection(X, Y, [X->Y]) :- connection(Y, X). connection('Amsterdam', 'Schiphol'). connection('Amsterdam', 'Haarlem'). connection('Schiphol', 'Leiden'). connection('Haarlem', 'Leiden'). print_connection_3 :- forall(connection(X,Y,Path), writeln(X->Y:Path)).
This code goes into an infinite loop because of the third argument (interestingly, it doesn’t run out of stack).
lattice option to the
table directive doesn’t do what I want because that only returns one result, for example a minimal path.
So, two questions:
Is there a way to mark the 3rd argument as “don’t table this”? (I think the answer is “no”, from a conversation I had a few years ago with David S. Warren.)
If I use the
connection/2 code in the example (no 3rd argument collecting the path), is there a way to read the tries for the table, to construct all the paths? I wrote this code to dump the trie, but I don’t know how to interpret it:
print_connection_2 :- forall(connection(X,Y), writeln(X->Y)). print_trie :- forall(current_table(Varient, Trie), ( setof(K-V, trie_gen(Trie, K, V), KVs), format('~q: ~q~n', [Varient,KVs]) )). ?- print_connection_2. ?- print_trie.