Оператор присвоения.
Значение некоторого оператора присвоения является функцией из одного состояния выполнения в другое. В таблице выполнения оператор присвоения заставляет идентификатор в своей левой части быть связанным с новой величиной, полученной из выражения справа. Box-нотация может быть расширена, чтобы обозначать значение выражения в правой части оператора присвоения. Частное значение такого выражения – это значение, взятое для данного состояния выполнения. Если оператор присвоения: Ch1:= Ch2; выражение справа – символьное выражение, представленное переменной, и ее значение доступно в данном состоянии выполнения. Рассмотрим значение символьной переменной, используя следующий пример. В состоянии, содержащем пару Ch2·B, символьная переменнаяCh2 имеет значение B. Таким образом, для идентификатора W, объявленного как CHAR, частным значением выражения W для состояния s является W(s). W = {<s, s(W)>} Например: Ch ({INPUT ·<††, ††, R>, OUTPUT ·<††, ††, W>,Ch·F, V1·C}) = {INPUT ·<††, ††, R>, OUTPUT ·<††, ††, W>,Ch·F, V1·C}(Ch) = F
Значение символьного литерала вычислить легче, потому что оно никак не зависит от состояния выполнения. Вне зависимости от того, что в состоянии выполнения, значением символьного литерала является сам литерал. ‘A’ (s) = A ‘B’ (s) = B и т.д.
Определение частного значения символьного выражения позволяет нам рассмотреть определение частного значения оператора присвоенияс идентификатором V в левой части и выражением E в правой части: V:= E = {<s, t>: t = (s – {<V, c >: c - символ}) È {<V, E (s)>}} Разность множеств удаляет старое значение V из состояния выполнения, объединение добавляет соответствующее новое значение.
Для идентификаторов V1 и V2 и символьного выражения, представленного литералом ‘A’, определение будет выглядеть как:
V1:= V2 ={<s, t>: t = t такое же как s за исключением V1 (t) = V2(s)} V1:= ‘A’ ={<s, t>: t = t такое же как s за исключением V1 (t) = A}
Примеры: V1:= ‘B’ ({V1·A, …}) = {V1·B, …} V2:= V1 ({V1·A, V2·B,…}) = {V1·A, V2·A, …} V1:= V2 ({V1·?, V2·A,…}) = {V1·A, V2·A, …} V1:= V2 ({V1·A, V2·?,…}) = {V1·?, V2·?, …}
Области определения и значений для рассмотренных частных значений приведены в следующей таблице.
Пустой оператор.
Пустой оператор ничего не выполняет, следовательно не изменяет состояние выполнения. Значением для такого поведения является функция эквивалентности I. Таким образом: = I = {<s, s>}
Оператор BEGIN
Оператор BEGIN может содержать одно или более вложенных операторов, разделенных точкой с запятой. Должен быть как минимум один оператор, BEGIN END содержит пустое выражение.
Значение оператора BEGIN может быть определено через значения входящих в него операторов. Пусть S будет одиночный оператор, T – последовательность из одного или более операторов, разделенных точкой с.запятой. BEGIN S END = S BEGIN S; T END = S ◦ BEGIN T END
Например: BEGIN V1:= V2; V2:= V3 END = V1:= V2 ◦ BEGIN V2:= V3 END и BEGIN V1:= V2; V2:= V3; V3:= V4 END = V1:= V2 ◦ BEGIN V2:= V3; V3:= V4 END = V1:= V2 ◦ V2:= V3 ◦ V3:= V4
Оператор BEGIN может изменять значения нескольких переменных. Например: BEGIN V1:= ‘A’; V2:= ‘B’ END ({V1·H, V2·K,…}) = V1:= ‘A’ ◦ V2:= ‘B’ ({V1·H, V2·K,…}) (1)
= V2:= ‘B’ (V1:= ‘A’({V1·H, V2·K,…})) (2) = V2:= ‘B’ ({V1·A, V2·K,…})) (3) = {V1·A, V2·B,…} (4)
На шаге 1 частное значение оператора BEGIN представляется как композиция входящих в него операторов. На шаге 2 выражение приводится к функциональной форме записи. На шаге 3 вычисляется значение первого входящего оператора, и на шаге 4 – значение второго входящего оператора.
Оператор BEGIN может изменять значения одной переменной несколько раз. Например: BEGIN V1:= ‘A’; V1:= ‘B’ END ({V1·H, V2·K,…}) = V1:= ‘A’ ◦ V1:= ‘B’ ({V1·H, V2·K,…}) = V1:= ‘B’ ({V1·A, V2·K,…})) = {V1·B, V2·K,…}
Перемещение двухсимвольного окна из V1, V2 в V2, V3 может быть проанализировано следующим образом: Похожий подход используется при обмене двух символьных значений
BEGIN V1:= V2; V2:= V3; V3:= V1 END ({V1·X, V2·Y, V3·Z, …}) = V1:= V2 ◦ V2:= V3 ◦ V3:= V1 ({V1·X, V2·Y, V3·Z, …}) = V2:= V3 ◦ V3:= V1 ({V1·Y, V2·Y, V3·Z, …}) = V3:= V1 ({V1·Y, V2·Z, V3·Z, …}) = {V1·Y, V2·Z, V3·Y, …}
Оператор WRITE.
Значение файлов описывается 3-спискоми и действие операторов READ и WRITE было описано ранее в разделе 5.2.2. То описание может легко быть трансформировано в формальное значение через влияние операторов на состояния выполнения. Пусть f будет файловый идентификатор, а c – символьное выражение.
REWRITE(f) = {<s, t>: t = (s – {<f, u>: u –3-список}) È {<f, <††, ††, W>>}} WRITE(f, e) = {<s, t>: s(f) =< x, ††, W>, где x – строка, t = (s – {<f, u>: u – 3-список}) È {<f, <xÑe(s), ††, W>>} } WRITELN(f) = {<s, t>: s(f) =< x, ††, W>, где x – строка, t = (s – {<f, u>: u – 3-список}) È {<f, <xÑ /, ††, W>>} }
Когда файловый идентификатор отсутствует, OUTPUT является файлом для выражений WRITE и WRITELN. Например:
WRITELN = {<s, t>: s(OUTPUT) =< x, ††, W>, где x – строка, t = (s – {<OUTPUT, u>: u – 3-список}) È {<OUTPUT, <xÑ /, ††, W>>} }
Например: REWRITE(F1) ({F1·<AXB, ††, W>, …}) = {F1·<††, ††, W>, …} WRITE(F1, Ch) ({F1·<AB, ††, W>, Ch·C,…}) = {F1·<†ABC†, ††, W>, Ch·C,…} WRITELN ({OUTPUT·<Line1, ††, W>, …}) = {OUTPUT·<Line1/, ††, W>, …} Операторы WRITE, включающие несколько выражений, определяются как комбинации более простых операторов с композицией их значений: WRITE(Ch, ‘A’) = WRITE(Ch) ◦ WRITE(‘A’) WRITE(‘AB’) = WRITE(‘A’) ◦ WRITE(‘B’) WRITELN(F1, Ch) = WRITE(F1, Ch) ◦ WRITELN(F1)
PROGRAM WriteHello (INPUT, OUTPUT); VAR LetterL: CHAR; BEGIN LetterL:= ‘L’; WRITELN(‘H’, ‘E’, LetterL, LetterL, ‘O’) END.
Следующие вычисления определяют значение программы для входного 1-списка <†ABC†>
PROGRAM WriteHello … END. (<†ABC†>) = (PROGRAM ◦ VAR … BEGIN … END. ◦.)(<†ABC†>) = VAR … BEGIN … END. ◦.)({INPUT ·<††, ABC/, R>, OUTPUT ·<††, ††, W>}) = VAR … ◦ BEGIN … END. ◦ VAR …T ◦. ({INPUT ·<††, ABC/, R>, OUTPUT ·<††, ††, W>}) = BEGIN … END. ◦ VAR …T ◦. ({INPUT ·<††, ABC/, R>, OUTPUT ·<††, ††, W>, Letter·?}) = (LetterL:= ‘L’ ◦ WRITELN(‘H’, ‘E’, LetterL, LetterL, ‘O’) ◦ VAR …T ◦.)({INPUT ·<††, ABC/, R>, OUTPUT ·<††, ††, W>, Letter·?}) = WRITELN(‘H’, ‘E’, LetterL, LetterL, ‘O’) ◦ VAR …T ◦.) ({INPUT ·<††, ABC/, R>, OUTPUT ·<††, ††, W>, Letter·L}) = (VAR …T ◦.)({INPUT ·<††, ABC/, R>, OUTPUT ·<†HELLO†, ††, W>, Letter·L}) = (.)({INPUT ·<††, ABC/, R>, OUTPUT ·<†HELLO†, ††, W>}) = <†HELLO†>
Таким образом, мы нашли значение программы для данного входа
PROGRAM WriteHello … END. (<†ABC†>)= <†HELLO†>
Оператор 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 Ñ / & k, / не подстрока 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>, Ch·Q,…}) = {F1·<ABC, D/,R>, Ch·C,…} 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>, C2·A) = (READ(C2) ◦ WRITELN(‘2’) ◦ VAR …T ◦.) ({INPUT·<†A†, BC/, R>, OUTPUT·<†A†, ††, W>, C2·A) = (WRITELN(‘2’) ◦ VAR …T ◦.) ({INPUT·<†AB†, C/, R>, OUTPUT·<†A†, ††, W>, C2·B) = (VAR …T ◦.) ({INPUT·<†AB†, C/, R>, OUTPUT·<†A2†, ††, W>, C2·B) =. ({INPUT·<†AB†, C/, R>, OUTPUT·<†A2†, ††, W>) = <†A2†>
Таким образом, PROGRAM Change2 END. (<†ABC†>) = <†A2†>
Простые процедуры.
Объявление символьных переменных добавляет к состоянию выполнения идентификатор с неизвестным значением. Значение переменной в дальнейшем может быть изменено и использовано при вычислении значений других выражений. Объявление процедуры также добавляет идентификатор к состоянию выполнения, значением его является полный текст процедуры. Например:
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)}
Читайте также: IV. Циклдік оператор алгоритмдерін программалау Воспользуйтесь поиском по сайту: ©2015 - 2025 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|