SWI-Prolog 中的 catch/3 和 call_with_time_limit/2 谓词 [英] catch/3 and call_with_time_limit/2 predicates in SWI-Prolog

查看:44
本文介绍了SWI-Prolog 中的 catch/3 和 call_with_time_limit/2 谓词的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用

catch(:Goal, +Catcher, :Recover)

目标在哪里

call_with_time_limit(+Time, :Goal)

它搞砸了,我找不到正确的方法来知道上述之一何时发生:

It's messed up and I can't find the right way to know when one of the above happened:

1) 目标因超时而停止.

1) Goal stopped because of time out.

2) 目标失败(有时可能会失败).

2) Goal failed (it's suppose to fail sometimes).

我试过了:

(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 秒或更长时间内不起作用 - 它只是忽略超时请求.

That pattern doesn't work for 4 or more seconds - it just ignores the request for timeout.

推荐答案

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

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.

一般来说,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 ),
   ...

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

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

各种系统提供了多种接口.但最基本的问题是你真正想要达到的目标.您想限制实时时间、CPU 时间还是仅限制资源?

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/3library(timeout) 可能是最先进的,它最初是在 1992 年左右为 SICStus Prolog 开发的.在 SWI 和 YAP 中有一些兼容的实现.但是,SWI 和 YAP 无法处理嵌套情况.并且 SWI 不限制 CPU 时间.界面为:

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 是一个相当特殊的 SWI 内置函数,它不符合内置函数的通用约定.此外,它仅将其目标称为 once(Goal_0).我宁愿不要.

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

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<如果您的超时仅与读取数据有关,则/strong> 可能是您的一个选择.

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

这篇关于SWI-Prolog 中的 catch/3 和 call_with_time_limit/2 谓词的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