
- •6. Исчисление последовательных программ.
- •Часть 6 развивает изложение программного исчисления для последовательных программ, что позволяет нам сформулировать правила проектирования операторов begin, которые выполняются корректно.
- •6.1. Значение частей программы.
- •6.1.1. Состояния выполнения.
- •6.1.2. Значение заголовка программы и точки.
- •6.1.3. Композиция отношений и функций.
- •6.1.4. Значение объявлений.
- •6.1.5. Значение блоков.
- •6.2. Значение последовательных выражений.
- •6.2.1. Оператор присвоения.
- •6.2.2. Пустой оператор.
- •6.2.3. Оператор begin
- •6.2.4. Оператор write.
- •6.2.5. Оператор read
- •6.2.6. Простые процедуры.
- •6.3. Анализ последовательных выражений
- •6.3.1. Одновременные присваивания.
- •6.3.2. Символическое выполнение и таблицы трассировки.
6.2.5. Оператор read
Действия, выполняемые оператором READ, которые мы рассмотрели в разделе 5.2.2 также могут быть рассмотрены с точки зрения изменения состояний выполнения. Пусть f – файловый идентификатор, а c – символьная переменная, тогда:
RESET(f) = {<s, t>: s(f) = <x, y, R>, где x и y – строки,
t = (s – {<f, u>: u –3-список}) {<f, <††, x&y, R>>}}
READ(f, c) = {<s, t>: s(f) = <x, y, R>, где x и y – строки, y ††
t = ((s – {<f, u>: u – 3-список}) – {<c, v>: v – символьное значение})
{<f, <x( Θ y, Λ y, R>>}
{<c, Θ y >: Θ y /} {<c, □>: Θ y = /}}
READLN(f) = {<s, t>: s(f) = <x, y, R>, где x и y – строки, y ††
y = (j не подстрока j,
t = (s – {<f, u>: u – 3-список}) {<f, <x & (j ), k, R>>}}
Когда файловый идентификатор отсутствует, INPUT является файлом для выражений READ и READLN. Например:
READ(c) = {<s, t>: s(INPUT) = <x, y, R>, где x и y – строки, y ††
t = ((s – {<INPUT, u>: u – 3-список}) – {<c, v>: v – символьное значение})
{<INPUT, <x( Θ y, Λ y, R>>}
{<c, Θ y >: Θ y /} {<c, □>: Θ y = /}}
Примеры:
RESET(F1) ({F1<AB,CD/,R>,…}) = {F1<ABCD/,††, R>, …}
READ(F1, Ch) ({F1<AB,CD/,R>, ChQ,…}) = {F1<ABC, D/,R>, ChC,…}
READLN ({INPUT<AB,CD/,R>,…}) = {INPUT<ABCD/, ††,R>,…}
Значение более сложных операторов READ определяется через композицию более простых:
READ (Ch1, Ch2) = READ (Ch1) ◦ READ (Ch2)
READLN(Ch) = READ (Ch) ◦ READLN
В качестве примера рассмотрим программу:
PROGRAM Change2 (INPUT, OUTPUT);
VAR
C2:CHAR;
BEGIN
READ(C2);
WRITE(C2);
READ(C2);
WRITELN(‘2’);
END.
При вычислении PROGRAM Change2 END. (<†ABC†>) первые шаги аналогичны тем, которые предпринимались при вычислении значения WriteHello в предыдущем разделе.
PROGRAM Change2 END. (<†ABC†>) =
(PROGRAM Change2 ◦ VAR … ◦ BEGIN … END ◦ VAR …T ◦ .) (<†ABC†>)
…
= ( BEGIN … END ◦ VAR …T ◦ .)
({INPUT<††, ABC/, R>, OUTPUT<††, ††, W>, C2?)
= ( READ(C2) ◦ WRITE(C2) ◦ READ(C2) ◦ WRITELN(‘2’) ◦ VAR …T ◦ .)
({INPUT<††, ABC/, R>, OUTPUT<††, ††, W>, C2?)
= ( WRITE(C2) ◦ READ(C2) ◦ WRITELN(‘2’) ◦ VAR …T ◦ .)
({INPUT<†A†, BC/, R>, OUTPUT<††, ††, W>, C2A)
= ( READ(C2) ◦ WRITELN(‘2’) ◦ VAR …T ◦ .)
({INPUT<†A†, BC/, R>, OUTPUT<†A†, ††, W>, C2A)
= ( WRITELN(‘2’) ◦ VAR …T ◦ .)
({INPUT<†AB†, C/, R>, OUTPUT<†A†, ††, W>, C2B)
= ( VAR …T ◦ .) ({INPUT<†AB†, C/, R>, OUTPUT<†A2†, ††, W>, C2B)
= . ({INPUT<†AB†, C/, R>, OUTPUT<†A2†, ††, W>)
= <†A2†>
Таким образом, PROGRAM Change2 END. (<†ABC†>) = <†A2†>
6.2.6. Простые процедуры.
Объявление символьных переменных добавляет к состоянию выполнения идентификатор с неизвестным значением. Значение переменной в дальнейшем может быть изменено и использовано при вычислении значений других выражений. Объявление процедуры также добавляет идентификатор к состоянию выполнения, значением его является полный текст процедуры. Например:
PROGRAM SimpleProc (INPUT, OUTPUT);
PROCEDURE Demo;
BEGIN
WRITELN(‘Invoked’);
END;
BEGIN
Demo;
END.
Объявление процедуры добавляет пару <†Demo†, †BEGIN WRITELN(‘Invoked’) END†> к состоянию выполнения. Значение процедурного оператора будет:
Demo = BEGIN WRITELN(‘Invoked’) END
Формальное описание частного значения процедуры соответствует вышесказанному. Пусть N – идентификатор процедуры, тогда:
N = {s, s(N)(s)}