关于谓词的序言推理

时间:2019-12-26 15:14:03

标签: prolog metaprogramming meta-predicate

假设有人编写了以下庞大的子句列表:

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).用一些复杂的规则定义了简单子句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的错误。

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

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


编辑:

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

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

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

1 个答案:

答案 0 :(得分: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,以避免要求用户输入({{1}的每个解决方案之后的;)。


编辑:

我完成了除一项功能外的所有工作...给定一个文件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.