OberonCore
https://forum.oberoncore.ru/

Еще раз о выходе из середины цикла
https://forum.oberoncore.ru/viewtopic.php?f=82&t=1500
Страница 3 из 7

Автор:  Сергей Губанов [ Суббота, 02 Май, 2009 20:55 ]
Заголовок сообщения:  Re: Еще раз о выходе из середины цикла

Валерий Лаптев писал(а):
Ну, такой простой вариант, естественно, понятен. Но как-то Дейкстры тут не видать - обычный программистский цикл.
Ваш пример тривиально выражается через обычный цикл, цикла Дейкстры тут нет.

Автор:  Илья Ермаков [ Суббота, 02 Май, 2009 21:16 ]
Заголовок сообщения:  Re: Еще раз о выходе из середины цикла

Valery Solovey писал(а):
Я не считаю, что Илья правильно использует этот цикл. Зачем оно надо, если тело выполняется только один раз? Какой же это цикл?

Подождите, в смысле - только один раз? Цикл повторяет попеременно то одну, то другую ветку.

Автор:  Илья Ермаков [ Суббота, 02 Май, 2009 21:20 ]
Заголовок сообщения:  Re: Еще раз о выходе из середины цикла

Сергей Губанов писал(а):
Валерий Лаптев писал(а):
Ну, такой простой вариант, естественно, понятен. Но как-то Дейкстры тут не видать - обычный программистский цикл.
Ваш пример тривиально выражается через обычный цикл, цикла Дейкстры тут нет.


Я хочу предложить к обсуждению такое правило. Цикл надо ориентировать на проверки условий окончания. Т.е. цикл должен быть настолько "гранулярен", чтобы каждая ситуация, когда становится определённым условие окончания, приходилась на отдельный виток цикла. Исходя из такого соображения, я и вводил цикл Дейкстры.
Давайте подумаем.

Сергей, про Ваш вариант "с обычным циклом" я выше сказал, что лично меня в нём смущает: конструкция IF внутри него играет роль только на последнем витке. Т.е. она не используется в процессе цикла, а просто "подсекает" его окончание, как особый случай. В варианте же с ЦД такого особого случая не возникает, всё гладко.

Автор:  Илья Ермаков [ Суббота, 02 Май, 2009 21:30 ]
Заголовок сообщения:  Re: Еще раз о выходе из середины цикла

Валерий Лаптев писал(а):
Между прочим, в процессе отладки в цикле выяснился еще один нюанс.
Код:
while (true)
{       RM = mem[RA];            // выбрать слово
       RA = (RA + 1) % N;         // изменение адреса - по модулю 1024
      RC = RM.cmd.first;         // выбрать команду first
      run();                         // выполнить команду
      [b]if (Jump) continue;   // если переход, то не выполнять вторую команду [/b]
      if (Error || stop) break;   // если команда stop или ошибка
      RC = RM.cmd.second;         // выбрать команду second
      run();                  // выполнить команду
      if (Error || stop) break;   // если команда stop или ошибка
}

Как это учесть в цикле Дейкстры, который Илья Ермаков написал?


Может, смену позиции команды зашить в тот же читающий интерфейс? И тогда:

