Assume someone wrote the following huge list of clauses:
loves(me, wife).
loves(me, dog).
loves(wife, dog).
hates(me, enemy).
attracts(iron, magnet).
...
Now I want to automatically generate reciprocal clauses given some higher-order predicate and rule similar to:
reciprocal([loves, hates, attracts, ...]).
some_conclusion :- some_premises.
so that I have the following expected result:
?- loves(wife, me).
true.
To keep things simple, I ignored the list argument and instead defined the simple clause reciprocal(loves).
with some complex rule using reciprocal(X)
, but I can't seem to assert
a rule with success.
I've tried different variations and orderings of
assert(
Y :- (reciprocal(P), Y =.. [P, B, A], X =.. [P, A, B], call(X))
).
or (to add the deduced clauses themselves)
assert(Y), reciprocal(P), Y =.. [P, B, A], X =.. [P, A, B], call(X)
but I've only got false
or errors like Arguments are not sufficiently instantiated
using SWI-Prolog.
My question is (obviously): how can I make this rule work? I don't care whether the rule is part of the database or just a preprocessor to add the actual clauses to the database (although the former would be preferable), I just want to learn how to reason about predicates (i.e. how to use higher-order predicates).
Note: I've learned logic programming since a month only, and I want to try out some ideas from Notation3 and N-triples etc.
EDIT:
The missing part, the absolute cherry on the cake, is some dynamic solution using a rule similar to
Y :- (reciprocal(P), call(P, A, B), Y =.. [P, B, A]).
If anyone has some solution for this one, please post it!