99492

Исчисление последовательных программ

Лекция

Информатика, кибернетика и программирование

Развивает изложение программного исчисления для последовательных программ, что позволяет нам сформулировать правила проектирования операторов BEGIN, которые выполняются корректно.

Русский

2016-09-20

165.5 KB

0 чел.

Исчисление последовательных программ.

Развивает изложение программного исчисления для последовательных программ, что позволяет нам сформулировать правила проектирования операторовBEGIN, которые выполняются корректно.

Несмотря на то, что для небольших программ возможно определить их значение непосредственно из текста, для больших и сложных программ это сделать практически невозможно. В этом случае используется систематический метод, позволяющий определить значение программ шаг за шагом.

Части программ, объявления переменных, процедур и операторы могут быть проанализированы по отдельности, затем скомбинированы для нахождения значения программы в целом. При этом программа разбивается на блоки возрастающей сложности, а именно последовательные, условные, циклические.

Последовательная программа не содержит операторовIF иWHILE и набор строк в ее таблице выполнения неизменен. Поскольку поток выполнения проходит последовательно через все операторы программы, вне зависимости от входных данных будут выполнены все части программы.

Но значения в столбцах таблицы выполнения могут быть разными для разных данных, каждый столбец представляет собой историю значений переменной в процессе выполнения программы, каждая строка представляет собой часть программы, которая переводит программу из одного состояния в другое. Эти преобразования являются функциями или отношениями, которые образуют основу для вычисления программ.

1. Значение частей программы.

Простые программы имеют простые значения, для вычисления значений сложных программ требуется их декомпозиция. Процесс вычисления значения программы  в этом случае заключается в вычислении значений составляющих ее частей, а затем комбинировании этих значений.

Новые идеи: Состояния выполнения, композиция отношений и функций,  обратная функция, транспонирование, значение блоков и объявлений.

Целью программного исчисления является вычислениеP для любой программыCFPascalP в терминах компонентовP. Разбиение программы на части производится в соответствии с ее синтаксисом.

Промежуточные преобразования , каждое из которых относится к отдельному фрагменту Паскаль-программы, называются частными значениями, в отличие от значения программы в целом. Частные значения обозначаются с помощьюbox-нотации.

1.1. Состояния выполнения.

В таблице выполнения кромеINPUT иOUTPUT могут присутствовать другие переменные программы для описания действий Паскаль-машины, таких как объявление переменных, присваивание им значений и т.д. Строки вINPUT иOUTPUT и значения переменных программы образуют ее рабочие данные.

Допустим, что частично задана следующая программа.

PROGRAM Copy1 (INPUT, OUTPUT);

VAR

 Ch1: CHAR;

 Ch2: CHAR;

 F1: TEXT;

BEGIN

 REWRITE(F1);

 Ch1:= ‘B’;

 READ(Ch2);

 WRITE(F1, Ch2);

 …

END.

Ее таблица выполнения для входаABC начинается:

INPUT

OUTPUT

F1

Ch1

Ch2

PROGRAM Copy1 (INPUT, OUTPUT);

VAR

 Ch1: CHAR;

 Ch2: CHAR;

 F1: TEXT;

BEGIN

 REWRITE(F1);

 Ch1:= ‘B’;

 READ(Ch2);

 WRITE(F1, Ch2);

 …

END.

ABC/

ABC/

_

?

_

A_

?

B

?

A

Значения переменныхINPUT,OUTPUT,F1,Ch1,Ch2 являются основными элементами истории выполнения программы. Основная информация в таблице выполнения – список переменных и их текущих значений (информация одной строки таблицы). Для описания строки таблицы выполнения со значениями переменных наиболее подходит множество пар идентификатор-величина. Например, состояние после выполнения оператораREAD может быть представлено в виде 5-множества пар:

s = {<†INPUT†, <†A†, †BC†Ñ/,R>>, <†OUTPUT†, <††, ††,W>>,

<†F1†, <††, ††,W>>,  <†Ch1†, B>, <†Ch2†, A>}

Каждому идентификатору сопоставлена величина соответствующего типа. Например, дляINPUT – 3-список, имеющий строку прошлого <†A†, строку будущего  †BCÑ/,и состояние выполненияR.

Такой набор пар, сформированный на основе таблицы выполнения, называетсясостоянием выполнения. Состояние выполненияs – это функция, область определения (domain) которой это множество идентификаторов, область значений – множество величин описывающих  значения (содержимое) соответствующих переменных.

Состояние выполнения изменяется от строки к строке в таблице выполнения. Центральной задачей программного исчисления является вычисление состояний программы от строки к строке, используя для этого части программы, которые их определяют.

Значение части программы (частное значение) – функция или отношение, которое связывает между собой два состояния выполнения соответствующие двум соседним строкам в таблице выполнения. Например, состояние выполнения, следующее заs, будет:

t = {<†INPUT†, <†A†, †BC†Ñ/,R>>, <†OUTPUT†, <††, ††,W>>,

<†F1†, <†A†, ††,W>>,  <†Ch1†, B>, <†Ch2†, A>}

Состояниеt практически идентично состояниюs да исключением пары <†F1†, <†A†, ††,W>>, изменение которой отражает выполнение оператораWRITE. Программное исчисление предполагает правило для оператораWRITE, которое позволит получать состояниеt изs без использования других частей программы, в результате выполнения которых получаетсяs.

