Научная статья на тему 'Особенности процедурно-параметрической парадигмы программирования'

Особенности процедурно-параметрической парадигмы программирования Текст научной статьи по специальности «Компьютерные и информационные науки»

CC BY
261
35
i Надоели баннеры? Вы всегда можете отключить рекламу.

Аннотация научной статьи по компьютерным и информационным наукам, автор научной работы — Легалов Александр Иванович

Рассматривается новый стиль разработки программ, названный процедурно-параметрической парадигмой программирования. В основе парадигмы лежит параметрический полиморфизм, обеспечивающий расширение и модификацию программ с минимальными изменениями существующего кода. Описываются программные объекты, которые необходимо включить в языки программирования, чтобы обеспечить инструментальную поддержку этой парадигмы.

i Надоели баннеры? Вы всегда можете отключить рекламу.
iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.
i Надоели баннеры? Вы всегда можете отключить рекламу.

Pocedure-parametric paradigm of programming is proposed. It's the new programming style, which uses parametric polymorphism for expanding and modification of programs and leads to minimal change of existing code. Program objects, which support this paradigm in programming languages, are described.

Текст научной работы на тему «Особенности процедурно-параметрической парадигмы программирования»

УДК 681.32

ОСОБЕННОСТИ ПРОЦЕДУРНО-ПАРАМЕТРИЧЕСКОЙ ПАРАДИГМЫ

ПРОГРАММИРОВАНИЯ

А.И.Легалов

Рассматривается новый стиль разработки программ, названный процедурно-параметрической парадигмой программирования. В основе парадигмы лежит параметрический полиморфизм, обеспечивающий расширение и модификацию программ с минимальными изменениями существующего кода. Описываются программные объекты, которые необходимо включить в языки программирования, чтобы обеспечить инструментальную поддержку этой парадигмы.

Pocedure-parametric paradigm of programming is proposed. It's the new programming style, which uses parametric polymorphism for expanding and modification of programs and leads to minimal change of existing code. Program objects, which support this paradigm in programming languages, are described.

ВВЕДЕНИЕ

Одним из главных критериев программных продуктов является сложность, а основными требованиями, предъявляемыми к методологиям разработки программного обеспечения, считаются: удобство сопровождения, возможность безболезненного наращивания уже существующей программы, возможность повторного использования разработанных программных объектов [1]. Этим требованиям во многом соответствует объектно-ориентированная методология (ООМ), которая, в настоящее время, получила наибольшее распространение. Составной частью ООМ является объектно-ориентированное программирование (ООП). Развитие ООП практически полностью вытеснило процедурное программирование из областей, связанных с разработкой сложных программных систем. Это обусловлено тем, что, несмотря на возможность написания объектно-ориентированных (ОО) программ с использованием процедурных языков, применение последних ведет к ошибкам, которые можно обнаружить лишь на более поздних этапах построения программы, чаще всего, во время выполнения. Такая ситуация возникает из-за того, что процедурные языки лишь моделируют объектную парадигму структурными средствами, используя при написании кода только динамические проверки состояния объектов и их типа. Применение объектно-ориентированных языков и инструментов зачастую позволяет избавиться от подобных ошибок уже во время компиляции.

Вместе с тем, практическое использование ОО подхода позволило выявить ряд недостатков [2, 3]. Их преодоление осуществляется так же, как и при использовании процедурных языков: моделированием с помощью языковых средств объектов, решающих проблемы, связанные с использованием объектно-ориентированных средств. В качестве одного из успешных примеров такого решения можно привести разработку образцов проектирования [4]. Однако использование моделирования вновь сдвигает

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

Одним из возможных путей, предложенным в работе [3], является разработка инструментальных средств поддерживающих процедурно-параметрическое программирование (ППП). Опираясь на процедурный подход, данная парадигма расширяет его механизмом, поддерживающим обработку альтернативных объектов без их явного описания в теле одной процедуры. Этот механизм похож на полиморфизм классов, используемый в ООП. В данной работе рассматриваются общие особенности процедурно-параметрического программирования и способы представления программных объектов, обеспечивающих его поддержку.

1. ОСОБЕННОСТИ ПРОЦЕДУРНО-

ПАРАМЕТРИЧЕСКОГО ПОДХОДА

