Автор Тема: Инварианты к двум циклам  (Прочитано 35458 раз)

Peter Almazov

  • Sr. Member
  • ****
  • Сообщений: 482
    • Просмотр профиля
Re: Инварианты к двум циклам
« Ответ #15 : Сентябрь 10, 2012, 04:33:35 am »
Как бы не расписывали, найти 00 можно только в просмотренной области  :)
Нет. Элемент a[ i ] в начале цикла не входит в просмотренную область. Мы "заглядываем вперед", и, если там 0 и oneZero=истина, то отваливаем. После этого имеем: один 0 на конце просмотренной области и один 0 впереди.

Название oneZero дурацкое, по сути надо lastCharIsZero.

albobin

  • Full Member
  • ***
  • Сообщений: 198
    • Просмотр профиля
Re: Инварианты к двум циклам
« Ответ #16 : Сентябрь 10, 2012, 04:42:47 am »
Как бы не расписывали, найти 00 можно только в просмотренной области  :)
Нет. Элемент a[ i ] в начале цикла не входит в просмотренную область. Мы "заглядываем вперед", и, если там 0 и oneZero=истина, то отваливаем. После этого имеем: один 0 на конце просмотренной области и один 0 впереди.

Название oneZero дурацкое, по сути надо lastCharIsZero.
Эпитеты не помогут. Вы ошиблись - пора признаться  :)

Peter Almazov

  • Sr. Member
  • ****
  • Сообщений: 482
    • Просмотр профиля
Re: Инварианты к двум циклам
« Ответ #17 : Сентябрь 10, 2012, 04:53:04 am »
Для особо бестолковых: нарисуте массив по клеточкам, в конце добавьте два 0, снизу между ними нарисуйте стрелку вверх. Это и будет граница просмотренной области. И в ней нет 00.

albobin

  • Full Member
  • ***
  • Сообщений: 198
    • Просмотр профиля
Re: Инварианты к двум циклам
« Ответ #18 : Сентябрь 10, 2012, 04:59:51 am »
Для особо бестолковых: нарисуте массив по клеточкам, в конце добавьте два 0, снизу между ними нарисуйте стрелку вверх. Это и будет граница просмотренной области. И в ней нет 00.
Сколько угодно можете себя убеждать  :)

DIzer

  • Гость
Re: Инварианты к двум циклам
« Ответ #19 : Сентябрь 10, 2012, 05:57:15 am »
  :) Петр , а теперь скажите
будут ли инвариантами цикла  (в вашем куске кода)
i < LEN(a)
-100 < i <= LEN(a)
-100 <= i <= LEN(a)+100

Peter Almazov

  • Sr. Member
  • ****
  • Сообщений: 482
    • Просмотр профиля
Re: Инварианты к двум циклам
« Ответ #20 : Сентябрь 10, 2012, 10:17:32 am »
А чего пожадничали, взяли бы все множество истинных утверждений.
Ответ подразумевает нудное описание, в чем тут засада. Я не готов его дать.
Более того, в ближайшие полторы недели перейду, в лучшем случае, в режим ReadOnly.

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Инварианты к двум циклам
« Ответ #21 : Сентябрь 10, 2012, 10:31:03 am »
Эх, столько было пафоса, и такой эпичный слив )))
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

DIzer

  • Гость
Re: Инварианты к двум циклам
« Ответ #22 : Сентябрь 10, 2012, 11:09:35 am »
Эх, столько было пафоса, и такой эпичный слив )))
В жизни всякое случается, Geniepro  ;), от таки вещей никто не застрахован.. тем больше  вы на себя берете, тем больше вероятность конфуза.... весь вопрос в том, что дальше.. лично я стараюсь делать так , что бы каждый подобный конфуз делал меня сильнее..

DIzer

  • Гость
