使用 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.
我正在尝试使用逻辑约束解决以下问题:
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.