Посколькуs иt – функции, мы можем использовать функциональную запись (value-нотация).

s(†INPUT†) = <†A†, †BC†Ñ/,R>

t(†Ch1†) =B

Состояния выполнения для первых строк программы не так очевидны. В заголовке программыF1,Ch1,Ch2 не имеют значений, потому что еще не определены. Поэтому эти переменные не входят в состояние выполнения для данной строки.

u = {<†INPUT†, <††, †ABCÑ/,R>>, <†OUTPUT†, <††, ††,W>>}

Состояние выполненияu – функция, область определения которой множество

{<†INPUT†, <†OUTPUT†}

Поскольку в дальнейшемu переходит вs, очевидно, что часть программы может изменить не только значение функции, но и ее область определения. После объявления переменныхF1,Ch1 иCh2 они принимаю неопределенное значение, обозначенное знаком вопроса. Таким образом, объявление переменнойCh1 порождает набор состояний, каждое из которых будет иметь следующую форму

v = {<†INPUT†, <††, †ABCÑ/,R>>, <†OUTPUT†, <††, ††,W>>,  <Ch1,x>}

гдеx – любой символ. Значением части программы будет одно из множества состояний, заданныхv,  но мы не знаем какое именно. Используя функциональную форму записи, мы можем сказать, чтоv(†Ch1†) равно некоторому неизвестному символьному значению, которое будет удобно обозначать символом знак вопроса, помня при этом, что ? в данном не является символьным литералом.

Для упрощения записи мы изменим форму записи состояний выполнения, используя следующие сокращения.

  1. Угловые скобки вокруг пары идентификатор-выражение опускаются. Вместо них между идентификатором и выражением будет помещаться символ.
  2. Маркеры строки для идентификаторов опускаются.
  3. Маркеры строк опускаются для значений переменных, в том случае, если это не создает путаницы.

При таком подходе состояниеs будет записано как:

s = {INPUT<†A†, BC/,R>, OUTPUT<††, ††,W>, F1<††, ††,W>, Ch1B, Ch2A}

1.2. Значение заголовка программы и точки.

Первая и последняя части программы – заголовок и точка имеют специальную роль в программном исчислении. Они связывают внутренние частные значения (состояния выполнения) программы с внешними значениями программы. Соответствие между внешними и внутренними значениями задается черезINPUT иOUTPUT, которые появляются в состояниях выполнения как переменные, но вне программы их содержимое – списки строк.

Любой список строкL используемый как вход программы, преобразуется заголовком программы в строку будущего с включенными в нее маркерами конца строк, т.е. список

L = <L1, L2, …, Ln>

Преобразуется в строку

(L1Ñ/)&(L2Ñ/)& …&(LnÑ/)

которая становится значением строки будущего дляINPUT.

Для данного заголовка программы

H = †PROGRAM† & N & †(INPUT, OUTPUT)†

для любого идентификатораN, частное значениеH будет:

H = {<<L1, L2, …, Ln>, s>: s = {INPUT<††, x,R>, OUTPUT<††, ††,W>}

где x = (L1Ñ/)&(L2Ñ/)& …&(LnÑ/) }

Если воспользоваться сокращенной формой записи и опустить маркеры строк, то можно записать:

H =  PROGRAM N (INPUT, OUTPUT)

гдеN- идентификатор

PROGRAM Copy1 (INPUT, OUTPUT) (†AB†, †CD†) =

{INPUT<††, (†AB†Ñ/)&(†CD†Ñ/) ,R>, OUTPUT<††, ††,W>}

При завершении выполнения точка преобразует строку прошлогоOUTPUT в выход программы, а именно список символьных строк. Разбиение на  элементы списка производится с помощью маркеров строки.

Таким образом, значение точки будет

. = {<s, <L1, L2, …, Ln>>: s(OUTPUT) = <(L1Ñ/)&(L2Ñ/)& …&(LnÑ/), ††, W>}

Остальные пары вs, кроме той, что содержитOUTPUT, теряются. Например:

.({INPUT<ABCÑ/, †† ,R>,OUTPUT<(ABÑ/)&(CDÑ/), ††,W>}) =

<AB ,CD>

что будет распечатано как

AB

CD

Объединим наши знания об области определения и значений для частей программы в следующей таблице.

Часть программы

Область определения

Область значений

программа

список строк

список строк

заголовок программы

список строк

состояния выполнения

точка

состояния выполнения

список строк

1.3. Композиция отношений и функций.

Частное значение заголовка программы - преобразование внешнего списка строк в строковое представление значенияINPUT в таблице выполнения; частное значение точки –преобразование строкового представленияOUTPUT в таблице выполнения во внешний список строк. Оставшаяся часть программы между заголовком и финальной точкой последовательно преобразует начальное состояние выполнения в финальное. Таким образом, функция, соответствующая частному значению заголовка программы, предоставляет входные данные для основной части программы, а основная часть программы предоставляет входные данные для функции, соответствующей частному значению финальной точки.

Результат последовательного выполнения функций, выполняющихся одна после другой, где выходные данные предыдущей функции используются как входные данные для следующей, называется композицией.

Композицией отношенийr иs, обозначаемая какrs, является новое отношение всех возможных пар <x,z>, таких, что для некоторого промежуточного значения у, <x,y>r и <y,z>s. Записанное вset-нотации данное определение будет выглядеть как:

rs = {<x,z>, :для некоторого у, <x,y>r, <y,z>s}

