@c English version 2011-09-03
@menu
* Introducción a los operadores::
* Operadores aritméticos::
* Operadores relacionales::
* Operadores lógicos::
* Operadores para ecuaciones::
* Operadores de asignación::
* Operadores definidos por el usuario::
@end menu

@node Introducción a los operadores, Operadores aritméticos, Operadores, Operadores
@section Introducción a los operadores

Maxima reconoce los operadores aritméticos, relacionales y lógicos
usuales de la matemática. Además, Maxima dispone de operadores para
la asignación de valores a variables y la definición de funciones.
La siguiente tabla muestra los operadores que se describen en este
capítulo, en la que se incluye el nombre del operador,
el rango de enlace por la izquierda @code{lbp}, el rango de enlace
por la derecha @code{rbp}, el tipo de operador y un ejemplo, para
finalizar, en cada caso, con su formato interno tal como 
es leída por el analizador sintáctico.

@verbatim

Operador  lbp rbp  Tipo     Ejemplo  Formato interno
                       
   +      100 134  nary     a+b      ((mplus) $A $B)
   -      100 134  prefix   -a       ((mminus) $A)
   *      120      nary     a*b      ((mtimes) $A $B)
   /      120 120  infix    a/b      ((mquotient) $A $B)
   ^      140 139  infix    a^b      ((mexpt) $A $B)
   **     140 139  infix    a**b     ((mexpt) $A $B)
   ^^     140 139  infix    a^^b     ((mncexpt) $A $B)
   .      130 129  infix    a.b      ((mnctimes) $A $B)
                                     
   <       80  80  infix    a<b      ((mlessp) $A $B)
   <=      80  80  infix    a<=b     ((mleqp) $A $B)
   >       80  80  infix    a>b      ((mqreaterp) $A $B)
   >=      80  80  infix    a>=b     ((mgeqp) $A $B)
                                     
   not         70  prefix   not a    ((mnot) $A)
   and     65      nary     a and b  ((mand) $A $B)
   or      60      nary     a or b   ((mor) $A $B)
                                     
   #       80  80  infix    a#b      ((mnotequal) $A $B)
   =       80  80  infix    a=b      ((mequal) $A $B)
                                     
   :      180  20  infix    a:b      ((msetq) $A $B)
   ::     180  20  infix    a::b     ((mset) $A $B)
   :=     180  20  infix    a:=b     ((mdefine) $A $B)
   ::=    180  20  infix    a::=b    ((mdefmacro) $A $B)

@end verbatim

Con los rangos de enlace de los operadores se definen las reglas de prioridad de 
cálculo de los mismos. Así, por ejemplo, el analizador
sintáctico interpreta la expresión @code{ a + b * c } como
@code{ a + (b * c) }, pues el rango de enlace por la izquierda de la
multiplicación es mayor que rango de enlace por la izquierda de la
suma.

Maxima clasifica los operadores de la siguiente manera:

@table @emph
@item Prefijo (prefix)
Los operadores prefijos son unarios con un único operando que
se escribe a continuación del operando. Ejemplos son @code{-} y @code{not}.
@item Sufijo (postfix)
Los operadores sufijos son unarios con un único operando que
se escribe precediendo al operando. Un ejemplo es el factorial @code{!}.
@item Infijo (infix)
Los operadores infijos son operadores binarios que necesitan dos operandos,
los cuales se colocan uno a cada lado del operador. Ejemplos son el operador
para la exponenciación, @code{^}, y el operador de asignación, @code{:}.
@item N-ario (n-ary)
Los operadores n-arios admiten un número arbitrario de operandos. Son
ejemplos la multiplicación, @code{*}, y la suma, @code{+}.
@item Acotador (matchfix)
Los acotadores son operadores que se utilizan para establecer el comienzo
y final de una lista de operandos. Los operadores @code{[} y @code{]} son
ejemplos de acotadores, que se utilizan para definir una lista tal como
@code{[a, b, ...]}.
@item No-fijo (nofix)
Un operador no-fijo carece de operandos. Maxima no tiene operadores internos
no-fijos, pero se pueden crear como cuando se escribe @code{nofix(quit)},
lo que permite obviar el uso de paréntesis, y utilizar simplemente @code{quit}
en lugar de @code{quit()}, para cerrar una sesión de Maxima.
@end table

En la sección dedicada a los operadores definidos por el usuario
se describe cómo redefinir los operadores internos de Maxima y cómo
crear otros nuevos.

El mecanismo para definir un nuevo operador es sencillo.
Tan solo es necesario declarar una función como operador;
la función operador puede estar definida o no.

Un ejemplo de operador definido por el usuario es el siguiente.
Nótese que la llamada a función @code{"dd" (a)} equivale a @code{dd a},
de igual manera que  @code{"<-" (a, b)} también equivale a @code{a <- b}.
Nótese también que las funciones @code{"dd"} y @code{"<-"} no están definidas en este ejemplo.

@c ===beg===
@c prefix ("dd");
@c dd a;
@c "dd" (a);
@c infix ("<-");
@c a <- dd b;
@c "<-" (a, "dd" (b));
@c ===end===
@example
(%i1) prefix ("dd");
(%o1)                          dd
(%i2) dd a;
(%o2)                         dd a
(%i3) "dd" (a);
(%o3)                         dd a
(%i4) infix ("<-");
(%o4)                          <-
(%i5) a <- dd b;
(%o5)                      a <- dd b
(%i6) "<-" (a, "dd" (b));
(%o6)                      a <- dd b
@end example

La tabla anterior no incluye todos los operadores definidos en Maxima,
ya que también lo son @code{!} para el factorial, @code{for}, @code{do} y
@code{while} para programar bucles, o @code{if}, @code{then} y @code{else}
para definir condicionales.

Las funciones @code{remove} y @code{kill} eliminan propiedades de operadores de un átomo.
La llamada @code{remove ("@var{a}", op)} sólo elimina las propiedades de operador de @var{a}.
La llamada @code{kill ("@var{a}")} elimina todas las propiedades de @var{a}, incluidas las propiedades de operador.
Nótese que el nombre del operador debe ir entre comillas.

@c MAYBE COPY THIS EXAMPLE TO remove AND/OR kill
@c ===beg===
@c infix ("##");
@c "##" (a, b) := a^b;
@c 5 ## 3;
@c remove ("##", op);
@c 5 ## 3;
@c "##" (5, 3);
@c infix ("##");
@c 5 ## 3;
@c kill ("##");
@c 5 ## 3;
@c "##" (5, 3);
@c ===end===
@example
(%i1) infix ("##");
(%o1)                          ##
(%i2) "##" (a, b) := a^b;
                                     b
(%o2)                     a ## b := a
(%i3) 5 ## 3;
(%o3)                          125
(%i4) remove ("##", op);
(%o4)                         done
(%i5) 5 ## 3;
Incorrect syntax: # is not a prefix operator
5 ##
  ^
(%i5) "##" (5, 3);
(%o5)                          125
(%i6) infix ("##");
(%o6)                          ##
(%i7) 5 ## 3;
(%o7)                          125
(%i8) kill ("##");
(%o8)                         done
(%i9) 5 ## 3;
Incorrect syntax: # is not a prefix operator
5 ##
  ^
(%i9) "##" (5, 3);
(%o9)                       ##(5, 3)
@end example










@node Operadores aritméticos, Operadores relacionales, Introducción a los operadores, Operadores
@section Operadores aritméticos


@deffn {Operador} +
@ifinfo
@fnindex Suma
@end ifinfo
@deffnx {Operador} -
@ifinfo
@fnindex Resta
@end ifinfo
@deffnx {Operador} *
@ifinfo
@fnindex Multiplicación
@end ifinfo
@deffnx {Operador} /
@ifinfo
@fnindex División
@end ifinfo
@deffnx {Operador} ^
@ifinfo
@fnindex Exponenciación
@end ifinfo

Los símbolos @code{+} @code{*} @code{/} y @code{^} representan
la suma, resta, multiplicación, división y exponenciación, respectivamente.
Los nombres de estos operadores son @code{"+"} @code{"*"} @code{"/"} y @code{"^"},
que pueden aparecer allá donde se requiera el nombre de una función u operador.

Los símbolos @code{+} y @code{-} representan el positivo y negativo unario,
siendo los nombres de estos operadores @code{"+"} y @code{"-"}, respectivamente.

En Maxima, la resta @code{a - b} se representa como la suma @code{a + (- b)}.
Expresiones tales como @code{a + (- b)} se muestran como restas. Maxima
reconoce @code{"-"} tan solo como el operador de negación unaria, no como
el nombre del operador de resta binaria.

La división @code{a / b} se representa en maxima como la multiplicación
@code{a * b^(- 1)}. Expresiones tales como @code{a * b^(- 1)} se muestran 
como divisiones. Maxima reconoce @code{"/"} como el nombre del operador
de división.

La suma y la multiplicación son operadores conmutativos n-arios. La 
división y la exponenciación son operadores no conmutativos binarios.

Maxima ordena los operandos de los operadores conmutativos para
formar lo que se conoce como representación canónica. A efectos de
almacenamiento interno, la ordenación viene determinada por @code{orderlessp}.
A efectos de presentación de las expresiones, la ordenación de la suma
la determina @code{ordergreatp}, y en el caso de la multiplicación, la
ordenación coincide con la del almacenamiento interno.

Los cálculos aritméticos se realizan con números literales
(enteros, racionales, decimales ordinarios y decimales grandes).
Excepto en el caso de la exponenciación, todas las operaciones
aritméticas con números dan lugar a resultados en forma de
números. La exponenciación da como resultado un número
si alguno de los operandos es decimal ordinario o grande (@i{bigfloat}),
o si el resultado es un entero o racional; en caso contrario,
la exponenciación puede expresarse como una raíz
cuadrada (@code{sqrt}), como otra potencia, o simplemente no
sufre cambios.

Se produce contagio de los decimales en coma flotante en los
cálculos aritméticos: si algún operando es un número decimal
grande (@i{bigfloat}), el resultado será también un número
decimal grande; no habiendo decimales grandes, pero sí
ordinarios, el resultado srá también un decimal ordinario; de no
haber operandos decimales, el resultado será un número racional o
entero. 

Los cálculos aritméticos son simplificaciones, no evaluaciones, por lo
que se realizan en expresiones comentadas.

Las operaciones aritméticas se aplican elemento a elemento en el
caso de las listas cuando la variable global @code{listarith} vale @code{true};
pero en el caso de las matrices, siempre se aplican elemento a elemento.
Cuando un operando es una lista o matriz y otro operando lo es de otro tipo
cualquiera, éste se combina con cada uno de los elementos de la lista o
matriz.

Ejemplos:

La suma y la multiplicación son operadores conmutativos n-arios.
Maxima ordena los operandos para formar lo que se conoce como 
representación canónica. Los nombres de estos operadores son
@code{"+"} y @code{"-"}.
@c ===beg===
@c c + g + d + a + b + e + f;
@c [op (%), args (%)];
@c c * g * d * a * b * e * f;
@c [op (%), args (%)];
@c apply ("+", [a, 8, x, 2, 9, x, x, a]);
@c apply ("*", [a, 8, x, 2, 9, x, x, a]);
@c ===end===

@example
(%i1) c + g + d + a + b + e + f;
(%o1)               g + f + e + d + c + b + a
(%i2) [op (%), args (%)];
(%o2)              [+, [g, f, e, d, c, b, a]]
(%i3) c * g * d * a * b * e * f;
(%o3)                     a b c d e f g
(%i4) [op (%), args (%)];
(%o4)              [*, [a, b, c, d, e, f, g]]
(%i5) apply ("+", [a, 8, x, 2, 9, x, x, a]);
(%o5)                    3 x + 2 a + 19
(%i6) apply ("*", [a, 8, x, 2, 9, x, x, a]);
                                 2  3
(%o6)                       144 a  x
@end example

La división y la exponenciación son operadores no conmutativos binarios.
Los nombres de estos operadores son @code{"/"} y @code{"^"}.
@c ===beg===
@c [a / b, a ^ b];
@c [map (op, %), map (args, %)];
@c [apply ("/", [a, b]), apply ("^", [a, b])];
@c ===end===

@example
(%i1) [a / b, a ^ b];
                              a   b
(%o1)                        [-, a ]
                              b
(%i2) [map (op, %), map (args, %)];
(%o2)              [[/, ^], [[a, b], [a, b]]]
(%i3) [apply ("/", [a, b]), apply ("^", [a, b])];
                              a   b
(%o3)                        [-, a ]
                              b
@end example

La resta y la división se representan internamente en
términos de la suma y multiplicación, respectivamente.
@c ===beg===
@c [inpart (a - b, 0), inpart (a - b, 1), inpart (a - b, 2)];
@c [inpart (a / b, 0), inpart (a / b, 1), inpart (a / b, 2)];
@c ===end===

@example
(%i1) [inpart (a - b, 0), inpart (a - b, 1), inpart (a - b, 2)];
(%o1)                      [+, a, - b]
(%i2) [inpart (a / b, 0), inpart (a / b, 1), inpart (a / b, 2)];
                                   1
(%o2)                       [*, a, -]
                                   b
@end example

Los cálculos se realizan con números literales.
Se produce el contagio de los números decimales.
@c ===beg===
@c 17 + b - (1/2)*29 + 11^(2/4);
@c [17 + 29, 17 + 29.0, 17 + 29b0];
@c ===end===

@example
(%i1) 17 + b - (1/2)*29 + 11^(2/4);
                                       5
(%o1)                   b + sqrt(11) + -
                                       2
(%i2) [17 + 29, 17 + 29.0, 17 + 29b0];
(%o2)                   [46, 46.0, 4.6b1]
@end example

Los cálculos aritméticos son una simplificación, no una
evaluación.
@c ===beg===
@c simp : false;
@c '(17 + 29*11/7 - 5^3);
@c simp : true;
@c '(17 + 29*11/7 - 5^3);
@c ===end===

@example
(%i1) simp : false;
(%o1)                         false
(%i2) '(17 + 29*11/7 - 5^3);
                              29 11    3
(%o2)                    17 + ----- - 5
                                7
(%i3) simp : true;
(%o3)                         true
(%i4) '(17 + 29*11/7 - 5^3);
                                437
(%o4)                         - ---
                                 7
@end example

Los cálculos aritméticos se realizan elemento a elemento 
en las listas (según sea el valor de @code{listarith}) y
matrices.
@c ===beg===
@c matrix ([a, x], [h, u]) - matrix ([1, 2], [3, 4]);
@c 5 * matrix ([a, x], [h, u]);
@c listarith : false;
@c [a, c, m, t] / [1, 7, 2, 9];
@c [a, c, m, t] ^ x;
@c listarith : true;
@c [a, c, m, t] / [1, 7, 2, 9];
@c [a, c, m, t] ^ x;
@c ===end===

@example
(%i1) matrix ([a, x], [h, u]) - matrix ([1, 2], [3, 4]);
                        [ a - 1  x - 2 ]
(%o1)                   [              ]
                        [ h - 3  u - 4 ]
(%i2) 5 * matrix ([a, x], [h, u]);
                          [ 5 a  5 x ]
(%o2)                     [          ]
                          [ 5 h  5 u ]
(%i3) listarith : false;
(%o3)                         false
(%i4) [a, c, m, t] / [1, 7, 2, 9];
                          [a, c, m, t]
(%o4)                     ------------
                          [1, 7, 2, 9]
(%i5) [a, c, m, t] ^ x;
                                      x
(%o5)                     [a, c, m, t]
(%i6) listarith : true;
(%o6)                         true
(%i7) [a, c, m, t] / [1, 7, 2, 9];
                              c  m  t
(%o7)                     [a, -, -, -]
                              7  2  9
(%i8) [a, c, m, t] ^ x;
                          x   x   x   x
(%o8)                   [a , c , m , t ]
@end example

@end deffn




@deffn {Operador} **

Operador de exponenciación.
Maxima identifica @code{**} con el operador @code{^} en la entrada
de expresiones, pero se representa como @code{^} en las salidas
no formateadas (@code{display2d=false}), o colocando un 
superíndice en la salida formateada (@code{display2d=true}).

La función @code{fortran} representa el operador de exponenciación
con @code{**}, tanto si se ha introducido como @code{**} o como @code{^}.

Ejemplos:

@c ===beg===
@c is (a**b = a^b);
@c x**y + x^z;
@c string (x**y + x^z);
@c fortran (x**y + x^z);
@c ===end===
@example
(%i1) is (a**b = a^b);
(%o1)                         true
(%i2) x**y + x^z;
                              z    y
(%o2)                        x  + x
(%i3) string (x**y + x^z);
(%o3)                        x^z+x^y
(%i4) fortran (x**y + x^z);
      x**z+x**y
(%o4)                         done
@end example

@end deffn




@deffn {Operator} ^^
@ifinfo
@fnindex Exponenciación no conmutativa
@end ifinfo

Operador de exponenciación no conmutativa.
Se trata del operador de exponenciación correspondiente a la
multiplicación no conmutativa @code{.}, del mismo modo que el
operador de exponenciación ordinario @code{^} se corresponde 
con la multiplicación conmutativa @code{*}.

La exponenciación no conmutativa se representa como @code{^^}
en las salidas no formateadas (@code{display2d=false}), o colocando un 
superíndice entre ángulos (@code{< >}) en la salida 
formateada (@code{display2d=true}).

Ejemplos:

@c ===beg===
@c a . a . b . b . b + a * a * a * b * b;
@c string (a . a . b . b . b + a * a * a * b * b);
@c ===end===
@example
(%i1) a . a . b . b . b + a * a * a * b * b;
                        3  2    <2>    <3>
(%o1)                  a  b  + a    . b
(%i2) string (a . a . b . b . b + a * a * a * b * b);
(%o2)                  a^3*b^2+a^^2 . b^^3
@end example

@end deffn



@deffn {Operador} .
@ifinfo
@fnindex Multiplicación no conmutativa
@end ifinfo
El operador punto, para multiplicación de matrices (no-conmutativo). 
Cuando @code{"."} se usa de esta forma, se dejarán espacios a
ambos lados de éste, como en @code{A . B}. Así se evita que se confunda con el punto decimal de los números. 

Véanse:
@code{dot},
@code{dot0nscsimp},
@code{dot0simp},
@code{dot1simp},
@code{dotassoc},
@code{dotconstrules},
@code{dotdistrib},
@code{dotexptsimp},
@code{dotident}
y
@code{dotscrules}.

@end deffn







@node Operadores relacionales, Operadores lógicos, Operadores aritméticos, Operadores
@section Operadores relacionales



@deffn {Operator} <
@ifinfo
@fnindex Menor que
@end ifinfo
@deffnx {Operator} <=
@ifinfo
@fnindex Menor o igual que
@end ifinfo
@deffnx {Operator} >=
@ifinfo
@fnindex Mayor o igual que
@end ifinfo
@deffnx {Operator} >
@ifinfo
@fnindex Mayor que
@end ifinfo

Los símbolos @code{<}, @code{<=}, @code{>=} y @code{>}
representan menor que, menor o igual que, mayor o igual que y mayor que, respectivamente.
Los nombres de estos operadores son @code{"<"} @code{"<="} @code{">="} y @code{">"},
que pueden aparecer allá donde se requiera el nombre de una función u operador.

Estos operadores relacionales son todos operadores binarios. Maxima
no reconoce expresiones del estilo @code{a < b < c}.

Las expresiones relacionales devuelven valores booleanos haciendo uso 
de las funciones @code{is} o @code{maybe}, así como de las
sentencias condicionales @code{if}, @code{while} y @code{unless}.
Las expresiones relacionales no se evalúan de otra manera, aunque sus
argumentos sí sean evaluados.

Cuando una expresión relacional no pueda ser evaluada a @code{true} o @code{false},
el comportamiento de @code{is} y de @code{if} estará controlado por la variable
global @code{prederror}. Si @code{prederror} toma el valor @code{true}, @code{is} y
@code{if} emiten un mensaje de error. Si @code{prederror} toma el valor @code{false},
@code{is} devuelve @code{unknown} y @code{if} devuelve una expresión condicional
parcialmente evaluada.

@code{maybe} se comporta siempre como si @code{prederror} fuese @code{false},
al tiempo que @code{while} y @code{unless} se comportan siempre como si
@code{prederror} fuese @code{true}.

Los operadores relacionales no se distribuyen sobre listas ni sobre cualesquiera
otros tipos de estructuras de datos.

Véanse también @code{=}, @code{#}, @code{equal} y @code{notequal}.

Ejemplos:

Las expresiones relacionales se reducen a valores booleanos a través de ciertas
funciones y sentencias condicionales.

@c ===beg===
@c [x, y, z] : [123, 456, 789];
@c is (x < y);
@c maybe (y > z);
@c if x >= z then 1 else 0;
@c block ([S], S : 0, 
@c        for i:1 while i <= 100 do S : S + i, return (S));
@c ===end===
@example
(%i1) [x, y, z] : [123, 456, 789];
(%o1)                    [123, 456, 789]
(%i2) is (x < y);
(%o2)                         true
(%i3) maybe (y > z);
(%o3)                         false
(%i4) if x >= z then 1 else 0;
(%o4)                           0
(%i5) block ([S], S : 0, 
             for i:1 while i <= 100 do S : S + i, return (S));
(%o5)                         5050
@end example

Las expresiones relacionales no se evalúan de otra manera, aunque sus
argumentos sí sean evaluados.

@c ===beg===
@c [x, y, z] : [123, 456, 789];
@c [x < y, y <= z, z >= y, y > z];
@c map (is, %);
@c ===end===
@example
(%o1)                    [123, 456, 789]
(%i2) [x < y, y <= z, z >= y, y > z];
(%o2)    [123 < 456, 456 <= 789, 789 >= 456, 456 > 789]
(%i3) map (is, %);
(%o3)               [true, true, true, false]
@end example

@end deffn







@node Operadores lógicos, Operadores para ecuaciones, Operadores relacionales, Operadores
@section Operadores lógicos




@deffn {Operador} and
@ifinfo
@fnindex Conjunción lógica
@end ifinfo
Operador de conjunción lógica.
El operador @code{and} es un operador infijo @code{n}-ario;
sus operandos son expresiones booleanas y su resultado es un valor lógico.

El operador @code{and} impone la evaluación (igual que @code{is}) de uno o más operandos,
y puede forzar la evaluación de todos los operandos.

Los operandos se evalúan en el orden en el que aparecen; 
sólo evalúa tantos operandos como sean necesarios para determinar el resultado.
Si algún operando vale @code{false},
el resultado es @code{false} y ya no se evalúan más operandos.

La variable global @code{prederror} controla el comportamiento de @code{and}
cuando la evaluación de un operando no da como resultado @code{true} o @code{false};
@code{and} imprime un mensaje de error cuando @code{prederror} vale @code{true}.
Cuando los operandos devuelven un valor diferente a @code{true} o @code{false}
al ser evaluados, el resultado es una expresión booleana.

El operador @code{and} no es conmutativo:
@code{a and b} puede no ser igual a @code{b and a} debido al tratamiento de operandos indeterminados.

@end deffn



@deffn {Operador} not
@ifinfo
@fnindex Negación lógica
@end ifinfo
Operador de negación lógica. El operador @code{not} es un operador prefijo;
su operando es una expresión booleana y su resultado es un valor lógico.

El operador @code{not} impone la evaluación (igual que @code{is}) de su operando.

La variable global @code{prederror} controla el comportamiento de
@code{not} cuando la evaluación de su operando no da como 
resultado @code{true} o @code{false}; @code{not} imprime un mensaje 
de error cuando @code{prederror} vale @code{true}.
Cuando los operandos devuelven un valor diferente a @code{true} o @code{false}
al ser evaluados, el resultado es una expresión booleana.

@end deffn




@deffn {Operador} or
@ifinfo
@fnindex Disyunción lógica
@end ifinfo
Operador de disyunción lógica. El operador @code{or} es un operador infijo @code{n}-ario;
sus operandos son expresiones booleanas y su resultado es un valor lógico.

El operador @code{or} impone la evaluación (igual que @code{is}) de uno o más operandos,
y puede forzar la evaluación de todos los operandos.

Los operandos se evalúan en el orden en el que aparecen; @code{or} sólo evalúa tantos operandos como sean necesarios para determinar el resultado. Si un operando vale @code{true}, el resultado es @code{true} y ya no se evalúan más operandos.

La variable global @code{prederror} controla el comportamiento 
de @code{or} cuando la evaluación de un operando no da como 
resultado @code{true} o @code{false}; @code{or} imprime un 
mensaje de error cuando @code{prederror} vale @code{true}.
Cuando los operandos devuelven un valor diferente a @code{true} o @code{false}
al ser evaluados, el resultado es una expresión booleana.

El operador @code{or} no es conmutativo: @code{a or b} puede no ser igual a @code{b or a} debido al tratamiento de operandos indeterminados.

@end deffn







@node Operadores para ecuaciones, Operadores de asignación, Operadores lógicos, Operadores
@section Operadores para ecuaciones



@deffn {Operador} #
@ifinfo
@fnindex Negación de la igualdad sintáctica
@end ifinfo
Representa la negación de la igualdad sintáctica @code{=}.

Nótese que debido a las reglas de evaluación de expresiones
de tipo predicado (en concreto debido a que @code{not @var{expr}}
obliga a la evaluación previa de @var{expr}), 
@code{not @var{a} = @var{b}} equivale a @code{is(@var{a} # @var{b})}, 
pero no a @code{@var{a} # @var{b}}.

Ejemplos:

@c ===beg===
@c a = b;
@c is (a = b);
@c a # b;
@c not a = b;
@c is (a # b);
@c is (not a = b);
@c ===end===
@example
(%i1) a = b;
(%o1)                         a = b
(%i2) is (a = b);
(%o2)                         false
(%i3) a # b;
(%o3)                         a # b
(%i4) not a = b;
(%o4)                         true
(%i5) is (a # b);
(%o5)                         true
(%i6) is (not a = b);
(%o6)                         true
@end example

@end deffn




@deffn {Operador} =
@ifinfo
@fnindex Operador de ecuación
@fnindex Igualdad sintáctica
@end ifinfo
Operador de ecuación.

La expresión @code{@var{a} = @var{b}} representa una ecuación
sin evaluar, la cual puede verificarse o no. Las ecuaciones sin evaluar 
pueden aparecer como argumentos de @code{solve}, @code{algsys}
y de algunas otras funciones.

La función @code{is} evalúa el operador @code{=} a un
resultado booleano; @code{is(@var{a} = @var{b})} asigna un valor
de verdad a @code{@var{a} = @var{b}}, siendo @code{true} si
@var{a} y @var{b} son idénticos, lo cual acontece si
ambos @var{a} y @var{b} son átomos idénticos, o si no
siendo átomos, sus operadores y argumentos respectivos
son idénticos; en caso contrario, @code{is(@var{a} = @var{b})}
devuelve el valor  @code{false}. Nunca se devuelve el valor @code{unknown}.
Cuando @code{is(@var{a} = @var{b})} toma el valor @code{true}, 
se dice que @var{a} y @var{b} son sintácticamente iguales,
no expresiones equivalentes, para las cuales 
@code{is(equal(@var{a}, @var{b}))} devuelve @code{true}.
Las expresiones pueden ser equivalentes, pero no 
sintácticamente iguales.

La negación de @code{=} se representa por @code{#}.
Como en el caso de @code{=}, la expresión 
@code{@var{a} # @var{b}} no está evaluada; sin embargo,
@code{is(@var{a} # @var{b})} evalúa @code{@var{a} # @var{b}}
a @code{true} o @code{false}.

Además de @code{is}, hay otros operadores que evalúan 
@code{=} y @code{#} a @code{true} o @code{false};
a saber, @code{if}, @code{and}, @code{or} y @code{not}.

Nótese que debido a las reglas de evaluación de expresiones
de tipo predicado (en concreto debido a que @code{not @var{expr}}
obliga a la evaluación previa de @var{expr}), 
@code{not @var{a} = @var{b}} equivale a @code{is(@var{a} # @var{b})}, 
pero no a @code{@var{a} # @var{b}}.

Las funciones @code{rhs} y @code{lhs} devuelven los miembros
derecho e izquierdo, respectivamente, de una ecuación o inecuación.

Véanse también @code{equal} y @code{notequal}.

Ejemplos:

La expresión @code{@var{a} = @var{b}} representa una ecuación
sin evaluar, la cual puede verificarse o no.

@c ===beg===
@c eq_1 : a * x - 5 * y = 17;
@c eq_2 : b * x + 3 * y = 29;
@c solve ([eq_1, eq_2], [x, y]);
@c subst (%, [eq_1, eq_2]);
@c ratsimp (%);
@c ===end===
@example
(%i1) eq_1 : a * x - 5 * y = 17;
(%o1)                    a x - 5 y = 17
(%i2) eq_2 : b * x + 3 * y = 29;
(%o2)                    3 y + b x = 29
(%i3) solve ([eq_1, eq_2], [x, y]);
                        196         29 a - 17 b
(%o3)          [[x = ---------, y = -----------]]
                     5 b + 3 a       5 b + 3 a
(%i4) subst (%, [eq_1, eq_2]);
         196 a     5 (29 a - 17 b)
(%o4) [--------- - --------------- = 17, 
       5 b + 3 a      5 b + 3 a
                                  196 b     3 (29 a - 17 b)
                                --------- + --------------- = 29]
                                5 b + 3 a      5 b + 3 a
(%i5) ratsimp (%);
(%o5)                  [17 = 17, 29 = 29]
@end example

@code{is(@var{a} = @var{b})} evalúa @code{@var{a} = @var{b}} 
a @code{true} si @var{a} y @var{b}
son sintácticamente iguales (es decir, idénticas).
Las expresiones pueden ser equivalentes, pero no 
sintácticamente iguales.

@c ===beg===
@c a : (x + 1) * (x - 1);
@c b : x^2 - 1;
@c [is (a = b), is (a # b)];
@c [is (equal (a, b)), is (notequal (a, b))];
@c ===end===
@example
(%i1) a : (x + 1) * (x - 1);
(%o1)                    (x - 1) (x + 1)
(%i2) b : x^2 - 1;
                              2
(%o2)                        x  - 1
(%i3) [is (a = b), is (a # b)];
(%o3)                     [false, true]
(%i4) [is (equal (a, b)), is (notequal (a, b))];
(%o4)                     [true, false]
@end example

Algunos operadores evalúan @code{=} y @code{#} a @code{true} o @code{false}.

@c ===beg===
@c if expand ((x + y)^2) = x^2 + 2 * x * y + y^2
@c    then FOO else BAR;
@c eq_3 : 2 * x = 3 * x;
@c eq_4 : exp (2) = %e^2;
@c [eq_3 and eq_4, eq_3 or eq_4, not eq_3];
@c ===end===
@example
(%i1) if expand ((x + y)^2) = x^2 + 2 * x * y + y^2
        then FOO else BAR;
(%o1)                          FOO
(%i2) eq_3 : 2 * x = 3 * x;
(%o2)                       2 x = 3 x
(%i3) eq_4 : exp (2) = %e^2;
                              2     2
(%o3)                       %e  = %e
(%i4) [eq_3 and eq_4, eq_3 or eq_4, not eq_3];
(%o4)                  [false, true, true]
@end example

Debido a que @code{not @var{expr}}
obliga a la evaluación previa de @var{expr}, 
@code{not @var{a} = @var{b}} equivale a @code{is(@var{a} # @var{b})}.

@c ===beg===
@c [2 * x # 3 * x, not (2 * x = 3 * x)];
@c is (2 * x # 3 * x);
@c ===end===
@example
(%i1) [2 * x # 3 * x, not (2 * x = 3 * x)];
(%o1)                   [2 x # 3 x, true]
(%i2) is (2 * x # 3 * x);
(%o2)                         true
@end example

@end deffn







@node Operadores de asignación, Operadores definidos por el usuario, Operadores para ecuaciones, Operadores
@section Operadores de asignación



@deffn {Operador} :
@ifinfo
@fnindex Operador de asignación
@end ifinfo
Operador de asignación.

Cuando el miembro de la izquierda es una variable simple (no subindicada),
@code{:} evalúa la expresión de la derecha y asigna ese
valor a la variable del lado izquierdo.

Cuando en el lado izquierdo hay un elemento subindicado correspondiente a
una lista, matriz, array declarado de Maxima o array de Lisp, la expresión de
la derecha se asigna a ese elemento. El subíndice debe hacer
referencia a un elemento ya existente, ya que los objetos anteriores no 
pueden ampliarse nombrando elementos no existentes.

Cuando en el lado izquierdo hay un elemento subindicado correspondiente a
un array no declarado de Maxima, la expresión de la derecha se asigna a ese elemento
en caso de que ya exista, o a un nuevo elemento, si éste todavía
no existe.

Cuando el miembro de la izquierda es una lista de átomos y/o variables subindicadas,
el miembro derecho debe evaluar también a una lista, cuyos elementos serán
asignados en paralelo a las variables de la lista de la izquierda.

Véanse también @code{kill} y @code{remvalue}, que deshacen las asociaciones
hechas por el operador @code{:}.

Ejemplos:

Asignación a una variable simple.

@c ===beg===
@c a;
@c a : 123;
@c a;
@c ===end===
@example
(%i1) a;
(%o1)                           a
(%i2) a : 123;
(%o2)                          123
(%i3) a;
(%o3)                          123
@end example

Asignación a un elemento de una lista.

@c ===beg===
@c b : [1, 2, 3];
@c b[3] : 456;
@c b;
@c ===end===
@example
(%i1) b : [1, 2, 3];
(%o1)                       [1, 2, 3]
(%i2) b[3] : 456;
(%o2)                          456
(%i3) b;
(%o3)                      [1, 2, 456]
@end example

La asignación crea un array no declarado.

@c ===beg===
@c c[99] : 789;
@c c[99];
@c c;
@c arrayinfo (c);
@c listarray (c);
@c ===end===
@example
(%i1) c[99] : 789;
(%o1)                          789
(%i2) c[99];
(%o2)                          789
(%i3) c;
(%o3)                           c
(%i4) arrayinfo (c);
(%o4)                   [hashed, 1, [99]]
(%i5) listarray (c);
(%o5)                         [789]
@end example

Asignación múltiple.

@c ===beg===
@c [a, b, c] : [45, 67, 89];
@c a;
@c b;
@c c;
@c ===end===
@example
(%i1) [a, b, c] : [45, 67, 89];
(%o1)                     [45, 67, 89]
(%i2) a;
(%o2)                          45
(%i3) b;
(%o3)                          67
(%i4) c;
(%o4)                          89
@end example

La asignación múltiple se hace en paralelo. Los valores
de @code{a} y @code{b} se intercambian en este ejemplo.

@c ===beg===
@c [a, b] : [33, 55];
@c [a, b] : [b, a];
@c a;
@c b;
@c ===end===
@example
(%i1) [a, b] : [33, 55];
(%o1)                       [33, 55]
(%i2) [a, b] : [b, a];
(%o2)                       [55, 33]
(%i3) a;
(%o3)                          55
(%i4) b;
(%o4)                          33
@end example
@end deffn




@deffn {Operador} ::
@ifinfo
@fnindex Operador de asignación (evalúa el miembro izquierdo)
@end ifinfo
Operador de asignación.

El operador @code{::} es similar a @code{:}, excepto que @code{::}
evalúa ambos miembros, tanto el derecho como el izquierdo.

Ejemplos:

@c ===beg===
@c x : 'foo;
@c x :: 123;
@c foo;
@c x : '[a, b, c];
@c x :: [11, 22, 33];
@c a;
@c b;
@c c;
@c ===end===
@example
(%i1) x : 'foo;
(%o1)                          foo
(%i2) x :: 123;
(%o2)                          123
(%i3) foo;
(%o3)                          123
(%i4) x : '[a, b, c];
(%o4)                       [a, b, c]
(%i5) x :: [11, 22, 33];
(%o5)                     [11, 22, 33]
(%i6) a;
(%o6)                          11
(%i7) b;
(%o7)                          22
(%i8) c;
(%o8)                          33
@end example
@end deffn




@deffn {Operador} ::=
@ifinfo
@fnindex Operador de definición de funciones macro
@end ifinfo
El operador de definición de macros @code{::=} define una función (llamada macro por razones históricas) que no evalúa sus argumentos, siendo la expresión que retorna (llamada "macroexpansión") evaluada dentro del contexto desde el cual se ha invocado la macro. En cualquier otro sentido, una función macro es igual que una función ordinaria.

@code{macroexpand} devuelve la expresión que a su vez fue devuelta por una macro (sin evaluar la expresión);
@code{macroexpand (foo (x))} seguida de @code{''%} es equivalente a @code{foo (x)} si @code{foo} es una función macro.

@code{::=} coloca el nombre de la nueva función macro en la lista global @code{macros}. Por otro lado, las funciones 
@code{kill}, @code{remove} y @code{remfunction} borran las definiciones de las funciones macro y eliminan sus nombres de la lista @code{macros}.

Las funciones @code{fundef} y @code{dispfun} devuelven la definición de una función macro y le asignan una etiqueta, respectivamente.

Las funciones macro normalmente contienen expresiones @code{buildq} y @code{splice} para construir una expresión, que luego será evaluada.

Ejemplos:

Una función macro no evalúa sus argumentos, por lo que el mensaje (1) muestra @code{y - z}, no el valor de @code{y - z}.
La macroexpansión (es decir, la expresión no evaluada @code{'(print ("(2) x is equal to", x))}) se evalúa en el contexto desde el cual se produjo la llamada a la macro, imprimiendo el mensaje (2).

@c ===beg===
@c x: %pi$
@c y: 1234$
@c z: 1729 * w$
@c printq1 (x) ::= block (print ("(1) x is equal to", x), 
@c                                 '(print ("(2) x is equal to", x)))$
@c printq1 (y - z);
@c ===end===
@example
(%i1) x: %pi$

(%i2) y: 1234$

(%i3) z: 1729 * w$

(%i4) printq1 (x) ::= block (print ("(1) x is equal to", x),
'(print ("(2) x is equal to", x)))$

(%i5) printq1 (y - z);
(1) x is equal to y - z
(2) x is equal to %pi
(%o5)                                 %pi
@end example


Una función ordinaria evalúa sus argumentos, por lo que el mensaje (1) muestra el valor de @code{y - z}.
El valor de retorno no se evalúa, por lo que el mensaje (2) no se imprime hasta la evaluación explícita @code{''%}.

@c ===beg===
@c x: %pi$
@c y: 1234$
@c z: 1729 * w$
@c printe1 (x) := block (print ("(1) x is equal to", x), 
@c       '(print ("(2) x is equal to", x)))$
@c printe1 (y - z);
@c ''%;
@c ===end===
@example
(%i1) x: %pi$

(%i2) y: 1234$

(%i3) z: 1729 * w$

(%i4) printe1 (x) := block (print ("(1) x is equal to", x),
'(print ("(2) x is equal to", x)))$

(%i5) printe1 (y - z);
(1) x is equal to 1234 - 1729 w
(%o5)                     print((2) x is equal to, x)
(%i6) ''%;
(2) x is equal to %pi
(%o6)                                 %pi
@end example

@code{macroexpand} devuelve la macroexpansión;
@code{macroexpand (foo (x))} seguida de @code{''%} es equivalente a @code{foo (x)} si @code{foo} es una función macro.

@c ===beg===
@c x: %pi$
@c y: 1234$
@c z: 1729 * w$
@c g (x) ::= buildq ([x], print ("x is equal to", x))$
@c macroexpand (g (y - z));
@c ''%;
@c g (y - z);
@c ===end===
@example
(%i1) x: %pi$

(%i2) y: 1234$

(%i3) z: 1729 * w$

(%i4) g (x) ::= buildq ([x], print ("x is equal to", x))$

(%i5) macroexpand (g (y - z));
(%o5)                     print(x is equal to, y - z)
(%i6) ''%;
x is equal to 1234 - 1729 w
(%o6)                            1234 - 1729 w
(%i7) g (y - z);
x is equal to 1234 - 1729 w
(%o7)                            1234 - 1729 w
@end example

@end deffn




@deffn {Operador} :=
@ifinfo
@fnindex Operador de definición de funciones
@end ifinfo

El operador de definición de funciones. 
La expresión @code{@var{f}(@var{x_1}, ..., @var{x_n}) := @var{expr}}
define una función de nombre @var{f} con argumentos
@var{x_1}, ..., @var{x_n} y cuerpo @var{expr}.
El operador @code{:=} no evalúa el cuerpo de la función (a menos que
se indique lo contrario mediante el operador comilla-comilla @code{'@w{}'}).
La función así definida puede ser una función ordinaria
de Maxima (con argumentos encerrados entre paréntesis) o una función
array (con argumentos encerrados entre corchetes).

Cuando el último o único argumento @var{x_n} es una lista de un solo
elemento, la función definida por @code{:=} acepta un número variable
de argumentos. Los valores de los argumentos se asignan uno a uno a los
argumentos formales @var{x_1}, ..., @var{x_(n - 1)}, y cualesquiera otros
valores de argumentos, si existen, se asignan a @var{x_n} en forma de lista.

Todas las definiciones de funciones aparecen en el mismo espacio de
nombres; definiendo una función @code{f} dentro de otra función @code{g}
no limita automáticamente el alcance de @code{f} a @code{g}.
No obstante, @code{local(f)} hace que la función @code{f}
sea efectiva solamente dentro del bloque o empaquetado de expresiones en la
que aparece @code{local}.

Si un argumento formal @var{x_k} es un símbolo afectado por el
operador comilla (expresión nominal), la función definida por @code{:=} no evalúa el
correspondiente valor de argumento. 
En cualquier otro caso, los argumentos que se pasan son evaluados.

Véanse también @code{define} y @code{::=}.

Ejemplos:

@code{:=} no evalúa el cuerpo de la función (a menos que
se indique lo contrario mediante el operador comilla-comilla @code{'@w{}'}).

@c ===beg===
@c expr : cos(y) - sin(x);
@c F1 (x, y) := expr;
@c F1 (a, b);
@c F2 (x, y) := ''expr;
@c F2 (a, b);
@c ===end===
@example
(%i1) expr : cos(y) - sin(x);
(%o1)                    cos(y) - sin(x)
(%i2) F1 (x, y) := expr;
(%o2)                   F1(x, y) := expr
(%i3) F1 (a, b);
(%o3)                    cos(y) - sin(x)
(%i4) F2 (x, y) := ''expr;
(%o4)              F2(x, y) := cos(y) - sin(x)
(%i5) F2 (a, b);
(%o5)                    cos(b) - sin(a)
@end example

La función así definida puede ser una función ordinaria
de Maxima o una función array.

@c ===beg===
@c G1 (x, y) := x.y - y.x;
@c G2 [x, y] := x.y - y.x;
@c ===end===
@example
(%i1) G1 (x, y) := x.y - y.x;
(%o1)               G1(x, y) := x . y - y . x
(%i2) G2 [x, y] := x.y - y.x;
(%o2)                G2     := x . y - y . x
                       x, y
@end example

Cuando el último o único argumento @var{x_n} es una lista de un solo
elemento, la función definida por @code{:=} acepta un número variable
de argumentos.

@c ===beg===
@c H ([L]) := apply ("+", L);
@c H (a, b, c);
@c ===end===
@example
(%i1) H ([L]) := apply ("+", L);
(%o1)                H([L]) := apply("+", L)
(%i2) H (a, b, c);
(%o2)                       c + b + a
@end example

@code{local} define una función como local.

@c ===beg===
@c foo (x) := 1 - x;
@c foo (100);
@c block (local (foo), foo (x) := 2 * x, foo (100));
@c foo (100);
@c ===end===
@example
(%i1) foo (x) := 1 - x;
(%o1)                    foo(x) := 1 - x
(%i2) foo (100);
(%o2)                         - 99
(%i3) block (local (foo), foo (x) := 2 * x, foo (100));
(%o3)                          200
(%i4) foo (100);
(%o4)                         - 99
@end example
@end deffn








@node Operadores definidos por el usuario, , Operadores de asignación, Operadores
@section Operadores definidos por el usuario




@deffn {Función} infix (@var{op})
@deffnx {Función} infix (@var{op}, @var{lbp}, @var{rbp})
@deffnx {Función} infix (@var{op}, @var{lbp}, @var{rbp}, @var{lpos}, @var{rpos}, @var{pos})
Declara @var{op} como operador infijo.
Un operador infijo es una función de dos argumentos,
con el nombre de la función escrito entre sus argumentos.
Por ejemplo, el operador de sustracción @code{-} es un operador infijo.

@code{infix (@var{op})} declara @var{op} como operador infijo
con fuerzas de ligadura por la izquierda y por la derecha iguales a 180, que es el valor por defecto, 
y partes izquierda y derecha iguales a @code{any}.
@c HOW IS pos DIFFERENT FROM lpos AND rpos ??

@code{infix (@var{op}, @var{lbp}, @var{rbp})} declara @var{op} como operador infijo
con fuerzas de ligadura por la izquierda y por la derecha declaradas en los argumentos, siendo las partes izquierda y derecha iguales a @code{any}.

@code{infix (@var{op}, @var{lbp}, @var{rbp}, @var{lpos}, @var{rpos}, @var{pos})}
declara @var{op} como operador infijo con fuerzas de ligadura por la 
izquierda y por la derecha, junto con los tipos de expresiones correspondientes
a @var{lpos}, @var{rpos} y @var{pos}, que son el operando de la izquierda,
el de la derecha y el operador del resultado; los tipos reconocidos son:
@code{expr}, @code{clause} y @code{any}, que indican expresión algebraica,
expresión booleana o cualquier otra, respectivamente. Maxima puede detectar
algunos errores sintácticos comparando los tipos declarados con los de la expresión
actual.

La precedencia de @var{op} con respecto a otros operadores deriva de las fuerzas de ligadura de los operadores en cuestión.
Si las fuerzas de ligadura a izquierda y derecha de @var{op} son ambas mayores que las fuerzas de ligadura a izquierda y derecha de otro operador, entonces @var{op} tiene preferencia sobre el otro operador. Si las fuerzas de ligadura no son ambas mayores o menores, se aplican otras relaciones más complejas.

La asociatividad de @var{op} depende de las fuerzas de ligadura.
Una mayor fuerza de ligadura a la izquierda (@var{lbp}) implica que @var{op} sea evaluado antes que otros operadores a su izquierda en la expresión, mientras que mayor fuerza de ligadura a la derecha (@var{rbp}) implica que @var{op} sea evaluado antes que otros operadores a su derecha en la expresión.
Así, si @var{lbp} es mayor, @var{op} es asociativo por la derecha, mientras que si @var{rbp} es mayor, @var{op} es asociativo por la izquierda.

Véase también @code{Syntax}.

Ejemplos:

Si las fuerzas de ligadura a izquierda y derecha de @var{op} son ambas mayores que las fuerzas de ligadura a izquierda y derecha de otro operador, entonces @var{op} tiene preferencia sobre el otro operador.

@c ===beg===
@c :lisp (get '$+ 'lbp)
@c :lisp (get '$+ 'rbp)
@c infix ("##", 101, 101);
@c "##"(a, b) := sconcat("(", a, ",", b, ")");
@c 1 + a ## b + 2;
@c infix ("##", 99, 99);
@c 1 + a ## b + 2;
@c ===end===
@example
(%i1) :lisp (get '$+ 'lbp)
100
(%i1) :lisp (get '$+ 'rbp)
100
(%i1) infix ("##", 101, 101);
(%o1)                          ##
(%i2) "##"(a, b) := sconcat("(", a, ",", b, ")");
(%o2)       (a ## b) := sconcat("(", a, ",", b, ")")
(%i3) 1 + a ## b + 2;
(%o3)                       (a,b) + 3
(%i4) infix ("##", 99, 99);
(%o4)                          ##
(%i5) 1 + a ## b + 2;
(%o5)                       (a+1,b+2)
@end example

Mayor @var{lbp} hace a @var{op} asociativo por la derecha,
mientras que mayor  @var{rbp} hace a @var{op} asociativo por la izquierda.

@c ===beg===
@c infix ("##", 100, 99);
@c "##"(a, b) := sconcat("(", a, ",", b, ")")$
@c foo ## bar ## baz;
@c infix ("##", 100, 101);
@c foo ## bar ## baz;
@c ===end===
@example
(%i1) infix ("##", 100, 99);
(%o1)                          ##
(%i2) "##"(a, b) := sconcat("(", a, ",", b, ")")$
(%i3) foo ## bar ## baz;
(%o3)                    (foo,(bar,baz))
(%i4) infix ("##", 100, 101);
(%o4)                          ##
(%i5) foo ## bar ## baz;
(%o5)                    ((foo,bar),baz)
@end example

Maxima puede detectar algunos errores sintácticos comparando
los tipos declarados con los de la expresión actual.

@c ===beg===
@c infix ("##", 100, 99, expr, expr, expr);
@c if x ## y then 1 else 0;
@c infix ("##", 100, 99, expr, expr, clause);
@c if x ## y then 1 else 0;
@c ===end===
@example
(%i1) infix ("##", 100, 99, expr, expr, expr);
(%o1)                          ##
(%i2) if x ## y then 1 else 0;
Incorrect syntax: Found algebraic expression where logical expression expected
if x ## y then 
             ^
(%i2) infix ("##", 100, 99, expr, expr, clause);
(%o2)                          ##
(%i3) if x ## y then 1 else 0;
(%o3)                if x ## y then 1 else 0
@end example
@end deffn




@deffn {Función} matchfix (@var{ldelimiter}, @var{rdelimiter})
@deffnx {Función} matchfix (@var{ldelimiter}, @var{rdelimiter}, @var{arg_pos}, @var{pos})

Declara un operador "matchfix" con delimitadores a la izquierda y derecha, @var{ldelimiter} y @var{rdelimiter}, respectivamente. Los delimitadores son cadenas alfanuméricas.

Un operador "matchfix" es una función con un número arbitrario de argumentos, de manera que los argumentos se presentan entre los delimitadores de la izquierda y derecha. Los delimitadores pueden ser cualquier tipo de cadena, en tanto que el analizador sintáctico pueda distinguirlos de los operandos y de expresiones con operadores. En la práctica esto excluye delimitadores como @code{%}, @code{,}, @code{$} y @code{;},  necesitando aislar los delimitadores con espacios en blanco. El delimitador de la derecha puede ser igual o diferente del de la izquierda.

Un delimitador de la izquierda sólo puede asociarse con un único delimitador de la derecha; dos operadores "matchfix" diferentes no pueden tener el mismo delimitador por la izquierda.

Un operador ya existente puede declararse como operador "matchfix" sin necesidad de que cambie el resto de propiedades. En particular, los operadores de Maxima tales como la suma @code{+} pueden ser declarados como "matchfix".

La llamada @code{matchfix (@var{ldelimiter}, @var{rdelimiter}, @var{arg_pos}, @var{pos})} 
declara el argumento @var{arg_pos} y el resultado @var{pos}, así
como los delimitadores  @var{ldelimiter} y @var{rdelimiter}.

Los argumentos @var{arg_pos} y @var{pos} son tipos de funciones,
reconociéndose como tales: @code{expr}, @code{clause} y @code{any},
los cuales hacen referencia a una expresión algebraica, booleana o
de cualquier otro tipo, respectivamente.
Maxima puede detectar ciertos errores sintácticos comparando el
tipo de expresión declarado con el de la expresión actual.

La función que ejecutará una operación "matchfix" será una típica función definida por el usuario. La función de operador se define por el método habitual con  @code{:=} o @code{define}. Los argumentos pueden escribirse entre los delimitadores, o con el delimitador izquierdo como una cadena precedida de apóstrofo y seguidamente los argumentos entre paréntesis. La llamada @code{dispfun (@var{ldelimiter})} muestra la definición de la función.

El único operador "matchfix" de Maxima es el constructor de listas @code{[ ]}. Los paréntesis  @code{( )} y las comillas dobles  @code{" "}  actúan como operadores "matchfix", pero son tratados como operadores "matchfix" por el analizador sintáctico de Maxima.

Ejemplos:

@itemize @bullet
@item
Los delimitadores pueden ser practicamente cualquier cadena.
@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
Los operadores "matchfix" son funciones definidas por el usuario.
@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



@deffn  {Función} nary (@var{op})
@deffnx {Función} nary (@var{op}, @var{bp}, @var{arg_pos}, @var{pos})

Un operador n-ario denota una función con un número arbitrario de
argumentos entre los que se intercal el símbolo del operador,
como en @code{A+B+C}. La instrucción @code{nary("x")} declara @code{x}
como operador n-ario. Las funciones se pueden declarar como n-arias;
de modo que si se ejecuta @code{declare(j,nary)}, el simplificador
transforma @code{j(j(a,b),j(c,d))} en @code{j(a, b, c, d)}.

@end deffn



@deffn  {Función} nofix (@var{op})
@deffnx {Función} nofix (@var{op}, @var{pos})

Los operadores no-fijos se utilizan para definir funciones sin argumentos.
La mera presencia de tal operador en una instrucción hará que se
evalúe la función correspondiente. Por ejemplo, cuando se teclea @code{exit;}
para salir de una interrupción de Maxima, @code{exit} se comporta como una
función no-fija. La instrucción @code{nofix("x")} declara @code{x}
como operador no-fijo.

@end deffn



@deffn  {Función} postfix (@var{op})
@deffnx {Función} postfix (@var{op}, @var{lbp}, @var{lpos}, @var{pos})

Los operadores sufijos son funciones de un único argumento en las que éste
precede al operador, como en @code{3!}. La instrucción @code{postfix("x")}
declara @code{x} como operador sufijo.

@end deffn



@deffn  {Función} prefix (@var{op})
@deffnx {Función} prefix (@var{op}, @var{rbp}, @var{rpos}, @var{pos})

Los operadores prefijos son funciones de un único argumento en las que éste
se coloca a continuación del operador. La instrucción 
@code{prefix("x")} declara @code{x} como operador prefijo.
@end deffn

