Главная Длительная эволюция [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30] [31] [32] [33] [34] [35] [36] [37] [38] [39] [40] [41] [42] [43] [44] [45] [46] [47] [48] [49] [50] [51] [ 52 ] [53] [54] [55] [56] [57] [58] [59] [60] [61] [62] [63] [64] [65] [66] [67] [68] [69] [70] [71] [72] [73] [74] [75] [76] [77] [78] [79] [80] [81] [82] [83] [84] [85] [86] /., Т.е. ReplaceAlI, и .,т.е. ReplaceRepeated. На применение шаблонов, как и в глобальных правилах преобразований, можно накладывать ограничения с помощью указания заголовков шаблонов или с помощью предикатов. Присутствие шаблонов, содержащих подчеркивание , приводит к некоторым особенностям вычисления функций ReplaceAlI и RepalceRepeated, которые необходимо обсудить. Они относятся к тем случаям, когда рассматриваемые функции применяют правила подстановок, содержащие списки подстановок. {ij} /• {i->l,j->2} {1,2} Результат этого вычисления достаточно очевиден. Следующее вычисление менее очевидно. {i,j} /. {i-,l,j-2, {i,j}->0} О Полученный ответ заставляет предположить, что шаблон в целом имеет большее соответствие с преобразуемым выражением, чем его отдельные части. Однако это правило работает отнюдь не во всех случаях. {i,i} /. {{х.,х }-1,{. }-0} 1 Этот результат как будто подтверждает правило, потому что шаблон {х ,х } определяет более узкий класс выражений, чем шаблон {-}. Тем не менее если мы изменим порядок шаблонов в подстановке, то получим другой ответ. {1,1}/.{{ -}-0,{х ,х }->1} О Следовательно, если требуется запрограммировать функцию, называемую <5-символом Кронекера: S{i,j) = 1 при г = j н S{iJ) = О в противном случае, то следует написать определение: delta[L,j ]:={i,j} /. {{х ,х }-> 1, { }-> 0} {delta[2,2], delta[l,2]} {1, 0} Определенные особенности имеет также и вычисление функции ReplaceRepeated с шаблонами. Вообще говоря, ее вычисление сводится к повторному вычислению функции ReplaceAU до тех пор, пока ни одно из подвыражений преобразуемого выражения не удается преобразовать в соответствии с хотя бы одним шаблоном списка. При этом порядок применения шаблонов следующий. Первый шаблон списка используется, пока в преобразуемом выражении находится хотя бы одно подвыражение, ему соответствующее. Затем применяется второй шаблон списка и т.д. Ни в коем случае не следует думать, что каждый раз применяется более чем один шаблон списка. Рассмотрим иллюстрирующий пример: {1,2,а} .{{.,х ,а} -> {х,а},{. ,2, } -> 2,{а} а} а Мы видим, что первый шаблон списка применяется два раза, сводя выражение к одноэлементному списку {а}, а затем применяется третий шаблон. Второй шаблон не работает после первого применения ReplaceAU, хотя в этот момент исходное выражение преобразовано к виду {2, а}. После применения третьего шаблона полученное выражение а уже не соответствует ни одному из шаблонов, поэтому вычисления прекращаются. Контроль за вычислением ReplaceRepeated может осуществляться с помощью условий, выраженных предикатами. В качестве примеров рассмотрим имитацию с помощью локальных правил преобразований некоторых функций, используемых для генерации и преобразования списков. Начнем с функции Range[n], порождающей список натуральных чисел от 1 до п. Идея состоит в том, чтобы, применяя подстановку {! -} :> {i,Z,enpf/i[{i}]-1-1}, с помощью функции ReplaceRepeated и стартуя со списка {1}, преобразовать последний в список {1,2,...,п}. {1} .{х } :> {x,Length[{x}]-bl}/;Length[{x}]<3 {1,2,3} Конструкция прекрасно работает и позволяет определить функцию range[n ]:={l} .{x. } :> {x,Length[{x}]-Ы}/; Length[{x}] < n range[10] {1,2,3,4,5,6,7,8,9,10} Аналогичная идея лежит в основе имитации функции Drop. drop[l List,n .Integer] :=1 .{х ,у } :> {у}/; Length[{y}] > Length[l] - n - 1 {drop[{a,b,c,d,e},3],drop[{a,b,c,d,e},5]} {{d,e},{}} Следующая задача предлагалась на соревновании по элегантному программированию на Первой конференции пользователей „Математики" в 1991 г. Дан список из повторяющихся чисел, например 1= {1,1,1,2,2,3,3,3,3,1,1}; Требуется составить список пар, первым элементом которых были бы элементы списка I, а вторыми - числа их смежных повторений. Таким образом, список / должен быть преобразован в список [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30] [31] [32] [33] [34] [35] [36] [37] [38] [39] [40] [41] [42] [43] [44] [45] [46] [47] [48] [49] [50] [51] [ 52 ] [53] [54] [55] [56] [57] [58] [59] [60] [61] [62] [63] [64] [65] [66] [67] [68] [69] [70] [71] [72] [73] [74] [75] [76] [77] [78] [79] [80] [81] [82] [83] [84] [85] [86] 0.0006 |