Код:
GetCommand(cmd); (* ASSERT(cmd # empty) *)
WHILE (cmd # empty) & (cmd # stop) & (cmd # jump) DO
  Execute(cmd, error); cmd := empty
ELSIF (cmd # empty) & (cmd = jump) DO
  SetCmdPos(newPos); GetCommand(cmd)
ELSIF (cmd = empty) & (error = no_error) DO
  GetCommand(cmd)
END

Автор:  Peter Almazov [ Воскресенье, 03 Май, 2009 06:50 ]
Заголовок сообщения:  Re: Еще раз о выходе из середины цикла

Вот решение:
Код:
first = true;
while (НЕ stop И НЕ Error) do
  if first then
    RM = mem[RA];         // выбрать слово
    RA = (RA + 1) % N;      // изменение адреса - по модулю 1024
    RC = RM.cmd.first;      // выбрать команду first
  else
    RC = RM.cmd.second;      // выбрать команду second
  endif;
  run();            // выполнить команду
  first = НЕ first ИЛИ ЭтоJump(RC);
end;

Цикл дейкстры (охраны в заголовке) приведет к дублированию кода:
Код:
first = true;
while НЕ stop И НЕ Error И first do
    RM = mem[RA];         // выбрать слово
    RA = (RA + 1) % N;      // изменение адреса - по модулю 1024
    RC = RM.cmd.first;      // выбрать команду first
    run();            // выполнить команду
    first = false ИЛИ ЭтоJump(RC);
elseif НЕ stop И НЕ Error И НЕ first do
    RC = RM.cmd.second;      // выбрать команду second
    run();            // выполнить команду
    first = true;
end;

Но главное в цикле – всё-таки инвариант, о котором здесь никто не вспоминает.

Автор:  Сергей Губанов [ Воскресенье, 03 Май, 2009 13:20 ]
Заголовок сообщения:  Re: Еще раз о выходе из середины цикла

Илья Ермаков писал(а):
Сергей, про Ваш вариант "с обычным циклом" я выше сказал, что лично меня в нём смущает
Представьте что составная инструкция состоит не из двух частей, а, например, из четырёх:
Код:
REPEAT
  ВыбратьСоставнуюИнструкцию;
  ЗагрузитьПервуюЧасть;
  Выполнить;
  IF надо_выполнять_вторую_часть THEN
    ЗагрузитьВторуюЧасть;
    Выполнить;
    IF надо_выполнять_третью_часть THEN
      ЗагрузитьТретьюЧасть;
      Выполнить;
      IF надо_выполнять_четвёртую_часть THEN
        ЗагрузитьЧетвёртуюЧасть;
        Выполнить
      END
    END
  END
UNTIL останов OR ошибка;

Условия стоящие под IF-ами могут быть самыми разнообразными, в том числе не иметь отношения к условию остановки цикла.

Автор:  Илья Ермаков [ Воскресенье, 03 Май, 2009 18:56 ]
Заголовок сообщения:  Re: Еще раз о выходе из середины цикла

Сергей Губанов писал(а):
Условия стоящие под IF-ами могут быть самыми разнообразными, в том числе не иметь отношения к условию остановки цикла.

Да, вот тут-то и существенная разница.
Если IF-ы не имеют отношения к условию остановки, то это - цикл с фильтрацией по какому-то условию внутри.

А если IF дублирует условие остановки - то он относится исключительно к последнему шагу цикла. И не имеет, вообще говоря, отношения к процессу выполнения цикла.

Автор:  Сергей Губанов [ Воскресенье, 03 Май, 2009 22:50 ]
Заголовок сообщения:  Re: Еще раз о выходе из середины цикла

> ...А если IF дублирует...

По Вашему получается, что малая деформация условий заключенных под IF-ами приводит к изменению топологии...

Автор:  Valery Solovey [ Понедельник, 04 Май, 2009 11:54 ]
Заголовок сообщения:  Re: Еще раз о выходе из середины цикла

Илья Ермаков писал(а):
Valery Solovey писал(а):
Я не считаю, что Илья правильно использует этот цикл. Зачем оно надо, если тело выполняется только один раз? Какой же это цикл?

Подождите, в смысле - только один раз? Цикл повторяет попеременно то одну, то другую ветку.
Смысл в том, что цикл нужен для повторяющихся действий. А у Вас ветка-цикл выполняется один раз и переходит к выполнению другой ветки-цикла, которая тоже выполняется один раз, снова переход к другой ветке. И так всё время!

То есть, смысл задачи - это просто цикл с IF-ом внутри или сопрограммы, "прыгающие" друг на друга. Но никак не цикл Дейкстры (если я его правильно понимаю).

Автор:  Madzi [ Понедельник, 04 Май, 2009 13:10 ]
Заголовок сообщения:  Re: Еще раз о выходе из середины цикла

Видимо понимаете не правильно.
Попробуйте себе представить.
Вы пишите программу и выполнение дальнейшего куска должно произойти только по достижении определённого условия. В таком случае мы напишем:
Код:
xxx:
yyy: IF <условие не достигнуто> THEN GOTO xxx

Между xxx и yyy происходят какие то действия, в зависимости от состояния некоторой переменной
Код:
xxx: IF <есть ещё команда> THEN GOTO ссс
aaa: <выбрать следующую пару команд>
bbb: IF <команда КОНЕЦ> THEN yyy
ccc: <исполнить команду>
ddd: <выбрать следующую команду из пары>
yyy IF <условие не достигнуто> THEN GOTO xxx

Таким образом мы будем повторять некоторую последовательность действий, пока не встретим команду <КОНЕЦ>.
Как это ещё назвать, кроме как цикл?

Обычно мы привыкли, что в цикле выполняется одна и та же последовательность действий, но есть и другие циклы.
Если убрать GOTO из примера выше, то всё сведётся к описываем выше (в других сообщениях) циклам.

Если бы мы точно знали сколько каких действий необходимо для достижения заданного условия, мы конечно же могли бы обойтись без цикла, но мы этого не знаем.

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

Автор:  Valery Solovey [ Понедельник, 04 Май, 2009 13:35 ]
Заголовок сообщения:  Re: Еще раз о выходе из середины цикла

Madzi писал(а):
Попробуйте себе представить...
Вы описываете работу обычного цикла. И это я нормально понимаю. Вопросы у меня по циклу Дейкстры.
Madzi писал(а):
Поэтому логично, описать работу имеющегося КА с помощью цикла Дейкстры.
Я не вижу в Ваших рассуждениях предпосылки для такого заключения. Недостаточно информации. Это понятно, что цикл будет работать как КА, но зачем оно надо? Если пойти дальше, то таким способом можно и от IF-ов всюду избавиться: везде ставить WHILE.

Автор:  Сергей Губанов [ Понедельник, 04 Май, 2009 13:39 ]
Заголовок сообщения:  Re: Еще раз о выходе из середины цикла

Valery Solovey писал(а):
Если пойти дальше, то таким способом можно и от IF-ов всюду избавиться: везде ставить WHILE.
Точно! Именно это и было зачем-то сделано: вместо IF написали ещё одну ветку "WHILE" в которой изменили значение дополнительно введённого флага, чтобы данная ветка "WHILE" выполнилась всего один раз. Зачем такой огород?

Автор:  Madzi [ Понедельник, 04 Май, 2009 14:01 ]
Заголовок сообщения:  Re: Еще раз о выходе из середины цикла

Valery Solovey писал(а):
Это понятно, что цикл будет работать как КА, но зачем оно надо? Если пойти дальше, то таким способом можно и от IF-ов всюду избавиться: везде ставить WHILE.

1. Работу микросхем логичнее моделировать КА (коими они по сути и являются).
2. Формальный аппарат для КА развит не в пример лучше.

Автор:  Peter Almazov [ Понедельник, 04 Май, 2009 14:48 ]
Заголовок сообщения:  Re: Еще раз о выходе из середины цикла

Сергей Губанов писал(а):
Точно! Именно это и было зачем-то сделано: вместо IF написали ещё одну ветку "WHILE" в которой изменили значение дополнительно введённого флага, чтобы данная ветка "WHILE" выполнилась всего один раз. Зачем такой огород?

Чтобы не было разночтений, уточните, пж, какой код имеется в виду.

Автор:  Сергей Губанов [ Понедельник, 04 Май, 2009 16:13 ]
Заголовок сообщения:  Re: Еще раз о выходе из середины цикла

Код Ильи Ермакова с циклом Дейкстры.

Автор:  Peter Almazov [ Понедельник, 04 Май, 2009 17:01 ]
Заголовок сообщения:  Re: Еще раз о выходе из середины цикла

Прошу прощения за назойливость. Илья Ермаков приводил два примера кода:
Илья Ермаков писал(а):
Код:
GetCommand(cmd); (* ASSERT(cmd # empty) *)
WHILE (cmd # empty) & (cmd # stop) DO
  Execute(cmd, error); cmd := empty
ELSIF (cmd = empty) & (error = no_error) DO
  GetCommand(cmd)
END

Илья Ермаков писал(а):
Код:
GetCommand(cmd); (* ASSERT(cmd # empty) *)
WHILE (cmd # empty) & (cmd # stop) & (cmd # jump) DO
  Execute(cmd, error); cmd := empty
ELSIF (cmd # empty) & (cmd = jump) DO
  SetCmdPos(newPos); GetCommand(cmd)
ELSIF (cmd = empty) & (error = no_error) DO
  GetCommand(cmd)
END
Просьба пояснить, где находится "ветка WHILE, которая выполняется всего один раз"
Сергей Губанов писал(а):
...вместо IF написали ещё одну ветку "WHILE" в которой изменили значение дополнительно введённого флага, чтобы данная ветка "WHILE" выполнилась всего один раз.

Автор:  Valery Solovey [ Понедельник, 04 Май, 2009 19:30 ]
Заголовок сообщения:  Re: Еще раз о выходе из середины цикла

Правильнее будет сказать "ветка WHILE, цикл которой выполняется всего один раз". Так, наверное, понятнее.

Автор:  Peter Almazov [ Понедельник, 04 Май, 2009 19:51 ]
Заголовок сообщения:  Re: Еще раз о выходе из середины цикла

Valery Solovey писал(а):
Правильнее будет сказать "ветка WHILE, цикл которой выполняется всего один раз". Так, наверное, понятнее.
Где в коде такая ветка-то? Ткните пальцем, наконец.

Автор:  Valery Solovey [ Понедельник, 04 Май, 2009 20:41 ]
Заголовок сообщения:  Re: Еще раз о выходе из середины цикла

Каждая строка за исключением END - ветка

Код:
WHILE (cmd # empty) & (cmd # stop) DO Execute(cmd, error); cmd := empty
ELSIF (cmd = empty) & (error = no_error) DO GetCommand(cmd)
END

Автор:  Илья Ермаков [ Понедельник, 04 Май, 2009 20:54 ]
Заголовок сообщения:  Re: Еще раз о выходе из середины цикла

Там ветки выполняются попеременно.

Страница 3 из 7 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/