Re: Инварианты к двум циклам
« Ответ #23 : Сентябрь 10, 2012, 11:17:30 am »
А чего пожадничали, взяли бы все множество истинных утверждений.
А разве инвариант цикла не есть логическое выражение выполняющееся перед выполнением цикла и после каждой ее итерации ?  ;D ;D ;D :)
Свое отношение к этому виду танцев  с бубном я  уже высказывал - но может быть вы таки сможете коротко и ясно пояснить причину конфуза и сделать некоторые выводы?

albobin

  • Full Member
  • ***
  • Сообщений: 198
    • Просмотр профиля
Re: Инварианты к двум циклам
« Ответ #24 : Сентябрь 10, 2012, 11:33:23 am »
Для особо бестолковых: нарисуте массив по клеточкам, в конце добавьте два 0, снизу между ними нарисуйте стрелку вверх. Это и будет граница просмотренной области. И в ней нет 00.
Сколько угодно можете себя убеждать  :)
Для особо бестолковых на месте П.А. я бы так объяснил точный смысл слова просмотренный применительно к этому циклу. Типа смотрим диафильм про массив. Показался элемент, смотрим. Не ноль - рот спокойно закрыт, ноль- рот в предвкушении радостного удивления округло приоткрывается. Надоело смотреть или невтерпёж -  моргнули - всё, на экране следующая картинка, старая просмотрена. Не ноль - рот прикрыли, ну а если опять ноль - то глаза радостно округло выпучиваются и в таком состоянии и столбенеем для истории. Вот и получается, что  последний ноль хоть и на виду, а не просмотрен.  :)
Ну, а ежели конец безрадостный, то самое больше  - остаться с приоткрытым ртом, но с грустными глазами. 

DIzer

  • Гость
Re: Инварианты к двум циклам
« Ответ #25 : Сентябрь 10, 2012, 11:33:28 am »
"выполняющееся перед выполнением цикла и после каждой ее итерации "  - сорри,коряво сказано ,правильно ИСТИННОЕ  перед выполнением цикла и после каждой его итерации, и зря в обвиняете меня в скудоумии - я без проблем могу состряпать такое выражение, что без знания матанализа ни х не разберешься...  ;)

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Инварианты к двум циклам
« Ответ #26 : Сентябрь 10, 2012, 11:43:02 am »
Эх, попробовал я таки сделать этот инвариант и понял, что в императивных языках, да ещё и с массивами и циклами, эти ваши инварианты гораздо труднее делать, чем на ФЯ со списками да рекурсиями. По крайней мере, для подобных задачек...

Вот функциональная программа на псевдокоде:
Прим.
list<TYPE> -- это тип "список с элементами типа TYPE", head и tail -- функции, возвращающие, соответственно, первый элемент списка и его хвост.
option<TYPE> -- это тип, который может иметь значение none, что означает "нет значения", или some<X>, что означает "есть значение X типа TYPE"
function find00 (xs: list<int>) : option<int>
  function find (xs: list<int>, i: int) : int
  begin
    {     (список пуст и тогда искомая последовательность не найдена)
      или (искомая последовательность находится в первых двух элементах списка)
      или (искомая последовательность находится в хвосте списка)
    }
    if xs = nil                                 then return none
    else if head(xs) = 0 and head(tail(xs)) = 0 then return some<i>
    else                                             return find (tail(xs), i+1)
  end;
begin
  return find (xs, 0)
end
Условие завершения для функции find, как видно, такое:
"(список пуст и тогда искомая последовательность не найдена)
или (искомая последовательность находится в первых двух элементах списка)
или (искомая последовательность находится в хвосте списка)"

Теперь вольный перевод этой программы на императивный язык с циклами и массивами:
Прим. Нумерация элементов массива идёт с 1, а не с 0
i := 1;

{ инв: (i > len(a)-1, а значит массив не содержит искомую последовательность)
  or   (элементы a[i] и a[i+1] содержит искомую последовательность)
  or   (искомая последовательность находится в части массива c позиции i+1 по len(a)-1)
}

while i < len(a) and (a[i] ≠ 0 or a[i+1] ≠ 0) do
  { инв }
  i := i + 1