Новое понятие, «некотороеy», может быть определено через известные нам понятие области определения отношения. Рассмотрим отношение между парами и промежуточными значениями.

t = {<<x, z>, y>: <x, y> r, <y, z> s }

Аргумент <x,z> находится в паре сy в t, только тогда когда промежуточное значениеy существует, таким образом, значениемrs будут все возможные аргументыt.

r ◦ s = domain(t)

Программное исчисление формализует интуитивно определяемые значения в таблице выполнения, но существует глубокое различие междуbox-функциями программного исчисления и таблицами выполнения.Box-функция определяет значение программы во всей егополноте, тогда как таблица выполнения описывает только один элемент значения программы, соответствующий заданным входным данным.

Информация в таблице выполнения получается вычислениемbox-функции к определенному значению аргумента. Начиная с этого аргумента, значение программы значение программы производит набор промежуточных значений в таблице выполнения.

Таким образом, таблица выполнения является представлением композиции частных значений, новычисленных для одного аргумента.

Композицияbox-функций является также функцией (а не просто значением), и может быть использована для вычисления функции значения больших частей программы, тогда как значение, которое предоставляется таблицей выполнения, не может быть использовано в таких вычислениях.

Определение композиции использует понятие промежуточного значения, которое может быть опущено для функций. Еслиr однозначно определено наx, определение может быть переписано с использованием функциональной формы записи (value-нотации):

rs = {<x,z>, :для некоторого у,y=r(x), <y,z>s}

если дополнительноs однозначно определено наy

rs = {<x,z>, :для некоторого у,y=r(x),z=s(y)}

Производя замену дляy

rs = {<x,s(r(x))>:r однозначно определено наx.s однозначно определено наr(x)  }

в этой форме промежуточное значение,y, не встречается. Когдаr иs однозначно определены, композиция также будет однозначно определена наx.

Поскольку все функции определены однозначно, композиция двух функций также является функцией.

Value-нотация предоставляет способ найти значение композиции двух функций. Для вычисления  (fg)(x) сначала находимy=f(x), затемg(y)

Например, функция, заданная композицией

PROGRAM Any (INPUT, OUTPUT).

Может быть прямо вычислена для списка строкL. Сначала найдем

y = PROGRAM Any (INPUT, OUTPUT)(L)

и затем.(y)

Такимобразом,PROGRAM Any (INPUT, OUTPUT).(L)= .(y),

где y = PROGRAM Any (INPUT, OUTPUT)(L)

Результат ,eltn:

y= {INPUT<††,u,R>,OUTPUT<††, ††,W>},

.(y)=<††>

вне зависимости от строкиu, полученной из спискаL. Значение строки прошлого вOUTPUT пусто, и этого достаточно для вычисления результата композиции, который оказалсяпостоянной функцией для любого входного списка строкL.

Композиция является ассоциативной, т.е. для любых отношенийr,s,t

(r ◦ s) ◦ t = r ◦ (s ◦ t)

потому что

(rs) ◦t = {<x,u>: для некоторогоz, <x,z> (rs), <x,u>t}

= {<x,u>: для некоторогоz, некоторогоy <x,y>r, <y,z>s, <z,u>t }

