首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Prolog解决一个难题,抛出错误“参数没有充分实例化”

用Prolog解决一个难题,抛出错误“参数没有充分实例化”
EN

Stack Overflow用户
提问于 2016-04-04 15:44:36
回答 2查看 133关注 0票数 1

我试图使用逻辑约束来解决以下问题:

封隔器必须将5个板条箱放在一辆长卡车上。这五个箱子里有鸡、大麦、狐狸、老鼠药和小麦。这些板条箱需要排成长队,两者之间没有任何空隙,以便: 鸡与狐狸分离; ·老鼠药不在大麦旁边; ·老鼠药不在小麦旁边。 找出如何可能有不同的方式安排这些箱子受这些包装限制。

到目前为止,这就是我所拥有的:

代码语言:javascript
复制
:- 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非常陌生,所以任何帮助都将不胜感激。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-04-04 18:10:35

首先,你把Regions限制在1..5上,而不是贴上标签。但你想知道五个箱子的可能位置。因此,限制和标签Crates。请注意,当您将Regions限制为1到5之间的值时,它是一个空闲变量,而列表Regions的长度根本不受限制,因此当您试图标记它时会出现错误。在这个版本中,在谓词位置/1的最后一个目标中,列表Crates已经被限制为固定长度(=5),在标记时限制在1到5之间。

然后你希望鸡和狐狸不在同一个箱子里:Chicken #\= Foxes。但根据任务描述,它们在不同的板条箱里。你更希望它们不在相邻的板条箱里。同样的情况也适用于鼠毒/大麦和鼠毒/小麦。另外,没有两个板条箱处于相同的位置:您可以为此使用all_distinct/1表单库(Clpfd)。把所有这些放在一起,你就会得到这样的结果:

代码语言:javascript
复制
:- 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.

现在尝试查询位置/1:

代码语言:javascript
复制
   ?- position(Crates).
Crates = [1,2,4,5,3] ? ;
Crates = [1,3,4,5,2] ? ;
Crates = [1,4,3,2,5] ?
...

如果您不想以交互方式遍历所有解决方案,可以使用findall/3和length/2来显示所有解决方案并对它们进行计数:

代码语言:javascript
复制
   ?- 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
票数 2
EN

Stack Overflow用户

发布于 2016-04-04 18:57:28

我的模型给出了不同的结果WRT @tas的答案。也许我不完全理解这个短语

鸡和狐狸分开了。

我把它翻译成

代码语言:javascript
复制
abs(Chicken - Foxes) #> 2

总之,完整的模型

代码语言:javascript
复制
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).

收益率

代码语言:javascript
复制
?- aggregate(count,Cs^position(Cs),N).
N = 8.
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36407173

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档