Prolog:从 DCG 生成查询
Prolog: generate queries out of 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 可以确定有效的问题,例如
"who is the brother of john",效果也不错。
question --> ip, verb, article, noun, pronoun, name.
现在我想让我的程序用这样的名词和名字调用我的家庭数据库:
noun(X, name).
在这个例子中应该是
brother(X, anna).
然后 return 作为自然语言答案的答案,例如:
"the brother of anna is john"
定义答案句的语法也没有问题。我唯一不知道的是,如何从我的 DCG 调用我的数据库并在其中填充正确的值。我环顾四周已经有一段时间了——也许我不知道正确的搜索词——但找不到与此相关的东西。
希望大家多多指教! :)
谢谢。
从 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 目标。在您的示例中,您希望将句子 "Who is the brother of susan?" 与 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
等
None 这需要任何副作用 (write/1
)!相反,专注于描述句子和目标之间的关系,让 Prolog 顶层为您打印。
我目前有一个小型 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 可以确定有效的问题,例如 "who is the brother of john",效果也不错。
question --> ip, verb, article, noun, pronoun, name.
现在我想让我的程序用这样的名词和名字调用我的家庭数据库:
noun(X, name).
在这个例子中应该是
brother(X, anna).
然后 return 作为自然语言答案的答案,例如:
"the brother of anna is john"
定义答案句的语法也没有问题。我唯一不知道的是,如何从我的 DCG 调用我的数据库并在其中填充正确的值。我环顾四周已经有一段时间了——也许我不知道正确的搜索词——但找不到与此相关的东西。
希望大家多多指教! :)
谢谢。
从 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 目标。在您的示例中,您希望将句子 "Who is the brother of susan?" 与 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
等
None 这需要任何副作用 (write/1
)!相反,专注于描述句子和目标之间的关系,让 Prolog 顶层为您打印。