= {<x,u>: некоторогоy <x,y>r, <y,u> (st}

= r◦ (s ◦ t)

Композиция более чем двух отношений не нуждается в скобках, порядок вычисления может быть любым и может определяться удобством вычисления.

Композиция не является коммутативной. Однако, функция эквивалентности (identityfunctionI) и пустая функция коммутативны с любым отношением, т.н. для любого отношенияs:

если domain(s) domain(I),тогда s ◦ I = I ◦ s = s

s ◦ {} = {} ◦ s = s

Функции и отношения, применение которых в отношении отменяет друг друга называютсяинверсными, т.е.r является инверсным отношением дляs если и только если,

r ◦ s = I

гдеI – функция эквивалентности дляdomain(r)

Транспозицией функции или отношенияr, обозначаемойrT является отношение, где поменяли местами элементы всех пар вr, т.е:

rT= {<x, y>: <y, x> r}

Транспонирование может бытьинверсным, и именно в таком качестве оно будет использоваться в программном исчислении. Полезна следующая проверка:

Если транспозицией отношенияr является функция, тогда такая транспозиция является прямой инверсией дляr.

Чтобы проиллюстрировать это, предположим, что транспозициейr является функция, тогда, по определению композиции,

rrT = {<x,z>: для некоторогоy, <x,y>r, <y,z>rT}

= {<x,z>: для некоторогоy, <y,x>rT, <y,z>rT}

ПосколькуrT – функция, любые два значения, находящиеся в паре с одним аргументом, идентичны, какx иz дляy в примере выше. Тогда

rrT = {<x,x>: для некоторогоy, <x,y>r, <y,x>rT}

= {<x,x>: для некоторогоy, <x,y>r }

=I, функция эквивалентности надdomain(r)

ПоэтомуrT является прямой инверсией дляr.

1.4. Значение объявлений.

Синтаксическим объектом, располагающимся между заголовком программы и финальной точкой является блокCFPascal. Частное значение блока преобразует начальное состояние выполнения для блока в конечное. Это преобразование может иметь несколько отдельных частей: декларация переменных и процедур, и корневое выражениеBEGIN блока.

Декларация изменяет состояние выполнения, добавляя к нему один или несколько идентификаторов. До выполнения декларации идентификаторы не существуют, после декларации они могут иметь значения. Частное значение декларации изменяет область определения состояния выполнения, добавляя идентификатор. Будет удобно отдельно разделять декларации для типовCHAR,TEXT иPROCEDURE.

Значение деклараций будет описываться с помощью отношений, которые не являются функциями. Отношение будет состоять из пар всех возможных значений и имени объявленного идентификатора, фиксируя идею, что значение неизвестно.

Для переменнойN типаCHAR определим:

VARN:CHAR = {<s,t>:t =s {<N,x>} для любого символьного значенияx}

СтрокаN соответствует синтаксису <идентификатора> и строкаVARN:CHAR формально должна быть представлена как:

V = †VAR† & N & †CHAR†

При использовании символа ? для обозначения значенияN:

VAR N: CHAR = {<s, t>: t = s {<N, ?>}}

не так очевидно, что любые символьные значения образуют пары сN. Например, пустьs будет аргументомVARN:CHAR, тогдаs будет:

s {ChA},

s {ChB},

для всех возможных символьных значений.

ХотяVARN:CHAR не является функцией,VARN:CHART является функцией, потому что ее пары имеют вид:

<s {NA}, s>

<s {NB}, s>

и каждому аргументу соответствует уникальное значение.

Значение декларации файловых переменных аналогично. ПустьN – идентификатор, определим:

VAR N: TEXT = {<s, t>: t = s {N<x, y, z>}длянекоторыхстрок x, yинекоторого z {R,W}}

Сокращенная форма записи присоединяет 3-список <?,?,?> к вновь созданному идентификатору.

Объявления более, чем одной переменной являются прямым обобщением рассмотренног. К состоянию выполнения добавлается несколько идентификаторов, каждый в паре с неопределенным символьным значением или 3-списком.

Это может быть выражено композицией:

VARСh1, Ch2: CHAR =VARСh1: CHARVAR Ch2: CHAR

= {<s, t>: t = s {Ch1?}{Ch2?}}

которая включает пары, такие как

<s, s {Ch1C} {Ch2F}>

и все остальные комбинации двух символьных значений.

Предположим, что

x = {INPUT<††, †† ,R>,OUTPUT<††, ††,W>}

является аргументом отношенияVAR Сh:CHAR, тогдаx образует пары в отношении для

{INPUT<††, †† ,R>,OUTPUT<††, ††,W>} {Chс}

для всех символьных значенийc. Представим это в виде формулы:

VARСh: CHAR ({INPUT<††, †† ,R>, OUTPUT<††, ††,W>})

= { INPUT<††, †† ,R>, OUTPUT<††, ††,W>, Ch?}

Объявление процедур, насколько нам в данный момент известно, не изменяет количество в столбцов в таблице выполнения. Когда позднее идентификатор процедуры используется в в процедурном выражении, вызывается <тело> процедуры. Задача объявления процедуры - записать информацию, которая сделает возможными действия описанные в процедуре. Этот текст присоединяется к идентификатору процедуры подобно значению из таблицы выполнения для переменной.

Для идентификатора процедурыN и тела T, определим:

PROCEDURE N; T = {<s, t>: t = s {<N, T>}}

При определении значения декларативной части и значений других частей программы мы принимаем, что программа и ее части синтаксически корректны. Строки, не соответствующие синтаксическим и контекстным правилам, не могут иметь значений.

Вычисляя значения только синтаксически корректных программ, мы исключаем из рассмотрения все затруднения связанные с неправильным синтаксисом. Например, если бы было возможным повторное объявление идентификатора, необходимо было бы описать и рассматривать такую ситуацию. Но поскольку это синтаксическая ошибка, семантическое определение не рассматривает такую возможность.

1.5. Значение блоков.

Блок может содержать ноль или больше объявлений переменных и процедур, но он должен завершаться операторомBEGIN. Простейший блок не содержит объявлений или операторов внутриBEGIN

BEGIN

END

Поскольку в таблице выполнения такой блок не меняет значений переменных, то его преобразование одно состояния программы в другое состояние программы является функцией эквивалентностиI.

BEGIN END= I

Когда блок содержит объявления, пары идентификатор-значение добавляются к исходному состоянию выполнения до того как выполнится операторBEGIN, а после его выполнения удаляются из состояния выполнения. Например, если частным значениемVAR добавлены переменные, тогда нам необходимоVART чтобы удалить эти значения из состояния выполнения.

Простой блок

VAR

 Ch: CHAR;

BEGIN

END

с частным значением:

VAR Ch: CHAR;BEGIN END= VAR Ch: CHAR ◦BEGIN END ◦  VAR Ch: CHAR T

а именно, композицией, которая сначала добавляетCh? к состоянию выполнения, потом выполняет эквивалентные преобразования, потом удаляетCh и значение из состояния выполнения. Начинаясь с состояния выполнения:

{INPUT<††,Ñ / ,R>, OUTPUT<††, ††,W>}

композиция имеет следующее значение:

(VAR Ch: CHAR ◦BEGIN END ◦  VAR Ch: CHAR T)

({INPUT<††,Ñ / ,R>, OUTPUT<††, ††,W>})

= (BEGIN END ◦  VAR Ch: CHAR T)

({INPUT<††,Ñ / ,R>, OUTPUT<††, ††,W>, Ch?})

= (VAR Ch: CHAR T)({INPUT<††,Ñ / ,R>, OUTPUT<††, ††,W>, Ch?})

= {INPUT<††,Ñ / ,R>, OUTPUT<††, ††,W>}

То есть как и ожидалось,VARCh:CHAR содержит все пары из

<s,s {Chc}>, для любого символьного значенияc

которое мы сокращенно записали добавивCh? К состоянию выполнения.

BEGINEND не изменяет состояние выполнения, аVARCh:CHART удаляет пару сокращенно обозначенную какCh?

Общий случай для частного значения блока следует аналогичен вышеописанному. Когда объявления отсутствуют, значение блока – это просто значение выраженияBEGIN. Когда присутствуют объявления процедур или переменныхF, за которыми следует операторBEGINB, значение блока будет

F; B = F ◦ B ◦ F T

Блок с объявлением одной переменно и одной процедуры может быть проанализирован примерно следующим образом:

VAR … ; PROCEDURE … ; BEGIN … END

= VAR … ; ◦  PROCEDURE … ; BEGIN … END ◦  VAR … ; T

= VAR … ; ◦  PROCEDURE … ; ◦  BEGIN … END ◦  VAR … ; T

Мы типично для программного исчисления описали частное значение блока. Подстрока программы, соответствующая определенной синтаксической части, в дальнейшем разбивается на подстроки и значение исходной подстроки определяется через значения элементов на которые она была разбита.

В дальнейшем мы рассмотрим частные значения операторовCFPascal, но рассматривая результаты выполнения операторов в таблице выполнения, мы уже сейчас можем получить формальное представление программы.

PROGRAM CopyChar (INPUT, OUTPUT);

VAR

 Ch: CHAR;

BEGIN

 READ(Ch);

 WRITELN(Ch)

END.

Значение программыQ может быть вычислено для 1-списка <†ABC†>

Q (<†ABC†>) =PROGRAM … END. (<†ABC†>)

=PROGRAM … ◦ VAR … END ◦. (<†ABC†>) (1)

=VAR … END ◦ . ({INPUT<††, ABC/ ,R>, OUTPUT<††, ††,W>})(2)

=VAR … ◦ BEGIN … END ◦  VAR … T ◦ .

({INPUT<††, ABC/ ,R>, OUTPUT<††, ††,W>})(3)

=BEGIN … END ◦  VAR … T ◦ .

({INPUT<††, ABC/ ,R>, OUTPUT<††, ††,W>, Ch?})(4)

=VAR … T ◦ .({INPUT<†A†, BC/ ,R>, OUTPUT<†A/†, ††,W>, ChA})(5)

=.({INPUT<†A†, BC/ ,R>, OUTPUT<†A/†, ††,W> })(6)

= <†A†>

Шаг (1) детализирует значение программыQ через композицию заголовка блока и точки. Шаг (2) применяет композицию оставшихся компонентов к значению заголовка. Шаг (3) расширяет значение блока до композиции объявлений, оператораBEGIN и транспозиции объявления. Шаг (4) применяет композицию оставшихся компонентов к значению программы после выполнения деклараций. Шаг (5) применяет композицию оставшихся компонентов к значению программы после выполнения оператораBEGIN. Шаг (6) показывает значение программы после применения к предыдущему значению транспозиции объявлений. Шаг (7) фиксирует значение программы после выполнения финальной точки.

Объединим наши знания об области определения и значений для частей программы в следующей таблице.

Часть программы

Область определения

Область значений

программа

список строк

список строк

заголовок программы

список строк

состояния выполнения

точка

состояния выполнения

список строк

блок

состояния выполнения

состояния выполнения

объявление

состояния выполнения

состояния выполнения

операторBEGIN

состояния выполнения

состояния выполнения

2. Значение последовательных выражений.

Раздел определяет значение операторовCFPascal, таких как: присваивание, пустой оператор, операторBEGIN,WRITE,READ и простых процедур.

Новые идеи: Семантика операторов.

Последовательные программы не имеют операторовIF илиWHILE, поэтому поток управления проходит от первого до последнего оператора. Для каждого вида операторовCFPascal будет определено его частное значение, которое соответствует преобразованиям над состояниями выполнения, выполняемым данным оператором. Мы будем использоватьBox-нотацию для обозначения частного значения оператора.

2.1. Оператор присвоения.

Значение некоторого оператора присвоения является функцией из одного состояния выполнения в другое. В таблице выполнения оператор присвоения заставляет идентификатор в своей левой части быть связанным с новой величиной, полученной из выражения справа.

Box-нотация может быть расширена, чтобы обозначать значение выражения в правой части оператора присвоения.  Частное значение такого выражения – это значение, взятое для данного состояния выполнения. Если оператор присвоения:

Ch1 := Ch2;

выражение справа– символьное выражение, представленное переменной, и ее значение доступно в данном состоянии выполнения. Рассмотрим значение символьной переменной, используя следующий пример.

В состоянии, содержащем паруCh2B, символьная переменнаяCh2 имеет значениеB. Таким образом, для идентификатора W, объявленного какCHAR, частным значением выраженияW для состоянияs являетсяW(s).

W = {<s, s(W)>}

Например:

Ch ({INPUT<††, ††,R>,OUTPUT<††, ††,W>,ChF,V1C})

= {INPUT<††, ††,R>,OUTPUT<††, ††,W>,ChF,V1C}(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’ ({V1A, …}) = {V1B, …}

V2 := V1 ({V1A, V2B ,…}) = {V1A, V2A, …}

V1 := V2 ({V1?, V2A ,…}) = {V1A, V2A, …}

V1 := V2 ({V1A, V2? ,…}) = {V1?, V2?, …}

Области определения и значений для рассмотренных частных значений приведены в следующей таблице.

Часть программы

Область определения

Область значений

программа

список строк

список строк

заголовок программы

список строк

состояния выполнения

точка

состояния выполнения

список строк

блок

состояния выполнения

состояния выполнения

объявление

состояния выполнения

состояния выполнения

оператор

состояния выполнения

состояния выполнения

символьное выражение

состояния выполнения

символьное значение

2.2. Пустой оператор.

Пустой оператор ничего не выполняет, следовательно не изменяет состояние выполнения. Значением для такого поведения является функция эквивалентностиI. Таким образом:

   = I = {<s, s>}

2.3. Оператор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 ({V1H, V2K,…})

= V1 := ‘A’ ◦ V2 := ‘B’ ({V1H, V2K,…})(1)

= V2 := ‘B’ (V1 := ‘A’({V1H, V2K,…}) )(2)

= V2 := ‘B’ ({V1A, V2K,…}) )(3)

= {V1A, V2B,…}(4)

На шаге 1 частное значение оператораBEGIN представляется как композиция входящих в него операторов.  На шаге 2 выражение приводится к функциональной форме записи. На шаге 3 вычисляется значение первого входящего оператора, и на шаге 4 – значение второго входящего оператора.

ОператорBEGIN может изменять значения одной переменной несколько раз. Например:

BEGIN V1 := ‘A’; V1 := ‘B’ END ({V1H, V2K,…})

= V1 := ‘A’ ◦ V1 := ‘B’ ({V1H, V2K,…})

= V1 := ‘B’ ({V1A, V2K,…}) )

