Особая форма unique
Реализуйте в языке запросов новую особую форму
unique
. Выражение
unique
должно быть успешно, если в базе данных ровно одна запись, удовлетворяющая указанному запросу. Например запрос
(unique (job ?x (computer wizard)))
должен печатать одноэлементный поток
(unique (job (Bitdiddle Ben) (computer wizard)))
поскольку Бен (Bitdiddle Ben) — единственный компьютерный гуру, а
(unique (job ?x (computer programmer)))
должно печатать пустой поток, поскольку программистов больше одного. Более того,
(and (job ?x ?j) (unique (job ?anyone ?j)))
должно перечислять все должности, на которых работает по одному человеку, а также самих этих людей.
Реализация
unique
состоит из двух частей. Первая заключается в том, чтобы написать процедуру, которая обрабатывает эту особую форму, а вторая в том, чтобы заставить
qeval
распознавать форму и вызывать ее процедуру. Вторая часть тривиальна, поскольку
qeval
написана в стиле программирования, управляемого данными. Если Ваша процедура называется
uniquely-asserted
, то нужно только написать
(put 'unique 'qeval uniquely-asserted)
и
qeval
будет передавать управление этой процедуре для всех запросов, у которых в
type (car)
стоит символ
unique
.
Собственно задача состоит в том, чтобы написать процедуру
uniquely-asserted
. В качестве входа она должна принимать
contents (cdr)
запроса
unique
и поток кадров. Для каждого кадра в потоке она должна с помощью
qeval
находить поток всех расширений, удовлетворяющих данному запросу. Потоки, в которых число элементов не равно одному, должны отбрасываться. Оставшиеся потоки нужно собирать в один большой поток. Он и становится результатом запроса
unique
. Эта процедура подобна реализации особой формы
not
.
Проверьте свою реализацию, сформировав запрос, который находит всех служащих, которые начальствуют ровно над одним человеком.
Комментарии отсутствуют.