0

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

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(loves).用一些复杂的规则定义了简单的子句 using reciprocal(X),但我似乎无法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)

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

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

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


编辑:

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

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

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

4

1 回答 1

0

我找到了将子句一一添加到数据库中的方法(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]).
于 2019-12-27T14:06:53.590 回答