Использование предиката "сократить" для того, чтобы сделать процедуру детерминированной

Детерминированной называется такая процедура, про которую интерпретатору известно, что она дает более одного (позитивного) ответа. Для того чтобы превратить процедуру в детерминированную, в большинстве случаев можно воспользоваться предикатом "сократить". К примеру, если в конце каждого правила рекурсивной процедуры, выполняющей обработку списков, поставить предикат "сократить", то это позволит избежать потерь времени, затрачиваемого впустую на поиск дополнительных ответов после достижения конца списка. Предикат "сократить" информирует интерпретатор о том, что процедура является детерминированной. Приведем текст детерминированной версии процедуры "элемент", которая получила название "элемент_тест":

элемент_тест (X, [X | Остаток]): - !.

элемент_тест (X, [Y | Остаток]): -

!, элемент_тест (X, Остаток).

|?— элемент_тест (с, [a, b, c, d]).

да

Однако применение предиката "сократить" приводит к тому, что данная процедура не может выдать все элементы списка:

|? -элемент_тест (X, [a, b, c, d]).

Х=а;

нет

Применение предиката "сократить" для отбрасывания части пространства поиска

При рассмотрении программы "регистрация", представленной ранее, было обнаружено, что интерпретатор тратит понапрасну время в попытке найти более чем одно значение возраста у одного и того же лица. Существуют два подхода к этой проблеме. Во-первых, ясно, что часть пространства поиска запроса к программе "регистрация" не несет полезной информации. Эту часть пространства можно отбросить без какого-либо ущерба для способности программы выдавать все правильные ответы. Во-вторых, нужно сделать так, чтобы отношение "возраст" регулировалось ограничением, обеспечивающим целостность отношения, вида многие-к-одному, а не принимаемым по умолчанию ограничением многие-к-многим. Возникает вопрос: как можно использовать предикат "сократить" при создании новой версии процедуры "регистрация", в которой выдавались бы все те же ответы, что и в исходной версии, а бесполезные траты времени на поиск нескольких значений возраста были бы устранены? В связи с этим возникает и другой вопрос: каким образом можно употребить предикат "сократить" для того, чтобы создать версию отношения "возраст", регулируемую ограничением, обеспечивающим целостность, вида многие-к-одному?

Остановка после выдачи одного ответа

Начнем с более простой задачи — написать запрос к базе данных "возраст", при котором будет выдаваться только один ответ. К какому решению мы бы ни пришли, оно может оказаться полезным при составлении будущей версии процедуры "регистрация".

Наиболее очевидным способом составления запроса к базе. данных "возраст", при котором будет выдаваться только один ответ, будет написание составного запроса, второй подцелью которого является предикат "сократить". Если первым аргументом предиката "возраст" будет константа (имя), а вторым - переменная (возраст), то запрос будет работать нормально:

возраст (брайен, 18).

возраст (майк, 17).

возраст (став, 18).

|? - возраст (брайен, Y),!.

Y=18;

нет

Заметьте, что при данном запросе интерпретатор не будет искать значение еще одного возраста Брайена.

Однако, если первым аргументом запроса "возраст" будет переменная, а вторым — константа, то при описанном подходе интерпретатор не найдет все правильные ответы на запрос:

|? -возраст (X, 18),!.

Х= брайен;

нет

В базе данных содержатся сведения более чем об одном восемнадцатилетнем мужчине, но из-за употребления предиката "сократить" этот запрос выдаст сведения только о первом из представленных мужчин. Поэтому множество ответов данной программы будет неполным.

Предикат "сократить " как подцель правила "регистрация "

Посмотрим, что получится, если составной запрос подобного вида (т. е. подцель "возраст" плюс предикат "сократить") будет записан в теле правила "регистрация".

регистрация2 (X):—

мужчина (X), возраст (X, Y),!, Y= 18.

Запрос к правилу "регистрация2" будет работать правильно, если его аргументом является константа:

|? - регистрация2 (бранен).

да

|? -регистрация2 (майк).

нет

Дело будет обстоять не так хорошо, если аргументом запроса является переменная:

|? - регистрация2 (X).

Х= брайен ;

нет

Этот запрос не выдает еще один ответ, «X = стив», поэтому опять множество ответов программы будет неполным.

Соседние файлы в папке Гл.0,1,2,3,4,5,Предисловие