我想用
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秒或更长时间 - 它只是忽略了超时请求。
答案 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
).