2013-04-04 62 views
0

我在使用SWI Prolog的新的,现在我试图解决使用Prolog的http://www.allstarpuzzles.com/logic/00335.html上SWI Prolog的琐事冠军逻辑难题

这种逻辑谜题但是,当我试图运行该程序时,程序似乎停止响应和Prolog冻结。看来我在确定每支球队的得分方面存在问题。 这里是我的Prolog代码:

team(dirtydozen). 
team(plough). 
team(barflyers). 
team(threestooges). 
team(friends). 

pub(maid). 
pub(old). 
pub(clown). 
pub(king). 
pub(queen). 

score(75). 
score(74). 
score(73). 
score(72). 
score(71). 
score(70). 
score(69). 
score(68). 
score(67). 
score(66). 
score(65). 
score(64). 
score(63). 
score(62). 
score(61). 
score(60). 


solve :- 
    score(Score1),score(Score2),score(Score3),score(Score4),score(Score5), 
    pub(Pub1),pub(Pub2),pub(Pub3),pub(Pub4),pub(Pub5), 

    Hasil = [[dirtydozen,Pub1,Score1], 
     [plough,Pub2,Score2], 
     [barflyers,Pub3,Score3], 
     [threestooges,Pub4,Score4], 
     [friends,Pub5,Score5]], 
Score1 is Score2 + 6, 
Score1 is Score3 + 9, 
\+ member([threestooges,maid,_],Hasil), 

member([friends,_,A],Hasil), 
member([_,old,B],Hasil), 
member([_,clown,C],Hasil), 
member([_,king,D],Hasil), 
(A-B) is 2*(C-D), 
member([_,queen,E],Hasil), 
member([threestooges,_,F],Hasil), 
F >= E+3. 

回答

1

几乎是正确的。只有四个问题。 ;-) 首先,这里几乎是一个工作版本:

team(dirtydozen). 
team(plough). 
team(barflyers). 
team(threestooges). 
team(friends). 

pub(maid). 
pub(old). 
pub(clown). 
pub(king). 
pub(queen). 

score(75). 
score(74). 
score(73). 
score(72). 
score(71). 
score(70). 
score(69). 
score(68). 
score(67). 
score(66). 
score(65). 
score(64). 
score(63). 
score(62). 
score(61). 
score(60). 

solve(Hasil) :- 
    Hasil = [[dirtydozen,Pub1,Score1], 
     [plough,Pub2,Score2], 
     [barflyers,Pub3,Score3], 
     [threestooges,Pub4,Score4], 
     [friends,Pub5,Score5]], 
    member([friends,_,A],Hasil), 
    member([_,old,B],Hasil), 
    member([_,clown,C],Hasil), 
    member([_,king,D],Hasil), 
    member([_,queen,E],Hasil), 
    member([threestooges,_,F],Hasil), 
    \+ member([threestooges,maid,_],Hasil), 
    score(Score2), 
    Score1 is Score2 + 6, 
    score(Score3), 
    Score1 is Score3 + 9, 
    score(Score1), 
    score(Score4), 
    score(Score5), 
    AB is A-B, 
    AB is 2*(C-D), 
    F >= E+3, 
    pub(Pub1), 
    pub(Pub2), 
    pub(Pub3), 
    pub(Pub4), 
    pub(Pub5). 

差不多,因为它提供了解决方案,并快速,他们按照您的要求是正确的。不过,也有很多,这是因为你没有指定所有的酒吧/团队/成绩必须彼此不同,因此,例如

[[dirtydozen,old,75],[plough,clown,69],[barflyers,queen,66], 
[threestooges,king,75], [friends,old,63]] 

是一个解决方案,虽然“老”和“75”在它两次。如果你正在使用SWI,然后从clp_fd包添加all_different来电或做手工:

A \= B, A \= C, ... B \= C etc. 

现在,关于冻结:这只是因为你的条款的次优排序的。先看看scorepub。在您的solve谓词的前两行中,将这两个变量的每个可能的排列分配给Score[N]Pub[N]变量。尝试计算有多少可能的作业!只有这样你的程序才会继续检查相关的任务是否符合规则。

通过对您的条件进行重新排序,我从一开始就排除了大量的作业。把这些线路,例如:

score(Score1), score(Score2), Score1 is Score2 + 2,... 

这可能评价是这样的:

Score1 = 75, Score2 = 75, 75 is 75+2? 
Score1 = 74, Score2 = 75, 74 is 75+2? 
Score1 = 73, Score2 = 75, 73 is 75+2? 
Score1 = 72, Score2 = 75, 72 is 75+2? 
... 

总而言之,最多必须检查Score1和Score2的225个组合,看看他们是否能得到正确的分配。

现在让我们考虑重新排序的版本:

score(Score2), Score1 is Score2 + 2, score(Score1),... 

评价现在沿着这些线路上运行:

Score2 = 75, Score1 = 77, score(77)? 
Score2 = 74, Score1 = 76, score(76)? 
Score2 = 73, Score1 = 75, score(75)? 

而且我们是下降到只有15个有效的分配。所以规则是:尽量将这些变量修正为彼此,以免让树分散得太多。修复移动目标!

只有两个其他的小问题:1)(A-B) is 2*(C-D)不起作用,因为它指出,在评估2*(C-D)的结果必然导致不能在一个整数,但在形式(A-B)的一个术语。引入一个中间变量来解决。 2)你没有让solve返回任何有用的东西,所以它只说true。不知道这是你想要的。 ;-)

+0

非常感谢解释,现在它终于工作了。 :) – 2013-04-04 15:39:21