
- •2.6. Заключение .............................................................................................................. 22
- •4. Язык исчисления вычислимых предикатов,
- •4.12. Однозначность предикатов .......................................................................................... 45
- •5. Семантика языка предикатного программирования.
- •6.9. Формулы .......................................................................................................................... 78
- •6.9. Процессы ......................................................................................................................... 79
- •6.11. Императивное расширение .......................................................................................... 82
- •7.8. Заключение ................................................................................................................... 108
- •Введение в курс предикатного программирования
- •1. Общее понятие программы
- •1.1. Автоматическая вычислимость
- •1.2. Спецификация программы
- •1.3. Формы спецификации программы
- •Список литературы
- •2. Корректность программ с предикатной спецификацией
- •2.1. Предикатная спецификация программы
- •2.2. Логическая семантика языка программирования
- •2.3. Модель корректности программы
- •2.4. Система правил доказательства корректности операторов
- •2.4.1. Правила для корректного оператора
- •2.4.2. Правила корректности для параллельного оператора
- •2.4.3. Правила корректности для оператора суперпозиции
- •2.4.4. Правила корректности для условного оператора
- •2.5. Система правил вывода программы из спецификации
- •2.5.1. Однозначность предикатов
- •2.5.2. Теорема тождества спецификации и программы
- •2.5.3. Правила корректности для параллельного оператора
- •2.5.4. Правила корректности для оператора суперпозиции
- •2.5.5. Правила корректности для условного оператора
- •2.6. Заключение
- •Список литературы
- •3. Математические основы
- •3.1. Отношения порядка
- •3.2. Наименьшая неподвижная точка
- •3.3. Математическая индукция
- •Список литературы
- •4. Язык исчисления вычислимых предикатов, его логическая и операционная семантика
- •4.1. Структура программы на языке ccp
- •4.2. Система типов данных
- •4.3. Логическая и операционная семантика языка ccp
- •4.4. Семантика вызова предиката
- •4.5. Оператор суперпозиции
- •4.6. Параллельный оператор
- •4.7. Условный оператор
- •4.8. Конструктор предиката
- •4.9. Конструктор массива
- •4.10. Программа
- •4.11. Рекурсивные определения предикатов
- •4.12. Однозначность предикатов
- •Список литературы
- •5. Семантика языка предикатного программирования. Методы доказательства корректности предикатных программ
- •5.1. Язык p1: подстановка определения предиката на место вызова
- •5.2. Язык p2: оператор суперпозиции и параллельный оператор общего вида
- •5.3. Язык p2: другое обобщение оператора суперпозиции
- •5.4. Язык p3: выражения
- •5.5. Методы доказательства корректности рекурсивных программ
- •6. Язык предикатного программирования
- •6.1. Введение
- •6.2. Лексемы
- •6.3. Предикаты
- •6.3.1. Определение предиката
- •6.3.2. Спецификация предиката
- •6.3.3. Вызов предиката
- •6.4. Программа
- •6.5. Операторы
- •6.6. Выражения
- •6.7. Типы
- •6.8. Массивы
- •6.8.1. Описание типа массива
- •6.8.2. Вырезка массива
- •6.8.3. Определение массива
- •6.8.4. Объединение массивов
- •6.9. Формулы
- •6.10. Процессы
- •6.11. Императивное расширение
- •Список литературы
- •7. Технология предикатного программирования
- •7.1. Подстановка определения предиката на место вызова
- •7.2. Замена хвостовой рекурсии циклом
- •7.3. Склеивание переменных
- •7.4. Метод обобщения исходной задачи
- •7.5. Трансформация кодирования структурных объектов
- •7.6. Пример. Сортировка простыми вставками
- •7.7. Гиперфункции
- •7.8. Заключение
- •Список литература
1. Общее понятие программы
Понятие программы обычно определяется в контексте некоторого языка программирования. Представление об общем понятии программы, абстрагированное от конкретного языка программирования, для специалиста в области информатики суммируется из его опыта работы с разными языками программирования. В литературе хорошо представлены различные аспекты языков программирования: типы данных, модульность, объектная ориентированность, параллелизм и др. (см., например, [13]). Однако сумма разных аспектов не дает четкой интегрированной концепции общего понятия программы. Этот пробел обнаруживается в учебных курсах по основам программирования и в энциклопедиях. Возможно, лучшим кратким определением в энциклопедиях является следующее: «программа есть описание алгоритма решения задачи, заданное на языке программирования» [1].
Понятия алгоритма и программы не тождественны. Понятие алгоритма известно давно и считается хорошо изученным. В математике существуют следующие формализации понятия алгоритма: машина Тьюринга [10], частично рекурсивные функции, нормальный алгорифм Маркова [2] и каноническая система Поста [3]. Понятие программы появилось вместе с первыми компьютерами в 1940-х 1.
Имеются два определяющих свойства программы: автоматическая вычислимость и существование спецификации.
1.1. Автоматическая вычислимость
Развитие средств вычислений сопровождается все большей степенью автоматизации вычислений. Потребность в проведении сложных и длительных расчетов привела человека к необходимости создания и совершенствования механических устройств и машин для облегчения процесса вычисления. С древних времен известно устройство, которое в России называется «счеты». Счеты можно встретить и в наши дни. Счетные машины и арифмометры, создаваемые в XVI IXIX вв., автоматизировали выполнение четырех арифметических действий. В середине XX столетия актуальные потребности науки и практики привели к созданию новой отрасли техники – конструированию и производству счетно-решающих устройств, т. е. приборов и машин для решения математических задач [11]. Применение счетно-решающих устройств становится массовым: они используются для быстрых расчетов в боевой обстановке, в навигации, в автоматизированном управлении сложными агрегатами и т. д. Однако производство счетно-решающих устройств было сложным и дорогим. Поэтому появление универсальных электронно-вычислительных машин (ЭВМ), умеющих автоматически выполнять программу, построенную для произвольного алгоритма, стало неизбежным.
Промежуточное состояние автоматизации вычислений алгоритма реализуется современными калькуляторами, сравнимыми по своим возможностям со счетно-решающими устройствами 1940-х гг. На очередном шаге своей работы калькулятор либо принимает данные от пользователя, либо в автоматическом режиме вычисляет одну из операций. Более развитые калькуляторы позволяют сохранять промежуточные значения вычислений, именовать отдельные значения и массивы значений и использовать эти имена в дальнейших вычислениях. Таким образом, эти калькуляторы могут хранить в своей памяти значения нескольких переменных. Подчеркнем, что в сравнении с ручным счетом калькулятор автоматизирует вычисление только одной операции на каждом шаге, а между шагами требуются действия человека. С помощью калькулятора можно провести расчеты в принципе по любому алгоритму. Если мы захотим исключить действия человека между шагами и ограничить его действия лишь вводом начальных данных, то потребуется каким-то способом задать всю совокупность операций алгоритма и указать порядок вычисления операций. Необходимым инструментом для этого является программа.
Программа есть алгоритм, реализованный таким способом и в такой форме, что вычисление алгоритма проводится автоматически. По способу реализации различаются аппаратно реализованные программы (например, в виде интегральной схемы) и программы на языках программирования. Автоматическая вычислимость является неотъемлемым свойством программы.
Первые программы для реализации простейших операций появились в аппаратной реализации как составные блоки счетно-решающих устройств. Аппаратно реализованная программа конструировалась в виде электронной схемы с использованием электронно-вакуумных ламп, резисторов и конденсаторов, т. е. на элементной базе для ЭВМ первого поколения. Автоматическое исполнение программы реализуется прохождением электрического сигнала по элементам электронной схемы, что обеспечивает на выходе схемы требуемое вычисление. В настоящее время аппаратно реализованная программа конструируется в форме интегральной микросхемы.
Язык программирования определяет правила представления программы в виде текста в конечном алфавите символов. Описание языка определяет: типы данных, структуру памяти исполняемой программы, виды языковых конструкций программы, правила исполнения конструкции каждого вида и программы в целом. Память исполняемой программы состоит из сегментов. Сегмент памяти содержит набор переменных и соответствует независимо исполняемому фрагменту программы (например, процедуре). Языковая конструкция – независимая часть программы: оператор, выражение, описание процедуры и т. д. Всякая конструкция принадлежит некоторому виду. Для вида определяется единый способ изображения (кодирования) конструкций. Вид имеет несколько позиций, в которые помещаются подконструкции. Например, вид Оператор присваивания, изображаемый композицией: <Переменная> := <Выражение>, имеет две позиции для подконструкций, соответствующих понятиям <Переменная> и <Выражение>. Для большинства видов конструкций определен процесс исполнения, составляемый из процессов исполнения подконструкций и связующих действий. Данная концепция описания языка программирования более детально представлена в работе [8]. Отметим, что приведенное определение не годится для языка логического программирования, где исполнение определяется в форме логического вывода.
Автоматическое исполнение произвольной программы на языке программирования реализуется процессором. Процессор языка программирования является либо программой, реализованной аппаратно или на некотором другом языке программирования, либо виртуальным. Аппаратно реализованный процессор входит в состав компьютера и определяет язык системы команд компьютера. Примером реализации процессора на другом языке программирования является программа интерпретатора байткода для языка Java [5]. Процессор языка высокого уровня является виртуальным, представленным лишь в описании языка, и не существует в действительности. Язык реализуется посредством трансляции программы на другой язык, для которого существует реализованный процессор.