Обратный поиск в Прологе? (Как я могу найти все, что правда о X?)
Итак, допустим, у меня есть следующее в базе данных Prolog:
person(john).
person(mary).
happy(john).
Ясно, что если я хочу перечислить всех людей, я могу напечатать:
person(X).
Но что, если я хочу найти все то, что правда о Джоне? Я не могу сделать:
X(john).
Но эффект, который я хотел бы получить, - это умение вставлять слова "Джон" и возвращать слова "человек" и "счастливый".
Ясно, что я мог хранить мою информацию:
is(person, john).
is(person, mary).
is(happy, john).
И тогда я могу сделать:
is(X, john).
Но я теряю здесь некоторую выразительность. Я действительно хотел бы иметь возможность сделать что-то вроде:
X(john).
Есть идеи?
Спасибо!
3 ответа
Параметризация запроса по предикатам (как при поиске ∀ x
над x(...)
) обычно не возможен изначально в PROLOG, поскольку такого рода вещи являются логической операцией второго (или более высокого) порядка, тогда как PROLOG основан на логике первого порядка.
Тем не менее, есть описания того, как возможны реализации логических функций высшего порядка в PROLOG, по крайней мере, в ограниченной степени - есть реальные применения для такой функциональности. См. "Искусство Пролога", Глава 16, и " Логическое программирование высшего порядка в Прологе" Ли Найша.
Хм, по моему опыту, это не типичный вариант использования Пролога. Если вы хотите перечислить все "факты" о Джоне, вы должны сначала определить их как термины и закодировать их арность. Тогда вы можете использовать call/N
и зайдите в кроличью нору еще на одну ступеньку (по памяти с помощью GNU Prolog):
relation(1,person).
relation(2,married).
person(john).
married(john,mary).
? relation(1,X), call(X,john).
X = person
| ?- relation(2,X),call(X,john,Y).
X = married
Y = mary
Обратите внимание, что с помощью call
имеет много интересных проблем и потенциальных ошибок во время выполнения.
Это приближение:
all_predicates(Term) :-
current_predicate(_, Pred), %% match Pred to any currently defined predicate
\+ predicate_property(Pred, built_in), %% filter out the built-in predicates
functor(Pred, Name, 1), %% check that Pred has 1 argument and match Name to its name
Goal =.. [Name, Term], %% construct the goal Name(Term)
call(Goal). %% Note that if Pred has side effects, they will happen.