5

我正在使用 Prolog 在我的项目中编码一些相当复杂的规则。有很多递归,包括相互递归。部分规则如下所示:

pred1(X) :- ...
pred1(X) :- someguard(X), pred2(X).

pred2(X) :- ...
pred2(X) :- othercondition(X), pred1(X).

pred1和之间有一个相当明显的无限循环pred2。不幸的是,这些谓词之间的交互非常复杂且难以隔离。在这种情况下,我可以通过传递已传递给的对象列表来消除无限循环pred1,但这非常笨拙!事实上,它在很大程度上违背了在这个应用程序中使用 Prolog 的目的。

如何让 Prolog 避免无限循环?例如,如果在证明过程中pred1(foo)试图证明它pred1(foo)是一个子目标,则失败并回溯。

是否可以使用元解释器来做到这一点?

4

2 回答 2

4

是的,正如 mat 建议的那样,您可以为此目的使用元解释器。但是对于正常的用例,这远远超出了常规工作。

您可能会考虑使用高阶谓词将循环功能与实际逻辑分开。这是一种非常安全的方法——SWI 甚至会检查所有用途是否都有相应的定义。此检查要么在键入时调用,make.要么check.

作为一个例子,考虑closure0/3path/4一个都处理循环检查“一次和永远”。

于 2015-11-07T11:56:14.457 回答
3

某些 Prolog 系统中提供的一项可以帮助您解决此类问题的功能称为制表。例如,请参阅相关问题

如果表格不可用,那么是的,元解释器肯定可以在这方面提供很多帮助。例如,您可以使用元解释器更改执行策略等。

在 SWI-Prolog 中,还可以检查call_with_inference_limit/3以稳健地限制执行,与 CPU 类型和系统负载无关。

相关且有用的是终止分析器,如cTI:它们允许您静态导出终止条件

于 2015-11-06T16:02:55.273 回答