Maxima Manual: Функции и переменные для правил преобразования и шаблонов

Previous: Введение в правила преобразований и шаблоны, Up: Правила преобразования и шаблоны [Contents][Index]

### 34.2 Функции и переменные для правил преобразования и шаблонов

Функция: apply1 (expr, rule_1, ..., rule_n)

  Осуществляет повторное применение правила преобразования rule_1 к expr до тех пор пока выражение отвечает шаблону преобразования, затем, таким же образом осуществляется повторное применение этого правила ко всем подвыражениям expr, слева направо. Далее, к полученному результату тем же способом применяется правило rule_2 и так далее все последующие правила вплоть до rule_n. Конечный результат возвращается.

  Переменная `maxapplydepth` контролирует нижнюю глубину уровня подвыражения до которого применяются правила преобразований в функциях `apply1` и `apply2`.

  См. также applyb1, `apply2` и `let`.

Функция: apply2 (expr, rule_1, ..., rule_n)

  Если правило rule_1 неприменимо на подвыражении expr, тогда применяется правило rule_2 и далее по той же схеме остальные правила. Только если каждое из правил является неприменимым на данном подвыражении expr, программа переходит на следующий уровень подвыражнния expr, и по той же схеме последовательно применяет весь набор правил, начиная с первого. Если применение одного из правил оказывается успешным, тогда весь набор правил заново применяется к этому подвыражению.

  Переменная `maxapplydepth` контролирует нижнюю глубину уровня подвыражения до которого применяются правила преобразований в функциях `apply1` и `apply2`.

  См. также `apply1` и `let`.

Функция: applyb1 (expr, rule_1, ..., rule_n)

  В отличие от `apply1` применяется по восходящей, т.е., сначала на самом глубоком уровне expr повторяется применение правила rule_1. Затем программа переходит на более высокие уровни expr и применяет данное правило по той же схеме. После того как применение правила rule_1 терпит неудачу на самом вернем уровне expr программа переходит к применению правила rule_2 по той же схеме (по восходящей) и так далее, заканчивая применением правила rule_n. После этого возвращается результат.

  Функция `applyb1` аналогична `apply1`, но работает по восходящей.

  Переменная `maxapplyheight` контролирует высоту уровня подвыражения до которого применяются правила преобразований в функции `applyb1`.

  См. также `apply1`, `apply2` и `let`.

Управляющая переменная: current_let_rule_package

  Значение по умолчанию: `default_let_rule_package`

  `current_let_rule_package` - имя пакета правил, которые, если не определен другой пакет правил, используются функциями из программы `let` (такими как, `letsimp`, и т.д.) Эта переменной может быть присвоено имя любого пакета правил преобразований, определенного при помощи функции `let`.

  При вызове `letsimp (expr, rule_pkg_name)`, пакет правил `rule_pkg_name` используется только во время данного действия, при этом значение переменной `current_let_rule_package` остается неизменным.

Управляющая переменная: default_let_rule_package

  Значение по умолчанию: `default_let_rule_package`

  `default_let_rule_package` - имя пакета правил, используемого по умолчанию, если пакет правил не был задан в явном виде при вызове `let` или через изменение значения переменной `current_let_rule_package`.