end;

{ ((i = len(a)) or (a[i] = 0 and a[i+1] = 0)) and инв }
Ну и инвариант, соответственно, такой:
"(i > len(a)-1, а значит массив не содержит искомую последовательность)
или (элементы a[i] и a[i+1] содержит искомую последовательность)
или (искомая последовательность находится в части массива c позиции i+1 по len(a)-1)"

Ужасно, должен вам сказать. Я этот ваш инвариант цикла осилил только после того, как описал словами условие завершения рекурсивной функции со списком...

ЗЫ. Опциональные типы option в ML-языках или Maybe в хаскелле гораздо безопаснее, чем null или всякие коды -1 в традиционных императивных языках...
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Инварианты к двум циклам
« Ответ #27 : Сентябрь 10, 2012, 11:59:21 am »
Ну и инвариант, соответственно, такой:
"(i > len(a)-1, а значит массив не содержит искомую последовательность)
или (элементы a[i] и a[i+1] содержит искомую последовательность)
или (искомая последовательность находится в части массива c позиции i+1 по len(a)-1)"
Эта чортова нумерация массивов с нуля и все эти +1 -1 только путают ((

Должно быть так (если принять нумерацию с 1):

"(i > len(a)-1, а значит массив не содержит искомую последовательность)
или (элементы a[i] и a[i+1] содержит искомую последовательность)
(искомая последовательность находится в части массива c позиции i+1 по len(a))"

или, если принять нумерацию с 0, то так:

"(i > len(a)-2, а значит массив не содержит искомую последовательность)
или (элементы a[i] и a[i+1] содержит искомую последовательность)
или (искомая последовательность находится в части массива c позиции i+1 по len(a)-1)"
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

DIzer

  • Гость
Re: Инварианты к двум циклам
« Ответ #28 : Сентябрь 10, 2012, 12:05:45 pm »
Эта чортова нумерация массивов с нуля и все эти +1 -1 только путают ((

Угу последние 3 года я заставляю студентов использовать массивы индексируемые с нуля... но на прошлой неделе пришлось пописать скриптики для статьи на Луа - там усе с единицы блин какой кайф...

Peter Almazov

  • Sr. Member
  • ****
  • Сообщений: 482
    • Просмотр профиля
Re: Инварианты к двум циклам
« Ответ #29 : Сентябрь 27, 2012, 12:52:46 pm »
что касается вашего виденья, Петр - по ссылке которую вы не постеснялись здесь дать  - я  привел  там вам еще пару инвариантов (по определению) и попросил прокомментировать их
- у вас КИШКА ТОНКА ОКАЗАЛАСЬ - ответ  сводился "рассуждения долгие и нудные , у меня нет времени на это", кроме того, Албобин нашел у вас ошибку (это свидетельство  что эта метода даже вам(ее адепту) не помогла ее избежать- если это так то НАХ. данная методика? и не е.-те другим мозги...
Сколько пафоса. Может, не надо было сразу так, большими буквами-то.
Можно было и помягше: "Тема все еще представляет интерес". А то я исхожу из худшего – что надоел уже всем повторением одно и того же.

Вопросы про инварианты от Dizer и про мифическую ошибку или "неточность" имеют, в сущности, один и тот же корень.
 
Рассмотим случай, когда в последовательности есть 00 и мы-таки это нашли в процессе выполнения цикла. Видимо, в голове не укладывается, почему после выполнения цикла истинен инвариант, в который входят слова "в просмотренной части последовательности нет 00". Прежде чем объяснять в четвертый раз, у меня большая просьба к albobin (на других надежды нет), попробуйте сформулировать инвариант для этого цикла.
i:= 0;
do
  i < len(a) - 1 and (a[i] <>0 or a[i+1]<>0) -> i:=i+1;
od
Может, и объяснять ничего не придется.
« Последнее редактирование: Сентябрь 27, 2012, 12:54:52 pm от Peter Almazov »