【问题标题】:Prolog reasoning about predicatesProlog 关于谓词的推理
【发布时间】:2020-04-16 19:16:11
【问题描述】:

假设有人写了以下一大串子句:

loves(me, wife).
loves(me, dog).
loves(wife, dog).
hates(me, enemy).
attracts(iron, magnet).
...

现在我想在给定一些高阶谓词和规则的情况下自动生成互惠子句:

reciprocal([loves, hates, attracts, ...]).
some_conclusion :- some_premises.

这样我就有了以下预期结果:

?- loves(wife, me).
true.

为了简单起见,我忽略了 list 参数,而是使用 reciprocal(X) 定义了带有一些复杂规则的简单子句 reciprocal(loves).,但我似乎无法成功地将 assert 规则。

我尝试了不同的变体和排序

assert(
    Y :- (reciprocal(P), Y =.. [P, B, A], X =.. [P, A, B], call(X))
).

或(添加推导子句本身)

assert(Y), reciprocal(P), Y =.. [P, B, A], X =.. [P, A, B], call(X)

但我只有 false 或使用 SWI-Prolog 的 Arguments are not sufficiently instantiated 之类的错误。

我的问题是(显然):我怎样才能使这条规则生效?我不在乎规则是数据库的一部分还是只是将实际子句添加到数据库的预处理器(尽管前者会更好),我只想学习如何推理谓词(即如何使用更高的-顺序谓词)。

注意:我学习逻辑编程才一个月,我想尝试一下 Notation3 和 N-triples 等的一些想法。


编辑:

缺少的部分,蛋糕上的绝对樱桃,是一些使用类似于规则的动态解决方案

Y :- (reciprocal(P), call(P, A, B), Y =.. [P, B, A]).

如果有人对此有一些解决方案,请发布!

【问题讨论】:

  • 首先,尝试熟悉call/NN > 1。例如,您可以将 X =.. [P, A, B], call(X) 替换为 call(P, A, B) &ct

标签: prolog metaprogramming meta-predicate


【解决方案1】:

我找到了将子句一一添加到数据库中的方法(MVP):

?- [user].
|: loves(me, wife).
|: loves(me, dog).
|: loves(wife, dog).
|: reciprocal(loves).
|: (Ctrl-Z)

?- dynamic loves/2   %! seems necessary for next clause...
true.

?- reciprocal(P), X =.. [P, A, B], Y =.. [P, B, A], assert(X :- (Y, !)).
P = loves,
X = loves(A, B),
Y = loves(B, A).

?- loves(wife, me).
true.

看来我没有以这种程序合理的方式安排“规则”。

现在我将关注findall 以避免需要用户输入(P 的每个解决方案之后的;)。


编辑:

我完成了除了一个功能之外的所有功能...给定一个文件 db.pl 包含

loves(me, wife).
loves(me, dog).
loves(wife, dog).
attracts(iron, magnets).

还有一个文件rules.pl 包含

reciprocal([
    loves,
    attracts
]).
parse_reciprocal([]).
parse_reciprocal([H|T]) :- 
    X =.. [H, A, B], Y =.. [H, B, A], dynamic(H/2), assert(X :- (Y, !)),
    parse_reciprocal(T).

:- initialization reciprocal(L), parse_reciprocal(L).

我的第一个目标成功了

?- [db].
true.

?- [rules].
true.

?- loves(dog, wife).
true.

?- attracts(magnets, iron).
true.

缺少的部分,蛋糕上绝对的樱桃,是一些使用类似于规则的动态解决方案

Y :- (reciprocal(P), call(P, A, B), Y =.. [P, B, A]).

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多