与prolog的填字游戏

时间:2017-03-12 14:02:01

标签: prolog crossword

目前我正在做一个Prolog tutorial

有一个练习来解决5个单词的填字游戏。

我的问题是Prolog在很早的时候就停止了我的解决方案的统一。

看起来像是:

enter image description here

并且有一个小知识库:

   word(astante,  a,s,t,a,n,t,e). 
   word(astoria,  a,s,t,o,r,i,a). 
   word(baratto,  b,a,r,a,t,t,o). 
   word(cobalto,  c,o,b,a,l,t,o). 
   word(pistola,  p,i,s,t,o,l,a). 
   word(statale,  s,t,a,t,a,l,e).

要解决该任务,我有一个谓词crossword/6

所以我认为谓词crossword必须包含6个由变量组成的单词,并且在每个字段中,两个单词交叉我在那里设置了相同的变量。

crossword(word(H1, A1, B1, C1, D1, E1, F1, G1),
          word(H2, A2, B2, C2, D2, E2, F2, G2),
          word(H3, A3, B3, C3, D3, E3, F3, G3),
          word(V1, _1, B1, _2, B2, _3, B3, _4),
          word(V2, _5, D1, _6, D2, _7, D3, _8),
          word(V3, _9, F1, _10, F2, _11, F3 _12)).

在SWI-Prolog中,我输入了以下请求:

?- crossword(H1, H2, H3, V1, V2, V3).

所以我要求解决填字游戏。

我得到的结果是这样的:

H1 = word(_720, _722, _724, _726, _728, _730, _732, _734),
H2 = word(_738, _740, _742, _744, _746, _748, _750, _752),
H3 = word(_756, _758, _760, _762, _764, _766, _768, _770),
V1 = word(_774, _776, _724, _780, _742, _784, _760, _788),
V2 = word(_792, _794, _728, _798, _746, _802, _764, _806),
V3 = word(_810, _812, _732, _816, _750, _820, _768).

问题:为什么Prolog在这么早的时候停止统一?为什么不返回任何解决方案?

1 个答案:

答案 0 :(得分:2)

您的代码声明了一个简单的事实:有一个crossword/6谓词,其参数为word/8谓词,word/8谓词的某些参数是相同的。特别是,由于crossword/6被声明为一个简单的事实,word/8声明中的crossword/6谓词与知识库之间没有任何关系(就像“astoria”的事实一样) t约束“astante”的事实。

相反,只有单词本身才是简单的事实:

word(astante,  a,s,t,a,n,t,e).
word(astoria,  a,s,t,o,r,i,a).
word(baratto,  b,a,r,a,t,t,o).
word(cobalto,  c,o,b,a,l,t,o).
word(pistola,  p,i,s,t,o,l,a).
word(statale,  s,t,a,t,a,l,e).

因为这些是没有条件的简单事实,我们总能证明存在word/8谓词,其第一个参数是astante/0,第二个参数是a/0,第三个参数是{{ 1}},等等。

你想说的是,如果这些词的其他方面都是正确的话,这六个词就形成了一个有效的解决方案:

s/0

接下来,定义crossword( H1, H2, H3, V1, V2, V3 ) :- <conditions for a successful crossword solution>. 的条件,以便有效的解决方案是使用crossword/6的第一个参数统一变量的解决方案,以确定那些word/8的第三,第五和第七个参数。 1}}参数以正确的方式相互统一。

对于(不完整)示例,如果H1的第二个字母是V1的第二个字母,而H1的第六个字母是V3的第二个字母,我可以说我有一个有效的跨字解决方案:

word/8

这里我使用下划线crossword( H1, H2, H3, V1, V2, V3 ) :- word( H1, _, TL, _, _, _, TR, _ ), word( V1, _, TL, _, _, _, _, _ ), word( V3, _, TR, _, _, _, _, _ ). 来避免为名称无关紧要的变量赋予名称。我也使用_TL代表“左上角”和“右上角”,让自己的推理更容易。 Prolog认为我们可以证明TR我们是否可以证明有crossword/6谓词的参数以特定方式统一,并搜索word/8谓词的组合。 “知识库”为每种可能的证据提供了公理。

您是否了解如何立即完成word/8定义?请注意,您需要提供一些下划线变量(称为“匿名变量”)名称才能完成解决方案,并在turnstyle的右侧引入其他crossword/6个术语。