如何在prolog中查询规则?

时间:2014-12-26 19:55:35

标签: prolog

我有以下代码:

word(aa, a, a).
word(ab, a, b).
word(ac, a, c).
word(ad, a, d).

word(bb, b, b).
word(bc, b, c).
word(bd, b, d).


word(cc, c, c).
word(cd, c, d).

word(dd, d, d).
word(dc, d, c).

null(a).

crossword(A, B, C, D) :-
    word(A, AC, AD),
    word(B, BC, BD),

    word(C, AC, BC),
    word(D, AD, BD),
    A \== B,
    B \== C,
    A \== C,
    B \== D,
    C \== D,

    writeln(A-B-C-D),
    null(b).

这是一个prolog代码,用于获取填充2x2单词表的所有可能方法,如下所示:

enter image description here

我想知道如何查询此代码以获取所有答案。我无法弄清楚null(a)null(b)的用途是什么?

1 个答案:

答案 0 :(得分:1)

以下是现有代码的细分。

word(aa, a, a).
...
word(dd, d, c).
word(dc, d, c).

这些定义word个事实似乎列出了有效的“单词”。额外的第二和第三个参数似乎是多余的,因为(a)它们很容易从第一个参数派生,并且(b)它们不会在所示程序中的任何地方使用(从摘录中不清楚是否还有其他部分程序)。同样不清楚为什么列出了cddc,但是没有给出其他“单词”的对称关系。

null(a).

这是一个事实,说“anull”,但鉴于上下文有限,语义不明确。

crossword(A, B, C, D) :-

这是一个谓词crossword/4,它接受​​4个参数。有这些论点的原因尚不清楚(见下文)。

    word(A, AC, AD),
    word(B, BC, BD),

    word(C, AC, BC),
    word(D, AD, BD),

以上4行代码收集了4个字的事实。你可以在使用ACAD等时看到一个依赖关系,它确保一对词是跨越的,而另一对词是你得到的那些词。在董事会上向下阅读相同的单词。

    A \== B,
    B \== C,
    A \== C,
    B \== D,
    C \== D,

以上5行代码确保收集的单词事实之间存在一些差异。同样,语义不清楚,因为它允许AD是同一个单词(考虑到其他约束,可能不是这样)。如果这些不平等测试中的任何一个失败,那么回溯将发生回上面的word/3查询以收集至少一个不同的单词事实,而Prolog将重试不等式检查。

    writeln(A-B-C-D),

这写出了满足所有上述不等式的“单词”的当前四元组。

    null(b).

此测试(查询)将失败的事实null(b),因为null(b)未被建立为事实或可从null(X)的任何给定规则派生。当它失败时,Prolog将再次回溯到通过word/3查询收集另一组单词事实。

word/3查询的所有组合都已用尽时(每个组合都提供了几个单词事实中的一个作为解决方案),整个crossword/4谓词在显示所有可能性后失败并结束与writeln。因此,当您发出查询crossword(A, B, C, D).时,它会依据上面的writeln继续迭代并显示每个可能的解决方案,直到不再存在解决方案并最终失败(意味着,没有更多解决方案)。

正如我在评论中提到的,代码有点奇怪。例如,使用null(b)作为无效事实导致代码通过回溯继续迭代。也许最初的意图是在需要时将事实null(a)更改为null(b)以“关闭迭代”。有点像“迭代标志”。根据给出的信息,这是不确定的。

构建代码的另一种方法是:

crossword(A, B, C, D) :-
    word(A, AC, AD),
    word(B, BC, BD),
    word(C, AC, BC),
    word(D, AD, BD),
    A \== B,
    A \== C,
    B \== C,
    B \== D,
    C \== D.

当使用crossword(A, B, C, D)查询时,Prolog将单独为您提供每个解决方案,直到找不到为止,或者您告诉它停止。您可以使用setof

在列表中一次性收集所有结果
setof(A-B-C-D, crossword(A, B, C, D), Solutions).