Функция: defmatch (progname, pattern, x_1, ..., x_n)
Функция: defmatch (progname, pattern)

  Определяет функцию `progname (expr, x_1, ..., x_n)`, которая проверяет выражение expr на соответствие шаблону pattern.

  Шаблон pattern - выражение, содержащее аргументы шаблона x_1, ..., x_n (если есть) и переменные шаблона (если есть). Аргументы шаблона задаются в явном виде, как аргументы функции `defmatch`, а переменные шаблона декларируются функцией `matchdeclare`. Всякая переменная, не декларированная как переменная шаблона при помощи `mathdeclare` или как аргумент шаблона при помощи `defmatch` соответствует только сама себе.

  Первым аргументом создаваемой функции progname является выражение, проверяемое на соответствие шаблону, а другие аргументы это актуальные параметры, соответствующие аргументам шаблона x_1, ..., x_n.

  Если проверка на соответствие шаблону оказывается успешной, то progname возвращает список уравнений, в которых левые части являются аргументами и переменными шаблона, а правые части - подвыражения expr, сопоставленные данным аргументам и переменным. Переменным шаблона, но не аргументам шаблона, присваиваются соответствующие значения. В случае неудачи сопоставления progname возвращает `false`.

  Любая переменная, не объявленная в параметрах шаблона в `matchdeclare` или в переменных шаблона в `defmatch`, сопоставляется только самой себе.

  Программа для буквального шаблона, т.е. шаблона не содержащего ни аргументов ни переменных, в случае удачи сопоставления возвращает `true`.

  См. также `matchdeclare`, `defrule`, `tellsimp` и `tellsimpafter`.

  Примеры:

  Определим функцию `linearp (expr, x)`, которая проверяет может ли `expr` быть представлено ввиде `a*x + b`, где `a` и `b` не содержат `x` и `a` отлично от нуля. Эта функция сопоставима с выражениями линейными по любой переменной, поскольку аргумент шаблона `x` определен в `defmatch`.

      (%i1) matchdeclare (a, lambda ([e], e#0 and freeof(x, e)), b,
                          freeof(x));
      (%o1)                         done
      (%i2) defmatch (linearp, a*x + b, x);
      (%o2)                        linearp
      (%i3) linearp (3*z + (y + 1)*z + y^2, z);
                               2
      (%o3)              [b = y , a = y + 4, x = z]
      (%i4) a;
      (%o4)                         y + 4
      (%i5) b;
                                      2
      (%o5)                          y
      (%i6) x;
      (%o6)                           x

  Определим функцию `linearp(expr)`, которая проверяет может ли `expr` быть представлено ввиде `a*x + b`, где `a` и `b` не содержат `x` и `a` отлично от нуля. Эта функция сопоставима с выражениями линейными только по `x`, поскольку в `defmatch` не заданы никакие аргументы шаблона.

      (%i1) matchdeclare (a, lambda ([e], e#0 and freeof(x, e)), b,
                          freeof(x));
      (%o1)                         done
      (%i2) defmatch (linearp, a*x + b);
      (%o2)                        linearp
      (%i3) linearp (3*z + (y + 1)*z + y^2);
      (%o3)                         false
      (%i4) linearp (3*x + (y + 1)*x + y^2);
                                   2
      (%o4)                  [b = y , a = y + 4]

  Определим функцию `checklimits(expr)`, которая проверяет, определяет ли `expr` интеграл.

      (%i1) matchdeclare ([a, f], true);
      (%o1)                         done
      (%i2) constinterval (l, h) := constantp (h - l);
      (%o2)        constinterval(l, h) := constantp(h - l)
      (%i3) matchdeclare (b, constinterval (a));
      (%o3)                         done
      (%i4) matchdeclare (x, atom);
      (%o4)                         done
      (%i5) simp : false;
      (%o5)                         false
      (%i6) defmatch (checklimits, 'integrate (f, x, a, b));
      (%o6)                      checklimits
      (%i7) simp : true;
      (%o7)                         true
      (%i8) 'integrate (sin(t), t, %pi + x, 2*%pi + x);
                             x + 2 %pi
                            /
                            [
      (%o8)                 I          sin(t) dt
                            ]
                            /
                             x + %pi
      (%i9) checklimits (%);
      (%o9)    [b = x + 2 %pi, a = x + %pi, x = t, f = sin(t)]

Функция: defrule (rulename, pattern, replacement)

  Определяет и именует правило преобразования для данного шаблона. Если правило c именем rulename применяется к выражению (путем `apply1`, `applyb1` или `apply2`), то каждое подвыражение, удовлетворяющее шаблону, заменяется соответствующей подстановкой. После этого выражение упрощается.

  Правила могут рассматриваться как функции, преобразующие выражение путем одной операции сопоставления с шаблоном и подстановки. При неудаче сопоставления, функция правила преобразования возвращает `false`.

Функция: disprule (rulename_1, ..., rulename_2)
Функция: disprule (all)

  Выводит правила преобразований и их имена rulename_1, ..., rulename_n, определенные в `defrule`, `tellsimp` или `tellsimpafter`, или шаблоны, определенные `defmatch`. Каждое правило выводится в форме промежуточного выражения, маркированного символом (`%t`).

  Вызов `disprule (all)` выводит все определенные правила.

  Функция `disprule` не вычисляет свои аргументы. Функция `disprule` возвращает список меток промежуточных выражений, соответствующих выведенным правилам.

  См. также функцию `letrules`, которая выводит правила определенные `let`.

  Примеры:

      (%i1) tellsimpafter (foo (x, y), bar (x) + baz (y));
      (%o1)                   [foorule1, false]
      (%i2) tellsimpafter (x + y, special_add (x, y));
      (%o2)                   [+rule1, simplus]
      (%i3) defmatch (quux, mumble (x));
      (%o3)                         quux
      (%i4) disprule (foorule1, "+rule1", quux);
      (%t4)        foorule1 : foo(x, y) -> baz(y) + bar(x)

      (%t5)          +rule1 : y + x -> special_add(x, y)

      (%t6)                quux : mumble(x) -> []

      (%o6)                    [%t4, %t5, %t6]
      (%i6) ''%;
      (%o6) [foorule1 : foo(x, y) -> baz(y) + bar(x),
           +rule1 : y + x -> special_add(x, y), quux : mumble(x) -> []]

Функция: let (prod, repl, predname, arg_1, ..., arg_n)
Функция: let ([prod, repl, predname, arg_1, ..., arg_n], package_name)

  Определяет правила подстановки для функции `letsimp` такие, что prod заменяется на repl. prod является произведением подвыражений положительной или отрицательной степени. Подвыражения могут быть следующего типа:

  - Атомы, поиск которых `letsimp` ведет только по имени, если перед вызовом `letsimp` в функции `matchdeclare` не был определен предикат, связанный с этим атомом. В последнем случае `letsimp` будет сопоставлять атом с любым членом произведения удовлетворяющим предикату.
  - Ядра типа `sin(x)`, `n!`, `f(x,y)` и т.п. Как и в предыдущем случае `letsimp` ищет буквальное соответствие, если в `matchdeclare` не был определен предикат.

  Члены положительной степени будут сопоставляться только членам, имеющим положительную степень. Члены отрицательной степени будут сопоставляться только членам, имеющим отрицательную степень. Для того чтобы `letsimp` работал с отрицательными степенями в prod переменная `letrat` должна быть установлена равной `true`. См. также `letrat`.

  Если в функцию `let` включен предикат, с последующим списком аргументов, то подстановки осуществляются только если `predname (arg_1', ..., arg_n')` дает `true`, где arg_i’ есть значение, сопоставленное arg_i. Переменная arg_i может быть именем атома или аргументом любого ядра, присутствующего в prod. repl может быть любым рациональным выражением. Если любой атом или аргумент из prod присутствует в repl, то выполняются соответствующие подстановки.

  Глобальная переменная `letrat` управляет упрощением дробных выражений в `letsimp`. Если `letrat` равена `false`, то `letsimp` упрощает отдельно числитель и знаменатель выражения expr, но не упрощает их частное. В этом случае подстановки типа `n!/n` на `(n-1)!` не будут работать. Если `letrat` равена `true`, тогда числитель, знаменатель и их частное упрощаются в данном порядке.

  Данные функции подстановок позволяют работать с несколькими пакетами правил одновременно. Каждый пакет правил может содержать любое количество правил преобразований `let` и обозначается некоторым заданным пользователем именем. Вызов `let ([prod, repl, predname, arg_1, ..., arg_n], package_name)` добавляет правило predname к пакету правил package_name. Вызов `letsimp (expr, package_name)` применяет правила преобразований из пакета package_name. Процедура `letsimp (expr, package_name1, package_name2, ...)` эквивалентна применению функций `letsimp (expr, package_name1)` и затем функции `letsimp (%, package_name2)`, ....

  Переменная `current_let_rule_package` содержит имя текущего пакета правил. Данной переменной может быть присвоено имя любого пакета правил, определенного при помощи `let`. Вызов команды `let` без упоминания имени пакета приводит к применению пакета, определенного `current_let_rule_package`. При вызове типа `letsimp (expr, rule_pkg_name)`, используются правила пакета rule_pkg_name, только для данного вызова `lrtsimp` а значение переменной `current_let_rule_package` не меняется. По умолчанию `current_let_rule_package` равно `default_let_rule_package`.

      (%i1) matchdeclare ([a, a1, a2], true)$
      (%i2) oneless (x, y) := is (x = y-1)$
      (%i3) let (a1*a2!, a1!, oneless, a2, a1);
      (%o3)         a1 a2! --> a1! where oneless(a2, a1)
      (%i4) letrat: true$
      (%i5) let (a1!/a1, (a1-1)!);
                              a1!
      (%o5)                   --- --> (a1 - 1)!
                              a1
      (%i6) letsimp (n*m!*(n-1)!/m);
      (%o6)                      (m - 1)! n!
      (%i7) let (sin(a)^2, 1 - cos(a)^2);
                              2               2
      (%o7)                sin (a) --> 1 - cos (a)
      (%i8) letsimp (sin(x)^4);
                              4           2
      (%o8)                cos (x) - 2 cos (x) + 1

Управляющая переменная: letrat

  Значение по умолчанию: `false`

  Если `letrat` равна `false`, то `letsimp` упрощает отдельно числитель и знаменатель выражения expr, и не упрощает их частное.

  Если `letrat` равна `true`, то числитель, знаменатель и их частное упрощаются в данном порядке.

      (%i1) matchdeclare (n, true)$
      (%i2) let (n!/n, (n-1)!);
                               n!
      (%o2)                    -- --> (n - 1)!
                               n
      (%i3) letrat: false$
      (%i4) letsimp (a!/a);
                                     a!
      (%o4)                          --
                                     a
      (%i5) letrat: true$
      (%i6) letsimp (a!/a);
      (%o6)                       (a - 1)!

Функция: letrules ()
Функция: letrules (package_name)

  Выводит правила, содержащиеся в пакете правил преобразований. `letrules ()` выводит правила текущего пакета правил преобразований. `letrules (package_name)` выводит правила преобразований в пакете package_name.

  Текущий пакет правил определяется значением `current_let_rule_package`. Если не определено иначе, то `current_let_rule_package` по умолчанию равен `default_let_rule_package`.

  См. также функцию `disprule`, отображающую правила, определенные путем `tellsimp` и `tellsimpafter`.

Функция: letsimp (expr)
Функция: letsimp (expr, package_name)
Функция: letsimp (expr, package_name_1, ..., package_name_n)

  Данная функция осуществляет повторное применение правил подстановки, определенных в `let`, до тех пор пока выражение expr не перестанет изменяться.

  `letsimp (expr)` использует правила из пакета `current_let_rule_package`.

  `letsimp (expr, package_name)` использует правила из пакета package_name без изменения значения переменной `current_let_rule_package`.

  `letsimp (expr, package_name_1, ..., package_name_n)` эквивалентно применению `letsimp (expr, package_name_1`, затем `letsimp (%, package_name_2)` и так далее.

Управляющая переменная: let_rule_packages

  Значение по умолчанию: `[default_let_rule_package]`

  `let_rule_packages` - список определенных пользователем пакетов правил вместе с пакетом `default_let_rule_package`.

Функция: matchdeclare (a_1, pred_1, ..., a_n, pred_n)

  Связывает предикат pred_k с переменной или списком переменных a_k, так что a_k сопоставляется с выражениями, для которых предикат возвращает значение отличное от `false`.

  Предикат это есть имя функции, или лямбда-выражение, или вызов функции или лямбда-выражения без последнего аргумента, или `true`, или `all`. Если предикат определен при помощи вызова функции или лямбда-выражения, то тестируемое выражение добавляется к списку аргументов; аргументы вычисляются во время вызова процедуры проверки на соответствие. Если предикат определен в виде имени функции или лямбда-выражения, то единственным аргументом является тестируемое выражение. Предикат не обязан быть определенным в момент вызова `matchdeclare`, поскольку он не вычисляется до тех пор пока не вызывается проверка на соответствие.

  Предикат может возвращать логическое выражение а также `true` или `false`. Логическое выражение вычисляется при помощи `is` внутри построенной функции правила, так что нет необходимости вызывать `is` в предикате.

  Если выражение удовлетворяет предикату, то переменной шаблона присваивается выражение за исключением переменных шаблона которые являются операндами сложения `+` или умножения `*`. Только сложение и умножение управляется специальным образом. Другие n-арные операторы, (как пользовательские, так и встроенные) рассматриваются как обычные функции.

  В случае операторов сложения и умножения, переменной шаблона может быть присвоено простое выражение, которое соответствует предикату, а также сумма или произведение таких выражений. Такое сложное сопоставление является ресурсоемким: предикаты вычисляются в порядке в котором, ассоциированные с ними переменные, встречаются в тестируемом выражении, и член, удовлетворяющий более чем одному предикату, сопоставляется первому соответствующему предикату. Каждый предикат проверяется для всех операндов суммы или произведения и только после этого проверяется следующий предикат. Кроме того, если 0 или 1 удовлетворяют предикату, а все остальные слагаемые выражения нет, тогда 0 или 1 присваиваются переменным шаблона ассоциированным с предикатом.

  Алгоритм проверки шаблонов, содержащий суммы и произведения, может давать разные результаты (например, шаблон, содержащий переменную соответствующую "всему, что угодно") в зависимости от порядка членов заданного шаблона и порядка членов тестируемого выражения. Если все операторы предикаты взаимно исключают друг друга, то результат не зависит от порядка, поскольку члены, соответствующие одному предикату, не могут соответствовать другому.

  Вызов `matchdeclare` с переменной a в качестве аргумента изменяет ранее объявленные свойства `matchdeclare` для a - при определении правил преобразования, учитываются только самый последний вызов `matchdeclare`. Все последующие изменения свойства `matchdeclare` (посредством `matchdeclare` или `remove`) не меняют существующих правил преобразований.

  `propvars (matchdeclare)` возвращает список всех переменных, имеющих свойство `matchdeclare`. `printprops (a, matchdeclare)` возвращает предикат для переменной `a`. `printprops (all, matchdeclare)` возвращает список всех предикатов для всех переменных `matchdeclare`. `remove (a, matchdeclare)` удаляет свойства `matchdeclare` для переменной a.

  Функции `defmatch`, `defrule`, `tellsimp`, `tellsimpafter` и `let` строят правила, которые сопоставляют выражения с шаблонами.

  Функция `matchdeclare` не вычисляет свои аргументы. Функция `matchdeclare` всегда возвращает `done`.

  Примеры:

  Предикат есть имя функции, или лямбда-выражение, или вызов функции или лямбда-вызов без последнего аргумента, или `true`, или `all`.

      (%i1) matchdeclare (aa, integerp);
      (%o1)                         done
      (%i2) matchdeclare (bb, lambda ([x], x > 0));
      (%o2)                         done
      (%i3) matchdeclare (cc, freeof (%e, %pi, %i));
      (%o3)                         done
      (%i4) matchdeclare (dd, lambda ([x, y], gcd (x, y) = 1) (1728));
      (%o4)                         done
      (%i5) matchdeclare (ee, true);
      (%o5)                         done
      (%i6) matchdeclare (ff, all);
      (%o6)                         done

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

      (%i1) matchdeclare (aa, integerp, bb, atom);
      (%o1)                         done
      (%i2) defrule (r1, bb^aa, ["integer" = aa, "atom" = bb]);
                          aa
      (%o2)        r1 : bb   -> [integer = aa, atom = bb]
      (%i3) r1 (%pi^8);
      (%o3)               [integer = 8, atom = %pi]

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

      (%i1) matchdeclare (aa, atom, bb, lambda ([x], not atom(x)));
      (%o1)                         done
      (%i2) defrule (r1, aa + bb, ["all atoms" = aa, "all nonatoms" =
                     bb]);
      bb + aa partitions `sum'
      (%o2)  r1 : bb + aa -> [all atoms = aa, all nonatoms = bb]
      (%i3) r1 (8 + a*b + sin(x));
      (%o3)     [all atoms = 8, all nonatoms = sin(x) + a b]
      (%i4) defrule (r2, aa * bb, ["all atoms" = aa, "all nonatoms" =
                     bb]);
      bb aa partitions `product'
      (%o4)   r2 : aa bb -> [all atoms = aa, all nonatoms = bb]
      (%i5) r2 (8 * (a + b) * sin(x));
      (%o5)    [all atoms = 8, all nonatoms = (b + a) sin(x)]

  При сопоставлении аргументов `+` и `*`, если все предикаты условия являются взаимоисключающими, то результат проверки не зависит порядка, так как один предикат не соответствует членам, соответствующим другому предикату.

      (%i1) matchdeclare (aa, atom, bb, lambda ([x], not atom(x)));
      (%o1)                         done
      (%i2) defrule (r1, aa + bb, ["all atoms" = aa, "all nonatoms" =
                     bb]);
      bb + aa partitions `sum'
      (%o2)  r1 : bb + aa -> [all atoms = aa, all nonatoms = bb]
      (%i3) r1 (8 + a*b + %pi + sin(x) - c + 2^n);
                                                           n
      (%o3) [all atoms = %pi + 8, all nonatoms = sin(x) + 2  - c + a b]
      (%i4) defrule (r2, aa * bb, ["all atoms" = aa, "all nonatoms" =
                     bb]);
      bb aa partitions `product'
      (%o4)   r2 : aa bb -> [all atoms = aa, all nonatoms = bb]
      (%i5) r2 (8 * (a + b) * %pi * sin(x) / c * 2^n);
                                                        n
                                               (b + a) 2  sin(x)
      (%o5) [all atoms = 8 %pi, all nonatoms = -----------------]
                                                       c

  Функции `propvars` и `printprops` возвращают информацию о переменных шаблона.

      (%i1) matchdeclare ([aa, bb, cc], atom, [dd, ee], integerp);
      (%o1)                         done
      (%i2) matchdeclare (ff, floatnump, gg, lambda ([x], x > 100));
      (%o2)                         done
      (%i3) propvars (matchdeclare);
      (%o3)             [aa, bb, cc, dd, ee, ff, gg]
      (%i4) printprops (ee, matchdeclare);
      (%o4)                    [integerp(ee)]
      (%i5) printprops (gg, matchdeclare);
      (%o5)              [lambda([x], x > 100, gg)]
      (%i6) printprops (all, matchdeclare);
      (%o6) [lambda([x], x > 100, gg), floatnump(ff), integerp(ee),
                            integerp(dd), atom(cc), atom(bb), atom(aa)]

Функция: matchfix (ldelimiter, rdelimiter)
Функция: matchfix (ldelimiter, rdelimiter, arg_pos, pos)

  Объявляет матчфиксный (matchfix) оператор с левым и правым ограничителями ldelimiter и rdelimiter соответственно. Ограничители являются строками.

  Матчфиксный оператор является функцией любого количества аргументов заключенных между ограничителями ldelimiter и rdelimiter. Ограничителем может являться любая строка, если синтаксический анализатор может различить ограничители от других выражений и операторов. На практике, это исключает такие ограничители, как `%`, `,`, `$` и `;`, и может потребовать при вводе изолировать ограничители пробелами. Правый ограничитель может совпадать с левым или отличаться от него.

  Левый ограничитель может быть ассоциирован только с одним правым; два различных матчфиксных оператора не могут иметь одинаковых левых ограничителя.

  Существующий оператор может быть переобъявлен, как матчфиксный оператор без изменения других его свойств. Например, встроенные операторы сложения `+` могут быть объявлены матчфиксными, однако операторные функции для встроенных операторов определены быть не могут.

  Вызов `matchfix (ldelimiter, rdelimiter, arg_pos, pos)` объявляет аргумент "часть речи" arg_pos и результат "часть речи" pos вместе с ограничителями ldelimiter и rdelimiter.

  Термин "чать речи" по отношению к декларации операторов означает тип выражения. Различаются три типа выражений: `expr`, `clause` и `any`, что обозначает алгебраическое выражение, логическое выражение и выражение произвольного типа соответственно. Maxima может обнаруживать некоторые синтаксические ошибки сравнивая объявленную часть речи с реальным выражением.

  Функция для выполнения матчфиксной операции является обычной пользовательской функцией. Операторная функция определяется стандартным образом при помощи операторов `:=` или `define`. Аргументы могут быть записаны между ограничителями или при помощи левого ограничителя в форме строки и последующих аргументов в скобках. `dispfun (ldelimiter)` выводит определение функции.

  Единственный встроенный матчфиксный оператор это конструктор списка `[ ]`. Скобки `( )` и двойные кавычки `" "` работают как матчфиксные операторы, однако не обрабатываются синтаксическим анализатором Maxima как таковые.

  Функция `matchfix` вычисляет свои аргументы. Функция `matchfix` возвращает свой первый аргумент ldelimiter.

  Примеры:

  - В качестве ограничителей можно задавать практически любые строки.

      (%i1) matchfix ("@@", "~");
      (%o1)                          @@
      (%i2) @@ a, b, c ~;
      (%o2)                      @@a, b, c~
      (%i3) matchfix (">>", "<<");
      (%o3)                          >>
      (%i4) >> a, b, c <<;
      (%o4)                      >>a, b, c<<
      (%i5) matchfix ("foo", "oof");
      (%o5)                          foo
      (%i6) foo a, b, c oof;
      (%o6)                     fooa, b, coof
      (%i7) >> w + foo x, y oof + z << / @@ p, q ~;
                           >>z + foox, yoof + w<<
      (%o7)                ----------------------
                                  @@p, q~

  - Матчфиксные операторы – это обычные пользовательские функции.

      (%i1) matchfix ("!-", "-!");
      (%o1)                         "!-"
      (%i2) !- x, y -! := x/y - y/x;
                                          x   y
      (%o2)                   !-x, y-! := - - -
                                          y   x
      (%i3) define (!-x, y-!, x/y - y/x);
                                          x   y
      (%o3)                   !-x, y-! := - - -
                                          y   x
      (%i4) define ("!-" (x, y), x/y - y/x);
                                          x   y
      (%o4)                   !-x, y-! := - - -
                                          y   x
      (%i5) dispfun ("!-");
                                          x   y
      (%t5)                   !-x, y-! := - - -
                                          y   x

      (%o5)                         done
      (%i6) !-3, 5-!;
                                      16
      (%o6)                         - --
                                      15
      (%i7) "!-" (3, 5);
                                      16
      (%o7)                         - --
                                      15

Функция: remlet (prod, name)
Функция: remlet ()
Функция: remlet (all)
Функция: remlet (all, name)

  Удаляет правило подстановки prod -> замена, определенное при самом последнем вызове функции `let`. При вызове с именем правила в качестве аргумента удаление производится из соответствующего пакета правил.

  Вызовы `remlet()` и `remlet(all)` удаляют все правила подстановки из текущего пакета правил. При указании имени, например, `remlet (all, name)`, пакет правил name также удаляется.

  Если необходимо изменить правило подстановки одного произведения, нет необходимости вызывать `remlet`, можно просто переопределить подстановку данного произведения при помощи функции `let`, с новой заменой и/или предикатом. После этого вызов `remlet (prod)` восстанавливает исходное правило подстановки.

  См. также функцию `remrule`, которая удаляет правила определенные функцией `tellsimp` или `tellsimpafter`.

Функция: remrule (op, rulename)
Функция: remrule (op, all)

  Удаляет правила, определенные функциями `tellsimp` или `tellsimpafter`.

  `remrule (op, rulename)` удаляет правило с именем rulename для оператора op. Если оператор op является встроенным оператором или определен пользователем (например, при помощи функций `infix`, `prefix`, и т.п.), тогда op и rulename необходимо заключить в двойные кавычки.

  `remrule (op, all)` удаляет все правила для оператора op.

  См. также функцию `remlet`, удаляющую правила, определенные при помощи `let`.

  Примеры:

      (%i1) tellsimp (foo (aa, bb), bb - aa);
      (%o1)                   [foorule1, false]
      (%i2) tellsimpafter (aa + bb, special_add (aa, bb));
      (%o2)                   [+rule1, simplus]
      (%i3) infix ("@@");
      (%o3)                          @@
      (%i4) tellsimp (aa @@ bb, bb/aa);
      (%o4)                   [@@rule1, false]
      (%i5) tellsimpafter (quux (%pi, %e), %pi - %e);
      (%o5)                  [quuxrule1, false]
      (%i6) tellsimpafter (quux (%e, %pi), %pi + %e);
      (%o6)             [quuxrule2, quuxrule1, false]
      (%i7) [foo (aa, bb), aa + bb, aa @@ bb, quux (%pi, %e),
             quux (%e, %pi)];
                                           bb
      (%o7) [bb - aa, special_add(aa, bb), --, %pi - %e, %pi + %e]
                                           aa
      (%i8) remrule (foo, foorule1);
      (%o8)                          foo
      (%i9) remrule ("+", "+rule1");
      (%o9)                           +
      (%i10) remrule ("@@", "@@rule1");
      (%o10)                         @@
      (%i11) remrule (quux, all);
      (%o11)                        quux
      (%i12) [foo (aa, bb), aa + bb, aa @@ bb, quux (%pi, %e),
              quux (%e, %pi)];
      (%o12) [foo(aa, bb), bb + aa, aa @@ bb, quux(%pi, %e),
                                               quux(%e, %pi)]

Функция: tellsimp (pattern, replacement)

  аналогична `tellsimpafter`, но добавляет новую информацию о правилах до уже существующей. Таким образом, сначала применяются пользовательские правила упрощения, а потом правила, встроенные в систему.

  Функция `tellsimp` используется, когда важно модифицировать выражение до того, как оно обработано упрощателем, например, встроенный механизм упрощения "знает" что-либо о структуре выражения, но возвращает результат, который вас не устраивает. Если встроенный механизм упрощения "знает" что-либо о главном операторе выражения, но работает не достаточно эффективно - можно попробовать использовать `tellsimpafter`.

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

  `rules` - список правил определенный функциями `defrule`, `defmatch`, `tellsimp` и `tellsimpafter`.

  Примеры:

      (%i1) matchdeclare (x, freeof (%i));
      (%o1)                         done
      (%i2) %iargs: false$
      (%i3) tellsimp (sin(%i*x), %i*sinh(x));
      (%o3)                 [sinrule1, simp-%sin]
      (%i4) trigexpand (sin (%i*y + x));
      (%o4)         sin(x) cos(%i y) + %i cos(x) sinh(y)
      (%i5) %iargs:true$
      (%i6) errcatch(0^0);
       0
      0  has been generated
      (%o6)                          []
      (%i7) ev (tellsimp (0^0, 1), simp: false);
      (%o7)                  [^rule1, simpexpt]
      (%i8) 0^0;
      (%o8)                           1
      (%i9) remrule ("^", %th(2)[1]);
      (%o9)                           ^
      (%i10) tellsimp (sin(x)^2, 1 - cos(x)^2);
      (%o10)                 [^rule2, simpexpt]
      (%i11) (1 + sin(x))^2;
                                            2
      (%o11)                    (sin(x) + 1)
      (%i12) expand (%);
                                         2
      (%o12)               2 sin(x) - cos (x) + 2
      (%i13) sin(x)^2;
                                        2
      (%o13)                     1 - cos (x)
      (%i14) kill (rules);
      (%o14)                        done
      (%i15) matchdeclare (a, true);
      (%o15)                        done
      (%i16) tellsimp (sin(a)^2, 1 - cos(a)^2);
      (%o16)                 [^rule3, simpexpt]
      (%i17) sin(y)^2;
                                        2
      (%o17)                     1 - cos (y)

Функция: tellsimpafter (pattern, replacement)

  Определяет правило упрощения, которое встроенный в Maxima механизм упрощения применяет после встроенных правил упрощения. pattern - выражение, включающее переменные шаблона (объявленные в `matchdeclare`) и другие атомы и операторы, которые рассматриваются как константы с точки зрения сопоставления с шаблоном. replacement подставляется вместо первоначального выражения, удовлетворяющего шаблону pattern; переменным шаблона из в replacement присваиваются соответствующие подвыражения из реального выражения.

  pattern может быть любым составным выражением в котором имя главного оператор не входит в число переменных шаблона; правило упрощения связывается с именем главного оператора. Имена функций (за исключением приведенных ниже), списки и массивы могут присутствовать в шаблоне pattern в качестве основного оператора только, как литералы (не переменные шаблона); это исключает шаблоны вида `aa(x)` и `bb[y]`, если `aa` и `bb` являются переменными шаблона. Имена функций, списки и массивы, которые являются переменными шаблона могут входить в качестве не основных операторов в описание шаблона pattern.

  Есть одно исключение к указанному правилу, касающееся имен функций. Имена функций с индексом в выражениях типа `aa[x](y)` могут быть переменными шаблона, поскольку в этом случае главный оператор не `aa`, а Lisp-атом `mqapply`. Это является следствием представления выражений, включающих функции с индексом.

  Правила упрощения применяются после вычисления (если вычисления не запрещены либо экранированием выражения, либо ключом `noeval`). Правила введенные `tellsimpafter` применяются в том порядке в котором они были определены после всех встроенных правил. Преобразования применяются "снизу-вверх", т.е., сначала к подвыражению, перед обработкой выражения в целом. Иногда для того, чтобы обеспечить, что применены все правила, необходимо повторное упрощение результата (например, при применении оператора кавычка-кавычка `''` или ключа `infeval`).

  Переменные шаблона рассматриваются как локальные переменные в правилах упрощения. Как только правило определено, значение переменной шаблона не влияет на правило, и наоборот, правило не влияет на значение переменной. Присваивание значений переменным шаблона, происходящее в результате успешного сопоставления шаблона, не влияет на текущие значения (или их отсутствие) переменных шаблона. Однако, как и у всех атомов в Maxima, свойства переменных шаблона (объявленные оператором `put` и подобными функциями) являются глобальными.

  Правило, построенное с помощью `tellsimpafter`, обозначаеся именем главного оператора pattern. Правила для встроенных операторов и пользовательских функций, определенных при помощи `infix`, `prefix`, `postfix`, `matchfix` и `nofix`, имеют имена, являющиеся Lisp-идентификаторами. Правила для других функций имеют имена, являющиеся идентификаторами Maxima.

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

  Правило, построенное с помощью `tellsimpafter`, является обычной Lisp- функцией. Если имя правила - `$foorule1`, то конструкция `:lisp (trace $foorule1)` дает трассировку ее вызовов, а `:lisp (symbol-function '$foorule1` выводит ее определение.

  Функция `tellsimpafter` не вычисляет свои аргументы. Функция `tellsimpafter` возвращает список правил для основного оператора шаблона pattern, включая вновь объявленные правила.

  См. также `matchdeclare`, `defmatch`, `defrule`, `tellsimp`, `let`, `kill`, `remrule` и `clear_rules`.

  Примеры:

  pattern может быть любым неатомарным выражением в котором главный оператор не является переменной шаблона.

      (%i1) matchdeclare (aa, atom, [ll, mm], listp, xx, true)$
      (%i2) tellsimpafter (sin (ll), map (sin, ll));
      (%o2)                 [sinrule1, simp-%sin]
      (%i3) sin ([1/6, 1/4, 1/3, 1/2, 1]*%pi);
                          1  sqrt(2)  sqrt(3)
      (%o3)              [-, -------, -------, 1, 0]
                          2     2        2
      (%i4) tellsimpafter (ll^mm, map ("^", ll, mm));
      (%o4)                  [^rule1, simpexpt]
      (%i5) [a, b, c]^[1, 2, 3];
                                      2   3
      (%o5)                      [a, b , c ]
      (%i6) tellsimpafter (foo (aa (xx)), aa (foo (xx)));
      (%o6)                   [foorule1, false]
      (%i7) foo (bar (u - v));
      (%o7)                    bar(foo(u - v))

  Правила применяются в том порядке в котором они были определены. Если два правила соответствуют выражению, то первым применяется то, которое было определено раньше.

      (%i1) matchdeclare (aa, integerp);
      (%o1)                         done
      (%i2) tellsimpafter (foo (aa), bar_1 (aa));
      (%o2)                   [foorule1, false]
      (%i3) tellsimpafter (foo (aa), bar_2 (aa));
      (%o3)              [foorule2, foorule1, false]
      (%i4) foo (42);
      (%o4)                       bar_1(42)

  Переменные шаблона являются локальными переменные правил упрощения. (Сравни с функцией `defmatch`, которая рассматривает переменные шаблона, как глобальные).

      (%i1) matchdeclare (aa, integerp, bb, atom);
      (%o1)                         done
      (%i2) tellsimpafter (foo(aa, bb), bar('aa=aa, 'bb=bb));
      (%o2)                   [foorule1, false]
      (%i3) bb: 12345;
      (%o3)                         12345
      (%i4) foo (42, %e);
      (%o4)                 bar(aa = 42, bb = %e)
      (%i5) bb;
      (%o5)                         12345

  Как и у всех атомов, свойства переменных шаблона являются глобальными даже если их значение локально. В данном примере свойство объявляется при помощи `define_variable`. Это свойство атома `bb` является глобальным.

      (%i1) matchdeclare (aa, integerp, bb, atom);
      (%o1)                         done
      (%i2) tellsimpafter (foo(aa, bb), bar('aa=aa, 'bb=bb));
      (%o2)                   [foorule1, false]
      (%i3) foo (42, %e);
      (%o3)                 bar(aa = 42, bb = %e)
      (%i4) define_variable (bb, true, boolean);
      (%o4)                         true
      (%i5) foo (42, %e);
      Error: bb was declared mode boolean, has value: %e
       -- an error.  Quitting.  To debug this try debugmode(true);

  Правила именуются по имени основного оператора. Имена правил для встроенных и пользовательских операторов являются Lisp-идентификаторами, тогда как имена других функций являются идентификаторами Maxima.

      (%i1) tellsimpafter (foo (%pi + %e), 3*%pi);
      (%o1)                   [foorule1, false]
      (%i2) tellsimpafter (foo (%pi * %e), 17*%e);
      (%o2)              [foorule2, foorule1, false]
      (%i3) tellsimpafter (foo (%i ^ %e), -42*%i);
      (%o3)         [foorule3, foorule2, foorule1, false]
      (%i4) tellsimpafter (foo (9) + foo (13), quux (22));
      (%o4)                   [+rule1, simplus]
      (%i5) tellsimpafter (foo (9) * foo (13), blurf (22));
      (%o5)                  [*rule1, simptimes]
      (%i6) tellsimpafter (foo (9) ^ foo (13), mumble (22));
      (%o6)                  [^rule1, simpexpt]
      (%i7) rules;
      (%o7) [foorule1, foorule2, foorule3, +rule1, *rule1, ^rule1]
      (%i8) foorule_name: first (%o1);
      (%o8)                       foorule1
      (%i9) plusrule_name: first (%o4);
      (%o9)                        +rule1
      (%i10) remrule (foo, foorule1);
      (%o10)                         foo
      (%i11) remrule ("^", ?\^rule1);
      (%o11)                          ^
      (%i12) rules;
      (%o12)        [foorule2, foorule3, +rule1, *rule1]

  Рабочий пример: антикоммутативное умножение.

      (%i1) gt (i, j) := integerp(j) and i < j;
      (%o1)           gt(i, j) := integerp(j) and i < j
      (%i2) matchdeclare (i, integerp, j, gt(i));
      (%o2)                         done
      (%i3) tellsimpafter (s[i]^^2, 1);
      (%o3)                 [^^rule1, simpncexpt]
      (%i4) tellsimpafter (s[i] . s[j], -s[j] . s[i]);
      (%o4)                   [.rule1, simpnct]
      (%i5) s[1] . (s[1] + s[2]);
      (%o5)                    s  . (s  + s )
                                1     2    1
      (%i6) expand (%);
      (%o6)                      1 - s  . s
                                      2    1
      (%i7) factor (expand (sum (s[i], i, 0, 9)^^5));
      (%o7) 100 (s  + s  + s  + s  + s  + s  + s  + s  + s  + s )
                  9    8    7    6    5    4    3    2    1    0

Функция: clear_rules ()

  Исполняет `kill (rules)` и обнуляет счетчик, т.е. новое правило будет иметь номер `1` вслед за встроенными правилами для операторов суммы `+`, умножения `*` и степени `^`.

Previous: Введение в правила преобразований и шаблоны, Up: Правила преобразования и шаблоны [Contents][Index]