Сравним между собой процедурный, объектно-ориентированный и процедурно-параметрический подходы. Основное отличие проявляется в организации языковых средств, обеспечивающих обработку альтернативных данных. Такая обработка встречается практически в любой задаче и связана с выполнением преобразований, проводимых над коллекциями разнотипных элементов, принадлежащих к одной категории. В качестве примера можно привести процедуру draw, осуществляющую рисование одной из геометрических фигур, включенной в состав некоторого изображения. Разные фигуры (круг, прямоугольник и т.д.), образующие изображение, принадлежат к одной категории (shape).

1.1. Организация процедурной программы

При процедурном подходе множество структур данных описывают отдельные геометрические фигуры. Для каждой фигуры создается специализированная процедура отображения. Для рисования одной из альтернатив формируется вариантное объединение, которое содержит признак хранимой фигуры и поле для хранения одной из фигур. Процедура отображения осуществляет анализ признака и рисует ту фигуру, которая соответствует этому признаку. Код, реализующий рассмотренные программные объекты, может быть разнообразным. Поэтому, представленный ниже фрагмент достаточно схематично отображает полученный результат. Для иллюстрации используется язык программирования C++.

//Геометрические фигуры и специализированные процедуры их обработки

struct circle {int r;}; // Круг радиуса r

void draw_ circle (circle &c) {...} // Рисование круга

struct rectangle {int a,b;}; // Прямоугольник со сторонами a, b

draw_rectangle (rectangle &r) {...} // Рисование прямоугольника

// Обобщенная фигура

enum shape_type {CIRCLE, RECTANGLE};

struct shape {

shape_type key; union {

circle c; rectangle r; } value;

};

// Обобщенная процедура рисования void draw (shape &s) { switch(s.key) {

case CIRCLE: draw(s.value.c); break; case RECTANGLE: draw(s.value.r); break;

}

}

Объединительной основой служит обобщающая процедура, в которой обрабатываются данные. Добавление новых методов обработки существующих данных не ведет к модификации написанного кода. Однако изменение числа фигур ведет к переделке всех процедур, обрабатывающих обобщенные фигуры. В реальной ситуации именно данные подвержены наибольшей модификации, а набор процедур, определяющий интерфейс программы, остается достаточно консервативным. Поэтому, процедурный подход не может обеспечить эффективного сопровождения при разработке больших программных систем, когда одно небольшое изменение данных ведет к огромному количеству изменений в процедурах.

1.2. Организация объектно-ориентированной программы

При объектно-ориентированном подходе первоначальный акцент смещается на проектирование (зачастую, абстрактное) сигнатур процедур, обеспечивающих обработку обобщающей фигуры. Создание такого обобщения предоставляет интерфейс и каркас для построения конкретных реализаций фигур на основе наследования. Оболочкой для хранения процедур, обрабатывающих конкретные фигуры, служит класс. Поэтому, появление новых фигур ведет к созданию нового класса и связанных с ним процедур без модификации уже написанного кода. Такое ортогональное проектирование оказывается ближе к реальной разработке больших программных систем. В качестве примера можно привести следующий фрагмент кода. // Обобщенная геометрическая фигура class shape {

public: virtual void draw()=0;//Чистый метод, определяющий

//рисование фигуры

... // Прочие члены класса

};

// Добавляемые геометрические фигуры class circle { // Круг

public: void draw() {...} // Рисует круг ... // Прочие члены класса

};

class rectangle { // Прямоугольник

public: void draw() {...} // Рисует прямоугольник ... // Прочие члены класса

};

Пример показывает, что в ОО программе происходит распределение обработчиков отдельных специализаций по классам, представляющим конкретные моделируемые объекты.

1.3. Моделирование процедурно-

параметрического механизма

Процедурно-параметрический механизм управления программой использует однозначную зависимость между данными, описывающими конкретные объекты, и процедурами их обработки. Как и при процедурном подходе, каждому из объектов (геометрической фигуре) ставится в соответствие признак, а общая для всех фигур процедура обработки (draw) использует этот признак в качестве ключа, определяющего конкретный обработчик. Отличие заключается в применении индексации вместо алгоритмического перебора вариантов, что позволяет обойтись без написания кода, анализирующего альтернативы. Признак, кроме идентификации специализации, выполняет функции переключателя на нужную процедуру. Моделирование процедурно-параметрического механизма можно осуществить с использованием процедурного языка: // Геометрические фигуры и их специализированные // обработчики

