next up previous contents
Next: Input/Output Facilities Up: Interactive Program Development Previous: Two Variations on

Avoiding Various Kinds of Trouble

There is a problem connected with a missing predicate definition. In SICStus Prolog, the default behaviour is to place you into the tracer. This is roughly what happens:

{Warning: The predicate foo/1 is undefined}

1 1 Fail: foo(_22) ?

Sometimes, however, we simply want to assume that if a call is made to a missing predicate then this is equivalent to not being able to solve the goal and the call therefore fails. This is connected with the closed world assumption which is outlined in chapter 7.

One way in which this can be controlled is to declare that the predicate, say foo/1 is dynamic with the declaration:

?- dynamic foo/1.

This has the effect that, if there are no clauses for a dynamic predicate then the program will quietly fail.

A `missing' predicate can be caused in a number of ways which will now be listed.

One way of dealing with all of these ---even if it is hard to locate the cause--- is to set a system flag to regard every call to an undefined predicate as some sort of error and to invoke the tracer. This is exactly what SICStus does. If you are using some other Prolog system that does not have this default behaviour, it may allow for you to use the following (perhapse even in your prolog.ini file):
 ?- unknown(X,trace).

The call unknown(X,trace) will change the behaviour from whatever the current setting is to `trace' (the only other behaviour is `fail'). To find the current setting without changing it you can use the query unknown(X,X) (SICSTUS can be reset to quietly fail with the command unknown(X,fail)).

Another problem can be caused by misspelling variables. For example, the definition:



probably features a misspelled variable. However, SICStus version 0.6 does not report such a definition. Some other Prolog systems, such as Edinburgh Prolog, provide something akin to:
Warning: singleton variable Animal in procedure mammal/1

Warning: singleton variable Aminal in procedure mammal/1

A singleton variable occurs in a clause if a variable is mentioned once and once only. Such a variable can never contribute a binding to the final result of the computation. Even though there are occasions when this does not matter, a singleton variable is an indication that there might be a misspelling.

Consider the clause member(X,[XY]). This has a legitimate singleton variable, Y. If you need to mention a singleton variable, then you can use the anonymous variable. This is a special symbol for a variable for which you don't want to know any binding made. It is written as an underscore ( _). Consequently, the above clause becomes member(X,[X_]).

(Note that some Prolog systems provide member/2 as a system predicate. For such systems it is probably sensible to change the name of the definition above to my_member/2)

This is fair enough and there will be no warning given when the clause is read in. It is, however, good practice to give meaningful names to variables ---as much for program maintenance as for any other reason. The way round this can be achieved with a variable that begins with an underscore ( _). For example, the above clause could be rewritten as member(X,[X_Tail]). The anonymous variable is also described in section 10.2.

next up previous contents
Next: Input/Output Facilities Up: Interactive Program Development Previous: Two Variations on

Paul Brna
Mon May 24 20:14:48 BST 1999