Ι need to write each element once, for example, Belgium borders France, and it should automatically imply that France borders Belgium.
Unfortunately, the statement borders(X, Y) :- borders(Y, X).
falls into an infinite loop.
% Knowledge
borders('Belgium', 'France').
borders('Belgium', 'Germany').
borders('Belgium', 'Luxembourg').
borders('Belgium', 'Netherlands').
borders('Denmark', 'Germany').
borders('France', 'Germany').
borders('France', 'Luxembourg').
borders('Germany', 'Luxembourg').
borders('Germany', 'Netherlands').
% Rule
borders(X, Y) :- borders(Y, X).
It shows me all of the following
? - borders('France', X).
X = 'Germany' ;
X = 'Luxembourg' ;
X = 'Belgium' ;
X = 'Germany' ;
X = 'Luxembourg' ;
X = 'Belgium' ;
X = 'Germany' ;
X = 'Luxembourg' ;
X = 'Belgium' ;
X = 'Germany' ;
X = 'Luxembourg' ;
X = 'Belgium' ;
X = 'Germany' .
while it should stop at borders
? - ('France', X).
X = 'Germany' ;
X = 'Luxembourg' ;
X = 'Belgium'
To avoid the infinite loop, due to the recursive definition, use distinct predicate names for rules and facts (for example, borders
and border
):
borders(X, Y) :- border(X, Y).
borders(X, Y) :- border(Y, X).
border('Belgium', 'France').
border('Belgium', 'Germany').
border('Belgium', 'Luxembourg').
border('Belgium', 'Netherlands').
border('Denmark', 'Germany').
border('France', 'Germany').
border('France', 'Luxembourg').
border('Germany', 'Luxembourg').
border('Germany', 'Netherlands').
Example:
?- borders('France', X).
X = 'Germany' ;
X = 'Luxembourg' ;
X = 'Belgium'.
EDIT
The computation performed to answer a query can be represented as a tree. Prolog searches this tree using depth-first search, automatically backtracking when it encounters a failure node (or when the user presses the key ';' to get an alternate answer). During the search, clauses are used in the order they appear in the program. At the end of the search, Prolog displays false
only if the last node visited in the tree is a failure node. So, to understand why Prolog behaves differently for different queries, you can compare the search trees that it explores in each of them:
borders/2
produce solutions:borders/2
produces a solution:borders/2
produces solutions: