Идеальным средством рассмотрения таких проблем, как проблема развития при теоретико-эвристическом подходе, представляется на первый взгляд программирование на ЦВМ, потому что задача запрограммировать модель развивающейся системы обязывает не только к точности мысли, но и к тому, чтобы видеть весь процесс в целом, причем эффективность модели немедленно проверяется при ее реализации на вычислительной машине. При этом такая модель не нуждается ни в каком анализе, поскольку она сама построена из исходных элементов программистом и в законченном виде в ней все учтено явно. На практике, однако, программирование имеет свои отрицательные стороны. В конце этой главы мы выясним, что это за отрицательные стороны.
В то время как, например, деятельность нервной системы моделировалась на машинах много раз и существуют даже, как мы видели в гл. 3, модели эволюционного процесса, до сих пор не было ни одного сообщения о каких-либо попытках моделировать процесс развития.
Для реализации моделей, о которых пойдет речь здесь, была выбрана машина марки Нэйшнл-Эллиот 803 [1, 2]. Это небольшая, со средним быстродействием универсальная электронная цифровая вычислительная машина. Хотя есть много машин больше и сложнее, для наших целей эта оказалась вполне подходящей и, более того, некоторые ее свойства, как мы вскоре увидим, были идеальными. Несколько коротких выдержек из [2] позволят составить о ней достаточное для дальнейшего представление.
Общее ее устройство обычно для одноадресных машин.
Каждая операция производится над двумя операндами,
из которых один находится в накопителе, а другой в
ячейке памяти, адрес которой записан в команде. После
выполнения операции в этой ячейке записывается либо
один из операндов, либо результат операции. Команда,
подлежащая выполнению, находится в регистре команд,
к которому присоединена декодирующая система для выборки
операции, которую надо выполнить, и нужной ячейки.
Две одноадресные команды помещаются в одном слове.
Благодаря специальному В-разряду, расположенному
между этими двумя командами, вторая без потери скорости
может быть модифицирована путем прибавления к ней содержимого
ячейки с адресом, указанным в адресной части первой,
каким бы этот адрес ни был.
Оперативная память содержит 4096 ячеек, в каждой из которых может быть записано слово из 39 разрядов. В той конкретной машине, которая использовалась, память была увеличена путем добавления нескольких магнитных лент общей вместимостью 4000 ячеек.
Машина может выполнять шестьдесят четыре операции и модификацию с помощью В-разряда. В приложении 1 дан список всех команд, которыми мы здесь будем пользоваться.
Удобно было бы пользоваться изящным автокодом, который существует для этой машины [3], и тот факт, что программа при пользовании им сама выбирает себе ячейки для работы, должен был бы быть особенно полезен, если мы хотим работать с недоопределенными программами развития, так как при этом было бы нежелательно задавать точно положения ячеек для хода развития, если вся соль такой модели в том, что неизвестно точно, как пойдет развитие до тех пор, пока программу не прогонят на машине. К сожалению, оказалось невозможным использовать автокод при составлении программ, моделирующих развитие. Дело в том, что если мы хотим, чтобы процесс развития удовлетворял аксиомам гл. 2, т. е. согласовался с тем, что довольно достоверно известно о реальном развитии, то программа, являющаяся моделью зиготы, должна быть в состоянии воспроизвести себе подобную и положить начало ряду таких самовоспроизведений, как основе процесса развития. Всякая иная модель развития тривиальна. Недостаточно, например, если программа последовательно увеличивает число ячеек, занятых числами; это будет, согласно доводам, приведенным в предыдущей главе, скорее рост, управляемый извне, чем развитие, управляемое изнутри. Очевидно, сами команды должны заполнять все новые ячейки. При этом трудность заключается в том, что для самовоспроизведения необходимо самообращение, а при пользовании автокодом программа не может оперировать со своими собственными ячейками, так как неизвестно точно, где они находятся. Автокод позволяет обращаться только к содержимому ячеек, но не к самим ячейкам. Можно еще обращаться к счетчикам и контрольным точкам, но даже их положений в машине мы тоже не знаем. Оказывается, на машине 803 можно дополнить программы на автокоде подпрограммами в машинном коде, но использование этой возможности очень ограничено, и обращение к определенным ячейкам основной программы на автокоде по-прежнему невозможно, а возможно лишь обращение к специальным точкам для передачи управления [4]. Таким образом, самообращение невозможно.
Поэтому при составлении программ самовоспроизведения и развития нам пришлось пользоваться машинным кодом. И здесь очень пригодилось то удобство машины 803, что при нормальных условиях в каждую ячейку можно вписать на выбор число или две команды, причем только сама программа определяет, рассматривается ли содержимое ячейки как число или как две команды, в зависимости от того, как она это содержимое использует. Это отличает 803 от многих других машин, в которых одна часть памяти закреплена за командами, а другая - за числами; при этом одни от других отличаются скорее положением, чем способом использования, и двойственное обращение с содержимым ячеек невозможно. Эта возможность двойственности в обращении с ячейками для нас существенна, так как она означает, что программа в ходе своей работы может обращаться с самой собой как с набором чисел. Таким образом, содержимое любой ячейки программы можно было скопировать (воспроизвести) в любой другой ячейке, пропуская его через накопитель, как если бы это было число, а затем снова использовать по назначению, как пару команд.