Язык KRL
Разработчики языка предположили, что наследование процедур позволит программировать в терминах родовых операций, детали реализации которых конкретизируются по-разному для объектов разных классов. Так же, как абстрактные типы данных позволяют программисту забыть о деталях хранения конкретных данных в машине, так и родовые операции позволяют на определенной стадии не принимать во внимание детали реализации однотипных операций в каждом конкретном случае. Пример поможет вам четче представить смысл этой идеи.
Предположим, вас назначили Верховным главнокомандующим при проведении военной операции, в которой принимают участие различные рода войск. Отданные в ваше распоряжение танки, корабли и самолеты ждут приказа атаковать. Получив такой приказ, каждый из родов войск будет действовать по-своему: самолеты начнут бомбить, корабли – выпускать ракеты и т.д. Но поведение каждого из родов войск – это частная реализация общей концепции наступательных военных действий. Как главнокомандующего, вас мало интересуют детали выполнения приказа: на какие рычаги нажимать, какие переключатели включать, – все это должно быть определено на более низких уровнях.
Возвращаясь вновь к KRL, отметим, что идея, которая стоит за объектно-центрической организацией процедур, состоит в том, чтобы попытаться программно воспроизвести тот естественный стиль выработки суждений, который реализуется в мозге человека. В частности, предполагается, что управление логическим выводом реализуется на локальном уровне, в отличие от глобальных задач, ассоциирующихся, например, с автоматическим доказательством теорем. Другими словами, зная, как реализовать родовые операции, классы объектов будут обладать знаниями и о том, когда активизировать те многочисленные процедуры, к которым они имеют доступ.
Мы не затрагивали многих других аспектов языка KRL, например средств управления процессом или составления расписаний работ. Читателям, интересующимся этим языком, рекомендуем познакомиться с критическим анализом этого языка, который выполнили Ленерт и Уилкс [Lehnert and Wilks, 1979], и ответом разработчиков на эти критические замечания [Bobrow and Winograd, 1979]. Нельзя не отметить, что язык KRL явился тем локомотивом, который существенно подтолкнул исследования в области теории представления знаний и, в частности, способствовал появлению практических систем, о которых речь пойдет в следующем разделе.
Процедуры и объекты
На рис. 7.1 мы попытались схематически представить, в чем основная разница между процедурно – и объектно-ориентированным подходами в программировании.
Серые эллипсы на схеме в левой части рисунка представляют процедуры, некоторые из которых напрямую обращаются к данным, хранящимся в файле или в базе данных. Зачерненный эллипс представляет процедуру самого верхнего уровня (в языке С – это процедура main). Эта функция вызывает другие функции, которые в конце концов вызывают функции самого нижнего уровня, выполняющие операции ввода/вывода.
На правой схеме объекты объединяют данные и процедуры работы с ними. Объекты организованы в виде одной или нескольких иерархических структур – деревьев или решеток. Утолщенный прямоугольник на схеме представляет базовый абстрактный класс. Экземпляры этих объектов взаимодействуют друг с другом, обмениваясь сообщениями, и таким образом образуются связи, ортогональные иерархии наследования.
Рис. 7.1. Процедурно- и объектно-ориентированные парадигмы программирования. Незаполненные фигуры представляют данные, а фигуры с заливкой – процедуры