Question

I have a prolog program:

link(liverpool,preston).
link(liverpool,manchester).
link(preston,lancaster).
link(preston,manchester).
link(lancaster,carlisle).
link(lancaster,leeds).
link(carlisle,leeds).
link(manchester,leeds).

%checks to see if X is in the supplied list
inlist( X, [X|_]).
inlist( X, [_|Ys]) :- inlist( X, Ys).


merge([],L,L).

merge([H|T],BList,CList):-
inlist(H,BList),
merge(T,BList,CList).

merge([H|T],BList,[H|CList]):-
merge(T,BList,CList),
not(inlist(H,BList)).

Merge works if I call it like this:

merge([a,b,c],[d,e,f],Result). --> [a,b,c,d,e,f]

or more importantly, what it was designed to solve:

merge([a,b,c],[a,d,e,f],Result). --> [a,b,c,d,e,f]

but if I call merge like this:

merge(X,[d,e,f],[a,b,c,d,e,f]).

There is a stack overflow. Is this generally acceptable behavior for a function that is designed to work one way? Or is there some convention that functions should work in both ways?

Edit: merge works if you call it like this:

merge([a,b,c],X,[a,b,c,d,e,f]). --> [d,e,f]

Was it helpful?

Solution

First, you should not call these "functions". "Predicates" is the correct term.

It's generally desirable for Prolog predicates to work "both ways". But it's not always possible or worth the effort in a particular situation.

To inform about ways a predicate is intended to be used mode-declarations can be used. These declarations conventions are different from system to system. These declarations are mostly serve as a documentation for programmers and rarely used by compilers, but can be used by testing frameworks and other helper tools.

Examples of conventions for mode declarations:

Also there is a convention (described in "The Craft of Prolog", for example) that input parameters of a predicate come first, output parameters come last.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top