我目前有一个小的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拨打我的数据库,并获得正确的值。我现在环顾了一段时间 - 也许我不知道正确的搜索条件 - 并且无法找到与此相关的内容。
我希望你们有一些好主意! :)
谢谢。
答案 0 :(得分:3)
{}/1
使用非终结{}//1
从DCG中调用任意Prolog目标。
例如:
verb --> [V], { verb(V) }.
这定义了一个非终结verb//1
。此DCG描述了一个由V
元素组成的列表,其中verb(V)
成立,其中verb/1
是正常的Prolog谓词。
请注意,还有第二种方法可以做到这一点,从某种意义上来说,更容易理解:您只需将所有内容转换为DCG非终结者即可!
例如,您可以说:
female(anna) --> [].
female(susan) --> [].
male(john) --> [].
male(timmy) --> [].
然后您可以直接使用这些非终结符。您可以定义term_expansion/2
规则,自动执行此类转换 。
在您的具体情况下,使用{}/1
可能更可取,因为您已经拥有Prolog事实和。但肯定有一些情况下,最好使用DCG。
编辑:从您的评论中,我发现您的问题更为复杂。
问题在于:
这非常简单:基本上,您只需要描述您想要的Prolog目标与相应句子之间的关系。
我们通过向DCG引入一个新参数来实现这一点,并且该参数将表示需要执行以回答该句子的Prolog目标。在你的例子中,你想把句子“谁是苏珊的兄弟?”与Prolog谓词brother(X, susan)
的调用联系起来。您已经有一个描述此类句子的非终结sentence//0
。你只需要明确这些句子对应的目标。例如:
sentence_goal(noun(X, name)) --> ip, v, a, noun, p, name.
这仅用于说明原则;我并没有声称这已经是完整的解决方案了。关键在于表明你可以用与所有其他术语完全相同的方式推理Prolog目标。
然后,您可以分两个阶段调用实际目标:
sentence_goal//1
call/1
调用目标或直接调用目标。例如:
?- phrase(sentence_goal(Goal), Sentence), Goal.
在您的情况下,剩下的就是将这些句子与您想要调用的Prolog目标相关联,例如brother_of/2
等。
这些都不需要任何副作用(write/1
)!相反,集中精力描述句子和目标之间的关系,让Prolog toplevel为你做印刷。