Обратный поиск в Прологе?(Как я могу найти все, что правда о X?) - PullRequest
4 голосов
/ 16 августа 2010

Итак, допустим, у меня есть следующее в базе данных 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 ]

2 голосов
/ 20 августа 2010

Параметризация запроса по предикатам (как при поиске & forall; x более x(...)) обычно не возможна изначально в PROLOG, поскольку такого рода вещи являются логикой второго (или более высокого) порядка операция, тогда как PROLOG основан на логике первого порядка.

Однако есть описания того, как возможны реализации логических функций высшего порядка в PROLOG, по крайней мере, в ограниченной степени - есть реальные применения для такой функциональности. См. Искусство Пролога, Глава 16 и Логическое программирование высшего порядка в Прологе Ли Наиш .

1 голос
/ 16 августа 2010

Хм, по моему опыту, это не типичный вариант использования Пролога. Если вы хотите перечислить все «факты» о Джоне, вы должны сначала определить их как термины и закодировать их арность. Затем вы можете использовать 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 имеет много интересных проблем и потенциальных ошибок во время выполнения.

0 голосов
/ 17 августа 2010

Это приближение:

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.
...