Доступ к программам и обработка программ
Программа 12.2.Чтение спискаслов.
Предикат read_word_list читает литеру С и обращается к процедуре read_word_list(C,Words). В этой процедуре выполняется одно из трех действий в зависимости от значения литеры С. Если С – литера, входящая в слово, т.е. прописнаяили строчная буква, или символ подчеркивания, то обрабатывается следующее слово и далее рекурсивно обрабатывается последовательность оставшихся слов. Второе действие состоит в игнорировании пробелов, т. е. считывается следующая литера, и работа программы рекурсивно продолжается. Если, наконец, встретилась литера, обозначающая конец последовательности слов, то программа завершает работу и возвращает список слов.
Существенно, что всегда программа прежде читает литеру, а затем уже проверяет, что следует делать. Если это полезная литера, например литера слова, то она должна быть включена в слово. Иначе литеры могут быть потеряны при возврате. Рассмотрим следующий цикл ввода и обработки:
process([ ])¬
get(C), end_of_words_char(C).
process ([W | Words])¬
get(C),word _char(C), get_word(C,W), process (Words).
Если первая литера слова не удовлетворяет предикату end_of_words_char, то первое предложение не выполнится, а второе предложение приведет к вводу следующей литеры.
Возвращаясь к программе 12.2, заметим, что предикат read_words(C,W,C1) читает слово W, начинающееся с текущей литеры С, и возвращает литеру, следующую за словом – С1. Список литер, образующих слово, находится с помощью процедуры word_chars/3 (аргументы те же, что и у процедуры read_words). Слово строится по списку литер с помощью системного предиката name. Процедура words__chars также обладает свойством опережающего просмотра одной литеры, так что литеры не теряются.
Такие предикаты, как fill_char/1 и word_char/1, упрощают представление данных в Прологе.
До сих пор предполагалось, что программы размещены в памяти компьютера, и вопрос о том, как они там представлены и каким образом были туда занесены, не рассматривался. Однако многие приложения Пролога зависят от того, как организован доступ к предложениям программы. Более того, если программа должна изменяться во время вычислений, то следует иметь средства, позволяющие добавлять и удалять предложения.
Системным предикатом, обеспечивающим доступ к программе, является предикат clause (Head, Body). К цели clause (Head, Body )? можно обращаться, если аргументу Head сопоставлено значение. Ищется первое предложение в программе, заголовок которого унифицируем с термом Head. Далее заголовок и тело этого правила унифицируются с аргументами Head и Body. При возврате каждое предложение унифицируемое с аргументами цели, дает одно решение. Отметим, что доступ к правилам, минуя заголовки, невозможен.
Считается, что телом факта является атом true. Конъюнктивная цель изображается с помощью бинарного функтора «,». Впрочем, можно легко абстрагироваться от конкретного представления.
Рассмотрим программу 3.12, задающую отношение member