= {V1B, V2K,…}

Перемещение двухсимвольного окна изV1,V2 вV2,V3 может быть проанализировано следующим образом:

Похожий подход используется при обмене двух символьных значений

BEGIN V1 := V2; V2 := V3; V3 := V1 END ({V1X, V2Y, V3Z, …})

= V1 := V2 ◦ V2 := V3 ◦ V3 := V1 ({V1X, V2Y, V3Z, …})

= V2 := V3 ◦ V3 := V1 ({V1Y, V2Y, V3Z, …})

=  V3 := V1 ({V1Y, V2Z, V3Z, …})

=  {V1Y, V2Z, V3Y, …}

2.4. Оператор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>, ChC,…}) = {F1<†ABC†, ††, W>, ChC,…}

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†>)

= (PROGRAMVAR … 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>, LetterL})

=(VAR …T .)({INPUT<††, ABC/,R>, OUTPUT<†HELLO†, ††,W>, LetterL})

=(.)({INPUT<††, ABC/,R>, OUTPUT<†HELLO†, ††,W>})

=<†HELLO†>

Таким образом, мы нашли значение программы для данного входа

PROGRAM WriteHello … END. (<†ABC†>)=<†HELLO†>

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Ñ / & 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>, 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†>

2.6. Простые процедуры.