struct circle {int r;}; // Круг радиуса r

void draw_ circle (circle &c) {...} // Рисование круга

struct rectangle {int a, b;}; // Прямоугольник со сторонами a, b

draw_rectangle (rectangle &r) {...} // Рисование прямоугольника

// Модель параметрического обобщения

enum shape_type {CIRCLE = 0, RECTANGLE};

struct shape {

shape_type key; // Признак параметрического обобщения void *value;// Указатель на конкретную фигуру

};

//Обобщенная параметрическая процедура рисования строится из: // - отдельных обработчиков специализаций обобщенной фигуры void draw_shape_circle(shape &s) {draw_circle(*((circle*)(s.value)));} void draw_shape_rectangle(shape &s) {draw_rectangle(*((rectangle*)(s.value)));} // - массива указателей на эти обработчики int const shape_number = 2; // Количество фигур void (*draw[shape_number]) (shape&s) = {draw_shape_circle, draw_shape_rectangle};

При выполнении ПП программы осуществляется создание конкретной специализации (например, circle) и привязка к указателю value объекта shape: shape s; s.key = CIRCLE; s.value = new circle; s.value->r = 5;

Вызов обработчика специализации осуществляется следующим образом:

draw [s.key] (s);

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

ции, определяющих процедурно-параметрическии язык программирования, позволит разработчику не менять уже написанныИ код.

2. ОРГАНИЗАЦИЯ ОБЪЕКТОВ ПРОЦЕДУРНО-

ПАРАМЕТРИЧЕСКОГО ЯЗЫКА

2.1. Основные понятия процедурно-

параметрической парадигмы

Основными объектами, используемыми в процедурно-параметрическом программировании, являются:

..Параметрические обобщения, поддерживающие однозначное соответствие между признаками и специализациями.

2.Обобщающие параметрические процедуры, определяющие сигнатуры обработчиков параметрических обобщениИ.

3.Обработчики параметрических специализаций, обеспечивающие манипуляции с конкретными экземплярами данных, включенными в состав параметрических обобщениИ.

4.Экземпляры параметрических обобщений, представляющие конкретные программные объекты, обрабатываемые в ходе вычислении.

5.Вызовы параметрических процедур, обеспечивающие доступ к отдельным обработчикам специализации через единые сигнатуры, определяемые обобщающими параметрическими процедурами.

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

Механизм параметрического обобщения - совокупность понятии и объектов, обеспечивающих поддержку процедурно-параметрического программирования. Различные способы организации механизма параметрического обобщения определяют множество методов процедурно-параметрического полиморфизма.

2.2. Организация параметрических обобщений

Параметрическое обобщение позволяет сгруппировать в единое понятие не связанные ранее программные объекты, однозначно сопоставляя их с признаками. Признак - это ключ, идентифицирующии программныи объект в рамках рассматриваемого контекста, задающего некоторую категорию. Множество признаков: Т = {¿2> •••> tn} , где п - количество признаков, используемых для построения параметрического обобщения. Каждому ti ставится в

соответствие специализация Sj = {я.я.2,...., Яу^,} , где Sj - программный объект, выступающий в роли специализации обобщения. Sj с S, множеству программных объектов, используемых в качестве специализации обобщения. Множество {яу., яу2, ...я. , •••, яук} - это значения,

принимаемые специализацией Sj .

Параметрическое обобщение задается отображением и: Т х S , где ы, = (ti, Si) определяет отдельный элемент

I I у

параметрического обобщения. При этом |Т ^ , то есть, различным признакам могут ставиться в соответствие одинаковые программные объекты, определяющие специализации. Это может быть связано с различными способами использования одинаковых программных объектов. Следует также отметить, что все признаки, специализации и параметрические обобщения принадлежат множеству различных программных объектов X: Т с X и S с X.

2.3. Организация обобщающих параметрических процедур

Обобщающая параметрическая процедура Г является отображением:

^ихи2х... XипХг1хгх •Xгт^¥хх^х •х¥к,

где - и., и2, • ••, ип - параметрические аргументы, являющиеся параметрическими обобщениями, г., г2, •.., гт - прочие аргументы, У., У2, • .., Ук - результаты отображения. Аргументы и результаты отображения принадлежат множеству X допустимых программных объектов:

и: е X, г. е X, У. е X.

1 у 1

