next up previous contents index
Next: Tabled Predicate Manipulations Up: Standard Predicates Previous: Execution State   Contents   Index


Exception Handling

abort

Abandons the current execution and returns to the top level. This predicate is normally used in one of the following two cases: Currently, all exception handling routines terminate with a call to predicate abort/0, so an exception encountered at a break level other than the top level will return the interpreter at the top level.

abort/0 does not close any files which may have been opened. If the program under execution is doing file manipulation using see/1 and tell/1, then unexpected behavior may occur after the program is aborted and restarted, unless the user manually closes the files.

Aborting closes all incomplete tables (those which may not have a complete set of answers). Closed tables are unaffected, even if the tables were created during the aborted computation.

abort/0 is implemented by throwing the term '_$abort_ball'/0. Implementations that wish to override the default behavior of abort/0 must call a top-level goal via catch/1 and ensure that '_$abort_ball'/0 is handled.

abort(+Message)

Acts as abort/0 but sents Message to STDERR before aborting.

catch(?Goal,?Catcher,?Handler)


throw(+Handler)

While very simple exceptions can be handled by abort/0, more sophisticated exception handling is performed by using catch/3 and throw/1 together. When catch(Goal,Catcher,Handler) is called, a continuation is saved, and Goal is called. If no exceptions are encountered, answers for Goal are obtained as usual. Within the execution of Goal, an exception can be signalled by a call to throw(Catcher). This predicate searches for an ancestor of the current environment in which a catch was set up whose catcher (second argument) unifies with Catcher. If such an ancestor is found, program execution reverts to the ancestor and all intervening choice points are removed. The ancestor's handler (third argument) is called and the exception is thereby handled. The following, somewhat fanciful example, helps clarify these concepts.

The following predicate userdiv/2 is designed to be called with the first argument instantiated to a number. A second number is then read from a console, and the first number is divided by the second, and unified with the second argument of userdiv/2. By using catch/3 and throw/1 together the various types of errors can be caught.

userdiv(X,Ans):- 
        catch(userdiv1(X,Ans),mydiv1(Y),handlefoo(Y,X)).

userdiv1(X,Ans):- 
        (number(X) -> true; throw(mydiv1(exception1))),
        write('Enter a number: '),read(Y),
        (number(Y) -> true ; throw(mydiv1(exception2(Y)))),
        (Y =;= 0 -> throw(mydiv1(exception3(Y))); true),
        Ans is X/Y.

The behavior of this program on some representative inputs is shown below.

| ?- userdiv(X,Y).
userdiv/1 called with non-numeric numerator: _h76

X = _h76
Y = _h90

yes
| ?- userdiv(3,Y).
Enter a number: foo.
in userdiv/1 a non-numeric denominator was entered: foo

Y = _h84

yes
| ?- userdiv(3,Y).
Enter a number: 0.
in userdiv/1 a denominator of 0 was entered.
Y = _h84

yes
| ?- userdiv(3,Y).
Enter a number: 2.

Y = 1.5000

yes

The actions of catch/3 and throw/1 resemble that of the Prolog cut in that they remove choice points that lie between a call to throw/1 and the matching catch/3 that serves as its ancestor. However, if this process encounters a choice point for an incomplete table, execution is aborted to the top user level.

All exceptions that occur during the execution of an XSB program can be caught. Below is a list of some of the more important exceptions:

'_$abort_ball':
  Thrown when abort/0 is executed.
'_$abort_ball'(Exception):
  Thrown when abort/1 is executed.
error(undefined_predicate(Name,Arity,ModName),ErrorMessage):
  Thrown when an undefined predicate is called.
throw(error(existence_error(module,ExpandedModName),ErrorMessage):
  Thrown when the program attempts to load a module, which cannot be found.


next up previous contents index
Next: Tabled Predicate Manipulations Up: Standard Predicates Previous: Execution State   Contents   Index
Luis Fernando P. de Castro 2003-06-27