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

I want to use

catch(:Goal, +Catcher, :Recover) 

where is the goal

 call_with_time_limit(+Time, :Goal) 

This messed up, and I can't find the right way to find out when one of the following events happened:

1) Target stopped due to timeout.

2) The goal is unsuccessful (sometimes it sometimes fails).

I tried:

 (catch(call_with_time_limit(Time, Goal), Catcher, Recover) -> (ground(Catcher), Catcher = time_limit_exceeded), **TIMEOUT ACTIONS**) ; (**SUCCESS ACTIONS**)) ; **FAILURE ACTIONS** ) 

* EDIT *

template:

I am using the following pattern:

 ((catch(call_with_time_limit(6,goal), Exception, true),(var(Exception);Exception=time_limit_exceeded)) -> (var(Exception) -> writeln(succ) ; writeln(timeout)) ; writeln(fail) ). 

This pattern does not work for 4 or more seconds - it simply ignores the timeout request.

+7
timeout prolog swi-prolog
source share
2 answers

Your question is about two different parts. First, catch/3 can be used to handle this situation. And then the timeout mechanism itself.

Catching bugs and exceptions with catch/3

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

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

However, catching all errors / exceptions often leads to error prone programs because a serious unexpected error can be hidden.

In your particular case, you want to catch only one pattern, like this:

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

Note that testing unconfirmed variables with var(Pat) can be an easy-to-use error source.

Processing Timeouts

Different systems offer several interfaces. But the most fundamental question is what you really want to achieve. Do you want to limit real-time time, processor time, or just resources?

time_out/3 in library(timeout) is probably the most advanced one that was originally developed for SICStus Prolog around 1992. There are several compatible implementations in SWI and YAP. However, SWI and YAP cannot handle nested cases. And SWI does not limit CPU time. Interface:

 time_out(:Goal_0, +TimeMs, -Result) 

call_with_time_limit/3 is a rather peculiar built-in SWI that does not comply with the general conventions for built-in modules. In addition, he only calls his goal once(Goal_0) . I would rather not.

call_with_inference_limit/3 , which is currently only available in recent versions of SWI and uses similar conventions as time_out/3 . This limits the number of pins, not processor time. Thus, it is well suited for detecting programmer cycles, but not suited to your task.

wait_for_input/3 may be an option for you if your timeouts are only related to reading data.

+6
source share

Try the template:

 ( catch(call_with_time_limit(Time,Goal), Error, true) -> ( var(Error) -> % success actions ; % error actions ) ; % failure actions ). 
+3
source share

All Articles