@c Language: Brazilian Portuguese, Encoding: iso-8859-1
@c /Rules.texi/1.26/Sat Jun  2 00:13:06 2007/-ko/
@menu
* Introdu@value{cedilha}@~{a}o a Regras e Modelos::  
* Fun@value{cedilha}@~{o}es e Vari@'{a}veis Definidas para Regras e Modelos::  
@end menu

@node Introdu@value{cedilha}@~{a}o a Regras e Modelos, Fun@value{cedilha}@~{o}es e Vari@'{a}veis Definidas para Regras e Modelos, Regras e Modelos, Regras e Modelos
@section Introdu@value{cedilha}@~{a}o a Regras e Modelos

Essa se@value{cedilha}@~{a}o descreve coincid@^{e}ncias de modelos definidos pelo usu@'{a}rio e
regras de simplifica@value{cedilha}@~{a}o.
Existem dois grupos de fun@value{cedilha}@~{o}es que implementam at@'{e} certo ponto diferentes esquemas de coincid@^{e}ncia de modelo.
Em um grupo est@~{a}o @code{tellsimp}, @code{tellsimpafter}, @code{defmatch}, @code{defrule},
@code{apply1}, @code{applyb1}, e @code{apply2}.
Em outro grupo est@~{a}o @code{let} e @code{letsimp}.
Ambos os esquemas definem modelos em termos de vari@'{a}veis de modelo declaradas por @code{matchdeclare}.

Regras de coincid@^{e}ncia de modelos definidas por @code{tellsimp} e @code{tellsimpafter} s@~{a}o aplicadas automaticamente
atrav@'{e}s do simplificador do Maxima.
Regras definidas atrav@'{e}s de @code{defmatch}, @code{defrule}, e @code{let} s@~{a}o aplicadas
atrav@'{e}s de uma chamada expl@'{i}cita de fun@value{cedilha}@~{a}o.

Existe mecanismos adicionais para regras aplicadas a polin@^{o}mios atrav@'{e}s de @code{tellrat},
e para @'{a}lgebra comutativa e n@~{a}o comutativa no pacote @code{affine}. 

@c end concepts Rules and Patterns
@node Fun@value{cedilha}@~{o}es e Vari@'{a}veis Definidas para Regras e Modelos,  , Introdu@value{cedilha}@~{a}o a Regras e Modelos, Regras e Modelos
@section Fun@value{cedilha}@~{o}es e Vari@'{a}veis Definidas para Regras e Modelos

@c NEEDS CLARIFICATION AND EXAMPLES
@deffn {Fun@value{cedilha}@~{a}o} apply1 (@var{expr}, @var{rule_1}, ..., @var{rule_n})
Repetidamente aplica @var{rule_1} a
@var{expr} at@'{e} que isso falhe, ent@~{a}o repetidamente aplica a mesma regra a todas
as subexpress@~{o}es de @var{expr}, da esquerda para a direita, at@'{e} que @var{rule_1} tenha falhado
sobre todas as subexpress@~{o}es.  Chama o resultado da transforma@value{cedilha}@~{a}o de @var{expr} dessa
maneira de @var{expr_2}.  Ent@~{a}o @var{rule_2} @'{e} aplicada no mesmo estilo
iniciando no topo de @var{expr_2}.  Quando @var{rule_n} falhar na subexpress@~{a}o
final, o resultado @'{e} retornado.

@code{maxapplydepth} @'{e} a intensidade de n@'{i}vel mais distante de subexpress@~{o}es processadas por
@code{apply1} e @code{apply2}.

Veja tamb@'{e}m @code{applyb1}, @code{apply2}, e @code{let}.

@end deffn

@c NEEDS CLARIFICATION AND EXAMPLES
@deffn {Fun@value{cedilha}@~{a}o} apply2 (@var{expr}, @var{rule_1}, ..., @var{rule_n})
Se @var{rule_1} falhar sobre uma dada subexpress@~{a}o, ent@~{a}o @var{rule_2} @'{e}
repetidamente aplicada, etc.  Somente se todas as regras falharem sobre uma dada
subexpress@~{a}o @'{e} que o conjunto completo de regras @'{e} repetidamente aplicada @`a pr@'{o}xima
subexpress@~{a}o.  Se uma das regras obt@'{e}m sucesso, ent@~{a}o a mesma
subexpress@~{a}o @'{e} reprocessada, iniciando com a primeira regra.

@code{maxapplydepth} @'{e} a intensidade do n@'{i}vel mais distante de subexpress@~{o}es processadas atrav@'{e}s de
@code{apply1} e @code{apply2}.

Veja tamb@'{e}m @code{apply1} e @code{let}.

@end deffn

@c NEEDS CLARIFICATION AND EXAMPLES
@deffn {Fun@value{cedilha}@~{a}o} applyb1 (@var{expr}, @var{rule_1}, ..., @var{rule_n})
Repetidamente aplica @var{rule_1} para a subexpress@~{a}o mais distante de @var{expr} at@'{e} falhar,
ent@~{a}o repetidamente aplica a mesma regra um n@'{i}vel mais acima (i.e., subexpress@~{a}os mais larga),
at@'{e} que @var{rule_1} tenha falhado sobre a express@~{a}o de n@'{i}vel mais alto.
Ent@~{a}o @var{rule_2} @'{e} aplicada com o mesmo estilo para o resultado de @var{rule_1}.
ap@'{o}s @var{rule_n} ter sido aplicada @`a express@~{a}o de n@'{i}vel mais elevado,
o resultado @'{e} retornado.

@code{applyb1} @'{e} similar a @code{apply1} mas trabalha da
base para cima em lugar de do topo para baixo.

@code{maxapplyheight} @'{e} o @'{a}pice que @code{applyb1} encontra
antes de interromper.

Veja tamb@'{e}m @code{apply1}, @code{apply2}, e @code{let}.

@end deffn