Объявление символьных переменных добавляет к состоянию выполнения идентификатор с неизвестным значением. Значение переменной в дальнейшем может быть изменено и использовано при вычислении значений других выражений. Объявление процедуры также добавляет идентификатор к состоянию выполнения, значением его является полный текст процедуры. Например:

PROGRAM SimpleProc (INPUT, OUTPUT);

 PROCEDURE Demo;

 BEGIN

   WRITELN(‘Invoked’);

 END;

BEGIN

 Demo;

END.

Объявление процедуры добавляет пару <†Demo†, †BEGINWRITELN(‘Invoked’)END†> к состоянию выполнения. Значение процедурного оператора будет:

Demo = BEGIN WRITELN(‘Invoked’) END

Формальное описание частного значения процедуры соответствует вышесказанному. ПустьN – идентификатор процедуры, тогда:

N = {s, s(N)(s)}

3.Анализ последовательных выражений

Значение оператораBEGIN с входящими в него последовательными операторами может быть обобщено одновременным присваиванием, в котором перечисляются переменные и их финальные значения. Символическое выполнение, записываемое в трассировочных таблицах, может быть использовано для вывода значений операторовBEGIN как одновременного присваивания или для верификации корректности значения полученного другим способом.

Новые идеи: одновременное присваивание, символическое выполнение, трассировочные таблицы

Программное исчисление имеет своей целью вычисление значенияP для любой программыP. В основу положен простой принцип, определение значения частей программы с последующей их композицией позволяет получить значение программы в целом. На практике, однако, такое определение значения программы может оказаться утомительно процедурой. В этом разделе даются упрощенные (стенографические) методы, которые делают практический анализ программ проще.

3.1. Одновременные присваивания.

ОператорBEGIN может присвоить значение более чем одной переменной. Возможность обобщения эффекта оператораBEGIN настолько важна, что она будет сделана в виде комментария кCFPascal, называемого одновременным присваиванием (concurrentassignment).

Паскаль-машина не имеет возможности выполнять одновременные присваивания – они не являются частью синтаксиса Паскаля. Однако, в формате комментария будет присутствовать как простое расширение оператора присваиванияCFPascal. Список переменных, встречающихся слева от оператора присваивания и список выражений встречающихся справа, оба эти списка одинаковой длины. Одновременное присваивание выражает знание, что выражения, вычисленные одновременно, являются значениями соответствующих переменных. Например, результат выполнения оператораBEGIN:

