prolog - 使用 clpfd 时,问题空间很小,超出了 SWI-Prolog 堆栈限制

标签 prolog swi-prolog clpfd

我尝试展示此行为的一个最小示例。这是我加载的代码:

:- use_module(library(clpfd)).

gcd(A, 0, A) :- !.
gcd(0, B, B) :- !.
gcd(A, B, C) :- A #> B, !, A1 #= A mod B, gcd(A1, B, C).
gcd(A, B, C) :- A #=< B, A1 #= B mod A, gcd(A1, A, C).

ncalc(N, X, Y) :-
    Y #=< N,
    X*X #= (Y),
    X #< Y,
    X #> 0,
    gcd(X, Y, 1).

查询ncalc(9, X, Y)。我得到:

ERROR: Stack limit (1.0Gb) exceeded
ERROR:   Stack sizes: local: 1Kb, global: 0.7Gb, trail: 9Kb
ERROR:   Stack depth: 1,548,057, last-call: 100%, Choice points: 5
ERROR:   In:
ERROR:     [1,548,057] clpfd:pop_queue(_176712142, <compound fast_slow/2>, 1)
ERROR:     [1,548,056] clpfd:pop_queue(_176712170)
ERROR:     [1,548,055] clpfd:fetch_propagator(_176712188)
ERROR:     [1,548,054] clpfd:do_queue
ERROR:     [1,548,052] clpfd:parse_clpfd('<garbage_collected>', _176712222)
ERROR:
ERROR: Use the --stack_limit=size[KMG] command line option or
ERROR: ?- set_prolog_flag(stack_limit, 2_147_483_648). to double the limit.

查询ncalc(8, X, Y)。立即返回false。。也通过 ncalc(9, 8, Y). 查询 ncalc(9, 1, Y).(X 的所有可能的有效范围)。为什么它只适用于更简单的情况?有解决方法吗?谢谢!

PS:我是序言新手,我计划做的事情更复杂,但知道解决方法后我可能可以调整解决方案。

最佳答案

(让我们忽略编程风格,请参阅@Capelli 的评论。)

未终止的实际原因是 SWI 的 CLP(FD) 系统存在缺陷。这是真正的罪魁祸首:

?- X in 2..3, Y in 4..9, Y mod X#=X1.
X in 2..3,
Y mod X#=X1,
Y in 4..9.

因此系统无法推断出 X1 的任何有用信息。 。将此与 SICStus 进行对比:

| ?- X in 2..3, Y in 4..9, Y mod X#=X1.
Y mod X#=X1,
X in 2..3,
Y in 4..9,
X1 in 0..2 

这里 SICStus 推断 X1必须在 0..2 范围内因此不是负面的。这反过来又避免了下一个推理中出现问题的循环。

您可以通过坚持非负数来帮助系统,因此模块总是小于操作数。

A1 #>= 0, A1 #=< B, A1 #=< A

同时修复于CLP(Z) .

关于prolog - 使用 clpfd 时,问题空间很小,超出了 SWI-Prolog 堆栈限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57336666/

相关文章:

Prolog 删除功能 - 几乎可以工作

Prolog:单引号和双引号的不同行为

list - 如何在Prolog中查找嵌套列表中的最大元素?

stream - Prolog中的字符串流?

list - 如何在序言中找到列表的模式?

multithreading - 具有流输出的 SWI-Prolog 线程

procedure - 序言 : Making a procedure to print Hello World

dynamic - 谓词 `contracting/1` 是否恢复已删除的不一致值?

prolog - 使用 clpfd Prolog 库解决斑马拼图(又名爱因斯坦拼图)

prolog - 你如何检查 Prolog 中子矩阵的元素