@defvr {Vari@'{a}vel de op@value{cedilha}@~{a}o} current_let_rule_package
Valor padr@~{a}o: @code{default_let_rule_package}

@code{current_let_rule_package} @'{e} o nome do pacote de regras que est@'{a} sendo usado por
fun@value{cedilha}@~{o}es no pacote @code{let} (@code{letsimp}, etc.) @c NEED TO GIVE AN EXPLICIT LIST HERE (NOT "ETC")
se nenhum outro pacote de regras for especificado.
A essa vari@'{a}vel pode ser atribu@'{i}do o nome de qualquer pacote de regras definido
via comando @code{let}.

Se uma chamada tal como @code{letsimp (expr, nome_pct_regras)} for feita,
o pacote de regras @code{nome_pct_regras} @'{e} usado para aquela chamada de fun@value{cedilha}@~{a}o somente,
e o valor de @code{current_let_rule_package} n@~{a}o @'{e} alterado.

@end defvr

@defvr {Vari@'{a}vel de op@value{cedilha}@~{a}o} default_let_rule_package
@c DEFAULT BINDING OF default_let_rule_package IS default_let_rule_package (BOUND TO ITSELF)
Valor padr@~{a}o: @code{default_let_rule_package}

@c THIS IS SORT OF CONFUSING. PROBABLY NEED TO GIVE MORE DETAIL HERE
@code{default_let_rule_package} @'{e} o nome do pacote de regras usado quando um
n@~{a}o for explicitamente escolhido pelo usu@'{a}rio com @code{let} ou atrav@'{e}s de altera@value{cedilha}@~{a}o do valor de
@code{current_let_rule_package}.

@end defvr

@deffn {Fun@value{cedilha}@~{a}o} defmatch (@var{prognome}, @var{modelo}, @var{x_1}, ..., @var{x_n})
@deffnx {Fun@value{cedilha}@~{a}o} defmatch (@var{prognome}, @var{modelo})
Define uma fun@value{cedilha}@~{a}o @code{@var{prognome}(@var{expr}, @var{x_1}, ..., @var{x_n})}
que testa @var{expr} para ver se essa express@~{a}o coincide com @var{modelo}.

@var{modelo} @'{e} uma express@~{a}o contendo os argumentos modelo @var{x_1}, ..., @var{x_n} (se existir algum)
e alguns modelos de vari@'{a}veis (se existir algum).
os argumentos modelo s@~{a}o fornecidos explicitamente como argumentos para @code{defmatch} enquanto os modelos de vari@'{a}veis
s@~{a}o declarados atrav@'{e}s da fun@value{cedilha}@~{a}o @code{matchdeclare}.
Qualquer vari@'{a}vel n@~{a}o declarada como modelo em @code{matchdeclare}
ou como um argumento modelo em @code{defmatch} coincide somente com si mesma.

O primeiro argumento para a fun@value{cedilha}@~{a}o criada @var{prognome} @'{e} uma express@~{a}o
a serem comparadas contra o modelo  e os outros argumentos s@~{a}o os atuais argumetnos
que correspondem @`as vari@'{a}veis respectivas @var{x_1}, ..., @var{x_n} no modelo.

Se a tentativa de coincid@^{e}ncia obtiver sucesso, @var{prognome} retorna
uma lista de equa@value{cedilha}@~{o}es cujos lados esquerdos s@~{a}o os
argumetnos de modelo e vari@'{a}veis de modelo, e cujo lado direito forem as subexpress@~{o}es
cujos argumentos de modelo e as vari@'{a}veis coincidem.
Os modelos de vari@'{a}veis, mas n@~{a}o tos argumentos de modelo, s@~{a}o atribu@'{i}dos @`as subexpress@~{o}es que coincidirem.
Se a coincid@^{e}ncia falhar, @var{prognome} retorna @code{false}.  

Um modelo literal
(isto @'{e}, um modelo que n@~{a}o contiver nem argumentos de modelo nem vari@'{a}veis de modelo)
retorna @code{true} se a coincid@^{e}ncia ocorrer.

Veja tamb@'{e}m @code{matchdeclare}, @code{defrule}, @code{tellsimp}, e @code{tellsimpafter}.

Exemplos:

Define uma fun@value{cedilha}@~{a}o @code{linearp(expr, x)} que
testa @code{expr} para ver se essa express@~{a}o da forma @code{a*x + b}
tal que @code{a} e @code{b} n@~{a}o contenham @code{x} e @code{a} seja n@~{a}o nulo.
Essa fun@value{cedilha}@~{a}o de coincid@^{e}ncia coincide com express@~{o}es que sejam lineares em qualquer vari@'{a}vel,
por que o argumento de modelo @code{x} @'{e} fornecido para @code{defmatch}.
@c HOW HARD WILL MAXIMA TRY TO COLLECT TERMS AND DO OTHER MUNGEING TO FIT THE PATTERN ??

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

Define uma fun@value{cedilha}@~{a}o @code{linearp(expr)} que testa @code{expr}
para ver se essa express@~{a}o @'{e} da forma @code{a*x + b}
tal que @code{a} e @code{b} n@~{a}o contenham @code{x} e @code{a} seja n@~{a}o nulo.
Essa fun@value{cedilha}@~{a}o de coincid@^{e}ncia somente coincide com express@~{o}es lineares em @code{x},
n@~{a}o em qualquer outra vari@'{a}vel, porque nenhum argumento de modelo @'{e} fornecido a @code{defmatch}.

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

Define uma fun@value{cedilha}@~{a}o @code{checklimits(expr)} que testa @code{expr}
para ver se essa express@~{a}o @'{e} uma integral definida.
 
@c ===beg===
@c matchdeclare ([a, f], true);
@c constinterval (l, h) := constantp (h - l);
@c matchdeclare (b, constinterval (a));
@c matchdeclare (x, atom);
@c simp : false;
@c defmatch (checklimits, 'integrate (f, x, a, b));
@c simp : true;
@c 'integrate (sin(t), t, %pi + x, 2*%pi + x);
@c checklimits (%);
@c ===end===
@example
(%i1) matchdeclare ([a, f], true);
(%o1)                         done
(%i2) constinterval (l, h) := constantp (h - l);
(%o2)        constinterval(l, h) := constantp(h - l)
(%i3) matchdeclare (b, constinterval (a));
(%o3)                         done
(%i4) matchdeclare (x, atom);
(%o4)                         done
(%i5) simp : false;
(%o5)                         false
(%i6) defmatch (checklimits, 'integrate (f, x, a, b));
(%o6)                      checklimits
(%i7) simp : true;
(%o7)                         true
(%i8) 'integrate (sin(t), t, %pi + x, 2*%pi + x);
                       x + 2 %pi
                      /
                      [
(%o8)                 I          sin(t) dt
                      ]
                      /
                       x + %pi
(%i9) checklimits (%);
(%o9)    [b = x + 2 %pi, a = x + %pi, x = t, f = sin(t)]
@end example

@end deffn

@c NEEDS CLARIFICATION AND EXAMPLES
@deffn {Fun@value{cedilha}@~{a}o} defrule (@var{nomeregra}, @var{modelo}, @var{substitui@value{cedilha}@~{a}o})
Define e nomeia uma
regra de substitui@value{cedilha}@~{a}o para o modelo dado.  Se a regra nomeada @var{nomeregra} for
aplicada a uma express@~{a}o (atrav@'{e}s de @code{apply1}, @code{applyb1}, ou @code{apply2}), toda
subexpress@~{a}o coincidindo com o modelo ser@'{a} substitu@'{i}da por
@code{substitui@value{cedilha}@~{a}o}. Todas as vari@'{a}veis em @code{substitui@value{cedilha}@~{a}o} que tiverem sido
atribuidos valores pela coincid@^{e}ncia com o modelo s@~{a}o atribuidas esses valores na
@code{substitui@value{cedilha}@~{a}o} que @'{e} ent@~{a}o simplificado.

As regras por si mesmas podem ser
tratadas como fun@value{cedilha}@~{o}es que transforma uma express@~{a}o atrav@'{e}s de uma
opera@value{cedilha}@~{a}o de coincid@^{e}ncia de modelo e substitui@value{cedilha}@~{a}o.
Se a coincid@^{e}ncia falhar, a fun@value{cedilha}@~{a}o da regra retorna @code{false}.

@end deffn

@c NEEDS EXAMPLES
@deffn {Fun@value{cedilha}@~{a}o} disprule (@var{nomeregra_1}, ..., @var{nomeregra_2})
@deffnx {Fun@value{cedilha}@~{a}o} disprule (all)
Mostra regras com os nomes @var{nomeregra_1}, ..., @var{nomeregra_n},
como retornado por @code{defrule}, @code{tellsimp}, ou @code{tellsimpafter},
ou um modelo definido por meio de @code{defmatch}.
Cada regra @'{e} mostrada com um r@'{o}tulo de express@~{a}o intermedi@'{a}ria (@code{%t}).

@code{disprule (all)} mostra todas as regras.

@code{disprule} n@~{a}o avalia seus argumentos.
@code{disprule} retorna a lista de r@'{o}tulos de express@~{o}es intermed@'{a}irias correspondendo @`as regras mostradas.

Veja tamb@'{e}m @code{letrules}, que mostra regras definidas atrav@'{e}s de @code{let}.

Examples:

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

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

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

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

@end deffn

@deffn {Fun@value{cedilha}@~{a}o} let (@var{prod}, @var{repl}, @var{prednome}, @var{arg_1}, ..., @var{arg_n})
@deffnx {Fun@value{cedilha}@~{a}o} let ([@var{prod}, @var{repl}, @var{prednome}, @var{arg_1}, ..., @var{arg_n}], @var{nome_pacote})
Define uma regra de substitui@value{cedilha}@~{a}o para @code{letsimp} tal que @var{prod} @'{e} substitu@'{i}do por @var{repl}.
@var{prod} @'{e} um produto de expoentes positivos ou negativos dos seguintes termos:

@itemize @bullet
@item
Atomos que @code{letsimp} ir@'{a} procurar literalmente a menos que previamente
chamando @code{letsimp} a fun@value{cedilha}@~{a}o @code{matchdeclare} @'{e} usada para associar um
predicado com o @'{a}tomo.  Nesse caso @code{letsimp} ir@'{a} coincidir com o @'{a}tomo para
qualquer termo de um produto satisfazendo o predicado.
@item
N@'{u}cleos tais como @code{sin(x)}, @code{n!}, @code{f(x,y)}, etc.  Como com @'{a}tomos acima
@code{letsimp} ir@'{a} olhar um literal coincidente a menos que @code{matchdeclare} seja usada para
associar um predicado com o argumento do n@'{u}cleo.
@end itemize

Um termo para um expoente positivo ir@'{a} somente coincidir com um termo tendo ao menos aquele
expoente.  Um termo para um expoente negativo
por outro lado ir@'{a} somente coincidir com um termo com um expoente ao menos j@'{a}
negativo.  o caso de expentes negativos em @var{prod} o comutador
@code{letrat} deve ser escolhido para @code{true}.
Veja tamb@'{e}m @code{letrat}.

Se um predicado for inclu@'{i}do na fun@value{cedilha}@~{a}o @code{let} seguido por uma lista de
argumentos, uma tentativa de coincid@^{e}ncia (i.e. uma que pode ser aceita se o
predicado fosse omitido) @'{e} aceita somente se
@code{prednome (arg_1', ..., arg_n')} avaliar para @code{true} onde @var{arg_i'} @'{e} o valor
coincidente com @var{arg_i}.  O @var{arg_i} pode ser o nome de qualquer @'{a}tomo ou o argumento
de qualquer n@'{u}cleo aparecendo em @var{prod}.
@var{repl} pode ser qualquer express@~{a}o racional. @c ONLY RATIONAL -- REALLY ??
Se quaisquer dos @'{a}tomos ou argumentos de @var{prod} aparecer em @var{repl} a
substitui@value{cedilha}@~{a}o @'{e} feita. @c SPELL OUT "APPROPRIATE" IN THIS CONTEXT

O sinalizador global @code{letrat} controla a simplifica@value{cedilha}@~{a}o dos quocientes atrav@'{e}s de @code{letsimp}.
Quando @code{letrat} for @code{false},
@code{letsimp} simplifica o numerador e o
denominador de @var{expr} separadamente, e n@~{a}o simplifica o quociente.
Substitui@value{cedilha}@~{o}es tais como @code{n!/n} v@~{a}o para @code{(n-1)!} ent@~{a}o falham quando @code{letrat} for @code{false}.
Quando @code{letrat} for @code{true}, ent@~{a}o o numerador,
o denominador, e o quociente s@~{a}o simplificados nessa ordem.

Essas fun@value{cedilha}@~{o}es de substitui@value{cedilha}@~{a}o permitem a voc@^{e} trabalhar com muitos pacotes de regras.
Cada pacote de regras pode conter qualquer n@'{u}mero de regras
@code{let} e @'{e} referenciado atrav@'{e}s de um nome definido pelo usu@'{a}rio.
@code{let ([@var{prod}, @var{repl}, @var{prednome}, @var{arg_1}, ..., @var{arg_n}], @var{nome_pacote})}
adiciona a regra @var{prednome} ao pacote de regras @var{nome_pacote}.
@code{letsimp (@var{expr}, @var{nome_pacote})} 
aplica as regras em @var{nome_pacote}.
@code{letsimp (@var{expr}, @var{nome_pacote1}, @var{nome_pacote2}, ...)}
@'{e} equivalente a @code{letsimp (@var{expr}, @var{nome_pacote1})}
seguido por @code{letsimp (%, @var{nome_pacote2})}, ....

@code{current_let_rule_package} @'{e} o nome do pacote de regras que est@'{a}
atualmente sendo usando.
Essa vari@'{a}vel pode receber o nome de
qualquer pacote de regras definidos via o comando @code{let}.
Quando qualquer das fun@value{cedilha}@~{o}es compreendidas no pacote @code{let} s@~{a}o chamadas sem o nome do pacote,
o pacote nomeado por @code{current_let_rule_package} @'{e} usado.
Se uma chamada tal como @code{letsimp (@var{expr}, @var{nome_pct_regras})} @'{e} feita,
o pacote de regras @var{nome_pct_regras} @'{e} usado somente para aquele comando @code{letsimp},
e @code{current_let_rule_package} n@~{a}o @'{e} alterada.
Se n@~{a}o especificado de outra forma,
@code{current_let_rule_package} avalia de forma padronizada para @code{default_let_rule_package}.

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

@c NEEDS ADDITIONAL EXAMPLES
@end deffn

@defvr {Vari@'{a}vel de op@value{cedilha}@~{a}o} letrat
Valor padr@~{a}o: @code{false}

Quando @code{letrat} for @code{false}, @code{letsimp} simplifica o
numerador e o denominador de uma raz@~{a}o separadamente,
e n@~{a}o simplifica o quociente.

Quando @code{letrat} for @code{true},
o numerador, o denominador, e seu quocienten s@~{a}o simplificados nessa ordem.

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

@end defvr

@c NEEDS EXAMPLES
@deffn {Fun@value{cedilha}@~{a}o} letrules ()
@deffnx {Fun@value{cedilha}@~{a}o} letrules (@var{nome_pacote})
Mostra as regras em um pacote de regras.
@code{letrules ()} mostra as regras no pacote de regras corrente.
@code{letrules (@var{nome_pacote})} mostra as regras em @code{nome_pacote}.

O pacote de regras corrente @'{e} nomeado por @code{current_let_rule_package}.
Se n@~{a}o especificado de outra forma, @code{current_let_rule_package}
avalia de forma padr@~{a}o para @code{default_let_rule_package}.

Veja tamb@'{e}m @code{disprule}, que mostra regras defindas por @code{tellsimp} e @code{tellsimpafter}.
@c WHAT ABOUT defmatch AND defrule ??

@end deffn

@deffn {Fun@value{cedilha}@~{a}o} letsimp (@var{expr})
@deffnx {Fun@value{cedilha}@~{a}o} letsimp (@var{expr}, @var{nome_pacote})
@deffnx {Fun@value{cedilha}@~{a}o} letsimp (@var{expr}, @var{nome_pacote_1}, ..., @var{nome_pacote_n})
Repetidamente aplica a substitui@value{cedilha}@~{a}o definida por @code{let}
at@'{e} que nenhuma mudan@value{cedilha}a adicional seja feita para @var{expr}.

@code{letsimp (@var{expr})} usa as regras de @code{current_let_rule_package}.

@code{letsimp (@var{expr}, @var{nome_pacote})} usa as regras de @var{nome_pacote}
sem alterar @code{current_let_rule_package}.

@code{letsimp (@var{expr}, @var{nome_pacote_1}, ..., @var{nome_pacote_n})}
@'{e} equivalente a @code{letsimp (@var{expr}, @var{nome_pacote_1}},
seguido por @code{letsimp (%, @var{nome_pacote_2})}, e assim sucessivamente.

@c NEEDS EXAMPLES
@end deffn

@defvr {Vari@'{a}vel de op@value{cedilha}@~{a}o} let_rule_packages
Valor padr@~{a}o: @code{[default_let_rule_package]}

@code{let_rule_packages} @'{e} uma lista de todos os pacotes de regras @code{let} definidos pelo usu@'{a}rio
mais o pacote padr@~{a}o @code{default_let_rule_package}.

@end defvr

@deffn {Fun@value{cedilha}@~{a}o} matchdeclare (@var{a_1}, @var{pred_1}, ..., @var{a_n}, @var{pred_n})
Associa um predicado @var{pred_k} 
com uma vari@'{a}vel ou lista de vari@'{a}veis @var{a_k}
de forma que @var{a_k} coincida com express@~{o}es
para as quais o predicado retorne qualquer coisa que n@~{a}o @code{false}.

Umpredicado @'{e} o nome de uma fun@value{cedilha}@~{a}o,
ou de uma express@~{a}o lambda,
ou uma chamada de fun@value{cedilha}@~{a}o ou chamada de fun@value{cedilha}@~{a}o lambda iomitindo o @'{u}lltimo argumento,
ou @code{true} ou @code{all}.
Qualquer express@~{a}o coincide com @code{true} ou @code{all}.
Se o predicado for especificado como uma chamada de fun@value{cedilha}@~{a}o ou chamada de fun@value{cedilha}@~{a}o lambda,
a express@~{a}o a ser testada @'{e} anexada ao final da lista de argumentos;
os argumentos s@~{a}o avaliados ao mesmo tempo que a coincid@^{e}ncia @'{e} avaliada.
De outra forma, o predicado @'{e} especificado como um nome de fun@value{cedilha}@~{a}o ou express@~{a}o lambda,
e a express@~{a}o a ser testada @'{e} o argumento sozinho.
Uma fun@value{cedilha}@~{a}o predicado n@~{a}o precisa ser definida quando @code{matchdeclare} for chamada;
o predicado n@~{a}o @'{e} avaliado at@'{e} que uma coincid@^{e}ncia seja tentada.

Um predicado pode retornar uma express@~{a}o Booleana al@'{e}m de @code{true} ou @code{false}.
Express@~{o}es Booleanas s@~{a}o avaliadas por @code{is} dentro da fun@value{cedilha}@~{a}o da regra constru@'{i}da,
de forma que n@~{a}o @'{e} necess@'{a}rio chamar @code{is} dentro do predicado.

Se uma express@~{a}o satisfaz uma coincid@^{e}ncia de predicado,
a vari@'{a}vel de coincid@^{e}ncia @'{e} atribu@'{i}da @`a express@~{a}o,
exceto para vari@'{a}veis de coincid@^{e}ncia que s@~{a}o operandos de adi@value{cedilha}@~{a}o @code{+} ou multiplica@value{cedilha}@~{a}o @code{*}.
Somente adi@value{cedilha}@~{a}o e multiplica@value{cedilha}@~{a}o s@~{a}o manuseadas de forma especial;
outros operadores en@'{a}rios (ambos os definidos internamente e os definidos pelo usu@'{a}rio) s@~{a}o tratados como fun@value{cedilha}@~{o}es comuns.
@c WOULD BE GREAT TO EXTEND PART+/PART* PROCESSING TO ALL N-ARY OPERATORS

No caso de adi@value{cedilha}@~{a}o e multiplica@value{cedilha}@~{a}o,
a vari@'{a}vel de coincid@^{e}ncia pode ser atribuida a uma express@~{a}o simples que satisfaz o predicado de coincid@^{e}ncia,
ou uma adi@value{cedilha}@~{a}o ou um produto (respectivamente) de tais express@~{o}es.
Tal coincid@^{e}ncia de termo multiplo @'{e} gulosa:
predicados s@~{a}o avaliados na ordem em que suas vari@'{a}veis associadas
aparecem no modelo de coincid@^{e}ncia,
e o termo que satisfizer mais que um predicado @'{e} tomado pelo primeiro
predicado que satisfizer.
Cada predicado @'{e} testado contra todos os operandos de adi@value{cedilha}@~{a}o ou produto antes que o pr@'{o}ximo predicado seja avaliado.
Adicionalmente,
se 0 ou 1 (respectivamente) satisfazem um predicado de coincid@^{e}ncia,
e n@~{a}o existe outros termos que satisfa@value{cedilha}am o predicado,
0 ou 1 @'{e} atribu@'{i}do para a vari@'{a}vel de coincid@^{e}ncia associada com o predicado.

O algor@'{i}tmo para processar modelos contendo adi@value{cedilha}@~{a}o e multiplica@value{cedilha}@~{a}o faz alguns resultados de coincid@^{e}ncia
(por exemplo, um modelo no qual uma vari@'{a}vel "coincida com qualquer coisa" aparecer)
dependerem da ordem dos termos no modelo de coincid@^{e}ncia e na express@~{a}o a ser testada a coincid@^{e}ncia.
Todavia,
se todos os predicados de coincid@^{e}ncia s@~{a}o mutuamente exclusivos,
o resultado de coincid@^{e}ncia @'{e} insens@'{i}vel a ordena@value{cedilha}@~{a}o,
como um predicado de coincid@^{e}ncia n@~{a}o pode aceitar termos de coincid@^{e}ncia de outro.

Chamado @code{matchdeclare} com uma vari@'{a}vel @var{a} como um argumento
muda a propriedade @code{matchdeclare} para @var{a}, se a vari@'{a}vel @var{a} tiver sido declarada anteriormente;
somente o @code{matchdeclare} mais recente est@'{a} em efeito quando uma regra @'{e} definida,
mudan@value{cedilha}as posteriores para a propriedade @code{matchdeclare}
(via @code{matchdeclare} ou @code{remove})
n@~{a}o afetam regras existentes.

@code{propvars (matchdeclare)} retorna a lista de todas as vari@'{a}veis
para as quais exista uma propriedade @code{matchdeclare}.
@code{printprops (@var{a}, matchdeclare)} retorna o predicado para a vari@'{a}vel @code{a}.
@code{printprops (all, matchdeclare)} retorna a lista de predicados para todas as vari@'{a}veis @code{matchdeclare}.
@code{remove (@var{a}, matchdeclare)} remove a propriedade @code{matchdeclare} da vari@'{a}vel @var{a}.

As fun@value{cedilha}@~{o}es
@code{defmatch}, @code{defrule}, @code{tellsimp}, @code{tellsimpafter}, e @code{let}
constroem regras que testam express@~{o}es contra modelos.

@code{matchdeclare} coloca ap@'{o}strofo em seus argumentos.
@code{matchdeclare} sempre retorna @code{done}.

Exemplos:

Um predicado @'{e} o nome de uma fun@value{cedilha}@~{a}o,
ou uma express@~{a}o lambda,
ou uma chamada de fun@value{cedilha}@~{a}o ou chamada a fun@value{cedilha}@~{a}o lambda omitindo o @'{u}ltimo argumento,
or @code{true} or @code{all}.

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

Se uma express@~{a}o satisfaz um predicado de coincid@^{e}ncia,
a vari@'{a}vel de coincid@^{e}ncia @'{e} atribu@'{i}da @`a express@~{a}o.

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

No caso de adi@value{cedilha}@~{a}o e multiplica@value{cedilha}@~{a}o,
@`a vari@'{a}vel de coincid@^{e}ncia pode ser atribu@'{i}da uma express@~{a}o simples que satisfaz o predicado de coincid@^{e}ncia,
ou um somat@'{o}rio ou produt@'{o}rio (respectivamente) de tais express@~{o}es.

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

Quando coincidindo argumentos de @code{+} e @code{*},
se todos os predicados de coincid@^{e}ncia forem mutuamente exclusivos,
o resultado da coincid@^{e}ncia @'{e} insens@'{i}ve @`a ordena@value{cedilha}@~{a}o,
como um predicado de coincid@^{e}ncia n@~{a}o pode aceitar termos que coincidiram com outro.

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

As fun@value{cedilha}@~{o}es @code{propvars} e @code{printprops} retornam informa@value{cedilha}@~{o}es sobre vari@'{a}vels de coincid@^{e}ncia.

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

@end deffn

@deffn {Fun@value{cedilha}@~{a}o} matchfix (@var{delimitador_e}, @var{delimitador_d})
@deffnx {Fun@value{cedilha}@~{a}o} matchfix (@var{delimitador_e}, @var{delimitador_d}, @var{arg_pos}, @var{pos})
Declara um operador @code{matchfix} com delimitadores esquerdo e direito @var{delimitador_e} e @var{delimitador_d}.
Os delimitadores s@~{a}o especificados como seq@"{u}@^{e}cias de caracteres.

Um operador "matchfix" @'{e} uma fun@value{cedilha}@~{a}o que aceita qualquer n@'{u}mero de argumentos,
tal que os argumentos ocorram entre os delimitadores correspondentes esquerdo e direito.
Os delimitadores podem ser quaisquer seq@"{u}@^{e}cias de caracteres, contanto que o analisador de express@~{o}es do Maxima possa
disting@"{u}ir os delimitadores dos operandos 
e de outras express@~{o}es e operadores.
Na pr@'{a}tica essas regras excluem delimitadores n@~{a}o analis@'{a}veis tais como
@code{%}, @code{,}, @code{$} e @code{;}, 
e pode ser necess@'{a}rio isolar os delimitadores com espa@value{cedilha}os em branco.
O delimitador da direita pode ser o mesmo ou diferente do delimitador da esquerda.

Um delimitador esquerdo pode ser associado com somente um delimitador direito;
dois diferentes operadores @code{matchfix} n@~{a}o podem ter o mesmo delimitador esquerdo.

Um operador existente pode ser redeclarado com um operador @code{matchfix}
sem alterar suas outras propriedades.
Particularmente, operadores internos tais como adi@value{cedilha}@~{a}o @code{+} podem
ser declarados @code{matchfix},
mas fun@value{cedilha}@~{o}es operadores n@~{a}o podem ser definidas para operadores internos.

@code{matchfix (@var{delimitador_e}, @var{delimitador_d}, @var{arg_pos}, @var{pos})} 
declara o argumento @var{arg_pos} como sendo um entre: express@~{a}o l@'{o}gica,
express@~{a}o comum do Maxima mas que n@~{a}o seja do tipo anterior, e qualquer outro
tipo de express@~{a}o que n@~{a}o esteja inclu@'{i}da nos dois primeiros tipos.
Essa declara@value{cedilha}@~{a}o resulta em @var{pos} sendo um entre: express@~{a}o l@'{o}gica,
express@~{a}o comum do Maxima mas que n@~{a}o seja do tipo anterior, e qualquer outro
tipo de express@~{a}o que n@~{a}o esteja inclu@'{i}da nos dois primeiros tipos 
e os delimitadores @var{delimitador_e} e @var{delimitador_d}.

@c DUNNO IF WE REALLY NEED TO MENTION BINDING POWER HERE -- AS NOTED IT'S IRRELEVANT
@c An operator declared by @code{matchfix} is assigned a low binding power.
@c Since a matchfix operator must be evaluated before any expression
@c which contains it,
@c binding power is effectively irrelevant
@c to the declaration of a matchfix operator.

A fun@value{cedilha}@~{a}o para realizar uma opera@value{cedilha}@~{a}o @code{matchfix} @'{e} uma fun@value{cedilha}@~{a}o
comum definida pelo usu@'{a}rio.
A fun@value{cedilha}@~{a}o operador @'{e} definida
da forma usual
com o operador de defini@value{cedilha}@~{a}o de fun@value{cedilha}@~{a}o @code{:=} ou @code{define}.
Os argumentos podem ser escritos entre os delimitadores,
ou com o delimitador esquerdo com uma seq@"{u}@^{e}ncia de caracteres com ap@'{o}strofo e os argumentos
seguindo entre par@^{e}ntesis.
@code{dispfun (@var{delimitador_e})} mostra a defini@value{cedilha}@~{a}o da fun@value{cedilha}@~{a}o operador.

O @'{u}nico operador interno @code{matchfix} @'{e} o construtor de listas @code{[ ]}.
Par@^{e}ntesis @code{( )} e aspas duplas @code{" "} 
atuam como operadores @code{matchfix},
mas n@~{a}o s@~{a}o tratados como tal pelo analisador do Maxima.

@code{matchfix} avalia seus argumentos.
@code{matchfix} retorna seu primeiro argumento, @var{delimitador_e}.
@c HOW TO TAKE AWAY THE MATCHFIX PROPERTY ??

Exemplos:

@itemize @bullet
@item
Delimitadores podem ser quase quaisquer seq@"{u}@^{e}ncia de caracteres.
@end itemize
@c ===beg===
@c matchfix ("@@", "~");
@c @@ a, b, c ~;
@c matchfix (">>", "<<");
@c >> a, b, c <<;
@c matchfix ("foo", "oof");
@c foo a, b, c oof;
@c >> w + foo x, y oof + z << / @@ p, q ~;
@c ===end===
@example
(%i1) matchfix ("@@@@", "~");
(%o1)                          @@@@
(%i2) @@@@ a, b, c ~;
(%o2)                      @@@@a, b, c~
(%i3) matchfix (">>", "<<");
(%o3)                          >>
(%i4) >> a, b, c <<;
(%o4)                      >>a, b, c<<
(%i5) matchfix ("foo", "oof");
(%o5)                          foo
(%i6) foo a, b, c oof;
(%o6)                     fooa, b, coof
(%i7) >> w + foo x, y oof + z << / @@@@ p, q ~;
                     >>z + foox, yoof + w<<
(%o7)                ----------------------
                            @@@@p, q~
@end example

@itemize @bullet
@item
Operadores @code{matchfix} s@~{a}o fun@value{cedilha}@~{o}es comuns definidas pelo usu@'{a}rio.
@end itemize
@example
(%i1) matchfix ("!-", "-!");
(%o1)                         "!-"
(%i2) !- x, y -! := x/y - y/x;
                                    x   y
(%o2)                   !-x, y-! := - - -
                                    y   x
(%i3) define (!-x, y-!, x/y - y/x);
                                    x   y
(%o3)                   !-x, y-! := - - -
                                    y   x
(%i4) define ("!-" (x, y), x/y - y/x);
                                    x   y
(%o4)                   !-x, y-! := - - -
                                    y   x
(%i5) dispfun ("!-");
                                    x   y
(%t5)                   !-x, y-! := - - -
                                    y   x

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

@end deffn

@c NEEDS CLARIFICATION AND EXAMPLES
@deffn {Fun@value{cedilha}@~{a}o} remlet (@var{prod}, @var{nome})
@deffnx {Fun@value{cedilha}@~{a}o} remlet ()
@deffnx {Fun@value{cedilha}@~{a}o} remlet (all)
@deffnx {Fun@value{cedilha}@~{a}o} remlet (all, @var{nome})
Apaga a regra de substitui@value{cedilha}ao, prod --> repl, mais
recentemente definida atrav@'{e}s dea fun@value{cedilha}@~{a}o @code{let}.  Se @code{nome} for fornecido a regra @'{e}
apagada do pacote de regras chamado @code{nome}.

@code{remlet()} e @code{remlet(all)} apagam todas as regras de substitui@value{cedilha}@~{a}o do pacote de regras corrente.
Se o nome de um pacote de regras for fornecido,
e.g. @code{remlet (all, @var{nome})}, o pacote de regras @var{nome} @'{e} tamb@'{e}m apagado.

Se uma substitui@value{cedilha}@~{a}o @'{e} para ser mudada usando o mesmo
produto, @code{remlet} n@~{a}o precisa ser chamada, apenas redefina a substitui@value{cedilha}@~{a}o
usando o mesmo produto (literalmente) com a fun@value{cedilha}@~{a}o @code{let} e a nova
substitui@value{cedilha}@~{a}o e/ou nome de predicado.  Pode agora @code{remlet (@var{prod})} ser
chamada e a regra de substitui@value{cedilha}@~{a}o original @'{e} ressuscitada.

Veja tamb@'{e}m @code{remrule}, que remove uma regra definida atrav@'{e}s de @code{tellsimp} ou de @code{tellsimpafter}.

@end deffn

@deffn {Fun@value{cedilha}@~{a}o} remrule (@var{op}, @var{nomeregra})
@deffnx {Fun@value{cedilha}@~{a}o} remrule (@var{op}, all)
Remove regras definidas por @code{tellsimp}, ou @code{tellsimpafter}.

@code{remrule (@var{op}, @var{nomeregra})}
remove a regra com o nome @code{nomeregra} do operador @var{op}.
Quando @var{op} for um operador interno ou um operador definido pelo usu@'{a}rio
(como definido por @code{infix}, @code{prefix}, etc.),
@var{op} e @var{rulename} devem ser colocados entre aspas duplas.

@code{remrule (@var{op}, all)} remove todas as regras para o operador @var{op}.

Veja tamb@'{e}m @code{remlet}, que remove uma regra definida atrav@'{e}s de @code{let}.

Examples:

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

@end deffn

@c NEEDS EXPANSION OR MAYBE JUST APPROPRIATE REFS TO tellsimpafter
@deffn {Fun@value{cedilha}@~{a}o} tellsimp (@var{pattern}, @var{replacement})
@'{e} similar a @code{tellsimpafter} mas coloca
nova informa@value{cedilha}@~{a}o antes da antiga de forma que essa nova regra seja aplicada antes das regras
de simplifica@value{cedilha}@~{a}o internas.

@code{tellsimp} @'{e} usada quando for importante modificar
a express@~{a}o antes que o simplificador trabalhe sobre ela, por exemplo se o
simplificador "sabe" alguma coisa sobre a express@~{a}o, mas o que ele retorna
n@~{a}o @'{e} para sua aprecia@value{cedilha}@~{a}o.
Se o simplificador "sabe" alguma coisa sobre o
principal operador da express@~{a}o, mas est@'{a} simplesmente escondendo de
voc@^{e}, voc@^{e} provavelmente quer usar @code{tellsimpafter}.

O modelo pode n@~{a}o ser uma
adi@value{cedilha}@~{a}o, um produto, vari@'{a}vel simples, ou n@'{u}mero.

@code{rules} @'{e} a lista de regras definidas por
@code{defrule}, @code{defmatch}, @code{tellsimp}, e @code{tellsimpafter}.

Exemplos:

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

@end deffn

@deffn {Fun@value{cedilha}@~{a}o} tellsimpafter (@var{modelo}, @var{substitui@value{cedilha}@~{a}o})
Define a uma regra de simplifica@value{cedilha}@~{a}o que o simplificador do Maxima
aplica ap@'{o}s as regras de simplifica@value{cedilha}@~{a}o internas.
@var{modelo} @'{e} uma express@~{a}o, compreendendo vari@'{a}veis de modelo (declaradas atrav@'{e}s de @code{matchdeclare})
e outros @'{a}tomos e opera@value{cedilha}@~{o}es, considerados literais para o prop@'{o}sito de coincid@^{e}ncia de modelos.
@var{substitui@value{cedilha}@~{a}o} @'{e} substitu@'{i}da para uma express@~{a}o atual que coincide com @var{modelo};
vari@'{a}veis de modelo em @var{substitui@value{cedilha}@~{a}o} s@~{a}o atribuidas a valores coincidentes na express@~{a}o atual.

@var{modelo} pode ser qualquer express@~{a}o n@~{a}o at@^{o}mica
na qual o principal operador n@~{a}o @'{e} uma vari@'{a}vel de modelo;
a regra de simplifica@value{cedilha}@~{a}o est@'{a} associada com o operador principal.
Os nomes de fun@value{cedilha}@~{o}es (com uma excess@~{a}o, descrita abaixo), listas, e arrays
podem aparecer em @var{modelo} como o principal operador somente como literais (n@~{a}o vari@'{a}veis de modelo);
essas regras fornecem express@~{o}es tais como @code{aa(x)} e @code{bb[y]} como modelos,
se @code{aa} e @code{bb} forem vari@'{a}veis de modelo.
Nomes de fun@value{cedilha}@~{o}es, listas, e arrays que s@~{a}o vari@'{a}veis de modelo podem aparecer como operadores
outros que n@~{a}o o operador principal em @var{modelo}.

Existe uma excess@~{a}o para o que foi dito acima com rela@value{cedilha}@~{a}o a regras e nomes de fun@value{cedilha}@~{o}es.
O nome de uma fun@value{cedilha}@~{a}o subscrita em uma express@~{a}o tal como @code{aa[x](y)}
pode ser uma vari@'{a}vel de modelo,
porque o operador principal n@~{a}o @'{e} @code{aa} mas ao contr@'{a}rio o @'{a}tomo Lisp @code{mqapply}.
Isso @'{e} uma conseq@"{u}@^{e}ncia da representa@value{cedilha}@~{a}o de express@~{o}es envolvendo fun@value{cedilha}@~{o}es subscritas.

@c LET'S NOT GO INTO DETAILS ABOUT MAIN OPERATORS HERE; BUT PRESERVE THIS FOR REFERENCE
@c The main operator of an expression @code{expr} is @code{caar $expr}.
@c For most kinds of expressions,
@c the main operator is the operator returned by @code{op (@var{pattern})};
@c the sole exception is the operator @code{mqapply},
@c which appears in indexed function expressions (e.g., @code{foo[i](x)}).

@c NEED TO REVIEW THIS PARAGRAPH FOR ACCURACY
Regras de simplifica@value{cedilha}@~{a}o s@~{a}o aplicadas ap@'{o}s avalia@value{cedilha}@~{a}o 
(se n@~{a}o suprimida atrav@'{e}s de coloca@value{cedilha}@~{a}o de ap@'{o}strofo ou do sinalizador @code{noeval}).
Regras estabelecidas por @code{tellsimpafter} s@~{a}o aplicadas na ordem em que forem definidas,
e ap@'{o}s quaisquer regras internas.
Regras s@~{a}o aplicadas de baixo para cima, isto @'{e},
aplicadas primeiro a subexpress@~{o}es antes de ser aplicada @`a express@~{a}o completa.
@c NO IT IS MORE COMPLICATED THAN THIS, ALTHOUGH IN SOME CIRCUMSTANCE IT APPEARS TO BE THE CASE:
@c For a given expression, at most one rule per operator is applied.
Isso pode ser necess@'{a}rio para repetidamente simplificar um resultado
(por exemplo, via o operador ap@'{o}strofo-ap@'{o}strofo @code{'@w{}'} ou o sinalizador @code{infeval})
para garantir que todas as regras s@~{a}o aplicadas.

Vari@'{a}veis de modelo s@~{a}o tratadas como vari@'{a}veis locais em regras de simplifica@value{cedilha}@~{a}o.
Assim que uma regra @'{e} definida, o valor de uma vari@'{a}vel de modelo
n@~{a}o afeta a regra, e n@~{a}o @'{e} afetado pela regra.
Uma atribui@value{cedilha}@~{a}o para uma vari@'{a}vel de modelo que resulta em uma coincid@^{e}ncia de regra com sucesso
n@~{a}o afeta a atribui@value{cedilha}@~{a}o corrente (ou necessita disso) da vari@'{a}vel de modelo.
Todavia,
como com todos os @'{a}tomos no Maxima,
as propriedades de vari@'{a}veis de modelo (como declarado por @code{put} e fun@value{cedilha}@~{o}es relacionadas) s@~{a}o globais.

A regra constru@'{i}da por @code{tellsimpafter} @'{e} nomeada ap@'{o}s o operador principal de @code{modelo}.
Regras para operadores internos, 
e operadores definidos pelo usu@'{a}rio 
definidos por meio de @code{infix}, @code{prefix}, @code{postfix}, @code{matchfix}, e @code{nofix},
possuem nomes que s@~{a}o seq@"{u}@^{e}ncias de caracteres do Maxima.
@c SLIGHTLY TOO MUCH DETAIL
@c (that is, the name begins with ampersand @code{&}).
Regras para outras fun@value{cedilha}@~{o}es possuem nomes que s@~{a}o identificadores comuns do Maxima.
@c SLIGHTLY TOO MUCH DETAIL
@c (that is, the name begins with dollar sign @code{$}).

O tratamento de substantivos e formas verbais @'{e} desprez@'{i}velmente confuso. @c THIS IS A BUG.
Se uma regra @'{e} definida para uma forma substantiva (ou verbal)
e uma regra para o verbo correspondente (ou substantivo) j@'{a} existe, 
ent@~{a}o a nova regra definida aplica-se a ambas as formas (substantiva e verbal).
Se uma regra para a correspondente forma verbal (ou substantiva) n@~{a}o existe,
a nova regra definida aplicar-se-@'{a} somente para a forma substantiva (ou verbal).

A regra constru@'{i}da atrav@'{e}s de @code{tellsimpafter} @'{e} uma fun@value{cedilha}@~{a}o Lisp comum.
Se o nome da regra for @code{$foorule1},
a constru@value{cedilha}@~{a}o @code{:lisp (trace $foorule1)} rastreia a fun@value{cedilha}@~{a}o,
e @code{:lisp (symbol-function '$foorule1} mostra sua defini@value{cedilha}@~{a}o.

@code{tellsimpafter} n@~{a}o avalia seus argumentos.
@code{tellsimpafter} retorna a lista de regras para o operador principal de @var{modelo},
incluindo a mais recente regra estabelecia.
@c WHAT IS simpfoo THAT SOMETIMES APPEARS, AND WHY DOES false SOMETIMES APPEAR IN RETURN VALUE ??

Veja tamb@'{e}m @code{matchdeclare}, @code{defmatch}, @code{defrule}, @code{tellsimp}, @code{let},
@code{kill}, @code{remrule}, e @code{clear_rules}.

Exemplos:

@var{modelo} pode ser qualquer express@~{a}o n@~{a}o at@^{o}mica na qual o 
principal operador n@~{a}o @'{e} uma vari@'{a}vel de modelo.

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

Regras s@~{a}o aplicadas na ordem em que forem definidas.
Se duas regras podem coincidir com uma express@~{a}o,
a regra que foi primeiro definida @'{e} a que ser@'{a} aplicada.

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

vari@'{a}veis de modelo s@~{a}o tratadas como vari@'{a}veis locais em regras de simplifica@value{cedilha}@~{a}o.
(Compare a @code{defmatch}, que trata vari@'{a}veis de modelo como vari@'{a}veis globais.)

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

Como com todos os @'{a}tomos, propriedades de vari@'{a}veis de modelo s@~{a}o globais embora valores sejam locais.
Nesse exemplo, uma propriedade de atribui@value{cedilha}@~{a}o @'{e} declarada via @code{define_variable}.
Essa @'{e} a propriedade do @'{a}tomo @code{bb} atrav@'{e}s de todo o Maxima.

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

Regras s@~{a}o nomeadas ap@'{o}s operadores principais.
Nomes de regras para operadores internos e operadores definidos pelo usu@'{a}rio s@~{a}o seq@"{u}@^{e}ncias de caracteres,
enquanto nomes para outras fun@value{cedilha}@~{o}es s@~{a}o identificadores comuns.

@c ===beg===
@c tellsimpafter (foo (%pi + %e), 3*%pi);
@c tellsimpafter (foo (%pi * %e), 17*%e);
@c tellsimpafter (foo (%i ^ %e), -42*%i);
@c tellsimpafter (foo (9) + foo (13), quux (22));
@c tellsimpafter (foo (9) * foo (13), blurf (22));
@c tellsimpafter (foo (9) ^ foo (13), mumble (22));
@c rules;
@c foorule_name: first (%o1);
@c plusrule_name: first (%o4);
@c [?mstringp (foorule_name), symbolp (foorule_name)];
@c [?mstringp (plusrule_name), symbolp (plusrule_name)];
@c remrule (foo, foorule1);
@c remrule ("^", "^rule1");
@c ===end===
@example
(%i1) tellsimpafter (foo (%pi + %e), 3*%pi);
(%o1)                   [foorule1, false]
(%i2) tellsimpafter (foo (%pi * %e), 17*%e);
(%o2)              [foorule2, foorule1, false]
(%i3) tellsimpafter (foo (%i ^ %e), -42*%i);
(%o3)         [foorule3, foorule2, foorule1, false]
(%i4) tellsimpafter (foo (9) + foo (13), quux (22));
(%o4)                   [+rule1, simplus]
(%i5) tellsimpafter (foo (9) * foo (13), blurf (22));
(%o5)                  [*rule1, simptimes]
(%i6) tellsimpafter (foo (9) ^ foo (13), mumble (22));
(%o6)                  [^rule1, simpexpt]
(%i7) rules;
(%o7) [trigrule0, trigrule1, trigrule2, trigrule3, trigrule4, 
htrigrule1, htrigrule2, htrigrule3, htrigrule4, foorule1, 
foorule2, foorule3, +rule1, *rule1, ^rule1]
(%i8) foorule_name: first (%o1);
(%o8)                       foorule1
(%i9) plusrule_name: first (%o4);
(%o9)                        +rule1
(%i10) [?mstringp (foorule_name), symbolp (foorule_name)];
(%o10)                    [false, true]
(%i11) [?mstringp (plusrule_name), symbolp (plusrule_name)];
(%o11)                    [true, true]
(%i12) remrule (foo, foorule1);
(%o12)                         foo
(%i13) remrule ("^", "^rule1");
(%o13)                          ^
@end example

Um exemplo trabalhado: multiplica@value{cedilha}@~{a}o anticomutativa.

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

@end deffn

@deffn {Fun@value{cedilha}@~{a}o} clear_rules ()
Executa @code{kill (rules)} e ent@~{a}o re-escolhe o pr@'{o}ximo n@'{u}mero de regra para 1
para adi@value{cedilha}@~{a}o @code{+}, multiplica@value{cedilha}@~{a}o @code{*}, e exponencia@value{cedilha}@~{a}o @code{^}.

@end deffn