Игнорируем особенности аргументов г., г2, •.., гт и результатов У., У2, •.., У к, обозначив их через Ж. Кроме

того, нас будут интересовать не столько отображения, сколько параметрические аргументы. Тогда обобщающую параметрическую процедуру можно будет представить как:

^х^ • х ипх грх г2х • гт^Ух У2 х •х У,= - ^х^ • хипхг.хг2х ^х У.хУ2х -хУк--^:и1хи2х •.. хипх Ж.

Сигнатуру обобщающеи процедуры можно представить в обычноИ функциональной форме: Г(и., и2, • .., ип, Ж) ,

где и., и2, •.., ип - параметрические аргументы, а Ж -

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

Л и 1, и2, •.., ип ](Ж) - и1, и2, •.., ип, Ж) .

Наряду с разделением аргументов, такая запись подчеркивает один из возможных способов реализации механизма параметрического полиморфизма посредством многомерных массивов указателей на обработчики параметрических специализации. Конструкцию [и., и2, •••, ип]

назовем параметрическим списком.

Основной задачей обобщающей параметрической процедуры является предоставление единого интерфейса для множества обработчиков параметрических специализаций. Обобщающая параметрическая процедура поддерживает выполнение следующих функций:

1. Обеспечивает доступ к требуемому обработчику параметрической специализации в зависимости от значения аргументов параметрического списка посредством параметрического полиморфизма. Реализация механизма доступа зависит от реализации параметрического обобщения и организации процесса обработки параметрических специализаций.

2. При необходимости, предоставляет обработчик параметрической специализации по умолчанию. Его можно использовать при отсутствии обработчика соответствующей специализации. Предоставление обработчика по умолчанию не является обязательным. В этом случае отсутствие обработчиков специализаций должно привести к выдаче ошибки во время компиляции, компоновки или выполнения. Момент выдачи такой ошибки определяется периодом окончательного формирования параметрического обобщения.

3. Обобщающая параметрическая процедура может предоставить и обработчик исключения, если отсутствует один из обработчиков специализации. Обработчик исключения можно использовать как во время компиляции, так и во время выполнения. Предполагается, что, при отсутствии обработчиков параметрических специализаций можно выбрать обработчик по умолчанию или обработчик исключения. Присутствие этих обработчиков предполагается определять опционально. Корректность логики функционирования программы при их отсутствии должна определяться средой разработки и исполнительной системой.

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

2.4. Организация обработчиков

параметрических специализаций

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

F [ Ui( tu ), U2 ( t2j ),..., un( tnk)]( xm ),

где tqr e T - одно из значений признака, принадлежащего множеству признаков T параметрического обобщения Uq . Множество обработчиков некоторой обобщающей параметрической процедуры отличаются друг от друга тем, что каждый имеет уникальную комбинацию признаков, определяющую ту специализацию параметрического списка, которую он может обработать. Тело каждого обработчика содержит свой набор инструкций. Максимально возможное число обработчиков

параметрических специализации определяется как произведение мощностей признаков обобщении, входящих в параметрический список:

N = \T.

X T2 X.

х T

где - множество признаков параметрического обобщения Ut.

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

2.5. Экземпляр параметрического обобщения

Экземпляром параметрического обобщения является размещаемый в памяти компьютера программный объект, для которого определено и зафиксировано одно из конкретных значений элемента отображения u, = (t,, S,) .

I I j

При этом, во время работы программы, элемент Sj может

принимать любое значение s ■ е S,. Значение признака t,

jq j i

в ходе вычислений должно оставаться неизменным.

2.6. Вызовы параметрических процедур

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

2.7. Возможная реализация процедурно-параметрических понятий

Ниже представлен фрагмент кода рисования геометрических фигур, написанный с использованием воображаемых процедурно-параметрических конструкций, встроенных в язык программирования, похожий на C++. // Реализуемые геометрические фигуры и их обработчики struct circle {int r;}; // Круг радиуса r void draw_ circle (circle &c) {...} // Рисование круга struct rectangle {int a, b;}; // Прямоугольник со сторонами a, b draw_rectangle (rectangle &r) {...} // Рисование прямоугольника // Параметрическое обобщение

union shape switch(auto) { // Использует автоматическое // формирование признака case CIRCLE: circle; case RECTANGLE: rectangle;

};

