3
votes

I have a Prolog problem here, I am trying to get unique airports into the list but my predicate does not work as expected.

not_member(C, []).
not_member(C, [H|L]) :-
   not_member(C, L),
   C \== H.

path(X, Y, [X,Y]) :-
   flight(X, Y, _, _, _, _).
path(X, Y, [X,P]) :-
   not_member(Z, P), 
   flight(X, Z, _, _, _, _),
   flight(Z, Y, _, _, _, _), 
   path(Z, Y, P).

Sample query with expected answers:

?- path(dublin, rome, L)
L = [dublin, rome] ;
L = [dublin, paris, rome] ...

If you need facts let me know, your help will be appreciated. Thanks!

1
Use dif/2 instead of (\==)/2. dif/2 is a pure predicate that will work as you expect, i.e., also if some of its arguments are not yet instantiated.mat
I assume you mean path(X, Y, [X|P]) not path(X, Y, [X,P])?lurker

1 Answers

1
votes

The problem is not the (\==)/2. The problem is that an uninstantiated P would make not_member/2 loop. So you need a predicate path/4 with four arguments:

:- use_module(library(basic/lists)).
path(_, X, L, _) :- member(X, L), !, fail.
path(X, X, L, [X|L]).
path(Y, X, L, R) :-
   flight(Z, X),
   path(Y, Z, [X|L], R).

The above predicate searches from the destination airport backwards, so that we don't need to reverse the resulting list. Here is an example database:

flight(zurich, frankfurt).
flight(frankfurt, zurich).
flight(zurich, munich).
flight(munich, zurich).
flight(munich, frankfurt).
flight(frankfurt, munich).

And here is an example run:

Jekejeke Prolog 2, Runtime Library 1.2.5
(c) 1985-2017, XLOG Technologies GmbH, Switzerland

?- path(zurich, frankfurt, [], L).
L = [zurich,frankfurt] ;
L = [zurich,munich,frankfurt] ;
No