
- •Глава 8
- •8.1. Системные арифметические предикаты
- •8.3. Замена рекурсии итерацией
- •8.4. Дополнительные сведения
- •Глава 9 Анализ структуры термов
- •9.1. Типовые предикаты
- •9.2. Составные термы
- •9.3. Дополнительные сведения
- •Глава 10
- •10.1 Типовые металогические предикаты
- •10.2. Сравнение неосновных термов
- •10.3. Использование переменных в качестве объектов
- •10.4. Доступность метапеременных
- •10.5. Дополнительные сведения
10.3. Использование переменных в качестве объектов
Нетривиальная проблема, связанная с явной обработкой переменных при определении отношения occurs_in в предыдущем разделе, подчеркивает слабость выразительных средств Пролога. Работа с переменными связана с некоторыми сложностями, и при анализе и обработке термов между переменными и значениями могут возникнуть случайные соответствия.
Такая проблема появляется при построении программы 9,3, определяющей отношение Substitute. Рассмотрим цель Substitute (a, b, X, Y}, задающую подстановку константы а вместо b в переменную X. Результатом подстановки является терм Y. Имеются две правдоподобные интерпретации отношения Substitute в этом случае. Логически обоснованным решением является сопоставление переменной Х константы а, а переменной Y- константы b. Это решение действительно находится программой 9.3 при унификации цели с основным фактом Substitute (ОId, New, Old, New).
Однако на практике предпочтительнее иная интерпретация. Будем считать термы Х и а различными; таким образом, переменной Y следует сопоставить терм X. При такой интерпретации следовало бы воспользоваться другим предложением программы 9.3, а именно:
Substitute(01d, New, Term, Term) constant(Terrn),Term Old.
Цель, однако, не будет доказана, так как переменная не является константой.
Мы можем избежать первого (логического) решения, используя металогический тест, гарантирующий подстановку в основной терм. Тогда неявная унификация с заголовком предложения становится выполняемой лишь в случае, если тест выполнен. Следовательно, унификация должна быть задана явно. Основной факт превращается в правило:
Substitute(01d, New, Term, New) ground(Term),Term = Old.
Рассмотрение переменных отдельно от констант требует специального правила также использующего металогический тест:
Substitute(01d,New,Var,Var)var(Var).
Добавление двух рассмотренных предложений к программе 9.3, определяющей отношение Substitute, а также добавление других металогических тестов позволяет применять программу к неосновным термам. Однако полученная программа будет громоздкой. В ней смешаны процедурный и декларативный подходы. Для понимания такой программы требуется знание механизма управления, реализованного в Прологе. Используя аналогию с медициной, можно сказать, что мы лечим симптомы (нежелательное сопоставление значения переменной), а не болезнь (отсутствие средств, позволяющих использовать переменные в качестве объектов). Для “исцеления” необходимы дополнительные металогические примитивы.
Сложности, возникающие при смешивании обработки термов на метауровне и на объектном уровне, связаны с некоторой теоретической проблемой. Строго говоря программы метауровня должны рассматривать переменные объектного уровня как константы и должны иметь возможность ссылаться на такие переменные по имени,
Расширяя Пролог
двумя системными предикатами:
freeze
(Term, Frozen)
и
melt
(Frozen,Thawed),
можно частично решить указанные проблемы.
“Замораживание”
терма
Term
с помощью предиката
freeze
создает копию терма
Frozen.
В этом терме все переменные исходного
терма, которым не были сопоставлены
значения заменяются уникальными
константами. Замороженный терм подобен
основному терму и может использоваться
так же, как и основной терм.
При унификации замороженные переменные рассматриваются как основные атомы. Две замороженные переменные унифицируемы тогда и только тогда, когда они совпадают. Аналогично, если переменная, которой не сопоставлено значение, унифицируется с замороженным термом, то значением переменной становится замороженный терм. Применение системного предиката к замороженной переменной приводит к тому же результату, что и применение к константе. Например, использование замороженных переменных в арифметических вычислениях приводит к безуспешным вычислениям.
Предикат freeze, как и предикат var, является металогическим предикатом. Оц позволяет анализировать структуру терма непосредственно в процессе вычисления.
Наличие предиката freeze позволяет иначе определить предикат occurs_in, рассматривавшийся в предыдущем разделе. Идея состоит в замораживании терма, что превращает переменные в основные обекты. Это позволяет использовать программу Subterm (программа 9.2), правильно обрабатывающую основные термы. Метод реализован в программе 10.7(Ь).
Замораживание позволяет решать вопрос идентичности двух термов. Два замороженных терма Х и Yунифицируемы тогда и только тогда, когда их незамороженные варианты идентичны, т. е, когда Х = = Y. Это свойство существенно для обоснования корректности программы 10.7(b).
Отличие замороженных
термов от основных состоит в том, что
замороженные термы можно “разморозить”,
превратив их в неосновные термы.
Предикатом, двойственным к
freeze,
является предикат
melt
(Frozen,Thawed).
Вычисление цели melt
(X, Y)
создает копию терма Y
терма
X,
в которой замороженные переменные
становятся обычными переменными языка
Пролог. При размораживании терма Y
учитываются все сопоставления значений
переменным терма
X,
сделанные
пока
терм был
заморожен.
Freeze
заморозить,
melt
разморозить.
- Прим.
перев.
Далее дается без
кавычек. -Прим.
ред.
См.
сноску 2)
на с. 125.-Прим.
ред.
Используя предикаты freeze и melt, можно построить вариант программы substitute, а именно non_ground_substitute, в котором не происходит нежелательных сопоставлений значений переменным. Процедурный подход к программе поп_ ground_substitute состоит в следующем: перед подстановкой терм замораживается; далее, используя программу substitute, правильно обрабатывающую основные термы, производится подстановка в замороженный терм; наконец, новый терм размораживается:
non_ground_substitute (X, Y, Old, New)
freeze(0ld,0ld1),
substitute(X,Y,Old,Old1),melt(Old, New).
Замороженный терм можно также использовать как шаблон для изготовления копий. Системный предикат melt_new (Frozen, Term) создает копию Term терма Frozen, в которой замороженные переменные заменены переменными с новыми именами.
Предикат melt_new используется для копирования термов. Предикат copy(Term, Copy) создает новую копию терма Term. Этот предикат можно задать одним правилом:
copy (Term, Copy)freeze (Term, Frozen), melt_new(Frozen,Copy).
Примитивы freeze, melt и melt_new полезны при задании вводимых в гл. 12 внелогических предикатов и описании их вычислений.