首页 > 解决方案 > 为什么我需要运行 clpfd:label/1 才能终止我的查询?

问题描述

这是一个序言会话:

?- use_module(library(clpfd)).
true.

?- Large #>= Small, Small #> 0, length([1, 2], Large).
Large = 2,
Small in 1..2.

?- Large #>= Small, Small #> 0, length([1, 2], Large), length(List, Small).
Large = 2,
Small = 1,
List = [_5770] ;
Large = Small, Small = 2,
List = [_5770, _5776] ;
^CAction (h for help) ? abort
% Execution Aborted
?- Large #>= Small, Small #> 0, length([1, 2], Large), label([Small]), length(List, Small).
Large = 2,
Small = 1,
List = [_4464] ;
Large = Small, Small = 2,
List = [_4478, _4484].

?-

第一个查询工作得很好。一旦枚举了所有解决方案,第二个查询就会永远循环。第三个查询有效,但我不知道为什么。

这就是 clpfd 的工作方式吗,我总是需要在尝试使用约束变量之前调用 label ?

标签: prologclpfd

解决方案


从某种意义上说,这是因为您使用“太少”的 clpfd:在当前的 Prolog 系统中,length/2没有考虑未决约束!

我把它作为一个挑战来实现它的变体length/2。但理想情况下,它也应该与 CLP(B)、CLP(Q) 等一起使用!一般来说,使求解器与此类谓词合作的方法尚不清楚。


推荐阅读