// Обобщенная параметрическая процедура void draw[shape&s]( ) = 0; // отсутствуют обработчики // по умолчанию и исключений // Обработчики специализаций

void draw[shape<CIRCLE> &s] {draw(s);} // Нарисует круг void draw[shape<RECTANGLE>&s] {draw(s);} // Нарисует // прямоугольник

Создать требуемый экземпляр круга можно так: shape<CIRCLE> c;

Дальнейшая работа с этим объектом осуществляется как с обычным кругом:

c.r = 5;

Вызов обработчика производится следующим образом: draw [c] ();

Более подробное описание других аспектов ППП представлено в работе [3].

ЗАКЛЮЧЕНИЕ

Использование объектов, поддерживающих процедурно-параметрическое программирование, позволяет расширить функциональные возможности существующих процедурных языков, сделать их более приспособленными для

разработки больших программных систем. Процедурно-параметрическую парадигму можно использовать в качестве альтернативы объектно-ориентированному подходу. Интересные эффекты могут быть получены и при совместном использовании ООП и ППП [3].

ПЕРЕЧЕНЬ ССЫЛОК

1. Буч Г. Объектно-ориентированный анализ и проектирование с примерами приложений на C++, 2-е изд./Пер. с англ. - М.: Издательства Бином, СПб: Невский диалект, 1998 г. -560 с., ил.

2. Moessenboeck H., Wirth N. The Programming Language Oberon-2. Institut fur Computersysteme, ETH Zurich, July, 1996.

3. Легалов А.И. Процедурно-параметрическая парадигма программирования. Возможна ли альтернатива объектно-ориентированному стилю? - Красноярск: 2000. Деп. рук. № 622-В00 Деп. в ВИНИТИ 13.03.2000. - 43 с.

4. Gamma E., Helm R., Johnson R., Vlissides J. Design Patterns: Elements of Reusable Object-Oriented Software. - ISBN 0-20163442-2 Hardback, 416 p. 1995.

УДК 519.72: 616.8 - 091.81

АНАЛИЗ ФОРМАЛЬНО-ЛОГИЧЕСКОЙ МОДЕЛИ НЕЙРОНА С ПОМОЩЬЮ ДИСКРЕТНОГО ПРОСТРАНСТВА СОСТОЯНИЙ

В.Н.Лопин

Рассмотрен метод комплексного анализа формально-логической модели нейрона с позиций его надежности и сложности, использующий дискретное пространство состояний. Полученные результаты позволяют подойти к решению задачи синтеза надежных искусственных нейронных сетей и объясняют возможный механизм надежности биологических нейронных сетей.

Considered method of complex analysis formally-logical neuron model from positions of its reliability and difficulty, using discrete condition space. Tinned results allow to decide the problem of syntheses reliable artificial neuronal nets and explain a possible mechanism of reliability biological neuronal nets.

ВВЕДЕНИЕ

Одним из важнейших достоинств биологических нейронных сетей является их высокая надежность. Этим можно объяснять постоянный интерес к изучению данной проблемы [1-4]. Исследования в этом направлении позволяют лучше понять высокоэффективный механизм функционирования нейронных структур и использовать полученные знания при создании искусственных информационных систем принципиально нового поколения. Можно отметить, что к настоящему времени еще не сложился единый подход к объяснению феномена высокой надежности и целостного механизма организации биологических нейронных сетей. Несомненно, ввиду чрезвычайной сложности этой проблемы, исследования надежности необходимо проводить комплексно, с учетом других взаимосвязанных характеристик нейронных сетей.

В данной работе делается попытка комплексного подхода к объяснению механизма высокой надежности нейрона с позиций его пространства состояний [5], а также к установлению связи надежности нейрона с его сложностью и внутренним состоянием.

АНАЛИЗ ФОРМАЛЬНО-ЛОГИЧЕСКОЙ

МОДЕЛИ НЕЙРОНА

Введем в рассмотрение, без потери общности, простейшую формально-логическую модель нейрона, реализующую все булевы функции одной переменной:

y = Sign(B • х + T), (1)

где y - выходной сигнал, х - входной сигнал, B - вес входа, T - порог,

, 0, A < 0 Sign (A) = + .

) 1, A > 0

Состоянием нейрона назовем пару действительных чисел (B, T) , тогда пространство состояний нейрона определится как:

R = {(B, T)} . (2)

i Надоели баннеры? Вы всегда можете отключить рекламу.