SWI-Prolog中的catch / 3和call_with_time_limit / 2谓词

时间:2014-05-27 23:18:44

标签: prolog timeout swi-prolog

我想用

catch(:Goal, +Catcher, :Recover)

目标是

call_with_time_limit(+Time, :Goal)

它搞砸了,我无法找到正确的方法来了解上述情况之一的发生时间:

1)由于超时,目标停止了。

2)目标失败(有时候会失败)。

我试过了:

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

*编辑*

模式:

我使用以下模式:

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

该模式不会工作4秒或更长时间 - 它只是忽略了超时请求。

2 个答案:

答案 0 :(得分:6)

您的问题涉及两个不同的部分。首先,catch/3如何用于处理这种情况。然后是超时机制本身。

使用catch/3

捕获错误和异常

一般来说,使用catch/3的最常用的方式是这样的:

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

但是,捕获所有错误/异常通常会导致容易出错的程序,因为可能会出现严重的意外错误。

在您的特定情况下,您只想捕获一个模式,因此:

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

请注意,使用var(Pat)测试未实例化的变量可能是一个容易错过的错误来源。

处理超时

各种系统提供了几种接口。但最根本的问题是你真正想要实现的目标。您想限制实时,CPU时间还是资源?

library(timeout)中的

time_out/3 可能是最初在1992年为SICStus Prolog开发的最先进的。在SWI和YAP中有一些兼容的实现。但是,SWI和YAP无法处理嵌套案例。并且SWI不限制CPU时间。界面是:

time_out(:Goal_0, +TimeMs, -Result)

call_with_time_limit/3 是一个相当特殊的SWI内置,它不符合内置插件的常见约定。此外,它仅将其目标称为once(Goal_0)。我不愿意。

call_with_inference_limit/3 目前仅在最新版本的SWI中出现,并使用与time_out/3类似的约定。它限制了推理的数量而不是CPU时间。因此,它非常适合检测程序员的循环,但可能不适合您的任务。

如果您的超时仅与阅读数据相关,

wait_for_input/3可能是您的选择。

答案 1 :(得分:3)

尝试模式:

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