Add symbol checks to translators for MCALL, MARRAYREF, and MARRAYSET
[maxima.git] / doc / info / ru / Rules.texi
blobb4f2f0d88a894dd4777f2e1a553b40528fba8d79
1 @c Language=Russian
2 @c Encoding=UTF-8
3 @c File=Rules.texi 
4 @c OriginalRevision=1.35
5 @c TranslatedBy: (c) 2007-09-11 Valery Pipin <pip@iszf.irk.ru>
8 @menu
9 * Введение в правила преобразований и шаблоны::  
10 * Функции и переменные для правил преобразования и шаблонов::  
11 @end menu
13 @node Введение в правила преобразований и шаблоны, Функции и переменные для правил преобразования и шаблонов, Правила преобразования и шаблоны, Правила преобразования и шаблоны
14 @section Введение в правила преобразований и шаблоны
16 Данный раздел описывает особенности программирования правил
17 преобразований и шаблонов, применяемые в Maxima для упрощения выражений.
18 Имеется две группы функций, реализующих несколько различающиеся схемы применения
19 шаблонов преобразований.
20 К одной группе относятся функции @code{tellsimp}, @code{tellsimpafter}, 
21 @code{defmatch}, @code{defrule},@code{apply1}, @code{applyb1} и @code{apply2}.
22 В другую группу входят функции @code{let} и @code{letsimp}.
23 В обоих группах шаблоны определяются через переменные
24 шаблонов, объявляемые функцией @code{matchdeclare}.
26 Правила преобразований, определенные в процедурах @code{tellsimp} и
27 @code{tellsimpafter}, применяются Maxima автоматически (если
28 управляющая переменная @code{simp} имеет значение @code{true}).
29 Правила преобразований, определенные в процедурах @code{defmatch},
30 @code{defrule} и @code{let} применяются только при явном вызове
31 соответствующих функций.
33 Имеются, также, дополнительные возможности использования правил
34 преобразований, например, при
35 работе с полиномами в процедуре @code{tellrat}, и для коммутативной и
36 некоммутативной алгебры в пакете  @code{affine}.  
38 @opencatbox{Категории:}
39 @category{Упрощение}
40 @category{Правила преобразования и шаблоны}
41 @closecatbox
43 @c end concepts Rules and Patterns
44 @node Функции и переменные для правил преобразования и шаблонов,  , Введение в правила преобразований и шаблоны, Правила преобразования и шаблоны
45 @section Функции и переменные для правил преобразования и шаблонов
47 @c NEEDS CLARIFICATION AND EXAMPLES
48 @deffn {Функция} apply1 (@var{expr}, @var{rule_1}, ..., @var{rule_n})
49 Осуществляет повторное применение правила преобразования @var{rule_1} к
50 @var{expr} до тех пор пока выражение отвечает шаблону преобразования,
51 затем, таким же образом осуществляется повторное применение этого правила ко всем
52 подвыражениям @var{expr}, слева направо. 
53 Далее, к полученному
54 результату тем же способом применяется правило @var{rule_2} и так далее 
55 все последующие правила вплоть до @var{rule_n}. Конечный результат возвращается.
57 Переменная @code{maxapplydepth} контролирует нижнюю глубину уровня подвыражения до
58 которого применяются правила преобразований в функциях @code{apply1} и @code{apply2}.
60 См. также @var{applyb1}, @code{apply2} и @code{let}.
62 @opencatbox{Категории:}
63 @category{Правила преобразования и шаблоны}
64 @closecatbox
65 @end deffn
67 @c NEEDS CLARIFICATION AND EXAMPLES
68 @deffn {Функция} apply2 (@var{expr}, @var{rule_1}, ..., @var{rule_n})
69 Если правило @var{rule_1} неприменимо на подвыражении  @var{expr},
70 тогда применяется правило @var{rule_2} и далее по той же схеме остальные
71 правила. Только если каждое из правил является неприменимым на данном подвыражении @var{expr}, 
72 программа переходит на следующий уровень подвыражнния @var{expr}, 
73 и по той же схеме последовательно применяет весь набор правил, 
74 начиная с первого. Если применение одного из правил оказывается
75 успешным, тогда весь набор правил заново применяется к
76 этому подвыражению.
78 Переменная @code{maxapplydepth} контролирует нижнюю глубину уровня подвыражения до
79 которого применяются правила преобразований в функциях @code{apply1} и @code{apply2}.
81 См. также @code{apply1} и @code{let}.
83 @opencatbox{Категории:}
84 @category{Правила преобразования и шаблоны}
85 @closecatbox
86 @end deffn
88 @c NEEDS CLARIFICATION AND EXAMPLES
89 @deffn {Функция} applyb1 (@var{expr}, @var{rule_1}, ..., @var{rule_n})
90 В отличие от @code{apply1} применяется по восходящей, т.е., сначала на
91 самом глубоком уровне @var{expr} повторяется применение правила
92 @var{rule_1}. Затем программа переходит на более высокие уровни
93 @var{expr} и применяет данное правило по той же схеме.  После того как
94 применение правила @var{rule_1} терпит неудачу на самом вернем уровне
95 @var{expr} программа переходит к применению правила  @var{rule_2} по
96 той же схеме (по восходящей) и так далее, заканчивая применением
97 правила  @var{rule_n}. После этого возвращается результат.
99 Функция @code{applyb1} аналогична @code{apply1}, но работает по восходящей.
101 Переменная @code{maxapplyheight} контролирует высоту уровня подвыражения до
102 которого применяются правила преобразований в функции @code{applyb1}.
104 См. также @code{apply1}, @code{apply2} и @code{let}.
106 @opencatbox{Категории:}
107 @category{Правила преобразования и шаблоны}
108 @closecatbox
109 @end deffn
111 @defvr {Управляющая переменная} current_let_rule_package
112 Значение по умолчанию: @code{default_let_rule_package}
114 @code{current_let_rule_package} - имя пакета правил, которые, если не
115 определен другой пакет правил, используются функциями из программы  @code{let} (такими как,
116 @code{letsimp}, и т.д.) @c NEED TO GIVE AN EXPLICIT LIST HERE (NOT "ETC")
117 Эта переменной может быть присвоено имя любого пакета правил 
118 преобразований, определенного при помощи функции @code{let}.
120 При вызове @code{letsimp (expr, rule_pkg_name)},
121 пакет правил @code{rule_pkg_name} используется только во время данного
122 действия, при этом  значение переменной @code{current_let_rule_package}
123 остается неизменным.
125 @opencatbox{Категории:}
126 @category{Правила преобразования и шаблоны}
127 @closecatbox
128 @end defvr
130 @defvr {Управляющая переменная} default_let_rule_package
131 @c DEFAULT BINDING OF default_let_rule_package IS default_let_rule_package (BOUND TO ITSELF)
132 Значение по умолчанию: @code{default_let_rule_package}
134 @c THIS IS SORT OF CONFUSING. PROBABLY NEED TO GIVE MORE DETAIL HERE
135 @code{default_let_rule_package} - имя пакета правил, используемого по умолчанию, если
136 пакет правил не был задан в явном виде при вызове @code{let} или через
137 изменение значения переменной @code{current_let_rule_package}.
139 @opencatbox{Категории:}
140 @category{Правила преобразования и шаблоны}
141 @closecatbox
142 @end defvr
144 @deffn {Функция} defmatch (@var{progname}, @var{pattern}, @var{x_1}, ..., @var{x_n})
145 @deffnx {Функция} defmatch (@var{progname}, @var{pattern})
146 Определяет функцию @code{@var{progname} (@var{expr}, @var{x_1}, ..., @var{x_n})}, 
147 которая проверяет выражение @var{expr} на соответствие шаблону @var{pattern}.
149 Шаблон @var{pattern} - выражение, содержащее аргументы шаблона @var{x_1}, ..., @var{x_n} (если есть)
150 и переменные шаблона (если есть).
151 Аргументы шаблона задаются в явном виде, как аргументы функции
152 @code{defmatch}, а переменные шаблона декларируются функцией @code{matchdeclare}.
153 Всякая переменная, не декларированная как переменная шаблона при помощи @code{mathdeclare}
154 или как аргумент шаблона при помощи @code{defmatch} соответствует только сама себе.
156 Первым аргументом создаваемой функции @var{progname} является выражение,
157 проверяемое на соответствие шаблону, а другие аргументы это
158 актуальные параметры, соответствующие аргументам шаблона  @var{x_1}, ..., @var{x_n}.
160 Если проверка на соответствие шаблону оказывается успешной, то
161 @var{progname} возвращает список уравнений, в которых левые части
162 являются аргументами и переменными шаблона, а правые части - подвыражения @var{expr},
163 сопоставленные данным аргументам и переменным. 
164 Переменным шаблона, но не аргументам шаблона, присваиваются соответствующие значения.
165 В случае неудачи сопоставления @var{progname} возвращает @code{false}.  
167 Любая переменная, не объявленная в параметрах шаблона в
168 @code{matchdeclare} или в переменных шаблона в @code{defmatch},
169 сопоставляется только самой себе.
171 Программа для буквального шаблона, т.е. шаблона не содержащего ни аргументов ни переменных, 
172 в случае удачи сопоставления возвращает @code{true}.
174 См. также @code{matchdeclare}, @code{defrule}, @code{tellsimp} и @code{tellsimpafter}.
176 Примеры:
178 Определим функцию @code{linearp (expr, x)}, которая проверяет может ли @code{expr}  быть представлено
179 ввиде @code{a*x + b}, где @code{a} и @code{b} не содержат @code{x} и @code{a} отлично от нуля.
180 Эта функция сопоставима с выражениями линейными по любой переменной,
181 поскольку аргумент шаблона @code{x} определен в @code{defmatch}.
182 @c HOW HARD WILL MAXIMA TRY TO COLLECT TERMS AND DO OTHER MUNGEING TO FIT THE PATTERN ??
184 @c ===beg===
185 @c matchdeclare (a, lambda ([e], e#0 and freeof(x, e)), b, 
186 @c                     freeof(x));
187 @c defmatch (linearp, a*x + b, x);
188 @c linearp (3*z + (y + 1)*z + y^2, z);
189 @c a;
190 @c b;
191 @c x;
192 @c ===end===
193 @example
194 (%i1) matchdeclare (a, lambda ([e], e#0 and freeof(x, e)), b,
195                     freeof(x));
196 (%o1)                         done
197 (%i2) defmatch (linearp, a*x + b, x);
198 (%o2)                        linearp
199 (%i3) linearp (3*z + (y + 1)*z + y^2, z);
200                          2
201 (%o3)              [b = y , a = y + 4, x = z]
202 (%i4) a;
203 (%o4)                         y + 4
204 (%i5) b;
205                                 2
206 (%o5)                          y
207 (%i6) x;
208 (%o6)                           x
209 @end example
211 Определим функцию @code{linearp(expr)}, которая проверяет может ли @code{expr} быть представлено
212 ввиде @code{a*x + b}, где @code{a} и @code{b} не содержат @code{x} и @code{a} отлично от нуля.
213 Эта функция сопоставима с выражениями линейными только по @code{x},
214 поскольку в @code{defmatch} не заданы никакие аргументы шаблона.
216 @c ===beg===
217 @c matchdeclare (a, lambda ([e], e#0 and freeof(x, e)), b, 
218 @c                     freeof(x));
219 @c defmatch (linearp, a*x + b);
220 @c linearp (3*z + (y + 1)*z + y^2);
221 @c linearp (3*x + (y + 1)*x + y^2);
222 @c ===end===
223 @example
224 (%i1) matchdeclare (a, lambda ([e], e#0 and freeof(x, e)), b,
225                     freeof(x));
226 (%o1)                         done
227 (%i2) defmatch (linearp, a*x + b);
228 (%o2)                        linearp
229 (%i3) linearp (3*z + (y + 1)*z + y^2);
230 (%o3)                         false
231 (%i4) linearp (3*x + (y + 1)*x + y^2);
232                              2
233 (%o4)                  [b = y , a = y + 4]
234 @end example
236 Определим функцию @code{checklimits(expr)}, которая проверяет,
237 определяет ли @code{expr} интеграл.
239 @c ===beg===
240 @c matchdeclare ([a, f], true);
241 @c constinterval (l, h) := constantp (h - l);
242 @c matchdeclare (b, constinterval (a));
243 @c matchdeclare (x, atom);
244 @c simp : false;
245 @c defmatch (checklimits, 'integrate (f, x, a, b));
246 @c simp : true;
247 @c 'integrate (sin(t), t, %pi + x, 2*%pi + x);
248 @c checklimits (%);
249 @c ===end===
250 @example
251 (%i1) matchdeclare ([a, f], true);
252 (%o1)                         done
253 (%i2) constinterval (l, h) := constantp (h - l);
254 (%o2)        constinterval(l, h) := constantp(h - l)
255 (%i3) matchdeclare (b, constinterval (a));
256 (%o3)                         done
257 (%i4) matchdeclare (x, atom);
258 (%o4)                         done
259 (%i5) simp : false;
260 (%o5)                         false
261 (%i6) defmatch (checklimits, 'integrate (f, x, a, b));
262 (%o6)                      checklimits
263 (%i7) simp : true;
264 (%o7)                         true
265 (%i8) 'integrate (sin(t), t, %pi + x, 2*%pi + x);
266                        x + 2 %pi
267                       /
268                       [
269 (%o8)                 I          sin(t) dt
270                       ]
271                       /
272                        x + %pi
273 (%i9) checklimits (%);
274 (%o9)    [b = x + 2 %pi, a = x + %pi, x = t, f = sin(t)]
275 @end example
277 @opencatbox{Категории:}
278 @category{Правила преобразования и шаблоны}
279 @closecatbox
280 @end deffn
282 @c NEEDS CLARIFICATION AND EXAMPLES
283 @deffn {Функция} defrule (@var{rulename}, @var{pattern}, @var{replacement})
284 Определяет и именует правило преобразования для данного шаблона.
285 Если правило c именем @var{rulename} применяется к выражению
286 (путем @code{apply1}, @code{applyb1} или @code{apply2}), то каждое
287 подвыражение, удовлетворяющее шаблону, заменяется соответствующей подстановкой. 
288 После этого выражение упрощается.
290 Правила могут рассматриваться как функции, преобразующие выражение путем
291 одной операции сопоставления с шаблоном и подстановки. 
292 При неудаче сопоставления, функция правила преобразования возвращает @code{false}.
294 @opencatbox{Категории:}
295 @category{Правила преобразования и шаблоны}
296 @closecatbox
297 @end deffn
299 @c NEEDS EXAMPLES
300 @deffn {Функция} disprule (@var{rulename_1}, ..., @var{rulename_2})
301 @deffnx {Функция} disprule (all)
302 Выводит правила преобразований и их имена @var{rulename_1}, ..., @var{rulename_n},
303 определенные в  @code{defrule}, @code{tellsimp} или @code{tellsimpafter}, или
304 шаблоны, определенные @code{defmatch}.
305 Каждое правило выводится в форме промежуточного выражения, маркированного символом (@code{%t}).
307 Вызов @code{disprule (all)} выводит все определенные правила.
309 Функция @code{disprule} не вычисляет свои аргументы.
310 Функция @code{disprule} возвращает список меток промежуточных выражений, соответствующих выведенным правилам.
312 См. также функцию @code{letrules}, которая выводит правила определенные @code{let}.
314 Примеры:
316 @c ===beg===
317 @c tellsimpafter (foo (x, y), bar (x) + baz (y));
318 @c tellsimpafter (x + y, special_add (x, y));
319 @c defmatch (quux, mumble (x));
320 @c disprule (foorule1, "+rule1", quux);
321 @c ''%;
322 @c ===end===
323 @example
324 (%i1) tellsimpafter (foo (x, y), bar (x) + baz (y));
325 (%o1)                   [foorule1, false]
326 (%i2) tellsimpafter (x + y, special_add (x, y));
327 (%o2)                   [+rule1, simplus]
328 (%i3) defmatch (quux, mumble (x));
329 (%o3)                         quux
330 (%i4) disprule (foorule1, "+rule1", quux);
331 (%t4)        foorule1 : foo(x, y) -> baz(y) + bar(x)
333 (%t5)          +rule1 : y + x -> special_add(x, y)
335 (%t6)                quux : mumble(x) -> []
337 (%o6)                    [%t4, %t5, %t6]
338 (%i6) ''%;
339 (%o6) [foorule1 : foo(x, y) -> baz(y) + bar(x), 
340      +rule1 : y + x -> special_add(x, y), quux : mumble(x) -> []]
341 @end example
343 @opencatbox{Категории:}
344 @category{Правила преобразования и шаблоны}
345 @category{Функции вывода}
346 @closecatbox
347 @end deffn
349 @deffn {Функция} let (@var{prod}, @var{repl}, @var{predname}, @var{arg_1}, ..., @var{arg_n})
350 @deffnx {Функция} let ([@var{prod}, @var{repl}, @var{predname}, @var{arg_1}, ..., @var{arg_n}],  @var{package_name})
351 Определяет правила подстановки для функции @code{letsimp} такие, что @var{prod} заменяется на @var{repl}.
352 @var{prod} является произведением подвыражений положительной или  отрицательной степени. 
353 Подвыражения могут быть следующего типа:
355 @itemize @bullet
356 @item
357 Атомы, поиск которых @code{letsimp} ведет только по имени, если перед
358 вызовом  @code{letsimp} в функции @code{matchdeclare} не был определен
359 предикат, связанный с этим атомом.  В последнем случае @code{letsimp}
360 будет сопоставлять атом с любым членом произведения удовлетворяющим предикату.
361 @item
362 Ядра типа @code{sin(x)}, @code{n!}, @code{f(x,y)} и т.п.  Как и в
363 предыдущем случае @code{letsimp} ищет буквальное соответствие, если
364 в @code{matchdeclare} не был определен предикат.
365 @end itemize
367 Члены положительной степени будут сопоставляться только членам, имеющим положительную
368 степень. Члены отрицательной степени будут сопоставляться только членам, имеющим отрицательную
369 степень. 
370 Для  того чтобы @code{letsimp} работал с отрицательными степенями в @var{prod} 
371 переменная  @code{letrat} должна быть установлена равной @code{true}.
372 См. также @code{letrat}.
374 Если в функцию @code{let} включен предикат, с последующим списком аргументов,
375 то подстановки осуществляются только если  @code{predname (arg_1', ...,
376 arg_n')} дает @code{true}, где @var{arg_i'} есть значение, сопоставленное  @var{arg_i}. 
377 Переменная @var{arg_i} может быть именем атома или аргументом любого ядра, присутствующего в @var{prod}.
378 @var{repl} может быть любым  рациональным выражением. @c ONLY RATIONAL -- REALLY ??
379 Если любой атом или аргумент из @var{prod} присутствует в
380 @var{repl}, то выполняются соответствующие подстановки. @c SPELL OUT "APPROPRIATE" IN THIS CONTEXT
382 Глобальная переменная @code{letrat} управляет упрощением дробных
383 выражений в @code{letsimp}.
384 Если @code{letrat} равена @code{false}, то
385 @code{letsimp} упрощает отдельно числитель и знаменатель выражения
386 @var{expr}, но не упрощает их частное.
387 В этом случае подстановки типа @code{n!/n} на @code{(n-1)!} не будут работать.
388 Если @code{letrat} равена @code{true}, тогда числитель, знаменатель и
389 их частное упрощаются в данном порядке.
391 Данные функции подстановок позволяют работать с несколькими пакетами
392 правил одновременно. Каждый пакет правил может содержать любое
393 количество правил преобразований @code{let} и обозначается некоторым
394 заданным пользователем именем.
395 Вызов @code{let ([@var{prod}, @var{repl}, @var{predname}, @var{arg_1}, ..., @var{arg_n}], @var{package_name})}
396 добавляет правило @var{predname} к пакету правил @var{package_name}.
397 Вызов @code{letsimp (@var{expr}, @var{package_name})}
398 применяет правила преобразований из пакета @var{package_name}.
399 Процедура @code{letsimp (@var{expr}, @var{package_name1}, @var{package_name2}, ...)}
400 эквивалентна применению функций @code{letsimp (@var{expr}, @var{package_name1})}
401 и затем функции @code{letsimp (%, @var{package_name2})}, ....
403 Переменная @code{current_let_rule_package} содержит имя текущего пакета правил.
404 Данной переменной может быть присвоено имя любого пакета правил,
405 определенного при помощи @code{let}.
406 Вызов команды @code{let} без упоминания имени пакета приводит к
407 применению пакета, определенного @code{current_let_rule_package}.
408 При вызове типа @code{letsimp (@var{expr}, @var{rule_pkg_name})},
409 используются правила пакета @var{rule_pkg_name}, только для данного вызова @code{lrtsimp} а 
410 значение переменной  @code{current_let_rule_package}
411 не меняется. По умолчанию @code{current_let_rule_package} равно @code{default_let_rule_package}.
413 @example
414 (%i1) matchdeclare ([a, a1, a2], true)$
415 (%i2) oneless (x, y) := is (x = y-1)$
416 (%i3) let (a1*a2!, a1!, oneless, a2, a1);
417 (%o3)         a1 a2! --> a1! where oneless(a2, a1)
418 (%i4) letrat: true$
419 (%i5) let (a1!/a1, (a1-1)!);
420                         a1!
421 (%o5)                   --- --> (a1 - 1)!
422                         a1
423 (%i6) letsimp (n*m!*(n-1)!/m);
424 (%o6)                      (m - 1)! n!
425 (%i7) let (sin(a)^2, 1 - cos(a)^2);
426                         2               2
427 (%o7)                sin (a) --> 1 - cos (a)
428 (%i8) letsimp (sin(x)^4);
429                         4           2
430 (%o8)                cos (x) - 2 cos (x) + 1
431 @end example
433 @c NEEDS ADDITIONAL EXAMPLES
435 @opencatbox{Категории:}
436 @category{Правила преобразования и шаблоны}
437 @closecatbox
438 @end deffn
440 @defvr {Управляющая переменная} letrat
441 Значение по умолчанию: @code{false}
443 Если @code{letrat} равна @code{false}, то @code{letsimp} упрощает отдельно числитель и знаменатель выражения
444 @var{expr}, и не упрощает их частное.
446 Если @code{letrat} равна @code{true}, то числитель, знаменатель и их частное упрощаются в данном порядке.
448 @example
449 (%i1) matchdeclare (n, true)$
450 (%i2) let (n!/n, (n-1)!);
451                          n!
452 (%o2)                    -- --> (n - 1)!
453                          n
454 (%i3) letrat: false$
455 (%i4) letsimp (a!/a);
456                                a!
457 (%o4)                          --
458                                a
459 (%i5) letrat: true$
460 (%i6) letsimp (a!/a);
461 (%o6)                       (a - 1)!
462 @end example
464 @opencatbox{Категории:}
465 @category{Правила преобразования и шаблоны}
466 @closecatbox
467 @end defvr
469 @c NEEDS EXAMPLES
470 @deffn {Функция} letrules ()
471 @deffnx {Функция} letrules (@var{package_name})
472 Выводит правила, содержащиеся в пакете правил преобразований.
473 @code{letrules ()} выводит правила текущего пакета правил
474 преобразований.
475 @code{letrules (@var{package_name})} выводит правила преобразований в
476 пакете @var{package_name}.
478 Текущий пакет правил определяется значением @code{current_let_rule_package}.
479 Если не определено иначе, то @code{current_let_rule_package}
480 по умолчанию равен @code{default_let_rule_package}.
482 См. также функцию @code{disprule}, отображающую правила, определенные
483 путем @code{tellsimp} и @code{tellsimpafter}.
484 @c WHAT ABOUT defmatch AND defrule ??
486 @opencatbox{Категории:}
487 @category{Правила преобразования и шаблоны}
488 @closecatbox
489 @end deffn
491 @deffn {Функция} letsimp (@var{expr})
492 @deffnx {Функция} letsimp (@var{expr}, @var{package_name})
493 @deffnx {Функция} letsimp (@var{expr}, @var{package_name_1}, ..., @var{package_name_n})
494 Данная функция осуществляет повторное применение правил подстановки,
495 определенных в @code{let}, до тех пор пока выражение @var{expr} не
496 перестанет изменяться.
498 @code{letsimp (@var{expr})} использует правила из пакета @code{current_let_rule_package}.
500 @code{letsimp (@var{expr}, @var{package_name})} использует правила из пакета @var{package_name}
501 без изменения значения переменной @code{current_let_rule_package}.
503 @code{letsimp (@var{expr}, @var{package_name_1}, ..., @var{package_name_n})}
504 эквивалентно применению  @code{letsimp (@var{expr}, @var{package_name_1}},
505 затем @code{letsimp (%, @var{package_name_2})} и так далее.
507 @c NEEDS EXAMPLES
508 @opencatbox{Категории:}
509 @category{Правила преобразования и шаблоны}
510 @closecatbox
511 @end deffn
513 @defvr {Управляющая переменная} let_rule_packages
514 Значение по умолчанию: @code{[default_let_rule_package]}
516 @code{let_rule_packages} - список определенных пользователем пакетов
517 правил вместе с пакетом @code{default_let_rule_package}.
519 @opencatbox{Категории:}
520 @category{Правила преобразования и шаблоны}
521 @closecatbox
522 @end defvr
524 @deffn {Функция} matchdeclare (@var{a_1}, @var{pred_1}, ..., @var{a_n}, @var{pred_n})
525 Связывает предикат @var{pred_k} с переменной или списком переменных
526 @var{a_k}, так что  @var{a_k} сопоставляется с выражениями,
527 для которых предикат возвращает значение отличное от @code{false}.
529 Предикат это есть имя функции, или лямбда-выражение, или вызов функции 
530 или лямбда-выражения без последнего аргумента, или @code{true}, или @code{all}.
531 Если предикат определен при помощи вызова функции или лямбда-выражения, то 
532 тестируемое выражение добавляется к списку аргументов; аргументы вычисляются 
533 во время вызова процедуры проверки на соответствие. 
534 Если предикат определен в виде имени функции или лямбда-выражения, 
535 то единственным аргументом является тестируемое выражение.
536 Предикат не обязан быть определенным в момент вызова
537 @code{matchdeclare}, поскольку он не вычисляется до тех пор пока 
538 не вызывается проверка на соответствие.
540 Предикат может возвращать логическое выражение а также @code{true} или @code{false}.
541 Логическое выражение вычисляется при помощи @code{is} внутри построенной функции правила,
542 так что нет необходимости вызывать @code{is} в предикате.
544 Если выражение удовлетворяет предикату, то переменной шаблона
545 присваивается выражение за исключением переменных шаблона которые
546 являются операндами сложения  @code{+} или умножения @code{*}. 
547 Только сложение и умножение управляется специальным образом. Другие n-арные операторы,
548 (как пользовательские, так и встроенные) рассматриваются как обычные функции.
549 @c WOULD BE GREAT TO EXTEND PART+/PART* PROCESSING TO ALL N-ARY OPERATORS
551 В случае операторов сложения и умножения, переменной шаблона может быть
552 присвоено простое выражение, которое соответствует предикату, а также сумма
553 или произведение таких выражений. 
554 Такое сложное сопоставление является ресурсоемким: предикаты 
555 вычисляются в порядке в котором, ассоциированные с ними переменные,
556 встречаются в тестируемом выражении, и член, удовлетворяющий более чем одному предикату,
557 сопоставляется первому соответствующему предикату.
558 Каждый предикат проверяется для всех операндов суммы или произведения и только после этого проверяется
559 следующий предикат.  Кроме того, если 0 или 1 удовлетворяют предикату, а все остальные слагаемые выражения нет, 
560 тогда 0 или 1 присваиваются переменным шаблона ассоциированным с
561 предикатом.
563 Алгоритм проверки шаблонов, содержащий суммы и произведения, 
564 может давать разные результаты (например,  шаблон, содержащий переменную соответствующую
565 "всему, что угодно") в зависимости от порядка 
566 членов заданного шаблона и порядка членов тестируемого выражения. 
567 Если все операторы предикаты взаимно исключают друг друга, то результат не зависит от порядка, 
568 поскольку члены, соответствующие одному предикату, не могут соответствовать другому.
570 Вызов  @code{matchdeclare} с переменной  @var{a} в качестве аргумента
571 изменяет ранее объявленные свойства  @code{matchdeclare} для @var{a} -
572 при определении правил преобразования, учитываются только самый последний 
573 вызов @code{matchdeclare}. 
574 Все последующие изменения свойства @code{matchdeclare} 
575 (посредством @code{matchdeclare} или @code{remove}) 
576 не меняют существующих правил преобразований.
578 @code{propvars (matchdeclare)} возвращает список всех переменных,
579 имеющих свойство @code{matchdeclare}.
580 @code{printprops (@var{a}, matchdeclare)} возвращает предикат
581 для переменной @code{a}.
582 @code{printprops (all, matchdeclare)} возвращает список всех предикатов
583 для всех переменных @code{matchdeclare}.
584 @code{remove (@var{a}, matchdeclare)} удаляет свойства
585 @code{matchdeclare} для переменной @var{a}.
587 Функции
588 @code{defmatch}, @code{defrule}, @code{tellsimp}, @code{tellsimpafter} и @code{let}
589 строят правила, которые сопоставляют выражения с шаблонами.
591 Функция @code{matchdeclare} не вычисляет свои аргументы.
592 Функция @code{matchdeclare} всегда возвращает @code{done}.
594 Примеры:
596 Предикат есть имя функции, или лямбда-выражение, или вызов функции или 
597 лямбда-вызов без последнего аргумента,
598 или @code{true}, или @code{all}.
600 @c ===beg===
601 @c matchdeclare (aa, integerp);
602 @c matchdeclare (bb, lambda ([x], x > 0));
603 @c matchdeclare (cc, freeof (%e, %pi, %i));
604 @c matchdeclare (dd, lambda ([x, y], gcd (x, y) = 1) (1728));
605 @c matchdeclare (ee, true);
606 @c matchdeclare (ff, all);
607 @c ===end===
608 @example
609 (%i1) matchdeclare (aa, integerp);
610 (%o1)                         done
611 (%i2) matchdeclare (bb, lambda ([x], x > 0));
612 (%o2)                         done
613 (%i3) matchdeclare (cc, freeof (%e, %pi, %i));
614 (%o3)                         done
615 (%i4) matchdeclare (dd, lambda ([x, y], gcd (x, y) = 1) (1728));
616 (%o4)                         done
617 (%i5) matchdeclare (ee, true);
618 (%o5)                         done
619 (%i6) matchdeclare (ff, all);
620 (%o6)                         done
621 @end example
623 Если выражение удовлетворяет предикату, то переменной 
624 шаблона присваивается выражение.
626 @c ===beg===
627 @c matchdeclare (aa, integerp, bb, atom);
628 @c defrule (r1, bb^aa, ["integer" = aa, "atom" = bb]);
629 @c r1 (%pi^8);
630 @c ===end===
631 @example
632 (%i1) matchdeclare (aa, integerp, bb, atom);
633 (%o1)                         done
634 (%i2) defrule (r1, bb^aa, ["integer" = aa, "atom" = bb]);
635                     aa
636 (%o2)        r1 : bb   -> [integer = aa, atom = bb]
637 (%i3) r1 (%pi^8);
638 (%o3)               [integer = 8, atom = %pi]
639 @end example
641 В случае суммы и произведения,
642 переменной шаблона может быть присвоено простое выражение, которое
643 удовлетворяет предикату, или также сумма или произведение 
644 таких выражений.
645 @c ===beg===
646 @c matchdeclare (aa, atom, bb, lambda ([x], not atom(x)));
647 @c defrule (r1, aa + bb, ["all atoms" = aa, "all nonatoms" = 
648 @c                bb]);
649 @c r1 (8 + a*b + sin(x));
650 @c defrule (r2, aa * bb, ["all atoms" = aa, "all nonatoms" = 
651 @c                bb]);
652 @c r2 (8 * (a + b) * sin(x));
653 @c ===end===
654 @example
655 (%i1) matchdeclare (aa, atom, bb, lambda ([x], not atom(x)));
656 (%o1)                         done
657 (%i2) defrule (r1, aa + bb, ["all atoms" = aa, "all nonatoms" =
658                bb]);
659 bb + aa partitions `sum'
660 (%o2)  r1 : bb + aa -> [all atoms = aa, all nonatoms = bb]
661 (%i3) r1 (8 + a*b + sin(x));
662 (%o3)     [all atoms = 8, all nonatoms = sin(x) + a b]
663 (%i4) defrule (r2, aa * bb, ["all atoms" = aa, "all nonatoms" =
664                bb]);
665 bb aa partitions `product'
666 (%o4)   r2 : aa bb -> [all atoms = aa, all nonatoms = bb]
667 (%i5) r2 (8 * (a + b) * sin(x));
668 (%o5)    [all atoms = 8, all nonatoms = (b + a) sin(x)]
669 @end example
671 При сопоставлении аргументов @code{+} и @code{*},
672 если все предикаты условия являются взаимоисключающими, то результат
673 проверки не зависит порядка, так как один предикат не соответствует
674 членам, соответствующим другому предикату.
676 @c ===beg===
677 @c matchdeclare (aa, atom, bb, lambda ([x], not atom(x)));
678 @c defrule (r1, aa + bb, ["all atoms" = aa, "all nonatoms" = 
679 @c                bb]);
680 @c r1 (8 + a*b + %pi + sin(x) - c + 2^n);
681 @c defrule (r2, aa * bb, ["all atoms" = aa, "all nonatoms" = 
682 @c                bb]);
683 @c r2 (8 * (a + b) * %pi * sin(x) / c * 2^n);
684 @c ===end===
685 @example
686 (%i1) matchdeclare (aa, atom, bb, lambda ([x], not atom(x)));
687 (%o1)                         done
688 (%i2) defrule (r1, aa + bb, ["all atoms" = aa, "all nonatoms" =
689                bb]);
690 bb + aa partitions `sum'
691 (%o2)  r1 : bb + aa -> [all atoms = aa, all nonatoms = bb]
692 (%i3) r1 (8 + a*b + %pi + sin(x) - c + 2^n);
693                                                      n
694 (%o3) [all atoms = %pi + 8, all nonatoms = sin(x) + 2  - c + a b]
695 (%i4) defrule (r2, aa * bb, ["all atoms" = aa, "all nonatoms" =
696                bb]);
697 bb aa partitions `product'
698 (%o4)   r2 : aa bb -> [all atoms = aa, all nonatoms = bb]
699 (%i5) r2 (8 * (a + b) * %pi * sin(x) / c * 2^n);
700                                                   n
701                                          (b + a) 2  sin(x)
702 (%o5) [all atoms = 8 %pi, all nonatoms = -----------------]
703                                                  c
704 @end example
706 Функции @code{propvars} и @code{printprops} возвращают информацию о
707 переменных шаблона.
709 @c ===beg===
710 @c matchdeclare ([aa, bb, cc], atom, [dd, ee], integerp);
711 @c matchdeclare (ff, floatnump, gg, lambda ([x], x > 100));
712 @c propvars (matchdeclare);
713 @c printprops (ee, matchdeclare);
714 @c printprops (gg, matchdeclare);
715 @c printprops (all, matchdeclare);
716 @c ===end===
717 @example
718 (%i1) matchdeclare ([aa, bb, cc], atom, [dd, ee], integerp);
719 (%o1)                         done
720 (%i2) matchdeclare (ff, floatnump, gg, lambda ([x], x > 100));
721 (%o2)                         done
722 (%i3) propvars (matchdeclare);
723 (%o3)             [aa, bb, cc, dd, ee, ff, gg]
724 (%i4) printprops (ee, matchdeclare);
725 (%o4)                    [integerp(ee)]
726 (%i5) printprops (gg, matchdeclare);
727 (%o5)              [lambda([x], x > 100, gg)]
728 (%i6) printprops (all, matchdeclare);
729 (%o6) [lambda([x], x > 100, gg), floatnump(ff), integerp(ee), 
730                       integerp(dd), atom(cc), atom(bb), atom(aa)]
731 @end example
733 @opencatbox{Категории:}
734 @category{Правила преобразования и шаблоны}
735 @category{Факты и выводы}
736 @closecatbox
737 @end deffn
739 @deffn {Функция} matchfix (@var{ldelimiter}, @var{rdelimiter})
740 @deffnx {Функция} matchfix (@var{ldelimiter}, @var{rdelimiter}, @var{arg_pos}, @var{pos})
741 Объявляет матчфиксный (matchfix) оператор с левым и правым ограничителями 
742 @var{ldelimiter} и @var{rdelimiter} соответственно. Ограничители являются строками.
744 Матчфиксный оператор является функцией любого количества аргументов
745 заключенных между ограничителями @var{ldelimiter} и @var{rdelimiter}. 
746 Ограничителем может являться любая строка, если синтаксический анализатор 
747 может различить ограничители от других выражений и операторов.
748 На практике, это исключает такие ограничители, как
749 @code{%}, @code{,}, @code{$} и @code{;}, и может потребовать при вводе
750 изолировать ограничители пробелами. Правый ограничитель может
751 совпадать с левым или отличаться от него. 
753 Левый ограничитель может быть ассоциирован только с одним правым; 
754 два различных матчфиксных оператора не могут иметь
755 одинаковых левых ограничителя. 
757 Существующий оператор может быть переобъявлен, как матчфиксный оператор   
758 без изменения других его свойств. Например, встроенные
759 операторы сложения @code{+} могут быть объявлены матчфиксными, однако
760 операторные функции для встроенных операторов определены быть не могут.
762 Вызов @code{matchfix (@var{ldelimiter}, @var{rdelimiter}, @var{arg_pos}, @var{pos})} 
763 объявляет аргумент "часть речи" @var{arg_pos} и результат "часть речи" @var{pos} 
764 вместе с ограничителями @var{ldelimiter} и @var{rdelimiter}.
766 Термин "чать речи" по отношению к декларации операторов означает тип выражения.
767 Различаются три типа выражений: @code{expr}, @code{clause} и @code{any},
768 что обозначает алгебраическое выражение, логическое выражение и выражение
769 произвольного типа соответственно.  Maxima может обнаруживать некоторые
770 синтаксические ошибки сравнивая объявленную часть речи с реальным
771 выражением.
773 @c DUNNO IF WE REALLY NEED TO MENTION BINDING POWER HERE -- AS NOTED IT'S IRRELEVANT
774 @c An operator declared by @code{matchfix} is assigned a low binding power.
775 @c Since a matchfix operator must be evaluated before any expression
776 @c which contains it,
777 @c binding power is effectively irrelevant
778 @c to the declaration of a matchfix operator.
780 Функция для выполнения матчфиксной операции является обычной пользовательской
781 функцией.  Операторная функция определяется стандартным образом 
782 при помощи операторов @code{:=} или @code{define}.
783 Аргументы могут быть записаны между ограничителями или при
784 помощи левого ограничителя в форме строки и последующих аргументов
785 в скобках.
786 @code{dispfun (@var{ldelimiter})} выводит определение
787 функции. 
789 Единственный встроенный матчфиксный оператор это конструктор
790 списка @code{[ ]}. Скобки @code{( )} и двойные кавычки @code{" "} 
791 работают как матчфиксные операторы, однако не обрабатываются
792 синтаксическим анализатором Maxima как таковые.
794 Функция @code{matchfix} вычисляет свои аргументы.
795 Функция @code{matchfix} возвращает свой первый аргумент @var{ldelimiter}.
796 @c HOW TO TAKE AWAY THE MATCHFIX PROPERTY ??
798 Примеры:
800 @itemize @bullet
801 @item
802 В качестве ограничителей можно задавать практически любые строки.
803 @end itemize
804 @c ===beg===
805 @c matchfix ("@@", "~");
806 @c @@ a, b, c ~;
807 @c matchfix (">>", "<<");
808 @c >> a, b, c <<;
809 @c matchfix ("foo", "oof");
810 @c foo a, b, c oof;
811 @c >> w + foo x, y oof + z << / @@ p, q ~;
812 @c ===end===
813 @example
814 (%i1) matchfix ("@@@@", "~");
815 (%o1)                          @@@@
816 (%i2) @@@@ a, b, c ~;
817 (%o2)                      @@@@a, b, c~
818 (%i3) matchfix (">>", "<<");
819 (%o3)                          >>
820 (%i4) >> a, b, c <<;
821 (%o4)                      >>a, b, c<<
822 (%i5) matchfix ("foo", "oof");
823 (%o5)                          foo
824 (%i6) foo a, b, c oof;
825 (%o6)                     fooa, b, coof
826 (%i7) >> w + foo x, y oof + z << / @@@@ p, q ~;
827                      >>z + foox, yoof + w<<
828 (%o7)                ----------------------
829                             @@@@p, q~
830 @end example
832 @itemize @bullet
833 @item
834 Матчфиксные операторы -- это обычные пользовательские функции.
835 @end itemize
836 @example
837 (%i1) matchfix ("!-", "-!");
838 (%o1)                         "!-"
839 (%i2) !- x, y -! := x/y - y/x;
840                                     x   y
841 (%o2)                   !-x, y-! := - - -
842                                     y   x
843 (%i3) define (!-x, y-!, x/y - y/x);
844                                     x   y
845 (%o3)                   !-x, y-! := - - -
846                                     y   x
847 (%i4) define ("!-" (x, y), x/y - y/x);
848                                     x   y
849 (%o4)                   !-x, y-! := - - -
850                                     y   x
851 (%i5) dispfun ("!-");
852                                     x   y
853 (%t5)                   !-x, y-! := - - -
854                                     y   x
856 (%o5)                         done
857 (%i6) !-3, 5-!;
858                                 16
859 (%o6)                         - --
860                                 15
861 (%i7) "!-" (3, 5);
862                                 16
863 (%o7)                         - --
864                                 15
865 @end example
867 @opencatbox{Категории:}
868 @category{Синтаксис}
869 @category{Операторы}
870 @closecatbox
871 @end deffn
873 @c NEEDS CLARIFICATION AND EXAMPLES
874 @deffn {Функция} remlet (@var{prod}, @var{name})
875 @deffnx {Функция} remlet ()
876 @deffnx {Функция} remlet (all)
877 @deffnx {Функция} remlet (all, @var{name})
878 Удаляет правило подстановки @var{prod} -> замена, 
879 определенное при самом последнем вызове функции @code{let}.  
880 При вызове с именем правила в качестве аргумента 
881 удаление производится из соответствующего пакета правил.
883 Вызовы @code{remlet()} и @code{remlet(all)} удаляют все правила
884 подстановки из текущего пакета правил. При указании имени, например,
885 @code{remlet (all, @var{name})}, пакет правил @var{name} также удаляется.
887 Если необходимо изменить правило подстановки одного 
888 произведения, нет необходимости вызывать @code{remlet}, можно просто
889 переопределить подстановку данного произведения при помощи функции
890 @code{let}, с новой заменой и/или предикатом.
891 После этого вызов @code{remlet (@var{prod})} восстанавливает исходное
892 правило подстановки.
894 См. также функцию @code{remrule}, которая удаляет правила
895 определенные функцией  @code{tellsimp} или @code{tellsimpafter}.
897 @opencatbox{Категории:}
898 @category{Правила преобразования и шаблоны}
899 @closecatbox
900 @end deffn
902 @deffn {Функция} remrule (@var{op}, @var{rulename})
903 @deffnx {Функция} remrule (@var{op}, all)
904 Удаляет правила, определенные функциями @code{tellsimp} или @code{tellsimpafter}.
906 @code{remrule (@var{op}, @var{rulename})}
907 удаляет правило с именем @var{rulename} для оператора @var{op}.
908 Если оператор @var{op} является встроенным оператором или определен
909 пользователем (например, при помощи функций @code{infix}, @code{prefix},
910 и т.п.), тогда @var{op} и @var{rulename} необходимо заключить в двойные кавычки.
912 @code{remrule (@var{op}, all)} удаляет все правила для оператора @var{op}.
914 См. также функцию @code{remlet}, удаляющую правила, определенные при помощи @code{let}.
916 Примеры:
918 @c ===beg===
919 @c tellsimp (foo (aa, bb), bb - aa);
920 @c tellsimpafter (aa + bb, special_add (aa, bb));
921 @c infix ("@@");
922 @c tellsimp (aa @@ bb, bb/aa);
923 @c tellsimpafter (quux (%pi, %e), %pi - %e);
924 @c tellsimpafter (quux (%e, %pi), %pi + %e);
925 @c [foo (aa, bb), aa + bb, aa @@ bb, quux (%pi, %e), 
926 @c        quux (%e, %pi)];
927 @c remrule (foo, foorule1);
928 @c remrule ("+", "+rule1");
929 @c remrule ("@@", "@@rule1");
930 @c remrule (quux, all);
931 @c [foo (aa, bb), aa + bb, aa @@ bb, quux (%pi, %e), 
932 @c         quux (%e, %pi)];
933 @c ===end===
934 @example
935 (%i1) tellsimp (foo (aa, bb), bb - aa);
936 (%o1)                   [foorule1, false]
937 (%i2) tellsimpafter (aa + bb, special_add (aa, bb));
938 (%o2)                   [+rule1, simplus]
939 (%i3) infix ("@@@@");
940 (%o3)                          @@@@
941 (%i4) tellsimp (aa @@@@ bb, bb/aa);
942 (%o4)                   [@@@@rule1, false]
943 (%i5) tellsimpafter (quux (%pi, %e), %pi - %e);
944 (%o5)                  [quuxrule1, false]
945 (%i6) tellsimpafter (quux (%e, %pi), %pi + %e);
946 (%o6)             [quuxrule2, quuxrule1, false]
947 (%i7) [foo (aa, bb), aa + bb, aa @@@@ bb, quux (%pi, %e),
948        quux (%e, %pi)];
949                                      bb
950 (%o7) [bb - aa, special_add(aa, bb), --, %pi - %e, %pi + %e]
951                                      aa
952 (%i8) remrule (foo, foorule1);
953 (%o8)                          foo
954 (%i9) remrule ("+", "+rule1");
955 (%o9)                           +
956 (%i10) remrule ("@@@@", "@@@@rule1");
957 (%o10)                         @@@@
958 (%i11) remrule (quux, all);
959 (%o11)                        quux
960 (%i12) [foo (aa, bb), aa + bb, aa @@@@ bb, quux (%pi, %e),
961         quux (%e, %pi)];
962 (%o12) [foo(aa, bb), bb + aa, aa @@@@ bb, quux(%pi, %e), 
963                                          quux(%e, %pi)]
964 @end example
966 @opencatbox{Категории:}
967 @category{Правила преобразования и шаблоны}
968 @closecatbox
969 @end deffn
971 @c NEEDS EXPANSION OR MAYBE JUST APPROPRIATE REFS TO tellsimpafter
972 @anchor{tellsimp}
973 @deffn {Функция} tellsimp (@var{pattern}, @var{replacement})
974 аналогична @code{tellsimpafter}, но добавляет
975 новую информацию о правилах до уже существующей. Таким образом, сначала
976 применяются пользовательские правила упрощения, а потом правила,
977 встроенные в систему.
979 Функция @code{tellsimp} используется, когда важно модифицировать выражение
980 до того, как оно обработано упрощателем, например, встроенный механизм
981 упрощения "знает" что-либо о структуре выражения, но возвращает результат,
982 который вас не устраивает. Если встроенный механизм
983 упрощения "знает" что-либо о главном операторе выражения, но работает не
984 достаточно эффективно - можно попробовать использовать @code{tellsimpafter}.
986 Шаблон не может быть суммой, произведением, одиночной переменной или числом.
988 @code{rules} - список правил определенный функциями
989 @code{defrule}, @code{defmatch}, @code{tellsimp} и @code{tellsimpafter}.
991 Примеры:
993 @example
994 (%i1) matchdeclare (x, freeof (%i));
995 (%o1)                         done
996 (%i2) %iargs: false$
997 (%i3) tellsimp (sin(%i*x), %i*sinh(x));
998 (%o3)                 [sinrule1, simp-%sin]
999 (%i4) trigexpand (sin (%i*y + x));
1000 (%o4)         sin(x) cos(%i y) + %i cos(x) sinh(y)
1001 (%i5) %iargs:true$
1002 (%i6) errcatch(0^0);
1004 0  has been generated
1005 (%o6)                          []
1006 (%i7) ev (tellsimp (0^0, 1), simp: false);
1007 (%o7)                  [^rule1, simpexpt]
1008 (%i8) 0^0;
1009 (%o8)                           1
1010 (%i9) remrule ("^", %th(2)[1]);
1011 (%o9)                           ^
1012 (%i10) tellsimp (sin(x)^2, 1 - cos(x)^2);
1013 (%o10)                 [^rule2, simpexpt]
1014 (%i11) (1 + sin(x))^2;
1015                                       2
1016 (%o11)                    (sin(x) + 1)
1017 (%i12) expand (%);
1018                                    2
1019 (%o12)               2 sin(x) - cos (x) + 2
1020 (%i13) sin(x)^2;
1021                                   2
1022 (%o13)                     1 - cos (x)
1023 (%i14) kill (rules);
1024 (%o14)                        done
1025 (%i15) matchdeclare (a, true);
1026 (%o15)                        done
1027 (%i16) tellsimp (sin(a)^2, 1 - cos(a)^2);
1028 (%o16)                 [^rule3, simpexpt]
1029 (%i17) sin(y)^2;
1030                                   2
1031 (%o17)                     1 - cos (y)
1032 @end example
1034 @opencatbox{Категории:}
1035 @category{Правила преобразования и шаблоны}
1036 @closecatbox
1037 @end deffn
1039 @deffn {Функция} tellsimpafter (@var{pattern}, @var{replacement})
1040 Определяет правило упрощения, которое встроенный в Maxima механизм
1041 упрощения применяет после встроенных правил упрощения.
1042 @var{pattern} - выражение, включающее переменные шаблона (объявленные в @code{matchdeclare})
1043 и другие атомы и операторы, которые рассматриваются как константы с точки зрения сопоставления с шаблоном.
1044 @var{replacement} подставляется вместо первоначального выражения, удовлетворяющего шаблону @var{pattern};
1045 переменным шаблона из в @var{replacement} присваиваются соответствующие подвыражения из
1046 реального выражения.
1048 @var{pattern} может быть любым составным выражением в котором имя главного
1049 оператор не входит в число переменных шаблона;
1050 правило упрощения связывается с именем главного оператора.
1051 Имена функций (за исключением приведенных ниже), списки и массивы могут присутствовать
1052 в шаблоне  @var{pattern} в качестве основного оператора только, как
1053 литералы (не переменные шаблона);
1054 это исключает шаблоны вида @code{aa(x)} и @code{bb[y]},
1055 если @code{aa} и @code{bb} являются переменными шаблона.
1056 Имена функций, списки и массивы, которые являются переменными шаблона
1057 могут входить в качестве не основных операторов в описание шаблона @var{pattern}.
1059 Есть одно исключение к указанному правилу, касающееся имен функций.
1060 Имена функций с индексом в выражениях типа @code{aa[x](y)}
1061 могут быть переменными шаблона, поскольку в этом случае главный оператор 
1062 не  @code{aa}, а Lisp-атом @code{mqapply}.
1063 Это является следствием представления выражений, включающих
1064 функции с индексом.
1066 @c LET'S NOT GO INTO DETAILS ABOUT MAIN OPERATORS HERE; BUT PRESERVE THIS FOR REFERENCE
1067 @c The main operator of an expression @code{expr} is @code{caar $expr}.
1068 @c For most kinds of expressions,
1069 @c the main operator is the operator returned by @code{op (@var{pattern})};
1070 @c the sole exception is the operator @code{mqapply},
1071 @c which appears in indexed function expressions (e.g., @code{foo[i](x)}).
1073 @c NEED TO REVIEW THIS PARAGRAPH FOR ACCURACY
1074 Правила упрощения применяются после вычисления (если вычисления не
1075 запрещены либо экранированием выражения, либо ключом @code{noeval}).
1076 Правила введенные @code{tellsimpafter} применяются в том порядке в
1077 котором они были определены после всех встроенных правил.
1078 Преобразования применяются "снизу-вверх", т.е.,
1079 сначала к подвыражению, перед обработкой выражения в  целом.
1080 @c NO IT IS MORE COMPLICATED THAN THIS, ALTHOUGH IN SOME CIRCUMSTANCE IT APPEARS TO BE THE CASE:
1081 @c For a given expression, at most one rule per operator is applied.
1082 Иногда для того, чтобы обеспечить, что применены все правила, необходимо повторное упрощение результата 
1083 (например, при применении оператора кавычка-кавычка @code{'@w{}'} или ключа @code{infeval}).
1085 Переменные шаблона рассматриваются как локальные переменные в правилах
1086 упрощения. Как только правило определено, значение переменной шаблона
1087 не  влияет на правило, и наоборот, правило не влияет на значение переменной.
1088 Присваивание значений переменным шаблона, происходящее в результате успешного
1089 сопоставления шаблона, не влияет на текущие значения (или их отсутствие)
1090 переменных шаблона. Однако, как и у всех атомов в Maxima,
1091 свойства переменных шаблона (объявленные оператором  @code{put}
1092 и подобными функциями) являются глобальными.
1094 Правило, построенное с помощью @code{tellsimpafter},
1095 обозначаеся именем главного оператора @var{pattern}.
1096 Правила для встроенных операторов и пользовательских функций,
1097 определенных  при помощи @code{infix}, @code{prefix}, 
1098 @code{postfix}, @code{matchfix} и @code{nofix},
1099 имеют имена, являющиеся Lisp-идентификаторами.
1100 @c SLIGHTLY TOO MUCH DETAIL
1101 @c (that is, the name is written with a leading question mark @code{?} in Maxima).
1102 Правила для других функций имеют имена, являющиеся идентификаторами Maxima.
1103 @c SLIGHTLY TOO MUCH DETAIL
1104 @c (that is, the name begins with dollar sign @code{$}).
1106 Обработка вычисляемых и не вычисляемых форм немного неоднозначна. @c THIS IS A BUG.
1107 Если правило определено для невычисляемой (или вычисляемой) формы
1108 выражения, а правило для соответствующей вычисляемой (или невычисляемой) 
1109 уже существует, то новое правило применяется к обеим формам
1110 выражения (вычисляемой и невычисляемой).
1111 Если правило для соответствующей вычисляемой (или невычисляемой) 
1112 не существует, то новое правило применяется к невычисляемой 
1113 (или вычисляемой) форме выражения.
1115 Правило, построенное с помощью @code{tellsimpafter}, является обычной
1116 Lisp- функцией. Если имя правила - @code{$foorule1}, то
1117 конструкция @code{:lisp (trace $foorule1)} дает трассировку ее вызовов, 
1118 а @code{:lisp (symbol-function '$foorule1} выводит ее определение.
1120 Функция @code{tellsimpafter} не вычисляет свои аргументы.
1121 Функция @code{tellsimpafter} возвращает список правил для основного оператора
1122 шаблона @var{pattern}, включая вновь объявленные правила.
1123 @c WHAT IS simpfoo THAT SOMETIMES APPEARS, AND WHY DOES false SOMETIMES APPEAR IN RETURN VALUE ??
1125 См. также @code{matchdeclare}, @code{defmatch}, @code{defrule}, @code{tellsimp}, @code{let},
1126 @code{kill}, @code{remrule} и @code{clear_rules}.
1128 Примеры:
1130 @var{pattern} может быть любым неатомарным выражением в котором главный
1131 оператор не является переменной шаблона.
1133 @c ===beg===
1134 @c matchdeclare (aa, atom, [ll, mm], listp, xx, true)$
1135 @c tellsimpafter (sin (ll), map (sin, ll));
1136 @c sin ([1/6, 1/4, 1/3, 1/2, 1]*%pi);
1137 @c tellsimpafter (ll^mm, map ("^", ll, mm));
1138 @c [a, b, c]^[1, 2, 3];
1139 @c tellsimpafter (foo (aa (xx)), aa (foo (xx)));
1140 @c foo (bar (u - v));
1141 @c ===end===
1142 @example
1143 (%i1) matchdeclare (aa, atom, [ll, mm], listp, xx, true)$
1144 (%i2) tellsimpafter (sin (ll), map (sin, ll));
1145 (%o2)                 [sinrule1, simp-%sin]
1146 (%i3) sin ([1/6, 1/4, 1/3, 1/2, 1]*%pi);
1147                     1  sqrt(2)  sqrt(3)
1148 (%o3)              [-, -------, -------, 1, 0]
1149                     2     2        2
1150 (%i4) tellsimpafter (ll^mm, map ("^", ll, mm));
1151 (%o4)                  [^rule1, simpexpt]
1152 (%i5) [a, b, c]^[1, 2, 3];
1153                                 2   3
1154 (%o5)                      [a, b , c ]
1155 (%i6) tellsimpafter (foo (aa (xx)), aa (foo (xx)));
1156 (%o6)                   [foorule1, false]
1157 (%i7) foo (bar (u - v));
1158 (%o7)                    bar(foo(u - v))
1159 @end example
1161 Правила применяются в том порядке в котором они были определены.
1162 Если два правила соответствуют выражению, то первым
1163 применяется то, которое было определено раньше.
1165 @c ===beg===
1166 @c matchdeclare (aa, integerp);
1167 @c tellsimpafter (foo (aa), bar_1 (aa));
1168 @c tellsimpafter (foo (aa), bar_2 (aa));
1169 @c foo (42);
1170 @c ===end===
1171 @example
1172 (%i1) matchdeclare (aa, integerp);
1173 (%o1)                         done
1174 (%i2) tellsimpafter (foo (aa), bar_1 (aa));
1175 (%o2)                   [foorule1, false]
1176 (%i3) tellsimpafter (foo (aa), bar_2 (aa));
1177 (%o3)              [foorule2, foorule1, false]
1178 (%i4) foo (42);
1179 (%o4)                       bar_1(42)
1180 @end example
1182 Переменные шаблона являются локальными переменные правил упрощения.
1183 (Сравни с  функцией @code{defmatch}, которая рассматривает переменные
1184 шаблона, как глобальные).
1186 @c ===beg===
1187 @c matchdeclare (aa, integerp, bb, atom);
1188 @c tellsimpafter (foo(aa, bb), bar('aa=aa, 'bb=bb));
1189 @c bb: 12345;
1190 @c foo (42, %e);
1191 @c bb;
1192 @c ===end===
1193 @example
1194 (%i1) matchdeclare (aa, integerp, bb, atom);
1195 (%o1)                         done
1196 (%i2) tellsimpafter (foo(aa, bb), bar('aa=aa, 'bb=bb));
1197 (%o2)                   [foorule1, false]
1198 (%i3) bb: 12345;
1199 (%o3)                         12345
1200 (%i4) foo (42, %e);
1201 (%o4)                 bar(aa = 42, bb = %e)
1202 (%i5) bb;
1203 (%o5)                         12345
1204 @end example
1206 Как и у всех атомов, свойства переменных шаблона
1207 являются глобальными даже если их значение локально.
1208 В данном примере свойство объявляется при помощи @code{define_variable}.
1209 Это свойство атома @code{bb} является глобальным.
1211 @c ===beg===
1212 @c matchdeclare (aa, integerp, bb, atom);
1213 @c tellsimpafter (foo(aa, bb), bar('aa=aa, 'bb=bb));
1214 @c foo (42, %e);
1215 @c define_variable (bb, true, boolean);
1216 @c foo (42, %e);
1217 @c ===end===
1218 @example
1219 (%i1) matchdeclare (aa, integerp, bb, atom);
1220 (%o1)                         done
1221 (%i2) tellsimpafter (foo(aa, bb), bar('aa=aa, 'bb=bb));
1222 (%o2)                   [foorule1, false]
1223 (%i3) foo (42, %e);
1224 (%o3)                 bar(aa = 42, bb = %e)
1225 (%i4) define_variable (bb, true, boolean);
1226 (%o4)                         true
1227 (%i5) foo (42, %e);
1228 Error: bb was declared mode boolean, has value: %e
1229  -- an error.  Quitting.  To debug this try debugmode(true);
1230 @end example
1232 Правила именуются по имени основного оператора.
1233 Имена правил для встроенных и пользовательских операторов
1234 являются Lisp-идентификаторами, тогда как имена других функций 
1235 являются идентификаторами Maxima.
1237 @c ===beg===
1238 @c tellsimpafter (foo (%pi + %e), 3*%pi);
1239 @c tellsimpafter (foo (%pi * %e), 17*%e);
1240 @c tellsimpafter (foo (%i ^ %e), -42*%i);
1241 @c tellsimpafter (foo (9) + foo (13), quux (22));
1242 @c tellsimpafter (foo (9) * foo (13), blurf (22));
1243 @c tellsimpafter (foo (9) ^ foo (13), mumble (22));
1244 @c rules;
1245 @c foorule_name: first (%o1);
1246 @c plusrule_name: first (%o4);
1247 @c remrule (foo, foorule1);
1248 @c remrule ("^", ?\^rule1);
1249 @c rules;
1250 @c ===end===
1251 @example
1252 (%i1) tellsimpafter (foo (%pi + %e), 3*%pi);
1253 (%o1)                   [foorule1, false]
1254 (%i2) tellsimpafter (foo (%pi * %e), 17*%e);
1255 (%o2)              [foorule2, foorule1, false]
1256 (%i3) tellsimpafter (foo (%i ^ %e), -42*%i);
1257 (%o3)         [foorule3, foorule2, foorule1, false]
1258 (%i4) tellsimpafter (foo (9) + foo (13), quux (22));
1259 (%o4)                   [+rule1, simplus]
1260 (%i5) tellsimpafter (foo (9) * foo (13), blurf (22));
1261 (%o5)                  [*rule1, simptimes]
1262 (%i6) tellsimpafter (foo (9) ^ foo (13), mumble (22));
1263 (%o6)                  [^rule1, simpexpt]
1264 (%i7) rules;
1265 (%o7) [foorule1, foorule2, foorule3, +rule1, *rule1, ^rule1]
1266 (%i8) foorule_name: first (%o1);
1267 (%o8)                       foorule1
1268 (%i9) plusrule_name: first (%o4);
1269 (%o9)                        +rule1
1270 (%i10) remrule (foo, foorule1);
1271 (%o10)                         foo
1272 (%i11) remrule ("^", ?\^rule1);
1273 (%o11)                          ^
1274 (%i12) rules;
1275 (%o12)        [foorule2, foorule3, +rule1, *rule1]
1276 @end example
1278 Рабочий пример: антикоммутативное умножение.
1280 @c ===beg===
1281 @c gt (i, j) := integerp(j) and i < j;
1282 @c matchdeclare (i, integerp, j, gt(i));
1283 @c tellsimpafter (s[i]^^2, 1);
1284 @c tellsimpafter (s[i] . s[j], -s[j] . s[i]);
1285 @c s[1] . (s[1] + s[2]);
1286 @c expand (%);
1287 @c factor (expand (sum (s[i], i, 0, 9)^^5));
1288 @c ===end===
1289 @example
1290 (%i1) gt (i, j) := integerp(j) and i < j;
1291 (%o1)           gt(i, j) := integerp(j) and i < j
1292 (%i2) matchdeclare (i, integerp, j, gt(i));
1293 (%o2)                         done
1294 (%i3) tellsimpafter (s[i]^^2, 1);
1295 (%o3)                 [^^rule1, simpncexpt]
1296 (%i4) tellsimpafter (s[i] . s[j], -s[j] . s[i]);
1297 (%o4)                   [.rule1, simpnct]
1298 (%i5) s[1] . (s[1] + s[2]);
1299 (%o5)                    s  . (s  + s )
1300                           1     2    1
1301 (%i6) expand (%);
1302 (%o6)                      1 - s  . s
1303                                 2    1
1304 (%i7) factor (expand (sum (s[i], i, 0, 9)^^5));
1305 (%o7) 100 (s  + s  + s  + s  + s  + s  + s  + s  + s  + s )
1306             9    8    7    6    5    4    3    2    1    0
1307 @end example
1309 @opencatbox{Категории:}
1310 @category{Правила преобразования и шаблоны}
1311 @closecatbox
1312 @end deffn
1314 @deffn {Функция} clear_rules ()
1315 Исполняет @code{kill (rules)} и обнуляет счетчик, т.е. новое правило
1316 будет иметь номер @code{1} вслед за встроенными правилами для операторов суммы
1317 @code{+}, умножения  @code{*} и степени @code{^}.
1319 @opencatbox{Категории:}
1320 @category{Правила преобразования и шаблоны}
1321 @closecatbox
1322 @end deffn