catch/3并在SWI Prolog中使用\u time\u limit/2谓词调用\u

catch/3并在SWI Prolog中使用\u time\u limit/2谓词调用\u,prolog,timeout,swi-prolog,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_e

我想用

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

尝试该模式:

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

你的问题涉及两个不同的部分。首先,如何使用
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时间还是仅限制资源

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

time_out(:Goal_0, +TimeMs, -Result)
call\u with\u time\u limit/3
是SWI的一种非常特殊的内置功能,它不符合内置功能的常见约定。此外,它只将其目标称为
一次(目标0)
。我宁愿不要

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


如果您的超时仅与读取数据有关,则可能是一个选项

首先,感谢您提供了内容丰富的答案。我想限制实时性。当我在0-3秒的超时时间内使用该模式时,它工作得很好,但在4秒或更长时间内它不会停止。我编辑了我的帖子并展示了我使用的模式。有什么建议吗?@Mockingbird:你想在两者之间执行什么样的目标?它是一个运行用C编写的satsolver的谓词。@Mockingbird:所以你有很多选择:进程级别的超时,等等。也许等待输入/3。但绝对不是超时/3,也不是带时间限制的调用/3,也不是带推断限制的调用/3。Pitty没有广泛的超时/3,可能对组合器算法有用。@false-似乎你不小心删除了swi prolog标记。这个问题是专门针对SWI内置的,甚至在标题中提到了SWI。@JSF:事实证明,它不是针对SWI的。也就是说:捕捉不是特定于SWI的,也不是超时。@false:有很多真正通用的序言问题,我不介意您主动删除标记。事实并非如此。超时不是“Prolog语言”的一部分。该问题明确询问了SWI Prolog的call\u和\u time\u limit/2。您是否考虑过SWI专家可能只遵循SWI prolog标签,而您阻止她/他看到和回答问题?@jschimpf:请使用MSO进行观察或讨论。