М. В. Ломоносова Факультет вычислительной математики и кибернетики Е. И. Большакова, Н. В. Груздева Основы программирования на языке Рефал Учебное пособие
![]()
|
3.3.Присоединённый блокВ языке Рефал-5 предложение функции может также иметь вид: образец последовательность_условий , присоединённый_блок присоединённый_блок ::= аргумент : { блок } Присоединённый блок вида выражение-аргумент : блок служит для определения новой функции без имени и её вызова внутри рефал-предложения. Блок (последовательность рефал-предложений) присоединяется к левой части рефал-предложения, он записывается после его основного образца и следующими за ним дополнительными условиями, в совокупности определяющими применимость этого предложения. Считается, что правая часть предложения в этом случае отсутствует, отсутствует и знак =, разделяющий левую и правую часть предложения, а перед присоединённым блоком ставится запятая, отделяющая его от левой части рефал-предложения. Выражение-аргумент присоединённого блока, как и выражение-аргумент условной конструкции, может содержать функциональные термы и переменные, но только связанные. Двоеточие между выражением-аргументом и блоком предложений означает в данном случае применение блока к заданному выражению-аргументу, т.е. применение функции, определённой предложениями блока, к заданному аргументу. Укажем правила обработки присоединённого блока рефал-машиной. Вычисление выражения-аргумента присоединенного блока осуществляется так же, как вычисление выражения-аргумента при обработке условной конструкции. Само выполнение присоединённого блока предложений реализуется так же, как и выполнение вызова функции по имени: вычисленное значение аргумента поочередно сопоставляется с левыми частями предложений блока – с тем, чтобы найти применимое предложение. Применение найденного предложения определяет не только результат вычисления блока, но и результат выполнения рефал-предложения, к которому этот блок был присоединён. В случае, когда ни одно из предложений блока неприменимо, возникает аварийный останов рефал-машины (аналогично обычному функциональному вызову). В присоединённом блоке могут использоваться переменные из основного образца рефал-предложения и дополнительных условий, к моменту выполнения блока эти переменные уже имеют значения (являются связанными). Подчеркнём, что начало выполнения присоединённого блока означает полное завершение процесса отождествления, осуществляемого при проверке основного образца предложения и дополнительных условий. Это означает, что никакие другие варианты отождествления основного образца и образцов этих условий в ходе дальнейших вычислений рассматриваться не будут. В качестве примера присоединённого блока рассмотрим функцию Tran, она ищет цепочку из трёх символов, средний символ – знак равенства, среди фрагментов, на которые входная цепочка символов делится знаками *. Если такая цепочка обнаруживается, Tran заключает её в скобки и выдаёт в качестве результата, иначе выдаёт 'No'. Например, результатом применения функции Tran к строке 'X‑2+Y*P/3=9*A=5*Z-8' будет выражение ('A=5'). В своей работе Tran использует Fract – вспомогательную функцию, которая возвращает Т, если её аргумент является искомой цепочкой, и F в ином случае. * Вспомогательная функция проверки цепочки символов Fract { s.1 '=' s.2 = T; e.X = F } * Функция Tran возвращает найденную цепочку * из трёх символов, заключённую в структурные скобки, * либо строку 'No' Tran { e.1 '*' e.2 , F = e.X = 'No' } Как можно заметить, присоединённый блок позволяет определить безымянную функцию именно в том месте, где нужно её использовать. В общем случае присоединённый блок может содержать внутри себя другие присоединённые блоки, и уровень вложенности не ограничивается. Функция OrdABC представляет пример функции, в которой используются вложенные присоединённые блоки. Эта функция выдает Т, если в обрабатываемом выражении на верхнем уровне встречаются символы 'А', 'В' и 'С', причём символ 'А' стоит левее символа 'В', а символ 'В' – левее символа 'С'. Во всех остальных случаях результатом является F. * Функция OrdABC возвращает Т, * если в исходном выражении * на верхнем уровне есть символ 'А', * правее него встречается символ 'В', * а правее этих двух символов встречается 'С'. * Иначе функция возвращает F. OrdABC { e.X 'A' e.1 , e.1 : { e.Y 'B' e.2 , e.2 : { e.Z 'C' e.3 = T ; e.Z = F } ; e.Y = F } ; e.X = F } Для решения рассмотренной задачи можно написать более простую и понятную функцию: SimpleOrdABC { e.X 'А' e.Y 'B' e.Z 'C' e.D = T ; e.X = F } Эта функция является менее эффективной, т.к. образец первого предложения содержит большое количество е-переменных, и в ходе его отождествления будут пробоваться их различные значения. В функции OrdABC отождествление выражений будет происходить быстрее: попытка найти символ 'В' будет происходить только после того, как в выражении-аргументе найден символ 'А'. Причём 'В' ищется только в подвыражении, расположенном правее 'А', а подвыражение, стоящее левее, более не рассматривается. Аналогичным образом будет происходить поиск символа 'С'. В итоге результат (Т или F) будет получен быстрее. |