'Why does SWI-Prolog fail when mentioning a predicate without any facts in a rule?

Here is my Prolog program:

:- set_prolog_flag(verbose, silent).
:- initialization(main).

:- use_module(library(tabling)).

:- table reachable/1.

reachable(X) :- start(X).
reachable(X) :- reachable(Y), link(Y, X).

start(london).

% link(london, paris).
% link(paris, london).
% link(london, frankfurt).
% link(paris, frankfurt).
% link(frankfurt, paris).

main :-
  forall(reachable(X), writeln(X)),
  halt.
main :-
  halt(1).

Running it gives this error:

swipl links.pl
Initialization goal raised exception:
ERROR: 'reachable tabled'/1: Undefined procedure: link/2

However this works:

:- set_prolog_flag(verbose, silent).
:- initialization(main).

:- use_module(library(tabling)).

:- table reachable/1.

reachable(X) :- start(X).
reachable(X) :- reachable(Y), link(Y, X).

start(london).

link(tokyo, hongkong).

main :-
  forall(reachable(X), writeln(X)),
  halt.
main :-
  halt(1).
swipl links.pl
london

How can I make my program work with and without and link facts?


swipl --version
SWI-Prolog version 7.6.4 for amd64


Solution 1:[1]

If you intend to dynamically add the facts to the database later (for example via assertz/2 or asserta/2) you should use the directive dynamic/1:

:-dynamic link/2.

This prevents bugs in your program due to typos.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1