处理复杂的prolog循环

时间:2015-11-06 15:52:09

标签: prolog

我正在使用Prolog在我的项目中编码一些相当复杂的规则。有很多递归,包括相互递归。部分规则看起来像这样:

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

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

pred1pred2之间有一个相当明显的无限循环。不幸的是,这些谓词之间的相互作用非常复杂,难以分离。通过传递已经传递给pred1的对象列表,我能够在这个实例中消除无限循环,但这非常笨拙!事实上,它在很大程度上违背了在这个应用程序中使用Prolog的目的。

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

是否可以使用meta-interpreters执行此操作?

2 个答案:

答案 0 :(得分:4)

是的,您可以使用元解释器来实现此目的,如垫子所示。但对于正常使用情况,这远远超出了常规工作。

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

时会调用此检查

作为一个例子,考虑closure0/3path/4,它们都“一次又一次地”处理循环检查。

答案 1 :(得分:3)

某些Prolog系统中可用的一项功能可以帮助您解决此类问题,称为 tabling 。例如,请参阅related question

如果没有表格,那么是的,元解释器肯定可以帮助很多。例如,您可以使用元解释器更改执行策略等。

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

终止分析器cTI相关且也很有用:它们允许您静态派生终止条件