Автор Тема: Раскручиваем компилятор O7  (Прочитано 40702 раз)

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Раскручиваем компилятор O7
« Ответ #90 : Ноябрь 11, 2013, 03:13:11 am »
С учетом всех тем, где упоминался цикл Дейкстры, что я наблюдал, можно прийти к выводу, что в мире современных программистов ЦД - могучий артефакт, притягивающий к себе внимание вне зависимости от его целесообразности в конкретном случае.

Да не. Просто после той мощной рекламной компании, которую устроил info21 для Цикла Дейкстры, хотелось найти хоть одно осмысленное применение на практике. А тут как раз язык с непосредственной поддержкой этого чуда. Вот и теперь, даже Петр Алмазов сказал, что Цикл Дейкстры тут не нужен. Будем искать :)

albobin

  • Full Member
  • ***
  • Сообщений: 198
    • Просмотр профиля
Re: Раскручиваем компилятор O7
« Ответ #91 : Ноябрь 11, 2013, 04:47:14 am »
Нет и мне успокоения :) 

Чуть подправлю свой последний вариант.
1. Без предположения, что слова в words отсортированы.
После последнего слова пробел обязателен.
PROCEDURE isReservedWorld(s: JsString.Type; words: JsString.Type): BOOLEAN;
VAR
    i, w, с: INTEGER;
BEGIN
    i := 0 ;
    w := 0 ;
    с := 0;
    WHILE (w < JsString.len(words))
        & ((с < JsString.len(s)) OR (i # JsString.len(s)) OR (JsString.at(words, w) # " ")) DO
        IF (i < JsString.len(s)) & (JsString.at(words, w) = JsString.at(s, i)) THEN
            INC(i);
            INC(c);
        ELSIF (JsString.at(words, w) # " ") THEN
            INC(i);
        ELSE
            i := 0;
            c := 0;
        END;
        INC(w);
    END;
    RETURN (w < JsString.len(words))
END isReservedWorld;

2. Если строка слов отсортирована, то
условие WHILE сокращается до
    WHILE (w < JsString.len(words))
        & (с < JsString.len(s)) DO
В этом случае будет выходить по первому совпадению проверяемого слова s с началом некоторого слова из words.
Возврат из функции тогда усиливается добавкой
    RETURN ((w < JsString.len(words)) & (JsString.at(words, w) = " "))

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Раскручиваем компилятор O7
« Ответ #92 : Ноябрь 11, 2013, 06:17:23 am »
Самое смешное -- это то, что в Обероне нет цикла Дейкстры. Есть цикл, синтаксически напоминающий цикл Дейкстры, но семантически всё-таки отличающийся от него...
Впрочем, настоящего ветвления Дейкстры в Оберонах/Модулах-2 тоже нет, есть ветвление, лишь синтаксически напоминающее его.

Предлагаю раскрыть мысль, дабы народ сейчас не нафантазировал чего-то странного.

Ну сколько ж можно раскрывать эту простую мысль? Я об этом много раз повторял (больше трёх точно).
Вспоминаем, что Дейкстра писал в своей "Дисциплине программироания" про оператор if (и аналогичные рассуждения по поводу оператора do):

if B1 → SL1 □ B2 → SL2 □ ... □ Bn → SLn fi
do B1 → SL1 □ B2 → SL2 □ ... □ Bn → SLn do

где B1...Bn -- "предохранители", логические выражения охраняемых команд,
SL1...SLn -- списки операторов,
а B1 → SL1 -- охраняемая команда

Цитата: Эдсгар Дейкстра
1. Предполагается, что все предохранители определены; если это не так, т.е. вычисление какого-то предохранителя может привести к работе без правильного завершения, то допускается, что и вся конструкция не сможет правильно завершить свою работу.

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

3. Если начальное состояние таково, что ни один из предохранителей не является истиной, то мы встречаемся с начальным состоянием, для которого не подходит ни один из вариантов, а следовательно, и вся конструкция в целом. Запуск при таком начальном состоянии приведёт к отказу.

Замечание. Если мы допускаем также и пустой набор охраняемых команд, то операторы "if-fi" и "do-od" семантически эквивалентны нашему прежнему оператору "Отказать".

Таким образом, для того, что бы операторы IF и WHILE в Обероне могли считаться операторами if и do Дейкстры (назовём их "Ветвлением Дейкстры" и "Циклом Дейкстры"), их предохранители быть написаны в предположении недетерменированного порядка вычисления, и если ни один из предохранителей не срабатывает, должен происходить авост (HALT).

В рапорте об Обероне же прямо сказано:
Цитата: Никлаус Вирт
The Boolean expression preceding a statement is called its guard. The guards are evaluated in sequence of occurrence, until one evaluates to TRUE, whereafter its associated statement sequence is executed. If no guard is satisfied, the statement sequence following the symbol ELSE is executed, if there is one.
...
While statements specify repetition. If any of the Boolean expressions (guards) yields TRUE, the corresponding statement sequence is executed. The expression evaluation and the statement execution are repeated until none of the Boolean expressions yields TRUE.
То есть семантика этих операторов отличается.

ЗЫ. Кстати, сам Дейкстра отнюдь не гнушался делать вложенные циклы и циклы с условиями внутри, а вовсе не всегда заморачивался с циклом своего имени. Например:
x, y, z := X, Y, 1;
do y ≠ 0 → do 2 | y → x, y := x*x, y/2 od;
           y, z := y − 1, z*x
od {R стало истинным}
илиx, y, z := X, Y, 1;
do y<>0 → if non 2|y → y, z := y − 1, z*x
           □   2|y   → пропустить fi;
          x, y := x*x, y/2
od
хотя, казалось бы, уж здесь-то самое ему (ЦД) место...
to iterate is human, to recurse, divine

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

kkkk

  • Full Member
  • ***
  • Сообщений: 135
    • Просмотр профиля
Re: Раскручиваем компилятор O7
« Ответ #93 : Ноябрь 11, 2013, 08:57:04 am »
Да не. Просто после той мощной рекламной компании, которую устроил info21 для Цикла Дейкстры, хотелось найти хоть одно осмысленное применение на практике. А тут как раз язык с непосредственной поддержкой этого чуда. Вот и теперь, даже Петр Алмазов сказал, что Цикл Дейкстры тут не нужен. Будем искать :)
Гм, я вроде бы и не ищу применимости ЦД, а тем не менее время от времени натыкаюсь на такие места, где он подходит, но никогда в работе его не использую, поскольку эмулировать его явно либо через макросы мне нравится. А в Обероне бы пошло.
Например, есть сканер, в котором работа с потоком данных ведётся с явными блоками памяти вместо абстракции посимвольного чтения над буферизированными данными. Это приводит к тому, что лексема может быть разделена между блоками. У меня чтение лексемы выглядит приблизительно так:
WHILE Suitable(buf[i]) DO
INC(i)
ELSIF buf[i] = NewPage DO
NextPage(buf, i, input)
END

albobin

  • Full Member
  • ***
  • Сообщений: 198
    • Просмотр профиля
Re: Раскручиваем компилятор O7
« Ответ #94 : Ноябрь 11, 2013, 09:03:40 am »
Пару слов в "защиту" прав  ЦД  на жизнь :)
Мне кажется, что все сомнения в нужности ЦД, возникают из-за неучета нюансов просто циклов и циклов поиска.
Просто цикл - это когда нет бинарной интерпретации результата работы цикла, типа успешно/неуспешно и т.п.
В этом случае ЦД как обобщённый вариант вообще не должен вызывать никаких сомнений.
WHILE ~X  DO ... END     условие окончания  X=TRUE ( или просто X)
соответственно для ЦД
WHILE ~X1 DO ...
ELSIF ~X2  DO ...
...
ELSIF ~Xn DO ...
END
условие окончания X1&X2&....Xn

В цикле поиска, грубо говоря, X=TRUE может и не наступить, поэтому условие WHILE должно это учитывать.
WHILE ~E & ~X  DO ... END
условие окончания  E OR X.    Заданные условия E и X желательно должны быть таковы, что после окончания цикла выполнялось X=~E

Так вот в данном случае проблема для ЦД в том что  условие выхода X1&X2&...Xn должно быть наглядно представимо в форме E OR X


Peter Almazov

  • Sr. Member
  • ****
  • Сообщений: 482
    • Просмотр профиля
Re: Раскручиваем компилятор O7
« Ответ #95 : Ноябрь 11, 2013, 09:46:14 am »
Например, есть сканер, в котором работа с потоком данных ведётся с явными блоками памяти вместо абстракции посимвольного чтения над буферизированными данными.

1. Во многих случаях ЦД - это смешение разных уровней абстракций.

kkkk

  • Full Member
  • ***
  • Сообщений: 135
    • Просмотр профиля
Re: Раскручиваем компилятор O7
« Ответ #96 : Ноябрь 11, 2013, 10:20:02 am »
Так плохо это или хорошо?
В приведенном примере я отказался от лишнего слоя абстракции чтобы избавиться от ненужного кода и накладных расходов, связанных с ним. ЦД позволил сделать это просто. Теперь не нужно абстрагироваться над буфером, чтобы потом складывать прочитанное в другой буфер, потому что иначе неудобно.

Peter Almazov

  • Sr. Member
  • ****
  • Сообщений: 482
    • Просмотр профиля
Re: Раскручиваем компилятор O7
« Ответ #97 : Ноябрь 11, 2013, 10:25:58 am »
Как говорится, it depends.
Но лозунг "Смело смешивайте разные уровни абстракции!" я бы не поддержал  :)

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Раскручиваем компилятор O7
« Ответ #98 : Ноябрь 11, 2013, 03:36:22 pm »
Например, есть сканер, в котором работа с потоком данных ведётся с явными блоками памяти вместо абстракции посимвольного чтения над буферизированными данными.

Можно было бы отнести ЦД к разряду оптимизационных вещей (со всеми оговорками), если бы он не страдал (как правило) от пессимизации в виде многократного дублирования повторяющихся условий.

kkkk

  • Full Member
  • ***
  • Сообщений: 135
    • Просмотр профиля
Re: Раскручиваем компилятор O7
« Ответ #99 : Ноябрь 11, 2013, 07:03:39 pm »
По сравнению с LOOP EXIT END цикл Дейкстры не несёт никаких оптимизаций, а только отсекает излишнию гибкость неструктурного цикла. Конечно, явная поддержка конструкции в языке даст оптимизирующему компилятору больше возможностей для ускорения, но такой компилятор выкинет и повторяющиеся проверки. Только это не в стиле Оберона, тем более что по моему опыту основной удар принимает первая ветка и повторные проверки не оказывают существенного влияния на время исполнения.