BEGIN

 V1 := ‘A’;

 V2 := ‘B

END

Может быть представлен одновременным присваиванием:

<V1, V2> := <’A’, ‘B’>

Тогда как результат выполнения оператора

BEGIN

V1 := ‘A’;

 V2 := ‘B’

END

будет представлен:

<V1 > := <‘B’>

Угловые скобки списков могут быть опущены, если это не вызовет путаницы, например:

V1, V2 := ’A’, ‘B’

С использованием одновременного присваивания получаются отличные комментарии, потому что они точно выражают, каков должен быть результат оператораBEGIN.

Например:

BEGIN {V1 := ‘B’}

 V1 := ‘A’;

 V2 := ‘B’

END

Комментарий уточняет, что такая конструкция сделана намеренно, а не по ошибке.

Для любых символовx,y,z

BEGIN V3 := V2; V2 : V1 END ({V1x, V2y, V3z, …}) = {V1x, V2x, V3y, …}

Одновременное присваивание

BEGIN

 V3 := V2;

 V2 := V1

END

Может быть представлено в комментированной версии:

BEGIN {V2, V3 := V1, V2}

 V3 := V2;

 V2 := V1

END

Преимущество одновременного присваивания над частным значением то, что в нем присутствуют только измененные переменные. Другие переменные могут присутствовать в состоянии выполнения, но если они не появляются в левой части одновременного присваивания, их значение не меняется.

Одновременные присваивания помогают определить значение части программы. Примеры операторовBEGIN приведенные выше были простыми, рассмотрим другие:

E

F

BEGIN

 V1 : V2;

 V2 := V3;

 V3 := V1

END

BEGIN

 V1 : V2;

 V3 := V1;

 V2 := V3

END

Второе и третье присваивания поменяли местами. Мы можем вычислить фугкции частного значения дляE иF, принимаяx,y,z – любые символы.

E({V1x, V2y V3z, …})

= (V1 := V2◦V2 := V3◦V3 := V1)({V1x, V2y V3z, …})

= (V2 := V3◦V3 := V1)({V1y, V2y V3z, …})

= (V3 := V1)({V1y, V2z V3z, …})

= {V1y, V2z V3y, …}

и

F({V1x, V2y V3z, …})

= (V1 := V2◦V3 := V1◦V2 := V3)({V1x, V2y V3z, …})

= (V3 := V1◦V2 := V3)({V1y, V2y V3z, …})

= (V2 := V3)({V1y, V2y V3y, …})

= {V1y, V2y V3y, …}

ВE совокупный эффект  - уничтожение старого значенияV1 и обмен значениямиV2 иV3, что обобщается одновременным присваиванием:

V1,V2,V3 :=V2,V3,V2

F имеет несколько иное значение, а именно – присвоить всем переменным изначальное значениеV2:

V1,V3 :=V2,V2

Добавление  к операторамBEGIN комментариев с одновременным присваиванием делает их понимание более ясным:

E

F

BEGIN {V1, V2, V3 := V2, V3, V2}

 V1 : V2;

 V2 := V3;

 V3 := V1

END

BEGIN {V1, V3 := V2, V2}

 V1 : V2;

 V3 := V1;

 V2 := V3

END

E – пример часто встречающегося блока, который обменивает значенияV2 иV3, используяV1 как переменную для сохранения промежуточного значения. Такие блоки какF обычно пишутся по ошибке.

3.2. Символическое выполнение и таблицы трассировки.

Одновременное присваивание для оператораBEGIN может быть определено напрямую или через функцию частного значения. Однако, для сложных операторовBEGIN есть необходимость в быстром и аккуратном способе прямого определения одновременного присваивания. Например:

BEGIN

 V1 := V2;

 V2 := V4;

 V3 := V1;

 V4 := V3

END

Кажется утомительным использовать для анализа функцию частного значения, прямое определение может дать неверный ответ.

Символическое выполнение – метод трассировки (отслеживания) значений переменных через использование их имен, а не значений. Таблица трассировки – систематический метод проведения символического выполнения.

Подобно таблице выполнения, таблица трассировки имеет строку для каждого выполняемого оператора и столбец для каждой переменной, которая может приобрести новое значение в процессе выполнения. Однако «значения» в трассировочной таблице являются выражениями и строки отслеживают текущие выражения в терминах изначальных выражений. Например, таблица трассировки для приведенного выше оператораBEGIN с четырьмя операторами присваивания будет:

V1

V2

V3

V4

V1 :=V2

V2 :=V4

V3 :=V1

V4 :=V3

V2

V2

V2

V2

V2

V4

V4

V4

V3

V3

V2

V2

V4

V4

V4

V2

