You should always document you Prolog programs in order that other people (or you, at some later date) can understand what they are meant to do. There aren't rigid guidelines for this but there is a reasonably well established set of conventions, which are as follows:
+(if the argument is instantiated whenever the predicate is called),
-(if the argument is uninstantiated when the predicate is called) or
?(if the argument can be either instantiated or uninstantiated when called).
Consider, for example, the following documentation for
% memberchk(+Element, +Set) % means the same thing, but may only be used to test whether a known % Element occurs in a known Set. In return for this limited use, it % is more efficient when it is applicable. memberchk(Element, [Element|_]) :- !. memberchk(Element, [_|Rest]) :- memberchk(Element, Rest).
Note the use of
% symbols at the start of lines which are
comments. When loading a program, Prolog ignores everything from this
symbol up to the end of the same line. Larger comments can be
both allocated mode
+ because both need to be instantiated for
the predicate to work as intended. Compare this to the definition of
member/2 (below), where either of the two elements may be either
instantiated or uninstantiated, as required, and are therefore given
? as their mode declarations.
% member(?Element, ?Set) % is true when Set is a list, and Element occurs in it. It may be used % to test for an element or to enumerate all the elements by backtracking. % Indeed, it may be used to generate the Set! member(Element, [Element|_]). member(Element, [_|Rest]) :- member(Element, Rest).
One final point about these examples. Notice that an underscore to
represent an anonymous variable is used wherever the name
of a variable is unimportant. How do you know that it is unimportant?
If you see a clause in which a named variable appears only once then
its name doesn't matter since it isn't matching to anything in the
clause. For instance the first clause of
member/2 could have
member(Element, [Element|Rest]).but it isn't important to distinguish
Restwith a special name, so the convention is to use an underscore. Many Prolog systems will generate warning messages when they find ``singleton'' variables, such as
Restin the example above. It is a good idea to get into the habit of using underscores to avoid these warning messages. That way, if you accidentally introduce a singleton variable ( e.g. by mistyping the name of a variable) you will always be able to spot it when you load the file and see the singleton warning message.