catch/3 and call_with_time_limit/2 predicates in SWI-Prolog

吃可爱长大的小学妹 提交于 2019-12-05 03:27:50

Your question concerns two different parts. First, the way how catch/3 can be used to handle such a situation. And then the timeout mechanism itself.

Catching errors and exceptions with catch/3

Generally speaking, the most idiomatic way to use catch/3 is like so:

   ...,
   catch((R = success, Goal), Pat, R = error(Pat)),
   ...

However, catching all errors/exceptions leads often to error-prone programs since a serious, unexpected error might be masked out.

In your particular case you want to catch a single pattern only, thus:

   ...,
   catch((R = success, call_with_time_limit(Time,Goal)),
          time_limit_exceeded,
          R = timeout ),
   ...

Please note that testing for uninstantiated variables using var(Pat) might be an easy-to-miss source of errors.

Handling timeouts

There are several interfaces offered in various systems. But the most fundamental question is what you actually want to achieve. Do you want to limit realtime, CPU time, or just resources?

time_out/3 in library(timeout) is probably the most advanced which was originally developed for SICStus Prolog about 1992. There are somewhat compatible implementations in SWI and YAP. However, SWI and YAP cannot handle nested cases. And SWI does not limit CPU-time. The interface is:

time_out(:Goal_0, +TimeMs, -Result)

call_with_time_limit/3 is a rather idiosyncratic built-in of SWI which does not conform to the common conventions for built-ins. Also, it calls its goal as once(Goal_0) only. I'd rather not.

call_with_inference_limit/3 this is currently present only in recent versions of SWI and uses similar conventions as time_out/3. It limits the number of inferences rather than CPU-time. It is thus well suited to detect programmer's loops but might not be suited for your task.

wait_for_input/3 might be an option for you should your timeouts be only related to reading data.

Try the pattern:

(   catch(call_with_time_limit(Time,Goal), Error, true) ->
    (   var(Error) ->
        % success actions
    ;   % error actions
    )
;   % failure actions
).
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!