【问题标题】:Understanding reification - “What relationships hold between x and y?"理解具体化——“x 和 y 之间有什么关系?”
【发布时间】:2019-08-20 03:15:39
【问题描述】:

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

在语义网络表示中,我们经常想问 [...] “福特与 公司?”

修改您对语义网络的表示,以允许这种新的 类型的问题和前一个问题中的类型。提示:治疗 语义网络关系作为 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').,但不知何故,我认为这不是正确的做法。

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

【问题讨论】:

  • "我如何编写一个查询,在上面的代码中发现 'Ford' 和 'Companies' 之间的关系是 isa?"您的意思是找到“绑定”两者的谓词吗?
  • 如果我正确理解“绑定”的含义,是的,我如何找到绑定两个变量的谓词。
  • 我没有尝试过,但根据这个答案 stackoverflow.com/a/8510861/131160> 和您的查询,我猜以下可能有效:forall(fact(X, 'Ford', 'Companies'), writeln(X))
  • ...但是“修改语义网络的表示”部分听起来您不应该真正编写这样的查询,而应该更改数据结构...不知道如何。 ..
  • @jcsahnwaldt 我不认为他想那样解决它,是否有一个 SWI-Prolog 函数可以打印出谓词。我找了它,但找不到任何东西

标签: prolog


【解决方案1】:

结合 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.

【讨论】:

  • 我非常喜欢保罗!当你喜欢三个答案时你怎么办!?!?!?
  • 您可以随时以适合您申请的方式结合他们的想法,然后将结果作为答案提交。
【解决方案2】:

不确定这个答案是否是本书的意图......我多年前读过它,意大利语翻译,但不记得问题了。

在 SWI-Prolog 中,模块扮演着重要的角色,所以我会选择:

:- module(so_relationships, [which_rel/3]).

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').

which_rel(A,B,R) :-
    current_predicate(so_relationships:R/2),
    C=..[R,A,B],
    %catch(call(C),E,(writeln(E),fail)).
    call(C).

注意(注释掉的)catch/3。在使用模块名称限定谓词指示符之前需要。

?- which_rel('Ford','Companies',R).
R = isa ;
false.

【讨论】:

  • C=..[R,A,B], call(C). ----> call(R,A,B).
  • 很好的答案!我喜欢!另请参阅我对 Paulo 的评论。我喜欢我不必重新定义数据库中的事实。
  • 当您无法修改事实时,这些解决方案非常棒,但它们是生成和测试算法,所以 O(n)。如果你可以具体化关系,它只是一个查找,索引可以是 O(1)。
【解决方案3】:

我想为之前的答案添加一点背景知识(非常有帮助)。

据我所知,Prolog 中没有普遍接受的reification 定义。可以说原始代码中的关系已经部分具体化了。例子:

isa('Ford', 'Companies').
% ...is a reification of...
company('Ford').

ako('Companies', 'Legal Persons').
% ...is a reification of...
legal_person(X) :- company(X).

have_mass('Physical Objects').
% ...is a reification of...
has_mass(X) :- physical_object(X).

self_propelled('Automobiles').
% ...is a reification of...
self_propelled(X) :- automobile(X).

详情请参阅Notes on Semantic Nets and FramesMatthew Huntbach 中的具体化部分。

【讨论】:

    【解决方案4】:

    出发地:

    isa('Ford','Companies').
    

    到:

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

    是具体化技术。在 Prolog 中,仿函数必须是原子,因为您可能已经发现了如下查询:

    ?- HowRelated('Ford', 'Companies').
    HowRelated = isa.
    

    将是无效的语法,Prolog 中的谓词是抽象的,你不能直接推理它。将其变成可以推理的具体事物就是具体化。典型的顺序是(主语、谓语、宾语):

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

    这样查询:

    ?- fact('Ford', HowRelated, 'Companies').
    HowRelated = isa.
    

    超越第一个参数索引的 Prolog 实现(例如 cmets SWI-Prolog 中提到的)在查找此类查询方面非常快,您现在可以将事实的任何部分作为查询中的变量.请放心,这是正确的做法,这也是在 RDF 和 OWL 中的做法,其中谓词具有自反性或传递性等属性。

    我没有给你特定的参考书目,但有一篇博文"Reification by Example" on PrologHub

    【讨论】:

    • “在计算机科学中没有什么是通过添加another level of indirection interpretation 解决不了的”。 :)
    • 感谢保罗的回答,您为我澄清了具体化,这与我的想法一致。但是,下面 Carlo 和 Paulo 的答案更接近我想象的解决方案,因为我不必重新定义我的事实数据库。
    • 当存在恒定时间解决方案时,您想象的是线性时间解决方法。要弄清楚“Mustangs”与“Universal”的关系,将使用您当前的数据库排序进行 9 次查找。将您的事实更改为三元组,无论它们的顺序如何,都将是 3。即使是大型事实数据库也可以通过脚本和通过规则提供的遗留访问快速重新定义,也由脚本编写。当您可以重新定义时,请重新定义。
    猜你喜欢
    • 2016-02-18
    • 2013-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-30
    • 2015-01-02
    • 2012-07-03
    • 1970-01-01
    相关资源
    最近更新 更多