我将如何创建 DCG 来解析有关数据库的查询?

How would I create a DCG to parse queries about a database?

我只是在玩弄学习 Prolog,正在尝试建立一个信息数据库,然后使用自然英语来查询关系。我该怎么做?

示例:

%facts

male(bob).
female(sarah).
male(timmy).
female(mandy).

parent(bob, timmy).
parent(bob, mandy).
parent(sarah, timmy).
parent(sarah, mandy).

spouse(bob, sarah).
spouse(sarah, bob).

%some basic rules

married(X,Y) :- spouse(X,Y).
married(X,Y) :- spouse(Y,X).

child(C,X) :- parent(X,C).

现在,我想问一些 "who" 个问题,即 "who is the parent of timmy"。

我阅读了一些关于 DCG 的内容,但是,任何人都可以指出一些好的资源或让我朝着正确的方向前进吗?

谢谢!

首先,我还想问一个"who"问题:事实上

parent(X, Y).

居然是parent?是 X 还是 Y?

为了使这一点更清楚,我强烈建议您使用一种命名约定来明确每个参数的含义。例如:

parent_child(X, Y).

现在,要将 "informal" 问题转化为对您的数据进行推理的 Prolog 目标,例如考虑以下 DCG

question(Query, Person) --> [who,is], question_(Query, Person).

question_(parent_child(Parent,Child), Parent) --> [the,parent,of,Child].
question_(parent_child(Parent,Child), Child)  --> [the,child,of,Parent].
question_(married(Person0,Person), Person)    --> [married,to,Person0].
question_(spouse(Person0,Person), Person)     --> [the,spouse,of,Person0].

在这里,我假设您已经将给定的句子转换为 tokens,我将其表示为 Prolog atoms.

为了方便使用DCGs,强烈推荐如下声明:

:- set_prolog_flag(double_quotes, chars).

这让你可以这样写:

?- Xs = "abc".
Xs = [a, b, c].

因此,使用此类程序变得非常方便。我将把 characters 的列表转换为 tokens 作为你的练习。

一旦您拥有此类标记,您就可以使用 DCG 将此类标记的 列表 与程序中的 Prolog 查询 相关联。

例如:

?- phrase(question(Query, Person), [who,is,the,parent,of,timmy]).
Query = parent_child(Person, timmy) .

另一个例子:

?- phrase(question(Query, Person), [who,is,the,spouse,of,sarah]).
Query = spouse(sarah, Person).

实际上运行这样的查询,只需post将它们作为目标。例如:

?- phrase(question(Query, Person), [who,is,married,to,bob]),
   Query.
Query = married(bob, sarah),
Person = sarah .

这说明这样的转换在Prolog中相当straight-forward

正如@GuyCoder 在评论中提到的那样,请务必查看 以了解有关 DCG 表示法的更多信息!