首页 > 解决方案 > 理解具体化——“x 和 y 之间有什么关系?”

问题描述

我正在阅读 Pereira 和 Shieber 所著的“Prolog and Natural-Language Analysis”(pdf)一书,我被问题 2.7 中的一句话困住了:

在语义网络表示中,我们经常想问 [...]“福特和公司类别之间有什么关系?”</p>

修改您对语义网络的表示,以允许这种新问题和前一个问题中的问题。提示:将语义网络关系视为 Prolog 个体。这是一种重要的 Prolog 编程技术,有时在哲学界被称为物化。

我不熟悉这种reification技术。

好的,让我们假设这个事实和规则数据库:

isa('Ole Black', 'Mustangs').
isa('Lizzy', 'Automobiles').
isa('Ford','Companies').
isa('GM','Companies').
isa('1968','Dates').

ako('Model T', 'Automobiles').
ako('Mustangs', 'Automobiles').
ako('Companies', 'Legal Persons').
ako('Humans', 'Legal Persons').
ako('Humans', 'Physical Objects').
ako('Automobiles', 'Physical Objects').
ako('Legal Persons', 'Universal').
ako('Dates', 'Universal').
ako('Physical Objects', 'Universal').

have_mass('Physical Objects').
self_propelled('Automobiles').

company(X) :- isa(X,'Companies').
legal_persons(X) :- ako(X,'Legal Persons').

如何编写一个查询,在上面的代码中发现'Ford'和之间的关系'Companies'isa?当然,我总是可以写一些类似的东西

fact(isa, 'Ford','Companies').

并查询?- fact(X, 'Ford','Companies').,但不知何故,我认为这不是正确的方法。

谁能解释我如何正确地做到这一点?

标签: prolog

解决方案


结合 Paul 和 Carlo 答案的各个方面,另一种可能的解决方案是引入元关系谓词。例如:

relation(isa/2).
relation(ako/2).
relation(have_mass/1).
...

这避免了由于关系的具体化而失去使用原始数据库的某些查询的第一个参数索引的好处。在 Carlo 的解决方案中,它还避免了调用current_predicate/2例如不应考虑的辅助谓词。

通过上面的relation/2谓词定义,我们可以写:

relation(Relation, Entity1, Entity2) :-
    relation(Relation/2),
    call(Relation, Entity1, Entity2).

relation(Relation, Entity) :-
    relation(Relation/1),
    call(Relation, Entity).

然后查询:

?- relation(Relation, 'Ford', 'Companies').
Relation = isa.

推荐阅读