处理复杂的序言循环
Dealing with complicated prolog loops
我正在使用 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)
作为一个子目标,失败并回溯。
是否可以用 meta-interpreters 做到这一点?
某些 Prolog 系统中提供的一项功能可以帮助您解决此类问题,称为 制表。例如参见 [=11=].
如果制表不可用,那么是的,元解释器肯定可以提供很多帮助。例如,你可以用元解释器改变执行策略等。
在 SWI-Prolog 中,还检查 call_with_inference_limit/3
以稳健地限制执行,独立于 CPU 类型和系统负载。
相关且有用的是 终止分析器,例如 cTI:它们允许您静态导出 终止条件。
是的,正如 mat 所建议的那样,您可以为此目的使用元解释器。但对于正常用例,这远远超出了常规工作。
您可能会考虑使用高阶谓词将循环功能与您的实际逻辑分开。这是一种非常安全的方式——SWI 甚至会检查所有的使用是否都有相应的定义。输入 make.
或 check.
时会调用此检查
例如,考虑 closure0/3
and path/4
,它都处理循环检查 "once and forever"。
我正在使用 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)
作为一个子目标,失败并回溯。
是否可以用 meta-interpreters 做到这一点?
某些 Prolog 系统中提供的一项功能可以帮助您解决此类问题,称为 制表。例如参见 [=11=].
如果制表不可用,那么是的,元解释器肯定可以提供很多帮助。例如,你可以用元解释器改变执行策略等。
在 SWI-Prolog 中,还检查 call_with_inference_limit/3
以稳健地限制执行,独立于 CPU 类型和系统负载。
相关且有用的是 终止分析器,例如 cTI:它们允许您静态导出 终止条件。
是的,正如 mat 所建议的那样,您可以为此目的使用元解释器。但对于正常用例,这远远超出了常规工作。
您可能会考虑使用高阶谓词将循环功能与您的实际逻辑分开。这是一种非常安全的方式——SWI 甚至会检查所有的使用是否都有相应的定义。输入 make.
或 check.
例如,考虑 closure0/3
and path/4
,它都处理循环检查 "once and forever"。