假设有人编写了以下庞大的子句列表:
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]).
如果有人对此有解决方案,请发布!
答案 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.