Практическое занятие №6 Тема: Построение и условия для проверки циклов. 1. Построение циклов исходя из инвариантов и ограничений. Существуют две стратегии построения циклов при данных предусловии Q, постусловии R, инварианте Р и ограничивающей функции t. Первая приводит к циклу с одной охраняемой командой: do B S od. Во второй учитываются преимущества, предоставляемые гибкостью конструкции повторения. 2. Условия для проверки циклов. 2.1. Покажите, что инвариант цикла Р истинен перед началом выполнения цикла. 2.2. Покажите, что i: 1 i n {P AND Bi} Si {P} – выполнение охраняемой команды завершается при истинном Р. 2.3. Покажите, что P AND NOT BB R – в момент завершения цикла R результат истинен. 2.4. Покажите, что P AND NOT BB (t > 0) – до завершения цикла ограничение снизу справедливо. 2.5. Покажите, что i: 1 i n {P AND Bi} t1 := t; Si {t < t1} – каждый шаг цикла приводит к уменьшению ограничивающей функции t. 3. Стратегия построения циклов №1. 3.1. Построить охрану В такую, что P AND NOT B R; 3.2. Построить тело цикла так, чтобы оно уменьшало ограничивающую функцию при сохранении инварианта цикла. 4. Стратегия построения циклов №2. 4.1. Стройте охраняемые команды так, чтобы каждая из них приближала цикл к завершению, а соответствующая охрана обеспечивала сохранение инварианта. 4.2. Завершайте процесс создания охраняемых команд, если их создано достаточно для доказательства P AND NOT BB R. 5. Пример применения стратегий построения циклов. Написать алгоритм нахождения фиксированного значения х в двумерном массиве b[0 : m-1][0 : n-1], m > 0, n > 0. Если х встречается в нескольких местах, определить любое. 5.1. i := 0; j := 0; do i m cand x b[i, j] if j < n-1 j := j+1 П j = n-1 i := i+1; j := 0 fi od 5.2. i := 0; j := 0; do i m AND j n cand x b[i, j] j := j+1 П i m AND j = n i := i+1; j := 0 od 6. Построение инвариантов циклов. При данных предусловии Q и постусловии R перед написанием цикла можно построить инвариант Р путем ослабления постусловии R. 6.1. Пример устранения конъюнктивного члена. Приближенно определить значение квадратного корня целого числа n 0. Постусловие R: 0 a2 n <(a+1)2 или R: 0 a2 AND a2 n AND n < (a+1)2. Устранение третьего конъюнктивного члена дает инвариант Р: 0 a2 n. В качестве охраны В цикла используем отрицание устраненного конъюнктивного члена, что обеспечит удовлетворение необходимого условия P AND NOT BB R. Получим алгоритм, время выполнения которого ~ n: а := 0; do (a+1)2 n а := a+1 od. 1 6.2. Пример замены константы переменной. Приближенно определить значение квадратного корня целого числа n 0. Постусловие R: 0 a2 n <(a+1)2. Заменим a+1 новой переменной b в границах а < b n+1 и получим инвариант Р: а < b n+1 AND a2 n < b2. Охрана В цикла, получаемая из условия P AND NOT B R, это а+1 b. Пусть ограничивающая функция уменьшает интервал (a, b) делением на 2. Получим алгоритм, время выполнения которого ~ log n < n: а := 0; b := n+1; do a+1 b d := (a+b)2; if d*d n a := d П d*d > n b := d fi od. 6.3. Пример расширения области значений переменной. Дан массив b[0 : n-1], n > 0 в котором содержится значение х. Найти первое вхождение х. Обозначим наименьшее i, удовлетворяющее условию : 0 i AND x = b[i], через iv. Постусловие R: i = iv. Инвариант Р: 0 i iv. Получим алгоритм: i := 0; do x b[i] i := i+1 od. 6.4. Пример комбинирования пред- и постусловий. Во многих случаях при построении инварианта последний следует рассматривать в качестве обобщения пред- и постусловия. Написать алгоритм вставки пробелов, который для строки слов b[0 : n-1], n 0 и р 0 прибавляет p*i к каждому элементу b[i]. Начальное значение b[i]=Вi, а Вi – это номера столбцов, в которых начинаются последовательные слова, в строке, выровненной по правому краю вставкой пробелов между словами, р – число пробелов между каждой парой слов. Предусловие Q: ( i: 0 i < n b[i]=Bi); постусловие R: ( i: 0 i < n b[i]=Bi + p*i). Заменим постоянной n переменной j, вспомогательный инвариант: P1: 0 j n AND ( i: 0 i < j b[i]=Bi + p*i) говорит, что первые j элементов b имеют окончательные значения. Стоит включить в инвариант и то, что оставшиеся n-j элементов сохраняют свои начальные значения. Тогда полный инвариант: P: 0 j n AND ( i: 0 i < j b[i]=Bi + p*i) AND ( i: j i < n b[i]=Bi). Получим алгоритм: j := 0; do j n j := j+1; b[j] := b[j] + p*j od. 2 Задания 1. Написать алгоритм решения Вашей задачи из практического занятия №5, используя обе стратегии построения циклов. 2. Написать алгоритм и программу решения задач: Вариант 1. 2.1. Дан массив b[0 : n-1], n > 0. Присвоить переменной х наименьшее значение из b. Если наименьшее значение встречается в b более одного раза, выбрать любой из них. Предусловие Q: n >0; Постусловие R: x b[0 : n-1] AND ( j: 0 j < n x = b[j]); Инвариант Р: 1 j n AND x b[0 : i-1] AND ( j: 0 j < i x = b[i]); Ограничение t: n-i. 2.2. Дан массив b[0 : m-1, 0 : n-1], m > 0, n > 0, в котором содержится значение х. Найти вхождение х, при котором х нет в предыдущих строках или в предыдущих столбцах той же строки. 2.3. Дан массив b[0 : n-1], n 0. Записать в переменную а число нечетных значений в b[0 : n-1]. Разрешено использование функций odd(), even(). Вариант 2. 2.1. Дан массив b[0 : n-1], n > 0. Присвоить переменной х наименьшее значение из b. Если наименьшее значение встречается в b более одного раза, выбрать любой из них. Предусловие Q: n >0; Постусловие R: x b[0 : n-1] AND ( j: 0 j < n x = b[j]); Инвариант Р: 0 j n AND x b[0 : n-1] AND ( j: i j < n x = b[j]); Ограничение t: i. 2.2. Дано n > 0. Присвоить переменной х наибольшее целое число, являющееся степенью двойки и не большее n. 2.3. Дан массив b[0 : n-1], n > 0. Найти в нем место максимального значения. Вариант 3. 2.1. Дано n > 0. Присвоить переменной х наивысшую степень двойки, не превосходящую n. Предусловие Q: n >0; Постусловие R: 0 < x n < 2*x AND ( j: x = 2j); Инвариант Р: 0 < x n AND ( j: x = 2j); Ограничение t: n-i. 2.2. Даны целые числа x > 0, y > 0. Не используя операций умножения и деления, найти частное q и остаток r от деления х на у. 2.3. Дан массив b[0 : n-1], n 0. Определить, состоит ли b[0 : n-1] из одних нулей. 3