1 @c English version 2011-06-13
3 * Introducción a reglas y patrones::
4 * Funciones y variables sobre reglas y patrones::
7 @node Introducción a reglas y patrones, Funciones y variables sobre reglas y patrones, Reglas y patrones, Reglas y patrones
8 @section Introducción a reglas y patrones
10 Esta sección describe las reglas de simplificación y los patrones de comparación definidos por el usuario. Hay dos grupos de funciones que implementan diferentes esquemas de comparación de patrones. En un grupo están @code{tellsimp}, @code{tellsimpafter}, @code{defmatch}, @code{defrule}, @code{apply1}, @code{applyb1} y @code{apply2}. En el otro, se encuentran @code{let} y @code{letsimp}. Ambos esquemas definen patrones en términos de variables de patrones declaradas mediante @code{matchdeclare}.
12 Las reglas de comparación de patrones definidas por @code{tellsimp} y @code{tellsimpafter} se aplican automáticamente por el simplificador de Maxima. Las reglas definidas por @code{defmatch}, @code{defrule} y @code{let} se aplican previa llamada a una función.
14 Hay otros mecanismos para las reglas; las relativas a polinomios se controlan mediante @code{tellrat} y las del álgebra conmutativa y no conmutativa se definen en el paquete @code{affine}.
16 @node Funciones y variables sobre reglas y patrones, , Introducción a reglas y patrones, Reglas y patrones
17 @section Funciones y variables sobre reglas y patrones
19 @deffn {Función} apply1 (@var{expr}, @var{regla_1}, ..., @var{regla_n})
21 Aplica de forma repetida la @var{regla_1} a @var{expr} hasta que falla, a continuación aplica repetidamente la misma regla a todas las subexpresiones de @var{expr}, de izquierda a derecha, hasta que la @var{regla_1} haya fallado en todas las subexpresiones. Llámese @var{expr_2} al resultado de transformar @var{expr} de esta forma. Entonces la @var{regla_2} se aplica de la misma manera comenzando en el nivel superior de @var{expr_2}. Cuando la @var{regla_n} falla en la última expresión, se devuelve el resultado.
23 @code{maxapplydepth} es el nivel de las subexpresiones más internas procesadas por @code{apply1} y @code{apply2}.
25 Véase también @code{applyb1}, @code{apply2} y @code{let}.
29 @deffn {Función} apply2 (@var{expr}, @var{regla_1}, ..., @var{regla_n})
31 Si la @var{regla_1} falla en una subexpresión dada, entonces se aplica la @var{regla_2} repetidamente, etc. Sólo si todas las reglas fallan en una subexpresión serán aplicadas todas las reglas de forma repetida a la siguiente subexpresión. Si alguna de las reglas tiene éxito entonces la misma subexpresión es reprocesada, comenzando por la primera regla.
33 @code{maxapplydepth} es el nivel de las subexpresiones más internas procesadas por @code{apply1} y @code{apply2}.
35 Véase también @code{applyb1} y @code{let}.
39 @deffn {Función} applyb1 (@var{expr}, @var{regla_1}, ..., @var{regla_n})
41 Aplica la @var{regla_1} reiteradamente hasta la subexpresión más interna de @var{expr} hasta que falle, a continuación pasa a aplicar la misma regla en un nivel superior (esto es, en subexpresiones más grandes), hasta que la @var{regla_1} falle en la expresión de nivel más alto. Después se aplica la @var{regla_2} de la misma manera al resultado obtenido de @var{regla_1}. Tras la aplicación de la @var{regla_n} a la expresión de mayor nivel, se devuelve el resultado.
43 La función @code{applyb1} es similar a @code{apply1} pero opera de abajo-arriba, en lugar de arriba-abajo.
45 @code{maxapplyheight} es la máxima altura a la que llega @code{applyb1} antes de terminar su cometido.
47 Véase también @code{apply1}, @code{apply2} y @code{let}.
51 @defvr {Variable opcional} current_let_rule_package
52 Valor por defecto: @code{default_let_rule_package}
54 La variable @code{current_let_rule_package} es el nombre del paquete de reglas que están utilizando las funciones del paquete @code{let} (@code{letsimp}, etc.), a menos que se especifique otro paquete de reglas. A esta variable se le puede asignar el nombre de cualquier paquete de reglas definido por medio de la instrucción @code{let}.
56 Si se hace la llamada @code{letsimp (expr, rule_pkg_name)}, el paquete de reglas @code{rule_pkg_name} será utilizado únicamente para esa llamada y el valor de @code{current_let_rule_package} no cambia.
60 @defvr {Variable opcional} default_let_rule_package
61 @c DEFAULT BINDING OF default_let_rule_package IS default_let_rule_package (BOUND TO ITSELF)
62 Valor por defecto: @code{default_let_rule_package}
64 @c THIS IS SORT OF CONFUSING. PROBABLY NEED TO GIVE MORE DETAIL HERE
65 La variable @code{default_let_rule_package} es el nombre del paquete de reglas utilizado cuando el usuario no especifica otro explícitamente con @code{let} o cambiando el valor de @code{current_let_rule_package}.
69 @deffn {Función} defmatch (@var{nombre_prog}, @var{patrón}, @var{x_1}, ..., @var{x_n})
70 @deffnx {Función} defmatch (@var{progname}, @var{pattern})
72 Define una función @code{@var{nombre_prog}(@var{expr}, @var{x_1}, ..., @var{x_n})} que analiza si @var{expr} coincide con el @var{patrón}.
74 El argumento @var{patrón} es una expresión que contiene los
75 argumentos de patrón @var{x_1}, ..., @var{x_n} y algunas variables de patrón.
76 Los argumentos de patrón se dan de forma explícita
77 como argumentos a @code{defmatch}, mientras que las variables de patrón
78 se declaran mediante la función @code{matchdeclare}.
79 Cualquier variable no declarada bien como variable patrón en @code{matchdeclare},
80 bien como argumento patrón en @code{defmatch} se hace coincidir con ella
83 El primer argumento de la función definida @var{nombre_prog} es una expresión
84 a ser comparada con el patrón y los demás argumentos son los argumentos
85 que se corresponden con las variables ficticias @var{x_1}, ..., @var{x_n} del patrón.
87 Si el resultado de la comparación es positivo, @var{nombre_prog} devuelve
88 una lista de ecuaciones cuyos miembros izquierdos son los argumentos y variables de
89 patrón, y cuyos miembros derechos son las subexpresiones en las que se han
90 producido las coincidencias con patrones. A las variables de patrón, no a los
91 argumentos, se les asignan las subexpresiones con las que coinciden. Si la
92 comparación falla, @var{nombre_prog} devuelve @code{false}.
94 Un patrón literal, es decir, que no contiene ni argumentos ni variables de patrón,
95 devuelve @code{true} en caso de coincidencia.
100 (that is, a pattern which contains neither pattern arguments nor pattern variables)
101 returns @code{true} if the match succeeds.
103 Véase también @code{matchdeclare}, @code{defrule}, @code{tellsimp} y @code{tellsimpafter}.
107 Define una función @code{linearp(expr, x)} que comprueba si
108 @code{expr} es de la forma @code{a*x + b}, donde
109 ni @code{a} ni @code{b} contienen a @code{x} y @code{a} es no nulo.
110 La función definida reconoce expresiones lineales respecto de
111 cualquier variable, pues el argumento de patrón @code{x} es
112 pasado a @code{defmatch}.
115 @c matchdeclare (a, lambda ([e],e#0 and freeof(x, e)),
117 @c defmatch (linearp, a*x + b, x);
118 @c linearp (3*z + (y + 1)*z + y^2, z);
124 (%i1) matchdeclare (a, lambda ([e], e#0 and freeof(x, e)),
127 (%i2) defmatch (linearp, a*x + b, x);
129 (%i3) linearp (3*z + (y + 1)*z + y^2, z);
131 (%o3) [b = y , a = y + 4, x = z]
141 Define una función @code{linearp(expr)} que comprueba si
142 @code{expr} es de la forma @code{a*x + b}, donde
143 ni @code{a} ni @code{b} contienen a @code{x} y @code{a} es no nulo.
144 La función definida sólo reconoce expresiones lineales
145 únicamente respecto de @code{x}, pues no se le pasa a @code{defmatch}
146 nigún argumento de patrón
149 @c matchdeclare (a, lambda ([e], e#0 and freeof(x, e)),
151 @c defmatch (linearp, a*x + b);
152 @c linearp (3*z + (y + 1)*z + y^2);
153 @c linearp (3*x + (y + 1)*x + y^2);
156 (%i1) matchdeclare (a, lambda ([e], e#0 and freeof(x, e)),
159 (%i2) defmatch (linearp, a*x + b);
161 (%i3) linearp (3*z + (y + 1)*z + y^2);
163 (%i4) linearp (3*x + (y + 1)*x + y^2);
165 (%o4) [b = y , a = y + 4]
168 Define una función @code{checklimits(expr)} que comprueba si
169 @code{expr} es una integral definida.
172 @c matchdeclare ([a, f], true);
173 @c constinterval (l, h) := constantp (h - l);
174 @c matchdeclare (b, constinterval (a));
175 @c matchdeclare (x, atom);
177 @c defmatch (checklimits, 'integrate (f, x, a, b));
179 @c 'integrate (sin(t), t, %pi + x, 2*%pi + x);
183 (%i1) matchdeclare ([a, f], true);
185 (%i2) constinterval (l, h) := constantp (h - l);
186 (%o2) constinterval(l, h) := constantp(h - l)
187 (%i3) matchdeclare (b, constinterval (a));
189 (%i4) matchdeclare (x, atom);
193 (%i6) defmatch (checklimits, 'integrate (f, x, a, b));
197 (%i8) 'integrate (sin(t), t, %pi + x, 2*%pi + x);
205 (%i9) checklimits (%);
206 (%o9) [b = x + 2 %pi, a = x + %pi, x = t, f = sin(t)]
211 @deffn {Función} defrule (@var{nombre_regla}, @var{patrón}, @var{reemplazamiento})
213 Define y da nombre a una regla de reemplazamiento para el patrón dado. Si la regla @var{nombre_regla} es aplicada a una expresión (por @code{apply1}, @code{applyb1} o @code{apply2}), cada subexpresión que coincida con el patrón será reemplazada por el contenido de @var{reemplazamiento}.
215 Las propias reglas pueden ser tratadas como funciones que transforman una expresión mediante una operación consistente en la búsqueda de una coincidencia y posterior aplicación de un reemplazamiento. Si la comparación falla, la función que implementa la regla devuelve @code{false}.
220 @deffn {Función} disprule (@var{nombre_regla_1}, ..., @var{nombre_regla_n})
221 @deffnx {Función} disprule (all)
223 Muestra las reglas de @var{nombre_regla_1}, ..., @var{nombre_regla_n}, tal como son devueltas por @code{defrule}, @code{tellsimp} o @code{tellsimpafter}, o un patrón definido por @code{defmatch}.
224 Cada regla se muestra con una etiqueta de expresión intermedia (@code{%t}).
226 La llamada @code{disprule (all)} muestra todas las reglas.
228 La función @code{disprule} no evalúa sus argumentos y devuelve la lista de etiquetas de expresiones intermedias correspondientes a las reglas mostradas.
230 Véase también @code{letrules}, que muestra las reglas definidas por @code{let}.
235 @c tellsimpafter (foo (x, y), bar (x) + baz (y));
236 @c tellsimpafter (x + y, special_add (x, y));
237 @c defmatch (quux, mumble (x));
238 @c disprule (foorule1, "+rule1", quux);
242 (%i1) tellsimpafter (foo (x, y), bar (x) + baz (y));
243 (%o1) [foorule1, false]
244 (%i2) tellsimpafter (x + y, special_add (x, y));
245 (%o2) [+rule1, simplus]
246 (%i3) defmatch (quux, mumble (x));
248 (%i4) disprule (foorule1, "+rule1", quux);
249 (%t4) foorule1 : foo(x, y) -> baz(y) + bar(x)
251 (%t5) +rule1 : y + x -> special_add(x, y)
253 (%t6) quux : mumble(x) -> []
255 (%o6) [%t4, %t5, %t6]
257 (%o6) [foorule1 : foo(x, y) -> baz(y) + bar(x),
258 +rule1 : y + x -> special_add(x, y), quux : mumble(x) -> []]
263 @deffn {Función} let (@var{prod}, @var{repl}, @var{predname}, @var{arg_1}, ..., @var{arg_n})
264 @deffnx {Función} let ([@var{prod}, @var{repl}, @var{predname}, @var{arg_1}, ..., @var{arg_n}], @var{nombre_paquete})
266 Define una regla de sustitución para @code{letsimp} tal que @var{prod} es sustituido por @var{repl}, donde @var{prod} es un producto de potencias positivas o negativas de los términos siguientes:
270 Átomos que @code{letsimp} buscará a menos que antes de llamar a @code{letsimp} se utilice la función @code{matchdeclare} para asociar un predicado con el átomo. En este caso @code{letsimp} hará coincidir el átomo con cualquier término del producto que satisfaga el predicado.
272 Expresiones básicas como @code{sin(x)}, @code{n!}, @code{f(x,y)}, etc. Como en el caso anterior, @code{letsimp} buscará coincidencias exactas, a menos que se utilice @code{matchdeclare} para asociar un predicado con el argumento de la expresión básica (@code{sin(x)}, @code{n!}, @code{f(x,y)}, ...).
275 Si se incluye un predicado en la función @code{let} seguido de una lista de argumentos, una coincidencia aceptable (es decir, una que fuese aceptada si se hubiese omitido el predicado) se aceptará sólo si @code{predname (arg_1', ..., arg_n')} vale @code{true}, donde @var{arg_i'} es el valor coincidente con @var{arg_i}. El argumento @var{arg_i} puede ser el nombre de cualquier átomo o el argumento de cualquier expresión básica que aparezca en @var{prod}.
276 @var{repl} puede ser cualquier expresión racional. @c ONLY RATIONAL -- REALLY ??
277 Si cualquiera de los átomos o argumentos de @var{prod} aparece en @var{repl} se llevan a cabo las sustituciones correspondientes.
279 La variable global @code{letrat} controla la simplificación de los cocientes por @code{letsimp}. Cuando @code{letrat} vale @code{false}, @code{letsimp} simplifica separadamente el numerador y denominador de @var{expr} y no simplifica el cociente. Sustituciones como que @code{n!/n} se reduzca a @code{(n-1)!} ya no se realizarán. Cuando @code{letrat} vale @code{true}, entonces se simplifican el numerador, el denominador y el cociente, en este orden.
281 Estas funciones de sustitución permiten al usuario trabajar con varios paquetes de reglas al mismo tiempo. Cada paquete de reglas puede contener cierto número de reglas @code{let} que son referenciadas por un nombre dado por el usuario.
282 @code{let ([@var{prod}, @var{repl}, @var{predname}, @var{arg_1}, ..., @var{arg_n}], @var{nombre_paquete})} añade la regla @var{predname} al paquete de reglas @var{nombre_paquete}. @code{letsimp (@var{expr}, @var{package_name})} aplica las reglas de @var{nombre_paquete}. La llamada @code{letsimp (@var{expr}, @var{nombre_paquete1}, @var{nombre_paquete2}, ...)}
283 es equivalente a @code{letsimp (@var{expr}, @var{nombre_paquete1})} seguida de @code{letsimp (%, @var{nombre_paquete2})}, ....
285 @code{current_let_rule_package} es el nombre del paquete de reglas que se está utilizando. A esta variable se le puede asignar el nombre de cualquier paquete de reglas definido mediante el comando @code{let}. Siempre que una de las funciones incluidas en el paquete @code{let} sean invocadas sin nombre de paquete, se utilizará el paquete cuyo nombre se guarde en @code{current_let_rule_package}. Si se hace una llamada tal como @code{letsimp (@var{expr}, @var{rule_pkg_name})}, el paquete de reglas @var{rule_pkg_name} es utilizado solamente para ese comando @code{letsimp}, sin efectuarse cambios en
286 @code{current_let_rule_package}. A menos que se indique otra cosa, @code{current_let_rule_package} toma por defecto el valor de @code{default_let_rule_package}.
289 (%i1) matchdeclare ([a, a1, a2], true)$
290 (%i2) oneless (x, y) := is (x = y-1)$
291 (%i3) let (a1*a2!, a1!, oneless, a2, a1);
292 (%o3) a1 a2! --> a1! where oneless(a2, a1)
294 (%i5) let (a1!/a1, (a1-1)!);
296 (%o5) --- --> (a1 - 1)!
298 (%i6) letsimp (n*m!*(n-1)!/m);
300 (%i7) let (sin(a)^2, 1 - cos(a)^2);
302 (%o7) sin (a) --> 1 - cos (a)
303 (%i8) letsimp (sin(x)^4);
305 (%o8) cos (x) - 2 cos (x) + 1
310 @defvr {Variable opcional} letrat
311 Valor por defecto: @code{false}
313 Cuando @code{letrat} vale @code{false}, @code{letsimp} simplifica separadamente el numerador y denominador de una fracción sin simplificar luego el cociente.
315 Cuando @code{letrat} vale @code{true}, se simplifican el numerador, denominador y cociente, por este orden.
318 (%i1) matchdeclare (n, true)$
319 (%i2) let (n!/n, (n-1)!);
321 (%o2) -- --> (n - 1)!
324 (%i4) letsimp (a!/a);
329 (%i6) letsimp (a!/a);
335 @deffn {Función} letrules ()
336 @deffnx {Función} letrules (@var{nombre_paquete})
338 Muestra las reglas de un paquete de reglas. La llamada @code{letrules ()} muestra las reglas del paquete de reglas actual. La llamada @code{letrules (@var{nombre_paquete})} muestra las reglas de @var{nombre_paquete}.
340 El paquete de reglas actual tiene su nombre almacenado en by @code{current_let_rule_package}. A menos que se indique de otra manera, @code{current_let_rule_package} toma por defecto el valor de @code{default_let_rule_package}.
342 Véase también @code{disprule}, que muestra las reglas definidas por @code{tellsimp} y @code{tellsimpafter}.
346 @deffn {Función} letsimp (@var{expr})
347 @deffnx {Función} letsimp (@var{expr}, @var{nombre_paquete})
348 @deffnx {Función} letsimp (@var{expr}, @var{nombre_paquete_1}, ..., @var{nombre_paquete_n})
350 Aplica repetidamente las reglas definidas por @code{let} hasta que no se puedan hacer más cambios en @var{expr}.
352 La llamada @code{letsimp (@var{expr})} utiliza las reglas de @code{current_let_rule_package}.
354 La llamada @code{letsimp (@var{expr}, @var{nombre_paquete})} utiliza las reglas de @var{nombre_paquete} sin efectuar cambios en @code{current_let_rule_package}.
356 La llamada @code{letsimp (@var{expr}, @var{nombre_paquete_1}, ..., @var{nombre_paquete_n})}
357 es equivalente a @code{letsimp (@var{expr}, @var{nombre_paquete_1}}, seguida de @code{letsimp (%, @var{nombre_paquete_2})} y así sucesivamente.
361 @defvr {Variable opcional} let_rule_packages
362 Valor por defecto: @code{[default_let_rule_package]}
364 La variable @code{let_rule_packages} guarda una lista con todos los paquetes de reglas definidos por el usuario, junto con el paquete por defecto @code{default_let_rule_package}.
368 @deffn {Función} matchdeclare (@var{a_1}, @var{pred_1}, ..., @var{a_n}, @var{pred_n})
369 Asocia un predicado @var{pred_k} con una variable o lista de variables @var{a_k}, de forma que @var{a_k} se comparará con expresiones para las cuales el predicado devuelva algo que no sea @code{false}.
371 Un predicado puede ser el nombre de una función, una expresión lambda, una
372 llamada a función, una llamada a una expresión lambda sin
373 el último argumento, @code{true} o @code{all}.
374 Cualquier expresión se hace coincidir con @code{true} o @code{all}.
376 Si el predicado se especifica como una llamada a función o a
377 una expresión lambda, la expresión a ser analizada es añadida
378 a la lista de argumentos, siendo los argumentos evaluados en el
379 momento de ser evaluada la comparación.
380 En cambio, si el predicado se especifica como un nombre de función
381 o como una expresión lambda, la expresión a ser analizada será
382 su único argumento. No es necesario definir una función de predicado cuando se hace una llamada a @code{matchdeclare}; el predicado no se evalúa hasta que se ensaya una comparación.
384 Un predicado puede devolver tanto una expresión booleana,
385 como @code{true} o @code{false}.
386 Las expresiones booleanas se evalúan con @code{is} dentro
387 de la regla, por lo que no es necesario llamar a @code{is}
388 desde dentro del predicado.
390 Si una expresión satisface un predicado, se asigna a la variable de comparación la expresión, excepto cuando las variables de comparación son operandos de sumas @code{+} o multiplicaciones @code{*}. Solamente las sumas y multiplicaciones son tratadas de forma especial; los demás operadores n-arios (tanto los del sistema como los definidos por el usuario) son tratados como funciones ordinarias.
392 En el caso de sumas y multiplicaciones, a la variable de comparación se le puede asignar una expresión simple que satisfaga el predicado de comparación, o una suma o producto, respectivamente, de tales expresiones. Los predicados son evaluados en el orden en el que sus variables asociadas aparecen en el patrón de comparación, y un término que satisfaga más de un predicado es tomado por el primer predicado que satisfaga. Cada predicado se compara con todos los operandos de la suma o producto antes de ser evaluado el siguiente predicado. Además, si 0 o 1, respectivamente, satisface un predicado de comparación, y no hay otros términos que lo satisfagan, se asignará el 0 o 1 a la variable de comparación asociada al predicado.
394 El algoritmo para procesar patrones de suma y multiplicación hace que los resultados de algunas comparaciones dependan del orden de los términos en el patrón de comparación y en la expresión a ser comparada. Sin embargo, si todos los predicados de comparación son mutuamente excluyentes, el resultado de la comparación no depende para nada de la ordenación, puesto que un predicado de comparación no puede aceptar términos aceptados por otros predicados.
396 Invocando @code{matchdeclare} con una variable @var{a} como argumento cambia la propiedad de @code{matchdeclare} para @var{a}, si ya había una declarada; solamente el @code{matchdeclare} más reciente está activo cuando se define una regla. Cambios posteriores en la propiedad de @code{matchdeclare} (via @code{matchdeclare} o @code{remove}) no afectan a las reglas existentes.
398 @code{propvars (matchdeclare)} devuelve la lista de todas las variables para las cuales hay una propiedad de @code{matchdeclare}. La llamada @code{printprops (@var{a}, matchdeclare)} devuelve el predicado para la variable @code{a}.
399 La llamada @code{printprops (all, matchdeclare)} devuelve la lista de predicados de todas las variables de @code{matchdeclare}. La llamada @code{remove (@var{a}, matchdeclare)} borra la propiedad @code{matchdeclare} de @var{a}.
401 Las funciones @code{defmatch}, @code{defrule}, @code{tellsimp}, @code{tellsimpafter} y @code{let} construyen reglas que analizan expresiones mediante patrones.
403 @code{matchdeclare} no evalúa sus argumentos y siempre devuelve @code{done}.
407 Un predicado puede ser el nombre de una función, una expresión lambda, una
408 llamada a función, una llamada a una expresión lambda sin
409 el último argumento, @code{true} o @code{all}.
412 @c matchdeclare (aa, integerp);
413 @c matchdeclare (bb, lambda ([x], x > 0));
414 @c matchdeclare (cc, freeof (%e, %pi, %i));
415 @c matchdeclare (dd, lambda ([x, y], gcd (x, y) = 1) (1728));
416 @c matchdeclare (ee, true);
417 @c matchdeclare (ff, all);
420 (%i1) matchdeclare (aa, integerp);
422 (%i2) matchdeclare (bb, lambda ([x], x > 0));
424 (%i3) matchdeclare (cc, freeof (%e, %pi, %i));
426 (%i4) matchdeclare (dd, lambda ([x, y], gcd (x, y) = 1) (1728));
428 (%i5) matchdeclare (ee, true);
430 (%i6) matchdeclare (ff, all);
434 Si una expresión satisface un predicado, se asigna a la variable de comparación la expresión.
437 @c matchdeclare (aa, integerp, bb, atom);
438 @c defrule (r1, bb^aa, ["integer" = aa, "atom" = bb]);
442 (%i1) matchdeclare (aa, integerp, bb, atom);
444 (%i2) defrule (r1, bb^aa, ["integer" = aa, "atom" = bb]);
446 (%o2) r1 : bb -> [integer = aa, atom = bb]
448 (%o3) [integer = 8, atom = %pi]
451 En el caso de sumas y multiplicaciones, a la variable de comparación se le puede asignar una expresión simple que satisfaga el predicado de comparación, o una suma o producto, respectivamente, de tales expresiones.
454 @c matchdeclare (aa, atom, bb, lambda ([x], not atom(x)));
455 @c defrule (r1, aa + bb,
456 @c ["all atoms" = aa, "all nonatoms" = bb]);
457 @c r1 (8 + a*b + sin(x));
458 @c defrule (r2, aa * bb,
459 @c ["all atoms" = aa, "all nonatoms" = bb]);
460 @c r2 (8 * (a + b) * sin(x));
463 (%i1) matchdeclare (aa, atom, bb, lambda ([x], not atom(x)));
465 (%i2) defrule (r1, aa + bb,
466 ["all atoms" = aa, "all nonatoms" = bb]);
467 bb + aa partitions `sum'
468 (%o2) r1 : bb + aa -> [all atoms = aa, all nonatoms = bb]
469 (%i3) r1 (8 + a*b + sin(x));
470 (%o3) [all atoms = 8, all nonatoms = sin(x) + a b]
471 (%i4) defrule (r2, aa * bb,
472 ["all atoms" = aa, "all nonatoms" = bb]);
473 bb aa partitions `product'
474 (%o4) r2 : aa bb -> [all atoms = aa, all nonatoms = bb]
475 (%i5) r2 (8 * (a + b) * sin(x));
476 (%o5) [all atoms = 8, all nonatoms = (b + a) sin(x)]
483 @defvr {Variable opcional} maxapplydepth
484 Valor por defecto: 10000
486 La variable @code{maxapplydepth} es la máxima profundidad a la que van a introducirse @code{apply1} y @code{apply2}.
491 @defvr {Variable opcional} maxapplyheight
492 Valor por defecto: 10000
494 La variable @code{maxapplyheight} es la m2'axima altura a la que escalará @code{applyb1} antes de detenerse.
499 @deffn {Función} remlet (@var{prod}, @var{nombre})
500 @deffnx {Función} remlet ()
501 @deffnx {Función} remlet (all)
502 @deffnx {Función} remlet (all, @var{nombre})
504 Elimina la última regla de sustitución @var{prod} --> repl que haya sido definida por la función @code{let}. Si se suministar el nombre la regla será borrada del paquete con ese mismo nombre.
506 Las llamadas @code{remlet()} y @code{remlet(all)} eliminan todas las reglas de sustitución del paquete de reglas actual. Si se suministra el nombre de un paquete de reglas, como en @code{remlet (all, @var{nombre})}, el paquete de reglas con ese @var{nombre} es también eliminado.
508 Si es necesario cambiar una sustitución haciendo uso de la misma producción, no es necesario llamar a @code{remlet}, simplemente redefínase la sustitución utilizando la misma producción con la función @code{let} junto con el nuevo reemplazamiento y/o nombre de predicado. De ser llamado nuevamente @code{remlet (@var{prod})} la sustitución original sería recuperada.
510 Véase también @code{remrule}, que elimina una regla definida por @code{tellsimp} o @code{tellsimpafter}.
514 @deffn {Función} remrule (@var{op}, @var{nombre_regla})
515 @deffnx {Función} remrule (@var{op}, all)
517 Elimina las reglas previamente definidas por @code{tellsimp} o @code{tellsimpafter}.
519 La llamada @code{remrule (@var{op}, @var{nombre_regla})} elimina la regla de nombre @var{nombre_regla} del operador @var{op}.
521 Independientemente de que @var{op} sea un operador propio de Maxima o haya sido definido por el usario (como los establecidos por @code{infix}, @code{prefix}, etc.), tanto @var{op} como @var{rulename} deben ir encerrados entre comillas dobles.
523 La llamada @code{remrule (@var{function}, all)} borra todas las reglas para el operador @var{op}.
525 Véase también @code{remlet}, que elimina una regla definida mediante @code{let}.
530 @c tellsimp (foo (aa, bb), bb - aa);
531 @c tellsimpafter (aa + bb, special_add (aa, bb));
533 @c tellsimp (aa @@ bb, bb/aa);
534 @c tellsimpafter (quux (%pi, %e), %pi - %e);
535 @c tellsimpafter (quux (%e, %pi), %pi + %e);
536 @c [foo (aa, bb), aa + bb, aa @@ bb, quux (%pi, %e),
538 @c remrule (foo, foorule1);
539 @c remrule ("+", ?\+rule1);
540 @c remrule ("@@", ?\@\@rule1);
541 @c remrule (quux, all);
542 @c [foo (aa, bb), aa + bb, aa @@ bb, quux (%pi, %e),
547 (%i1) tellsimp (foo (aa, bb), bb - aa);
548 (%o1) [foorule1, false]
549 (%i2) tellsimpafter (aa + bb, special_add (aa, bb));
550 (%o2) [+rule1, simplus]
551 (%i3) infix ("@@@@");
553 (%i4) tellsimp (aa @@@@ bb, bb/aa);
554 (%o4) [@@@@rule1, false]
555 (%i5) tellsimpafter (quux (%pi, %e), %pi - %e);
556 (%o5) [quuxrule1, false]
557 (%i6) tellsimpafter (quux (%e, %pi), %pi + %e);
558 (%o6) [quuxrule2, quuxrule1, false]
559 (%i7) [foo (aa, bb), aa + bb, aa @@@@ bb, quux (%pi, %e),
562 (%o7) [bb - aa, special_add(aa, bb), --, %pi - %e, %pi + %e]
564 (%i8) remrule (foo, foorule1);
566 (%i9) remrule ("+", ?\+rule1);
568 (%i10) remrule ("@@@@", ?\@@\@@rule1);
570 (%i11) remrule (quux, all);
572 (%i12) [foo (aa, bb), aa + bb, aa @@@@ bb, quux (%pi, %e),
574 (%o12) [foo(aa, bb), bb + aa, aa @@@@ bb, quux(%pi, %e),
580 @deffn {Función} tellsimp (@var{patrón}, @var{reemplazamiento})
582 La función @code{tellsimp} es similar a @code{tellsimpafter} pero coloca nueva información antes que la antigua, de manera que se aplica antes que las reglas de simplificación de Maxima.
584 La función @code{tellsimp} se utiliza cuando es importante utilizar la expresión antes de que el simplificador opere sobre ella; por ejemplo, cuando el simplificador ya "sabe" algo sobre una expresión, pero lo que devuelve no es lo que quiere el usuario. En cambio, cuando el simplificador ya "sabe" algo sobre una expresión pero lo que devuelve no es lo suficiente para el usuario, entonces éste podrá estar interesado en utilizar @code{tellsimpafter}.
586 El patrón no puede ser una suma, ni un producto, ni una variable ni un número.
588 @code{rules} es la lista de reglas definidas por
589 @code{defrule}, @code{defmatch}, @code{tellsimp} y @code{tellsimpafter}.
594 (%i1) matchdeclare (x, freeof (%i));
597 (%i3) tellsimp (sin(%i*x), %i*sinh(x));
598 (%o3) [sinrule1, simp-%sin]
599 (%i4) trigexpand (sin (%i*y + x));
600 (%o4) sin(x) cos(%i y) + %i cos(x) sinh(y)
606 (%i7) ev (tellsimp (0^0, 1), simp: false);
607 (%o7) [^rule1, simpexpt]
610 (%i9) remrule ("^", %th(2)[1]);
612 (%i10) tellsimp (sin(x)^2, 1 - cos(x)^2);
613 (%o10) [^rule2, simpexpt]
614 (%i11) (1 + sin(x))^2;
619 (%o12) 2 sin(x) - cos (x) + 2
625 (%i15) matchdeclare (a, true);
627 (%i16) tellsimp (sin(a)^2, 1 - cos(a)^2);
628 (%o16) [^rule3, simpexpt]
636 @deffn {Función} tellsimpafter (@var{patrón}, @var{reemplazamiento})
638 Define una regla de simplificación que el simplificador aplicará después de las reglas de simplificación propias de de Maxima. El @var{patrón} es una expresión que contiene variables de patrón (declaradas por @code{matchdeclare}) junto con otros átomos y operadores. El contenido de @var{reemplazamiento} sustituye una expresión que coincida con el patrón; a las variables de patrón en @var{reemplazamiento} se les asignan los valores coincidentes en la expresión.
640 El @var{patrón} puede ser una expresión no atómica en la que el operador principal no sea una variable de patrón; la regla de simplificación se asocia con el operador principal. Los nombres de las funciones (con una excepción que se indica más abajo), listas y arrays pueden aparecer en el @var{patrón} como operador principal sólo como literales (no variables de patrones); esto excluye expresiones como @code{aa(x)} y @code{bb[y]}, si tanto @code{aa} como @code{bb} son patrones de variables. Nombres de funciones, listas y arrays que sean variables de patrón pueden aparecer como operadores que no sean el operador principal de @var{patrón}.
642 Hay una excepción a la regla indicada más arriba concerniente a los nombres de funciones. El nombre de una función subindicada en una expresión tal como @code{aa[x](y)} puede ser una variable de patrón porque el operador principal no es @code{aa} sino el átomo de Lisp @code{mqapply}. Esta es una consecuencia de la representación de expresiones que contienen funciones subindicadas.
644 Las reglas de simplificación se aplican tras las evaluaciones (a menos que se supriman con el apóstrofo o la variable @code{noeval}). Las reglas establecidas por @code{tellsimpafter} se aplican en el orden en que han sido definidas y después de las reglas propias de Maxima. Las reglas se aplican de abajo arriba, esto es, se aplican primero a las subexpresiones antes que a toda la expresión. Puede ser necesario simplificar repetidamente un resultado (por ejemplo, mediante el operador de doble comilla simple @code{'@w{}'} o la variable @code{infeval}) para asegurar que se aplican todas las reglas.
646 Las variables de patrón se tratan como variables locales en las reglas de simplificación. Una vez definida una regla, el valor de una variable de patrón no afecta a la regla, ni se ve influenciada poe ésta. Una asignación a una variable de patrón que resulta de la aplicación exitosa de una regla no afecta a la asignación actual de la variable de patrón. Sin embargo, como cualquier otro átomo de Maxima, las propiedades de las variables de patrón (tal como se definen con @code{put} y sus funciones relacionadas) son globales.
648 La regla construida por @code{tellsimpafter} es nombrada detrás del operador principal de @var{patrón}. Reglas para operadores de Maxima y operadores definidos por el usuario con @code{infix}, @code{prefix}, @code{postfix}, @code{matchfix} y @code{nofix}, tienen nombres que son cadenas alfanuméricas de Maxima. Reglas para otras funciones tienen nombres que son identificadores ordinarios de Maxima.
650 El tratamiento de formas nominales y verbales es hasta cierto punto confuso. Si se define una regla para una forma nominal (o verbal) y ya existe una regla para la correspondiente forma verbal (o nominal), la regla recién definida se aplica a ambas formas (nominal y verbal). Si no existe regla para una forma verbal (o nominal) la regla recién definida se aplica únicamente a la forma nominal (o verbal).
652 La regla construida por @code{tellsimpafter} es una típica función de Lisp. Si el nombre de la regla es @code{$foorule1}, la sentencia @code{:lisp (trace $foorule1)} hace una traza de la función y @code{:lisp (symbol-function '$foorule1)} muestra su definición.
654 La función @code{tellsimpafter} no evalúa sus argumentos y devuelve la lista de reglas para el operador principal de @var{patrón}, incluida la regla recién establecida.
656 Véanse también @code{matchdeclare}, @code{defmatch}, @code{defrule}, @code{tellsimp}, @code{let},
657 @code{kill}, @code{remrule} y @code{clear_rules}.
661 @var{pattern} puede ser cualquier expresión no atómica en la que el operador principal no sea una variable de patrón.
664 (%i1) matchdeclare (aa, atom, [ll, mm], listp, xx, true)$
665 (%i2) tellsimpafter (sin (ll), map (sin, ll));
666 (%o2) [sinrule1, simp-%sin]
667 (%i3) sin ([1/6, 1/4, 1/3, 1/2, 1]*%pi);
669 (%o3) [-, -------, -------, 1, 0]
671 (%i4) tellsimpafter (ll^mm, map ("^", ll, mm));
672 (%o4) [^rule1, simpexpt]
673 (%i5) [a, b, c]^[1, 2, 3];
676 (%i6) tellsimpafter (foo (aa (xx)), aa (foo (xx)));
677 (%o6) [foorule1, false]
678 (%i7) foo (bar (u - v));
679 (%o7) bar(foo(u - v))
682 Las reglas se aplican en el orden en que se definen. Si dos reglas coinciden con una expresión, se aplica aquélla que haya sido definida en primer lugar.
685 (%i1) matchdeclare (aa, integerp);
687 (%i2) tellsimpafter (foo (aa), bar_1 (aa));
688 (%o2) [foorule1, false]
689 (%i3) tellsimpafter (foo (aa), bar_2 (aa));
690 (%o3) [foorule2, foorule1, false]
695 Las variables de patrón se tratan como variables locales en las reglas de simplificación.
696 (Compárese con @code{defmatch}, que trata las variables de patrón como globales.)
699 (%i1) matchdeclare (aa, integerp, bb, atom);
701 (%i2) tellsimpafter (foo(aa, bb), bar('aa=aa, 'bb=bb));
702 (%o2) [foorule1, false]
706 (%o4) bar(aa = 42, bb = %e)
711 Como cualquier otro átomo, las propiedades de las variables de patrón son globales, incluso cuando sus valores sean locales. En este ejemplo se declara una propiedad de asignación a treavés de @code{define_variable}. Esta es una propiedad del átomo @code{bb} en todo Maxima.
714 (%i1) matchdeclare (aa, integerp, bb, atom);
716 (%i2) tellsimpafter (foo(aa, bb), bar('aa=aa, 'bb=bb));
717 (%o2) [foorule1, false]
719 (%o3) bar(aa = 42, bb = %e)
720 (%i4) define_variable (bb, true, boolean);
723 Error: bb was declared mode boolean, has value: %e
724 -- an error. Quitting. To debug this try debugmode(true);
727 Las reglas se nombran después de los operadores principales. Los nombres de reglas tanto para las funciones de Maxima como para las definidas por el usuario son cadenas alfanuméricas, mientras que los nombres de las otras funciones son identificadores típicos.
730 (%i1) tellsimpafter (foo (%pi + %e), 3*%pi);
731 (%o1) [foorule1, false]
732 (%i2) tellsimpafter (foo (%pi * %e), 17*%e);
733 (%o2) [foorule2, foorule1, false]
734 (%i3) tellsimpafter (foo (%i ^ %e), -42*%i);
735 (%o3) [foorule3, foorule2, foorule1, false]
736 (%i4) tellsimpafter (foo (9) + foo (13), quux (22));
737 (%o4) [+rule1, simplus]
738 (%i5) tellsimpafter (foo (9) * foo (13), blurf (22));
739 (%o5) [*rule1, simptimes]
740 (%i6) tellsimpafter (foo (9) ^ foo (13), mumble (22));
741 (%o6) [^rule1, simpexpt]
743 (%o7) [trigrule0, trigrule1, trigrule2, trigrule3, trigrule4,
744 htrigrule1, htrigrule2, htrigrule3, htrigrule4, foorule1,
745 foorule2, foorule3, +rule1, *rule1, ^rule1]
746 (%i8) foorule_name: first (%o1);
748 (%i9) plusrule_name: first (%o4);
750 (%i10) [?mstringp (foorule_name), symbolp (foorule_name)];
752 (%i11) [?mstringp (plusrule_name), symbolp (plusrule_name)];
754 (%i12) remrule (foo, foorule1);
756 (%i13) remrule ("^", "^rule1");
760 Un ejemplo de producto anticonmutativo.
763 @c gt (i, j) := integerp(j) and i < j;
764 @c matchdeclare (i, integerp, j, gt(i));
765 @c tellsimpafter (s[i]^^2, 1);
766 @c tellsimpafter (s[i] . s[j], -s[j] . s[i]);
767 @c s[1] . (s[1] + s[2]);
769 @c factor (expand (sum (s[i], i, 0, 9)^^5));
772 (%i1) gt (i, j) := integerp(j) and i < j;
773 (%o1) gt(i, j) := integerp(j) and i < j
774 (%i2) matchdeclare (i, integerp, j, gt(i));
776 (%i3) tellsimpafter (s[i]^^2, 1);
777 (%o3) [^^rule1, simpncexpt]
778 (%i4) tellsimpafter (s[i] . s[j], -s[j] . s[i]);
779 (%o4) [.rule1, simpnct]
780 (%i5) s[1] . (s[1] + s[2]);
786 (%i7) factor (expand (sum (s[i], i, 0, 9)^^5));
787 (%o7) 100 (s + s + s + s + s + s + s + s + s + s )
793 @deffn {Función} clear_rules ()
795 Ejecuta @code{kill (rules)} y después inicializa el siguiente número de regla a 1 para la adición @code{+}, multiplicación @code{*} y exponenciación @code{^}.