使用 Prolog 解决难题,抛出错误 "Arguments are not sufficiently instantiated"

Solving a puzzle with Prolog, throws error "Arguments are not sufficiently instantiated"

我正在尝试使用逻辑约束解决以下问题:

The packer has to place 5 crates onto a long lorry. The 5 crates contain chickens, barley, foxes, rat poison and wheat. The crates need to be arranged in a long line without any gaps between them so that:

• the chickens are separated from the foxes;

• the rat poison is not next to the barley;

• the rat poison is not next to the wheat.

Find out how may different ways there are of arranging these crates subject to these packing constraints.

这是我目前拥有的:

:- use_module(library(clpfd)).

position(Crates) :-
   Crates = [Chicken, Barley, Foxes, RatPoison, Wheat],
   Regions ins 1..5,
   Chicken   #\= Foxes,
   RatPoison #\= Barley,
   RatPoison #\= Wheat,
   labeling([], Regions).

当我尝试 运行 它时,它抛出错误“参数未充分实例化”。

我是 Prolog 的新手,如有任何帮助,我们将不胜感激。

首先,您将 Regions 限制为 1..5,而不是对其进行标记。但是您想知道 5 个板条箱的可能位置。所以限制和标记Crates。请注意,当您将 Regions 限制为 1 到 5 之间的值时,它是一个自由变量,并且列表 Regions 的长度根本不受限制,因此当您尝试标记它时会出现错误。在这个版本中,在谓词 position/1 的最后一个目标中,列表 Crates 已经被限制为固定长度(=5),并且在被标记时限制为 1 到 5 之间的值。

然后你想让鸡和狐狸不在同一个箱子里:Chicken #\= Foxes。但是根据任务描述,它们无论如何都在不同的板条箱中。您更希望它们不在相邻的板条箱中。 ratpoison/barley 和 ratpoison/wheat 也是如此。也没有两个箱子可以在同一个位置:你可以使用 all_distinct/1 form library(clpfd) 来做到这一点。把这些放在一起你会得到类似的东西:

:- use_module(library(clpfd)).

position(Crates) :-
    Crates = [Chicken, Barley, Foxes, RatPoison, Wheat],
    Crates ins 1..5,
    all_distinct(Crates),
    not_adjacent(Chicken,Foxes),
    not_adjacent(RatPoison,Barley),
    not_adjacent(RatPoison,Wheat),
    labeling([], Crates).

not_adjacent(X,Y) :-
    X #\= Y+1,
    Y #\= X+1.

现在尝试查询 position/1:

   ?- position(Crates).
Crates = [1,2,4,5,3] ? ;
Crates = [1,3,4,5,2] ? ;
Crates = [1,4,3,2,5] ?
...

如果您不想以交互方式浏览所有解决方案,您可以使用 findall/3 和 length/2 来显示所有解决方案并计算它们:

   ?- findall(Crates,position(Crates),L),length(L,X).
L = [[1,2,4,5,3],[1,3,4,5,2],[1,4,3,2,5],[1,5,3,2,4],[2,1,4,3,5],[2,1,4,5,3],[2,3,4,1,5],[2,3,4,5,1],[2,3,5,1,4],[2,4,5,1,3],[2,5,4,1,3],[2,5,4,3,1],[3,1,5,4,2],[3,2,5,4,1],[3,4,1,2,5],[3,5,1,2,4],[4,1,2,3,5],[4,1,2,5,3],[4,2,1,5,3],[4,3,1,5,2],[4,3,2,1,5],[4,3,2,5,1],[4,5,2,1,3],[4,5,2,3,1],[5,1,3,4,2],[5,2,3,4,1],[5,3,2,1,4],[5,4,2,1,3]],
X = 28

我的模型给出了不同的结果 WRT @tas 答案。可能我没完全理解这句话

the chickens are separated from the foxes

我翻译的像

abs(Chicken - Foxes) #> 2

无论如何,完整模型

position(Crates) :-
    Crates = [Chicken, Barley, Foxes, RatPoison, Wheat],
    all_different(Crates),
    Crates ins 1..5,
    abs(Chicken - Foxes) #> 2,
    abs(RatPoison - Barley) #> 1,
    abs(RatPoison - Wheat) #> 1,
    label(Crates).

产量

?- aggregate(count,Cs^position(Cs),N).
N = 8.