2

目前我正在做一个 Prolog教程

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

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

它看起来像这样:

在此处输入图像描述

并且给出了一个小的知识库:

   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这么早就停止统一?为什么它不返回任何解决方案?

4

1 回答 1

2

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

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

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,第三个参数是s/0,依此类推。

您想说的是,如果这些词的其他情况属实,那么这六个词构成了一个有效的解决方案:

crossword( H1, H2, H3, V1, V2, V3 ) :-
  <conditions for a successful crossword solution>.

接下来,定义条件,crossword/6以便一个有效的解决方案是一个有效的解决方案,其中变量与word/8谓词的第一个参数统一,如果这些参数的第三个、第五个和第七个参数word/8以正确的方式相互统一。

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

crossword( H1, H2, H3, V1, V2, V3 ) :-
  word( H1, _, TL, _, _, _, TR, _ ),
  word( V1, _, TL, _, _, _, _, _ ),
  word( V3, _, TR, _, _, _, _, _ ).

在这里,我使用下划线_来避免为名称无关紧要的变量命名。我还使用TLandTR表示“左上角”和“右上角”,以使自己的推理更容易。Prolog 看到我们可以证明crossword/6我们是否可以证明存在word/8其参数以特定方式统一的谓词,并搜索word/8这样做的谓词组合。“知识库”为每个可能的证明提供公理。

您现在看到如何完成crossword/6定义了吗?请注意,您需要给出一些下划线变量(称为“匿名变量”)的名称来完成解决方案,并word/8在转弯样式的右侧引入其他术语。

于 2017-03-12T15:39:48.653 回答