Выражения в столбцах представляют исходные значения соответствующих переменных. Таким образом, перед тем как было выполнено первое присваивание, переменные имели их исходные значения.  Но после первого присваивания, (первая строка в таблице,V1 приняла значение, которое изначально имелаV2, и это показано значениемV2 в столбцеV1. Остальные переменные не были изменены, их значения соответствуют заголовкам столбцов. Во второй строкеV2 приобрела значениеV4 (которое на тот момент было ее исходным значением). В третьей строчкеV2 приходит в столбецV3 из столбцаV1, потому чтоV3 принимает текущее значениеV1, которое уже равно оригинальному значениюV2.

Правило таково, что в таблице используются только оригинальные значения, но имена переменных всегда доступны в верхней строчке.

Одновременное присваивание для оператораBEGIN может быть записано прямо из трассировочной таблицы, используя список идентификаторов в заголовке таблицы в левой части и список в последней строчке таблицы в правой части. Для примера выше одновременное присваивание будет:

V1,V2,V3,V4 :=V2,V4,V2.V2

Таблица трассировки упрощается, если мы опустим неизменяемые значения. Для приведенного выше примера с некорректной попыткой обменять значенияV2 иV3 получим таблицу выполнения:

V1

V2

V3

V1 :=V2

V3 :=V1

V2 :=V3

V2

V2

V2

С одновременным присваиванием:

V1,V2,V3 :=V2,V2,V2

что эквивалентно:

V1,V3 :=V2,V2

Трассировочная таблица для оператораBEGIN

BEGIN

 V1 := V4;

 V2 := V3;

 V3 := V2;

 V4 := V1

END

будет:

V1

V2

V3

V4

V1 :=V4

V2 :=V3

V3 :=V2

V4 :=V1

V4

V3

V3

V4

Полученное одновременное присваивание комментирует операторBEGIN

BEGIN {V1, V2 := V4, V3}

 V1 := V4;

 V2 := V3;

 V3 := V2;

 V4 := V1

END

Может оказаться сюрпризом, что одновременное присваивание показывает, что последние два оператора присвоения не нужны. Обстоятельства могут быть таковы, что программист хотел сделать что-то другое, а нахождение одновременного присваивания выявило ошибку.


 

А также другие работы, которые могут Вас заинтересовать

53064. ПРЕОБРАЗОВАНИЕ ГРАФИКОВ ФУНКЦИЙ 41.5 KB
  Построить графики функций: у=2х3 у=2х3 у=2х. Один ученик строит графики на компьютере программа на диске. Затем отвечают на вопрос учителя: Как можно получить графики функций у =2х3 и у=2х3 с помощью графика у=2х Вывод записать в тетрадь. Слайд 6 Построить в готовой системе координат графики функций у=3х1 у=3х у=3х2 используя параллельный перенос.
53065. Логарифмічна функція, її властивості та графік 2.46 MB
  Учитель Старостенко Світлана Богданівна спеціаліст вищої категорії учительметодист Тема: Логарифмічна функція її властивості та графік Мета: ввести поняття логарифмічної функції формувати вміння будувати графік логарифмічної функції дослідити її властивості познайомити учнів з використанням логарифмічної функції при вивченні явищ навколишнього світу; розвивати творче мислення математичне мовлення; виховувати вміння працювати разом почуття відповідальності культуру спілкування. Назвіть достатню умову існування оберненої...
53066. Показникова функція, її властивості та графік 345.5 KB
  Сойер Мета: розглянути фізичні моделі пов‘язані з процесами органічної зміни величин що дозволяють дати означення показникової функції перелічити її властивості та побудувати її графік; розширювати світогляд учнів; виховувати інтерес до вивчення математики. Означення показникової функції. Властивості показникової функції. Побудова графіка показникової функції.
53067. Применение производной функции 97.5 KB
  Итоговый урок по теме Применение производной функции. Цель урока: систематизировать и обобщить знания учащихся по теме Применение производной функции; развивать логическое мышление культуру математической речи стимулировать познавательную деятельность способствовать формированию знаний; воспитывать интерес к предмету умение работать в коллективе. Оборудование: мультимедийная доска диск с презентацией Применение производной функции раздаточный материал карточки контроля знаний....
53068. Футбольний уікенд 113.5 KB
  Футбольний уік енд сценарій спортивної розважальної програми Мета: популяризація та пропаганда здорового способу життя серед підлітків; забезпечити відповідну рухову активність дітей; оволодіння учасниками програми основними техніками ведення м’яча; розвиток спортивних та творчих здібностей та уміння грати у команді; виховання моральновольових якостей наполегливості працелюбства сміливості; формування позитивного ставлення до занять спортом в особливості до футболу. Обладнання: папір для оформлення м’яча скотч...
53069. МОВА — НАЙВАЖЛИВІШИЙ ЗАСІБ СПІЛКУВАННЯ, ПІЗНАННЯ І ВПЛИВУ 1.08 MB
  У всякому випадку цю думку можна виразити лише з допомогою слів якоїсь людської мови. Про яку функцію мови йдеться в прочитаному тексті Пригадати які основні функції виконує мова. Які із записаних функцій мови є на ваше переконання основними Творче осмислення висловлювання робота в мінігрупах Прочитати мовчки висловлювання.
53070. Особливості композиції, колорит, кольорова гамма. Творчість К. Білокур. Декоративний натюрморт «Весняні квіти» 63 KB
  Декоративний натюрморт Весняні квіти Мета: Навчальна: розширювати знання учнів про натюрморт як один із жанрів образотворчого мистецтва вчити розпізнавати форми реалістичні декоративні їх специфіку порівнювати реалістичне і декоративне стилізоване зображення предметів локальний і зумовлений кольори стилізувати реальні форми в декоративні ознайомити учнів з творчістю видатної української художниці К. Літературний ряд: Ольга Косач Олена Пчілка Весняні квіти. Так квіти фрукти овочі та предмети побуту можна трактувати...