Prolog:从DCG生成查询

时间:2016-04-17 07:17:36

标签: prolog call dcg

我目前有一个小的Prolog数据库,其中包含一些人和一些关系的谓词。例如:

female(anna).
female(susan).

male(john).
male(timmy).

siblings(anna, susan).
siblings(anna, john).
siblings(susan, john).

sibling(X, Y) :- siblings(X, Y) ; siblings(Y, X).

%X is brother of Y
brother(X, Y) :- male(X), sibling(X, Y).

我有一个可以确定有效问题的DCG “谁是约翰的兄弟”,这也很有效。

question --> ip, verb, article, noun, pronoun, name.

现在我希望我的程序用名词和名字来调用我的家庭数据库,如下所示:

noun(X, name).

在示例中应该是

brother(X, anna).

然后将答案作为自然语言答案返回,如:

"the brother of anna is john"

为答案句定义语法也没问题。我唯一不知道的是,如何从我的DCG拨打我的数据库,并获得正确的值。我现在环顾了一段时间 - 也许我不知道正确的搜索条件 - 并且无法找到与此相关的内容。

我希望你们有一些好主意! :)

谢谢。

1 个答案:

答案 0 :(得分:3)

从DCG调用Prolog谓词

常规方式:使用{}/1

使用非终结{}//1从DCG中调用任意Prolog目标。

例如:

verb --> [V], { verb(V) }.

这定义了一个非终结verb//1。此DCG描述了一个由V元素组成的列表,其中verb(V)成立,其中verb/1是正常的Prolog谓词。

从某种意义上说,更为规律:始终使用DCG!

请注意,还有第二种方法可以做到这一点,从某种意义上来说,更容易理解:您只需将所有内容转换为DCG非终结者即可!

例如,您可以说:

female(anna)  --> [].
female(susan) --> [].
male(john)    --> [].
male(timmy)   --> [].

然后您可以直接使用这些非终结符。您可以定义term_expansion/2规则,自动执行此类转换

在您的具体情况下,使用{}/1可能更可取,因为您已经拥有Prolog事实和。但肯定有一些情况下,最好使用DCG。

编辑:从您的评论中,我发现您的问题更为复杂。

问题在于:

从句子构建Prolog目标

这非常简单:基本上,您只需要描述您想要的Prolog目标与相应句子之间的关系

我们通过向DCG引入一个新参数来实现这一点,并且该参数将表示需要执行以回答该句子的Prolog目标。在你的例子中,你想把句子“谁是苏珊的兄弟?”与Prolog谓词brother(X, susan)的调用联系起来。您已经有一个描述此类句子的非终结sentence//0。你只需要明确这些句子对应的目标。例如:

sentence_goal(noun(X, name)) --> ip, v, a, noun, p, name.

这仅用于说明原则;我并没有声称这已经是完整的解决方案了。关键在于表明你可以用与所有其他术语完全相同的方式推理Prolog目标。

然后,您可以分两个阶段调用实际目标:

  1. 首先,使用这个新的非终结sentence_goal//1
  2. 将给定的句子与目标联系起来
  3. 只需使用call/1调用目标或直接调用目标。
  4. 例如:

    ?- phrase(sentence_goal(Goal), Sentence), Goal.
    

    在您的情况下,剩下的就是将这些句子与您想要调用的Prolog目标相关联,例如brother_of/2等。

    这些都不需要任何副作用(write/1)!相反,集中精力描述句子和目标之间的关系,让Prolog toplevel为你做印刷。