Дилемма первичности для операций и данных, операции с операциями
sergey shishkinМодели информации и данных. Атом и универсум информации
В отношении информационных технологий мы можем поднять вопрос первичности: что возникло раньше – данные или операции? Эта дилемма возникает не из праздного интереса, это дилемма определения главенства и выстраивания зависимостей. Должны ли обработки подстраиваться под структуры данных либо структуры данных должны строиться, исходя из особенностей обработок, в том числе языка программирования, особенностей доступа к данным?
С точки зрения агентов, информация является первичной, поскольку в окружающем мире информация не является собственностью самого агента, а потому агент существует в среде, насыщенной информацией. Кроме того, сошлемся на понятие априорной информации, описанное выше: она должна существовать до того, как первый процесс начнет «работать».
С точки зрения современных информационных систем и, в частности интеллектуальных систем, внутреннее хранилище данных также является первичным, поскольку результаты и исходные данные обычно напрямую определяются в структуре данных системы. Особенности архитектуры, поддерживаемые алгоритмы обработки данных обычно не влияют на структуру данных, поскольку все современные системы могут работать через универсальные интерфейсы с самыми разными хранилищами данных. Другими словами, при создании информационных систем сначала проектируется структура данных, и затем алгоритмы, работающие с этими данными.
Однако, если методы обработки данных предопределены заранее (например, мы вынуждены пользоваться каким-либо внешним программным модулем), то мы вырабатываем и подстраиваем под программу собственные структуры данных. В том числе эти структуры должны отвечать условиям необходимости и полноты внешнего программного модуля. Формально мы можем трансформировать данные, но не можем влиять на полноту данных, так как мы вынуждены оперировать требуемым от нас набором данных, а процедура дополнения данных до некоторого требуемого уровня – это неординарная и не всегда решаемая задача.
Возвращаясь к вопросам, освещенным в предыдущей главе, мы можем рассмотреть программный код как данные. И в этом случае дилемма первичности приводит нас к задаче структурирования кода как данных и дальнейшему управлению кодом (хотя бы даже кодом различного уровня, не обязательно кодом низкого уровня – машинным кодом). И тогда дилемма первичности превращается в несколько иную дилемму: что первично – курица или курица из яйца? Не воспринимайте этот вопрос как игру слов с целью затуманить Ваш мозг, это лишь попытка привести рассуждение к рассмотрению кода как данных.
Для рассмотрения возможностей соединения двух полярных субстанций (данных и процессов) рассмотрим эту дилемму с точки зрения аппаратных архитектур.
Код в данном случае представляет собой управляющие данные. Данные, которые обрабатываются программным кодом, называются операционными данными. Часто возникает вопрос разделения управляющих и операционных данных. Поскольку управляющие данные, то есть программы, хранятся ровно так же, как и операционные данные, возникает вопрос, могут ли смешиваться эти виды данных.
Если проанализировать историю программных и аппаратных архитектур, программных продуктов и парадигм программирования, то можно найти различия в подходах реализации хранения данных обработки и программных кодов.
Идеи, основанные на автоматном программировании, явно разделяют инструкции и память. Самые известные примеры автоматного программирования – это машина Тьюринга и машина Поста.
Аналогичная ситуация складывается и с продукционным программированием (нормальные алгоритмы Маркова). Продукции описываются одной структурой, а операционные данные рассматриваются как другая структура. Функциональное программирование (лямбда-исчисление) также разделяет описательную и операционную часть.
Ещё в 1946 году фон Нейманом при проектировании первых процессоров были сформированы несколько принципов построения ЭВМ. Одним из его принципов был принцип однородности памяти, в котором говорилось, что программы и данные хранятся в одной и той же памяти. С командами можно выполнять такие же действия, как и с данными. Альтернативой фон Неймановской архитектуре является гарвардская архитектура, которую отличает раздельное хранение команд и данных.
В практическом применении процессоры в начальной стадии развития разделяли общую область памяти на отдельные сегменты. В одном сегменте хранились управляющие данные, то есть коды команд, другой сегмент был областью памяти для хранения операционных данных. С развитием архитектуры процессоров для защиты программы от некорректных операций и, следовательно, для поддержания целостности управляющих инструкций процессора (команд), сам процессор контролировал область памяти с программным кодом и не позволял записывать в нее какие-либо значения.
В высокоуровневых языках программирования транслятор обычно ограничивает доступ к памяти, где хранится исполняемый код, а в интерпретируемых языках и вовсе отсутствует возможность не то, что скорректировать текст программы, но и даже получить этот текст. Одним из исключений является инструкция List некоторых реализаций языка программирования Basic, выводящая на экран исходный код программы. В других языках программирования для этих целей специально придумывают специальные программы, называемые «квайн» (quine). Аналогично, в скриптовых языках типа bat-файлов в dos/windows и *sh в Unix-системах код существует в текстовых файлах, а соответственно и доступ к ним может осуществляться через операции с файлами. В части языков программирования такая возможность реализуется через возможности интерпретатора или p-кода (пи-кода).
Другим исключением является операции аналогичного вида со встраиваемыми языками и скриптами. Первые – это SDK VBA, которые позволяют вызывать интерпретируемые VBA-процедуры из программного кода и скрипты обычно относятся к собственным языкам программирования либо тому же интерпретируемому языку программирование (как, например, команда exec в T-SQL и eval () в PHP).
Но фактически эти возможности остаются невостребованными с точки зрения модификации кода.
Говоря о различии между программным кодом и данными, нельзя забывать, что и программный код содержит данные.
Строгое разделение данных и программной обработки данных влияет и на целостность самих данных. В частности, программный код содержит константы, которые ссылаются на данные в хранилище данных, в том числе в СУБД. Данные со временем могут меняться, в то время как ссылки на них остаются неизменными. Часто эти ссылки невозможно отследить, что является потенциальным источником ошибок как результат несогласованности между данными внутри программного кода и данными в хранилище данных, что называется нарушением логической целостности данных.
Например, мы настраиваем финансовый отчет на основании оборотов по продажам и затратам. В программном коде отчета мы жестко привязываемся к счету плана счетов «Затраты на командировки», чтобы по этому конкретному коду счета настроить отчет, собирающий финансовые проводки из главной книги. В результате, если в дальнейшем потребуется изменить план счетов, например, изменить код для счета «затраты на командировки» либо создать дополнительный счёт с новым кодом для этих же целей, то отчет не будет работать так, как нужно – не будет работать вовсе либо будет работать частично по используемой ранее более узкой логике.
С одной стороны, вместо определения константы с кодом мы можем брать его из отдельного справочника или элемента данных, привязанного к плану счетов. Но с другой стороны, мы не можем это сделать, поскольку структура данных является фиксированной, а, кроме того, в таком случае нас ждёт сложная процедура администрирования этих структур, включая организацию ссылки на план счетов, массовых данных при необходимости (например, вместо одного счета мы должны указывать ряд счетов) и визуализации данных. Такой комплекс процедур влечет за собой существенные накладные расходы при настройке отчета, поэтому от этого пути отказываются в пользу отказа от контроля над целостностью данных.
В этой главе мы определили необходимые требования к реализации агента: это были требования сверху. То есть требования, которые помогут достичь критерия необходимости для достижения универсальности структур информации и данных.
Однако сам процесс структурирования и обработки информации невозможно начать, не обратившись к началам теории информации. Этому будут посвящены следующие главы.