Jere
Jere

Reputation: 1266

Prolog: Redirect system output

There are Prolog predicates that output error messages, like load_files/1 in case the file could not be found:

error(existence_error(source_sink,'/home/foo/nothinghere.txt'),_3724).

These error messages are just printed to stdout but are not returned as prolog return value.

In my case, load_files/1 gets called deep down as part of a procedure that I don't want to modify. I just deliver the file name and wait for the return value. But as far as I understand, the return value, in this case, is either True or an error. Is there any way for me to redirect the error output to the return value so that I can actually do something with the output I am getting?

Upvotes: 1

Views: 121

Answers (1)

rajashekar
rajashekar

Reputation: 3753

You could use catch/3.

?- catch(load_files('/tmp/exists.prolog'), E, true).
true.

?- catch(load_files('/tmp/notexists.prolog'), E, true).
E = error(existence_error(source_sink, '/tmp/notexists.prolog'), _).

catch(:Goal, +Catcher, :Recover) is used for catching throw(_) from the :Goal.

  1. Catcher is unified with the argument of throw/1.
  2. Recover is called using call/1.

In the above example E unifies with any error. We do not want that, so we can do something like:

catchFileErrors(G, F) :-
    catch(G, error(existence_error(source_sink, F), _), true).
?- catchFileErrors(load_files('exists.prolog'), E).
true.

?- catchFileErrors(load_files('notexists.prolog'), E).
E = 'notexists.prolog'.

You can pass a goal as the last argument to catch if you have a strategy to recover from the error.

Upvotes: 2

Related Questions