@c Language=Russian
@c Encoding=CP1251
@c File=Operators.texi 
@c OriginalRevision=1.49
@c TranslatedBy: (c) 2007-11-06 Andrey Siver <ihep-2005@yandex.ru>


@menu
* N-арные операторы (nary)::                        
* Безфиксные операторы (nofix)::                       
* Постфиксные операторы (postfix)::                     
* Префиксные операторы (prefix)::                      
* Арифметические операторы::   
* Операторы отношения::   
* Общие операторы::   
@end menu

@c FOLLOWING @NODES SHOULD BE CHANGED TO @DEFFN
@c SINCE NARY, NOFIX, POSTFIX, AND PREFIX ARE ALL MAXIMA FUNCTIONS

@node N-арные операторы (nary), Безфиксные операторы (nofix), Операторы, Операторы
@section N-арные операторы (nary)
N-арный @code{nary} оператор используется для того, чтобы задать функцию любого числа аргументов, каждый из которых разделен 
оператором, например A+B или A+B+C. Функция @code{nary("x")} - синтаксическое
расширение функции для объявления @code{x} как n-арный оператор.
Функции могут быть объявлены n-арными. 
Если @code{declare(j,nary);} выполнено, это указывает упрощателю (simplifier) то, 
что требуется упрощение, то есть, например, @code{j(j(a,b),j(c,d))} упростится до @code{j(a, b, c, d)}.

См. также @code{Синтаксис}.

@opencatbox
@category{Операторы} @category{Синтаксис}
@closecatbox

@node Безфиксные операторы (nofix), Постфиксные операторы (postfix), N-арные операторы (nary), Операторы
@section Безфиксные операторы (nofix)
Безфиксные операторы (@code{nofix}, операторы без аргументов) используются, чтобы обозначить функции без аргументов.
Простое присутствие такого оператора в команде вызовет то, что
соответствующая функция будет вычислена.  Например, когда набирают
"exit;" для выхода из Maxima, "exit" ведет себя аналогично 
безфиксному оператору. Функция @code{nofix("x")} - это функция расширения,
которая объявляет @code{x} как безфиксный оператор. 

См. также @code{Синтаксис}.

@opencatbox
@category{Операторы} @category{Синтаксис}
@closecatbox

@node Постфиксные операторы (postfix), Префиксные операторы (prefix), Безфиксные операторы (nofix), Операторы
@section Постфиксные операторы (postfix)
Постфиксные операторы (@code{postfix}), как и префиксные операторы, обозначают функции
одного аргумента, но в этом случае этот аргумент непосредственно
предшествует появлению этого оператора в входной строке, например 3!.
Функция @code{postfix("x")} - это функция синтаксического расширения, 
которая объявлять @code{x} как постфиксный оператор.

См. также @code{Синтаксис}.

@opencatbox
@category{Операторы} @category{Синтаксис}
@closecatbox

@node Префиксные операторы (prefix), Арифметические операторы, Постфиксные операторы (postfix), Операторы
@section Префиксные операторы (prefix)
Префиксный оператор (@code{prefix}) обозначает функцию одного
аргумента, который непосредственно идет за вхождением оператора.  
@code{prefix("x")} - это функция синтаксического расширения, которая объявляет @code{x} как префиксный оператор.

См. также @code{Синтаксис}.

@opencatbox
@category{Операторы} @category{Синтаксис}
@closecatbox

@node Арифметические операторы, Операторы отношения, Префиксные операторы (prefix), Операторы 
@section Арифметические операторы

@deffn {Оператор} +
@ifinfo
@fnindex Сложение
@end ifinfo
@deffnx {Оператор} -
@ifinfo
@fnindex Вычитание
@end ifinfo
@deffnx {Оператор} *
@ifinfo
@fnindex Умножение
@end ifinfo
@deffnx {Оператор} /
@ifinfo
@fnindex Деление
@end ifinfo
@deffnx {Оператор} ^
@ifinfo
@fnindex Возведение в степень
@end ifinfo

Символы @code{+}, @code{*}, @code{/} и @code{^} обозначают
суммирование, умножение, деление и возведение в степень, соответственно.
Имена этих операторов @code{"+"}, @code{"*"}, @code{"/"} и @code{"^"}
могут появляться там, где требуется имя функции или оператора.

Символы @code{+} и @code{-} представляют унарное суммирование и вычитание, соответственно,
и имена этих операторов: @code{"+"} и @code{"-"}, соответственно.

Вычитание @code{a - b} представляется в Maxima как суммирование @code{a + (- b)}.
Выражения, такие как @code{a + (- b)}, отображаются как вычитание.
Maxima распознает @code{"-"} только как имя унарного оператора вычитания,
а не как имя бинарного оператора вычитания.

Деление @code{a / b} представляется в Maxima как умножение, @code{a * b^(- 1)}.
Выражения, такие как @code{a * b^(- 1)}, отображаются как деление.
Maxima распознает @code{"/"} как имя оператора деления.

Суммирование и умножение - n-арные (n-ary), коммутативные операторы.
Деление и возведение в степень - бинарные, некоммутативные операторы.

Maxima сортирует операнды коммутативных операторов для конструирования канонического представления.
Во внутреннем хранилище упорядочивание управляется с помощью @code{orderlessp}.
Для отображения, упорядочивание при суммировании управляется с помощью @code{ordergreatp},
а для умножения, флаг тот же, что и для внутреннего упорядочивания.

Арифметические вычисления выполняются для буквальных чисел
(целых, рациональных, обыкновенных чисел с плавающей точкой и чисел с плавающей точкой повышенной точности (bigfloat)).
За исключением возведения в степень, все арифметические операции для чисел упрощаются до чисел.
Возведение в степень упрощается до числа, в случае если, либо операнд является обыкновенным числом с плавающей точкой 
или числом с плавающей точкой повышенной точности (bigfloat),
или если результат есть точное целое или рациональное число;
иначе возведение в степень может быть упрощено до @code{sqrt} или другого возведения в степень, 
или оставлено неизменным.

В арифметических вычислениях имеет место приведение типов значений результата:
если любой операнд есть bigfloat, то результат будет bigfloat;
или же, если любой операнд есть обыкновенное число с плавающей точкой,  
результат будет обыкновенным числом с плавающей точкой;
или же, если операнды являются рациональными или целыми значениями, 
то  результат будет рациональным или целым.

Арифметические вычисления являются упрощением, а не в вычислением.
Таким образом, арифметические операции выполняется в экранированных (но упрощенных) выражениях.

Арифметические операции применяются элемент-за-элементом
к спискам, когда глобальный флаг @code{listarith} есть @code{true},
и всегда применяется элемент-за-элементом к матрицам.
Когда один операнд есть список или матрица и другой есть операнд некоторого другого типа,
то другой операнд объединяется с каждым из элементом списка или матрицы.

Примеры:

Суммирование и умножение являются n-арными (n-ary) коммутативными операторами.
Maxima сортирует операнды для того, чтобы сконструировать каноническое представление.
Имена этих операторов @code{"+"} и @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

Деление и возведение в степень - бинарные, некоммутативные операторы.
Имена этих операторов @code{"/"} и @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

Вычитание и деление внутренне представляются 
в терминах суммирования и умножения, соответственно.
@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

Вычисления выполняются над буквальными числами.
Выполняется приведение типов значений результата.
@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

Арифметические вычисления являются упрощением, а не вычислением.
@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

Арифметические операции выполняется элемент-за-элементом для списков 
(в зависимости от значения @code{listarith}) и матриц.
@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

@opencatbox
@category{Операторы}
@closecatbox

@end deffn

@deffn {Оператор} **
Оператор возведения в степень.
Maxima распознает @code{**} как тот же оператор, что и @code{^} при вводе,
и он отображается как @code{^} в 1D (одномерном) выводе,
или в виде показателя степени как верхний индекс в 2D (двумерном) выводе.

Функция @code{fortran} выводит оператор возведения в степень как @code{**},
не в зависимости от того, как он был задан при вводе, как @code{**} или @code{^}.

Примеры:

@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

@opencatbox
@category{Операторы}
@closecatbox

@end deffn

@node Операторы отношения, Общие операторы, Арифметические операторы, Операторы
@section Операторы отношения

@deffn {Оператор} <
@ifinfo
@fnindex Меньше
@end ifinfo
@deffnx {Оператор} <=
@ifinfo
@fnindex Меньше или равно
@end ifinfo
@deffnx {Оператор} >=
@ifinfo
@fnindex Больше или равно
@end ifinfo
@deffnx {Оператор} >
@ifinfo
@fnindex Больше
@end ifinfo

Символы @code{<} , @code{<=} , @code{>=} и @code{>} представляют отношения
меньше, меньше или равно, больше или равно и больше, соответственно.
Имена этих операторов есть @code{"<"} , @code{"<="} , @code{">="} и @code{">"}.
Эти имена могут применяться в случае, если требуется имя функции или оператора.

Данные операторы отношения являются бинарными. 
Конструкции типа @code{a < b < c} недопустимы в Maxima.

Операторы отношения вычисляются до логических значений функциями @code{is} и @code{maybe},
и программными конструкциями @code{if}, @code{while} и @code{unless}.
В других случаях операторы отношения не вычисляются или упрощаются до логических значений,
хотя аргументы операторов отношения вычисляются
(если вычисление не блокировано при помощи оператора кавычка).

Если выражение отношения не может быть вычислено до логического значения @code{true} или @code{false},
то поведение @code{is} и @code{if} управляется глобальным флагом @code{prederror}.
Если значение @code{prederror} равно @code{true},
то @code{is} и @code{if} вызывает ошибку.
Если значение @code{prederror} равно @code{false},
то @code{is} возвращает @code{unknown} 
а @code{if} возвращает частично-вычисленное условное выражение.

@code{maybe} всегда ведет себя так, если бы @code{prederror} равнялось @code{false},
а @code{while} и @code{unless} всегда ведут себя так, если бы @code{prederror} равнялось @code{true}.

Операторы отношения не дистрибутивны по отношению к спискам и другим конструкциям.

См. также @code{=} , @code{#} , @code{equal} и @code{notequal}.

Примеры:

Операторы отношения вычисляются до логических значений некоторыми функциями 
и программными конструкциями.

@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, 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

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

@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

@opencatbox
@category{Операторы}
@closecatbox

@end deffn

@node Общие операторы, , Операторы отношения, Операторы
@section Общие операторы

@deffn {Оператор} ^^
@ifinfo
@fnindex Некоммутативное возведение в степень
@end ifinfo

Оператор некоммутативного возведение в степень.
@code{^^} - оператор некоммутативного возведение в степень, соответствующий  некоммутативному умножению @code{.},
ровно так же как обычный оператор возведение в степень @code{^} соответствует коммутативному умножению @code{*}.

Некоммутативное возведение в степень отображается как @code{^^} в 1D (одномерном) выводе,
и в виде показателя степени как верхний индекс в угловых скобка @code{< >} в 2D (двумерном) выводе.

Примеры:

@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

@opencatbox
@category{Операторы}
@closecatbox

@end deffn

@deffn {Оператор} !
@ifinfo
@fnindex Факториал
@end ifinfo
Оператор факториала.
Для всех комплексных чисел @code{x} (включая целые, рациональные, и вещественные числа), 
за исключением отрицательных целых, @code{x!} задается как @code{gamma(x+1)}.

Для целого @code{x}, @code{x!} упрощается до произведения целых чисел от
 1 до @code{x} включительно.
@code{0!} упрощается до 1.
Для чисел с плавающей точкой @code{x}, @code{x!} упрощается  до значения @code{gamma (x+1)}.
Для @code{x} равных @code{n/2}, где @code{n} - нечетное целое,
@code{x!} упрощается до рационального множителя, умноженного на @code{sqrt (%pi)}
(т. к. @code{gamma (1/2)} равно @code{sqrt (%pi)}).
Если @code{x} - что то еще, то @code{x!} не упрощается.

Переменные @code{factlim}, @code{minfactorial} и @code{factcomb} управляют упрощением выражений,
содержащих факториалы.

Функции @code{gamma}, @code{bffac} и @code{cbffac}
являются разновидностями гамма функции.
@code{makegamma} заменяет @code{gamma} для факториалов и связанных функций.

См. также @code{binomial}.

Факториал целого, полуцелого или аргумента с плавающей точкой, упрощается
если операнд не больше чем @code{factlim}.

@c ===beg===
@c factlim : 10;
@c [0!, (7/2)!, 4.77!, 8!, 20!];
@c ===end===
@example
(%i1) factlim : 10;
(%o1)                          10
(%i2) [0!, (7/2)!, 4.77!, 8!, 20!];
            105 sqrt(%pi)
(%o2)   [1, -------------, 81.44668037931199, 40320, 20!]
                 16
@end example

Факториал комплексного числа, известной константы, или выражение общего вида не упрощается.
Но в этом случае возможно упростить факториал после вычисления операнда.

@c ===beg===
@c [(%i + 1)!, %pi!, %e!, (cos(1) + sin(1))!];
@c ev (%, numer, %enumer);
@c ===end===
@example
(%i1) [(%i + 1)!, %pi!, %e!, (cos(1) + sin(1))!];
(%o1)      [(%i + 1)!, %pi!, %e!, (sin(1) + cos(1))!]
(%i2) ev (%, numer, %enumer);
(%o2) [(%i + 1)!, 7.188082728976037, 4.260820476357, 
                                               1.227580202486819]
@end example

Факториал символа, не имеющего значения, не упрощается.

@c ===beg===
@c kill (foo);
@c foo!;
@c ===end===
@example
(%i1) kill (foo);
(%o1)                         done
(%i2) foo!;
(%o2)                         foo!
@end example

Факториалы упрощаются, а не вычисляются.
Таким образом, @code{x!} можно заменять даже в экранированном (quoted) выражении.

@c ===beg===
@c '([0!, (7/2)!, 4.77!, 8!, 20!]);
@c ===end===
@example
(%i1) '([0!, (7/2)!, 4.77!, 8!, 20!]);
          105 sqrt(%pi)
(%o1) [1, -------------, 81.44668037931199, 40320, 
               16
                                             2432902008176640000]
@end example

@opencatbox
@category{Операторы} @category{Гамма функции и факториалы}
@closecatbox

@end deffn

@deffn {Оператор} !!
@ifinfo
@fnindex Двойной факториал
@end ifinfo
Оператор двойного факториала.

Для целого, числа с плавающей точкой или рационального числа @code{n},
@code{n!!} вычисляется как произведение @code{n (n-2) (n-4) (n-6) ... (n - 2 (k-1))}
где @code{k} равно @code{entier (n/2)},
то есть, наибольшее целое меньше или равное @code{n/2}.
Заметим, что это определение не совпадает с другими опубликованными определениями
для нецелых аргументов.
@c REPORTED TO BUG TRACKER AS BUG # 1093138 !!!

Для четного (или нечетного) целого @code{n}, @code{n!!} вычисляется как произведение 
всех последовательных четных (или нечетных) целых от 2 (или 1) до @code{n} включительно.

Для аргумента @code{n}, который не является целым, числом с плавающей точкой, или рациональным числом,
@code{n!!} дает невычисляемую форму @code{genfact (n, n/2, 2)}.
@c n!! IS NEITHER SIMPLIFIED NOR EVALUATED IN THIS CASE -- MENTION THAT? OR TOO MUCH DETAIL ???

@opencatbox
@category{Операторы} @category{Гамма функции и факториалы}
@closecatbox

@end deffn

@deffn {Оператор} #
@ifinfo
@fnindex Не равно (синтаксическое неравенство)
@end ifinfo
Обозначает отрицание синтаксического равенства @code{=}.

Заметим, что из-за правил для вычисления предикатных выражений
(в частности из-за того, что @code{not @var{expr}} вызывает вычисление  @var{expr}),
@code{not @var{a} = @var{b}} эквивалентно @code{is(@var{a} # @var{b})},
вместо @code{@var{a} # @var{b}}.

Примеры:

@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

@opencatbox
@category{Операторы}
@closecatbox

@end deffn

@deffn {Оператор} .
@ifinfo
@fnindex Некоммутативное умножение
@end ifinfo
Оператор "точка" предназначен для матричного (некоммутативного) умножения.
Когда @code{"."} используется таким образом, пробелы должны присутствовать с обеих сторон, 
то есть @code{A . B}.  Это позволяет различать оператор от десятичной точки в числе с плавающей точкой.

См. также
@code{dot},
@code{dot0nscsimp},
@code{dot0simp},
@code{dot1simp},
@code{dotassoc},
@code{dotconstrules},
@code{dotdistrib},
@code{dotexptsimp},
@code{dotident},
и
@code{dotscrules}.

@opencatbox
@category{Операторы}
@closecatbox

@end deffn

@deffn {Оператор} :
@ifinfo
@fnindex Присваивание
@end ifinfo
Оператор присваивания. 

Если левая сторона есть простая переменная (не переменная с индексом),
то @code{:} вычисляет правую сторону присваивания 
и присваивает значение с левой частью.

Если левая строна есть индексированный элемент списка, матрица, объявленного Maxima массива или Lisp массива,
то значение правой части присваивается этому элементу.
Индекс должен выделять существующий элемент.
Подобные конструкции нельзя расширить на несуществующие элементы.

Если левая сторона есть индексированный элемент необъявленного массива,
то значение правой части присваивается этому элементу, если таковой уже существует,
или вновь созданному объекту, если он еще не существует.

Если левая строна присваивания есть список простых переменных и/или переменных с индексом, то
правая часть должна вычисляться в список, и элементы этого списка присваиваются
элементам левой части параллельно.

См. также @code{kill} и @code{remvalue},
которые отменяют присваивание.

Примеры:

Присваивание простой переменной.

@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

Присваивание элементу списка.

@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

Присваивание создает необъявленный массив.

@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

Множественные присваивания.

@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

Множественные присваивания выполняются параллельно.
В этом примере переменные @code{a} и @code{b} обмениваются значениями.

@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

@opencatbox
@category{Вычисление} @category{Операторы}
@closecatbox

@end deffn

@deffn {Оператор} ::
@ifinfo
@fnindex Присваивание (с вычислением левого выражения)
@end ifinfo
Оператор присваивания.  

Оператор @code{::} аналогичен оператору присваивания @code{:} 
за исключением того, что @code{::} вычисляет свою левую часть наряду с вычислением правой части.

Примеры:

@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

@opencatbox
@category{Вычисление} @category{Операторы}
@closecatbox

@end deffn

@deffn {Оператор} ::=
@ifinfo
@fnindex Определение макро функции
@end ifinfo
Оператор определения макро функции.
@code{::=} задает функцию (называемую "макрос" по историческим причинам)
которое экранирует (quote) свои аргументы,
и выражение, которое она возвращает (называемое "макро расширение"),
вычисляется в том контексте, из которого этот макрос был вызван.
В других отношениях макро функция такая же как и обыкновенная функция.

Функция @code{macroexpand} возвращает макро расширение (без ее вычисления).
@code{macroexpand (foo (x))} следующее за @code{''%} эквивалентно @code{foo (x)},
где @code{foo} есть макро функция.

Оператор @code{::=} помещает имя новой макро функции в глобальный список @code{macros}.
Функции @code{kill}, @code{remove} и @code{remfunction} удаляет определения макро функций 
и удаляет имена из @code{macros}.

Функции @code{fundef} или @code{dispfun}, соответственно, 
возвращает определение макро функции или присваивает его метке.

Макро функции обычно содержат @code{buildq} и @code{splice}
выражения для конструирования выражения,
которое затем вычисляется.

Примеры.

Макро функция экранирует свои аргументы,
так что сообщение (1) показывает выражение @code{y - z}, а не значение @code{y - z}.
Макро расширение (экранированное выражение @code{'(print ("(2) x  равно ", x))}
вычисляется в том контексте, из которого этот макрос был вызван,
печатая сообщение (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;
(%o1)                          %pi
(%i2) y: 1234;
(%o2)                         1234
(%i3) z: 1729 * w;
(%o3)                        1729 w
(%i4) printq1 (x) ::= block (print ("(1) x is equal to", x),
      '(print ("(2) x is equal to", x)));
(%o4) 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

Обыкновенная функция вычисляет свои аргументы, так что сообщение (1) показывает значение @code{y - z}.
Возвращаемое значение не вычисляется, так что сообщение (2) не печатается
до момента явного вычисления @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;
(%o1)                          %pi
(%i2) y: 1234;
(%o2)                         1234
(%i3) z: 1729 * w;
(%o3)                        1729 w
(%i4) printe1 (x) := block (print ("(1) x is equal to", x),
      '(print ("(2) x is equal to", x)));
(%o4) 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} возвращает макро расширение.
Выражение @code{macroexpand (foo (x))}, идущее перед @code{''%} эквивалентно @code{foo (x)},
когда @code{foo} есть макро функция.

@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;
(%o1)                          %pi
(%i2) y: 1234;
(%o2)                         1234
(%i3) z: 1729 * w;
(%o3)                        1729 w
(%i4) g (x) ::= buildq ([x], print ("x is equal to", x));
(%o4)    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

@opencatbox
@category{Определение функций} @category{Операторы}
@closecatbox

@end deffn

@deffn {Оператор} :=
@ifinfo
@fnindex Определение функции
@end ifinfo

Оператор определения функции.

@code{@var{f}(@var{x_1}, ..., @var{x_n}) := @var{expr}}
определяет функцию с именем @var{f}, аргументами @var{x_1}, ..., @var{x_n} и телом функции @var{expr}.
Оператор @code{:=} никогда не вычисляет тело функции (если только вычисление не задано явно оператором
кавычка-кавычка @code{'@w{}'}).
Функция заданная таким образом может быть обыкновенной Maxima функцией (с аргументами, заключенными в скобки)
или функцией массивом (с аргументами, заключенными в квадратные скобки).

Когда последний или единственный аргумент функции @var{x_n} есть список из одного элемента,
функция, заданная @code{:=} принимает переменное число аргументов.
Фактические аргументы присваиваются один-в-один формальным аргументам @var{x_1}, ..., @var{x_(n - 1)},
и любые дальнейшие фактические аргументы, если присутствуют, присваиваются к @var{x_n} как список.

Все определения функций появляются в том же пространстве имен;
задав функцию @code{f} внутри другой функции @code{g}, определение
не ограничивает зону видимости @code{f} в @code{g}.

Если некоторый формальный аргумент @var{x_k} есть экранированный (quoted) символ,
функция, заданная с помощью @code{:=}, не вычисляет соответствующий фактический аргумент.
В противном случае, все фактические аргументы вычисляются.

См. также @code{define} и @code{::=}.

Примеры:

@code{:=} никогда не вычисляет тело функции (если только явно не задано вычисление).

@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

Функция, заданная @code{:=}, может быть обыкновенной Maxima функцией или функцией массивом.

@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

Когда последний или единственный аргумент функции @var{x_n} есть список из одного элемента,
функция, заданная @code{:=}, принимает переменное число аргументов.

@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

@opencatbox
@category{Определение функций} @category{Операторы}
@closecatbox

@end deffn

@deffn {Оператор} =
@ifinfo
@fnindex Оператор равенства
@fnindex Равенство (синтаксическое равенство)
@end ifinfo
Оператор равенства.

Выражение @code{@var{a} = @var{b}}, само по себе, представляет собой
невычисляемое уравнение, которое может или может не выполняться.
Невычисляемые уравнения могут появляться как аргументы в @code{solve} и @code{algsys},
или в некоторых других функциях.

Функция @code{is} вычисляет @code{=} до логического значения.
@code{is(@var{a} = @var{b})} вычисляет @code{@var{a} = @var{b}} в @code{true}, когда @var{a} и @var{b}
тождественны. То есть, @var{a} и @var{b} есть атомы, которые идентичны,
или они не атомы и их операторы идентичны и их аргументы идентичны.
В противном случае, @code{is(@var{a} = @var{b})} вычисляется в @code{false};
он никогда не вычисляется в @code{unknown}.
Когда @code{is(@var{a} = @var{b})} есть @code{true}, говорят что @var{a} и @var{b} синтаксически равны,
в противоположность эквивалентным выражениям, для которых @code{is(equal(@var{a}, @var{b}))} есть @code{true}.
Выражения могут быть равны, но синтаксически не равны.

Отрицание @code{=} представляется как @code{#}.
Как и в случае с @code{=}, выражение @code{@var{a} # @var{b}}, само по себе, не вычисляется.
@code{is(@var{a} # @var{b})} вычисляется @code{@var{a} # @var{b}} до
@code{true} или @code{false}.

Кроме @code{is},
некоторые другие операторы вычисляют @code{=} и @code{#} до @code{true} или @code{false},
а именно @code{if}, @code{and}, @code{or} и @code{not}.

Заметим, что из-за правил для вычисления предикатных выражений
(в частности из-за того, что @code{not @var{expr}} вызывает вычисление @var{expr}),
@code{not @var{a} = @var{b}} эквивалентно @code{is(@var{a} # @var{b})},
а не @code{@var{a} # @var{b}}.

@code{rhs} и @code{lhs} возвращают правую и левую часть
уравнения или неравенства соответственно.

См. также @code{equal} или @code{notequal}.

Примеры:

Выражение @code{@var{a} = @var{b}}, само по себе, представляет
невычисляемое уравнение, которое может или может не выполняться.

@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})} вычисляет @code{@var{a} = @var{b}} в @code{true}, 
когда @var{a} и @var{b} тождественны (синтаксически равны).
Выражения могут быть равны, но синтаксически не равны.

@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

Некоторые операторы вычисляют @code{=} и @code{#} до @code{true} или @code{false}.

@c ===beg===
@c if expand ((x + y)^2) = x^2 + 2 * x * y + y^2 then FOO else 
@c       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

Из-за того, что @code{not @var{expr}} вызывает вычисление @var{expr},
@code{not @var{a} = @var{b}} эквивалентно @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

@opencatbox
@category{Операторы}
@closecatbox

@end deffn

@c NEEDS EXAMPLES
@deffn {Оператор} and
@ifinfo
@fnindex Логическое умножение
@end ifinfo
Оператор логического умножения.
Оператор @code{and} есть n-арный инфиксный оператор.
Его операнды есть логические выражения и его результат есть логическое значение.

Оператор @code{and} вызывает вычисление (как и @code{is}) одного или более операндов,
и может вызвать вычисление всех операндов.

Операнды вычисляются в том же порядка, к котором они встречаются.
Оператор @code{and} вычисляет только столько своих операндов, сколько необходимо для того, 
чтобы определить результат.
Если хотя бы один операнд есть @code{false},
результат есть @code{false}, и более ни один из операндов не вычисляется.

Глобальный флаг @code{prederror} управляет поведением @code{and},
когда вычисляемый операнд не может быть определен как @code{true} или @code{false}.
Оператор @code{and} печатает сообщение об ошибке, когда @code{prederror} есть @code{true}.
Иначе, операнды, которые не могут быть вычислены как @code{true} или @code{false}, принимаются,
и результат есть логическое выражение.

Оператор @code{and} не является коммутативным:
@code{a and b} может быть не равно @code{b and a} из-за трактовки неопределенных операндов.

@opencatbox
@category{Операторы}
@closecatbox

@end deffn

@c NEEDS EXAMPLES
@deffn {Оператор} or
@ifinfo
@fnindex Логическое сложение
@end ifinfo
Оператор логического сложения.
@code{or} есть n-арный инфиксный оператор.
Его операнды есть логические выражения и его результат есть логическое значение.

@code{or} вызывает вычисление (как и @code{is}) одного или более операндов,
и может вызвать вычисление всех операндов.

Операнды вычисляются в том же порядка, к котором они встречаются.
@code{or} вычисляет только столько своих операндов, сколько необходимо для того, чтобы определить результат.
Если хотя бы один операнд есть @code{true},
результат есть @code{true}, и более ни один из операндов не вычисляется.

Глобальный флаг @code{prederror} управляет поведением @code{or},
когда вычисляемый операнд не может быть определен как @code{true} или @code{false}.
Оператор @code{or} печатает сообщение об ошибке, когда @code{prederror} есть @code{true}.
Иначе, операнды, которые не могут быть вычислены как @code{true} или @code{false}, принимаются,
и результат есть логическое выражение.

Оператор @code{or} не является коммутативным:
@code{a or b} может быть не равно @code{b or a} из-за трактовки неопределенных операндов.

@opencatbox
@category{Операторы}
@closecatbox

@end deffn

@c NEEDS EXAMPLES
@deffn {Оператор} not
@ifinfo
@fnindex Логическое отрицание
@end ifinfo
Оператор логического отрицания.
Оператор @code{not} есть префиксный оператор.
Его операнд есть логическое выражение и его результат есть логическое значение.

Оператор @code{not} вызывает вычисление (как и @code{is}) своего операнда.

Глобальный флаг @code{prederror} управляет поведением @code{not},
когда его операнд не может быть определен как значения @code{true} или @code{false}.
Оператор @code{not} печатает сообщение об ошибке, когда @code{prederror} есть @code{true}.
Иначе, операнды, которые не могут быть вычислены как @code{true} или @code{false}, принимаются,
и результат есть логическое выражение.

@opencatbox
@category{Операторы}
@closecatbox

@end deffn

@deffn {Функция} abs (@var{expr})
Возвращает абсолютное значение @var{expr} (модуль выражения). 
Если @var{expr} - комплексное, возвращается комплексный модуль @var{expr}.

@opencatbox
@category{Математические функции}
@closecatbox

@end deffn

@defvr {Ключевое слово} additive
Если @code{declare(f,additive)} было выполнено, то:

(1) Если @code{f} одномерно, пока упрощение не столкнулось с @code{f} примененному к сумме, 
@code{f} будет распространено вдоль этой суммы.  То есть, @code{f(y+x)} будет
упрощено как @code{f(y)+f(x)}.

(2) Если @code{f} есть функция двух или более аргументов, аддитивность задается как 
аддитивность по первому аргументу @code{f}, как в случае @code{sum} или 
@code{integrate}, то есть @code{f(h(x)+g(x),x)} будет упрощено как @code{f(h(x),x)+f(g(x),x)}.
Это упрощение не произойдет, когда @code{f} применена к выражению вида @code{sum(x[i],i,lower-limit,upper-limit)}.

@opencatbox
@category{Операторы} @category{Факты и выводы}
@closecatbox

@end defvr

@c NEEDS TO BE REWORKED. NOT CONVINCED THIS SYMBOL NEEDS ITS OWN ITEM
@c (SHOULD BE DESCRIBED IN CONTEXT OF EACH FUNCTION WHICH RECOGNIZES IT)
@defvr {Ключевое слово} allbut
Работает с командами @code{part} (например, @code{part}, @code{inpart}, @code{substpart},
@code{substinpart}, @code{dpart} и @code{lpart}).  Например:

@c ===beg===
@c expr : e + d + c + b + a;
@c part (expr, [2, 5]);
@c ===end===
@example
(%i1) expr : e + d + c + b + a;
(%o1)                   e + d + c + b + a
(%i2) part (expr, [2, 5]);
(%o2)                         d + a
@end example

хотя

@c ===beg===
@c expr : e + d + c + b + a;
@c part (expr, allbut (2, 5));
@c ===end===
@example
(%i1) expr : e + d + c + b + a;
(%o1)                   e + d + c + b + a
(%i2) part (expr, allbut (2, 5));
(%o2)                       e + c + b
@end example

@code{allbut} также распознается @code{kill}.

@c ===beg===
@c [aa : 11, bb : 22, cc : 33, dd : 44, ee : 55];
@c kill (allbut (cc, dd));
@c [aa, bb, cc, dd];
@c ===end===
@example
(%i1) [aa : 11, bb : 22, cc : 33, dd : 44, ee : 55];
(%o1)                 [11, 22, 33, 44, 55]
(%i2) kill (allbut (cc, dd));
(%o0)                         done
(%i1) [aa, bb, cc, dd];
(%o1)                   [aa, bb, 33, 44]
@end example

@code{kill(allbut(@var{a_1}, @var{a_2}, ...))} имеет тот же эффект, что  @code{kill(all)}
за исключением того, что это не очищает символы @var{a_1}, @var{a_2}, ... .

@end defvr

@defvr {Декларация} antisymmetric
Если @code{declare(h,antisymmetric)} выполнена, этот говорит 
упрощателю, что @code{h} - антисимметричная.  Например, @code{h(x,z,y)}  упростится до
@code{- h(x, y, z)}.  То есть, это дает (-1)^n умноженное на @code{symmetric} 
или @code{commutative} результат, где n есть число перестановок двух
аргументов необходимых для того, чтобы перевести к конечной форме.

@opencatbox
@category{Операторы} @category{Факты и выводы}
@closecatbox

@end defvr

@deffn {Функция} cabs (@var{expr})
Возвращает комплексное абсолютное значение (комплексный модуль) @var{expr}.

@opencatbox
@category{Комплексные переменные}
@closecatbox

@end deffn

@deffn {Функция} ceiling (@var{x})

Когда @var{x} есть вещественное число - возвращает наименьшее целое, которое 
больше чем или равно @var{x}.  

Если @var{x} - константное выражение (@code{10 * %pi}, например), 
@code{ceiling} вычисляет @var{x} используя большие числа с плавающей точкой и 
применяет @code{ceiling} к конечному большому числу с плавающей точкой. 
Из-за того, что @code{ceiling} использует вычисления
с числами с плавающей точкой, возможно, хотя маловероятно, 
что @code{ceiling} может вернуть ошибочное значение для константных
входных данных. Чтобы защититься от ошибок, вычисление с числами с плавающей точкой
выполняется с использованием трех значений для @code{fpprec}.

Для неконстантных входных данных, @code{ceiling} пытается вернуть упрощенное
значение. Вот примеры упрощений, о которых @code{ceiling}
знает:

@c ===beg===
@c ceiling (ceiling (x));
@c ceiling (floor (x));
@c declare (n, integer)$
@c [ceiling (n), ceiling (abs (n)), ceiling (max (n, 6))];
@c assume (x > 0, x < 1)$
@c ceiling (x);
@c tex (ceiling (a));
@c ===end===
@example
(%i1) ceiling (ceiling (x));
(%o1)                      ceiling(x)
(%i2) ceiling (floor (x));
(%o2)                       floor(x)
(%i3) declare (n, integer)$
(%i4) [ceiling (n), ceiling (abs (n)), ceiling (max (n, 6))];
(%o4)                [n, abs(n), max(n, 6)]
(%i5) assume (x > 0, x < 1)$
(%i6) ceiling (x);
(%o6)                           1
(%i7) tex (ceiling (a));
$$\left \lceil a \right \rceil$$
(%o7)                         false
@end example

Функция @code{ceiling} автоматически не распространяется (map) для списков или матриц.
Наконец, для всех входных данных, которые объявлены комплексными, 
@code{ceiling} возвращает невычисляемую форму.

Если диапазон функции есть подмножество целых, она может быть
объявлена как @code{integervalued}. Обе функции @code{ceiling} и @code{floor} 
могут использовать эту информацию. Например:

@c ===beg===
@c declare (f, integervalued)$
@c floor (f(x));
@c ceiling (f(x) - 1);
@c ===end===
@example
(%i1) declare (f, integervalued)$
(%i2) floor (f(x));
(%o2)                         f(x)
(%i3) ceiling (f(x) - 1);
(%o3)                       f(x) - 1
@end example

@opencatbox
@category{Математические функции}
@closecatbox

@end deffn

@deffn {Функция} charfun (@var{p})

Возвращает 0, когда предикат @var{p} вычисляется как @code{false}; возвращает
1, когда предикат вычисляется как @code{true}.  Когда предикат
вычисляется до чего-то другого, чем @code{true} или @code{false} (unknown), 
возвращает невычисляемую форму.

Примеры:

@c ===beg===
@c charfun (x < 1);
@c subst (x = -1, %);
@c e : charfun ('"and" (-1 < x, x < 1))$
@c [subst (x = -1, e), subst (x = 0, e), subst (x = 1, e)];
@c ===end===
@example
(%i1) charfun (x < 1);
(%o1)                    charfun(x < 1)
(%i2) subst (x = -1, %);
(%o2)                           1
(%i3) e : charfun ('"and" (-1 < x, x < 1))$
(%i4) [subst (x = -1, e), subst (x = 0, e), subst (x = 1, e)];
(%o4)                       [0, 1, 0]
@end example

@opencatbox
@category{Математические функции}
@closecatbox

@end deffn

@defvr {Декларация} commutative
Если @code{declare(h,commutative)} выполнено, это говорит 
упрощателю, что @code{h} есть коммутативная функция.  То есть @code{h(x,z,y)} 
упроститься до @code{h(x, y, z)}.  Это тоже самое, что и @code{symmetric}.

@opencatbox
@category{Операторы} @category{Факты и выводы} 
@closecatbox

@end defvr

@deffn {Функция} compare (@var{x}, @var{y})

Возвращает оператор отношения @var{op}
(@code{<}, @code{<=}, @code{>}, @code{>=}, @code{=} или @code{#}) так что
@code{is (@var{x} @var{op} @var{y})} вычисляется до @code{true};
когда @var{x} или @var{y} зависит от @code{%i} и
@code{@var{x} # @var{y}}, возвращает @code{notcomparable};
когда нет такого оператора или
Maxima не может определить оператор, возвращает @code{unknown}.

Примеры:

@c ===beg===
@c compare (1, 2);
@c compare (1, x);
@c compare (%i, %i);
@c compare (%i, %i + 1);
@c compare (1/x, 0);
@c compare (x, abs(x));
@c ===end===
@example
(%i1) compare (1, 2);
(%o1)                           <
(%i2) compare (1, x);
(%o2)                        unknown
(%i3) compare (%i, %i);
(%o3)                           =
(%i4) compare (%i, %i + 1);
(%o4)                     notcomparable
(%i5) compare (1/x, 0);
(%o5)                           #
(%i6) compare (x, abs(x));
(%o6)                          <=
@end example

Функция @code{compare} не пытается определить, действительно ли области определения ее аргументов непусты. 
Таким образом

@c ===beg===
@c compare (acos (x^2 + 1), acos (x^2 + 1) + 1);
@c ===end===
@example
(%i1) compare (acos (x^2 + 1), acos (x^2 + 1) + 1);
(%o1)                           <
@end example

@c IT IS NOT QUITE TRUE, WHAT ABOUT x=0 ?
Действительная область определения @code{acos (x^2 + 1)} пуста.

@opencatbox
@category{Факты и выводы} 
@closecatbox

@end deffn

@deffn {Функция} entier (@var{x})
Возвращает наибольшее целое меньше или равное чем @var{x}, где @var{x} - численное.  
Функция @code{fix} (как и в @code{fixnum}) есть синоним, 
так что @code{fix(@var{x})} в точности тоже самое.

@opencatbox
@category{Математические функции} 
@closecatbox

@end deffn

@deffn {Функция} equal (@var{a}, @var{b})
Представляет эквивалентность, то есть, равное значение.

Само по себе, @code{equal} не вычисляется или упрощается.
Функция @code{is} пытается вычислить @code{equal} до логического значения.
Функция @code{is(equal(@var{a}, @var{b}))} 
возвращает @code{true} (или @code{false}), если
и только если, @var{a} и @var{b} равны (или не равны) для всех возможных
значений своих переменных, как определено вычислением @code{ratsimp(@var{a} - @var{b})}.
Если @code{ratsimp} возвращает 0, два выражения рассматриваются эквивалентными.
Два выражения могут быть эквивалентными даже если они не являются синтаксически равными (то есть, идентичными).

Когда @code{is} не может упростить @code{equal} до @code{true} или @code{false},
результат управляется глобальным флагом @code{prederror}.
Когда @code{prederror} есть @code{true},
@code{is} выдает сообщение об ошибке.
Иначе, @code{is} возвращает @code{unknown}.

В добавление к @code{is},
некоторые другие операторы вычисляют @code{equal} и @code{notequal} до @code{true} или @code{false},
а именно @code{if}, @code{and}, @code{or} и @code{not}.

@c FOLLOWING STATEMENT IS MORE OR LESS TRUE BUT I DON'T THINK THE DETAILS ARE CORRECT
@c Declarations (integer, complex, etc)
@c for variables appearing in @var{a} and @var{b} are ignored by @code{equal}.
@c All variables are effectively assumed to be real-valued.

Отрицанием @code{equal} является @code{notequal}.

Примеры:

Само по себе, @code{equal} не вычисляет и не упрощает.

@c ===beg===
@c equal (x^2 - 1, (x + 1) * (x - 1));
@c equal (x, x + 1);
@c equal (x, y);
@c ===end===
@example
(%i1) equal (x^2 - 1, (x + 1) * (x - 1));
                        2
(%o1)            equal(x  - 1, (x - 1) (x + 1))
(%i2) equal (x, x + 1);
(%o2)                    equal(x, x + 1)
(%i3) equal (x, y);
(%o3)                      equal(x, y)
@end example

Функция @code{is} пытается вычислить @code{equal} до логического значения.
@code{is(equal(@var{a}, @var{b}))} возвращает @code{true} когда @code{ratsimp(@var{a} - @var{b})} возвращает 0.
Два выражения могут быть эквивалентными даже если они синтаксически не равны (то есть, не идентичны).

@c ===beg===
@c ratsimp (x^2 - 1 - (x + 1) * (x - 1));
@c is (equal (x^2 - 1, (x + 1) * (x - 1)));
@c is (x^2 - 1 = (x + 1) * (x - 1));
@c ratsimp (x - (x + 1));
@c is (equal (x, x + 1));
@c is (x = x + 1);
@c ratsimp (x - y);
@c is (equal (x, y));
@c is (x = y);
@c ===end===
@example
(%i1) ratsimp (x^2 - 1 - (x + 1) * (x - 1));
(%o1)                           0
(%i2) is (equal (x^2 - 1, (x + 1) * (x - 1)));
(%o2)                         true
(%i3) is (x^2 - 1 = (x + 1) * (x - 1));
(%o3)                         false
(%i4) ratsimp (x - (x + 1));
(%o4)                          - 1
(%i5) is (equal (x, x + 1));
(%o5)                         false
(%i6) is (x = x + 1);
(%o6)                         false
(%i7) ratsimp (x - y);
(%o7)                         x - y
(%i8) is (equal (x, y));
(%o8)                        unknown
(%i9) is (x = y);
(%o9)                         false
@end example

Когда @code{is} не может упростить @code{equal} до @code{true} или @code{false},
результат управляется глобальным флагом @code{prederror}.

@c ===beg===
@c [aa : x^2 + 2*x + 1, bb : x^2 - 2*x - 1];
@c ratsimp (aa - bb);
@c prederror : true;
@c is (equal (aa, bb));
@c prederror : false;
@c is (equal (aa, bb));
@c ===end===
@example
(%i1) [aa : x^2 + 2*x + 1, bb : x^2 - 2*x - 1];
                    2             2
(%o1)             [x  + 2 x + 1, x  - 2 x - 1]
(%i2) ratsimp (aa - bb);
(%o2)                        4 x + 2
(%i3) prederror : true;
(%o3)                         true
(%i4) is (equal (aa, bb));
Maxima was unable to evaluate the predicate:
       2             2
equal(x  + 2 x + 1, x  - 2 x - 1)
 -- an error.  Quitting.  To debug this try debugmode(true);
(%i5) prederror : false;
(%o5)                         false
(%i6) is (equal (aa, bb));
(%o6)                        unknown
@end example

Некоторые операторы вычисляют @code{equal} или @code{notequal} до @code{true} или @code{false}.

@c ===beg===
@c if equal (y, y - 1) then FOO else BAR;
@c eq_1 : equal (x, x + 1);
@c eq_2 : equal (y^2 + 2*y + 1, (y + 1)^2);
@c [eq_1 and eq_2, eq_1 or eq_2, not eq_1];
@c ===end===
@example
(%i1) if equal (y, y - 1) then FOO else BAR;
(%o1)                          BAR
(%i2) eq_1 : equal (x, x + 1);
(%o2)                    equal(x, x + 1)
(%i3) eq_2 : equal (y^2 + 2*y + 1, (y + 1)^2);
                         2                   2
(%o3)             equal(y  + 2 y + 1, (y + 1) )
(%i4) [eq_1 and eq_2, eq_1 or eq_2, not eq_1];
(%o4)                  [false, true, true]
@end example

Из-за того, что @code{not @var{expr}} вызывает вычисление @var{expr},
@code{not equal(@var{a}, @var{b})} эквивалентно @code{is(notequal(@var{a}, @var{b}))}.

@c ===beg===
@c [notequal (2*z, 2*z - 1), not equal (2*z, 2*z - 1)];
@c is (notequal (2*z, 2*z - 1));
@c ===end===
@example
(%i1) [notequal (2*z, 2*z - 1), not equal (2*z, 2*z - 1)];
(%o1)            [notequal(2 z, 2 z - 1), true]
(%i2) is (notequal (2*z, 2*z - 1));
(%o2)                         true
@end example

@opencatbox
@category{Операторы} 
@closecatbox

@end deffn

@deffn {Функция} floor (@var{x})

Когда @var{x} есть вещественное число - возвращает наибольшее целое, которое 
меньше или равно @var{x}.

Если @var{x} есть константное выражение (@code{10 * %pi}, например), 
@code{floor} вычисляет @var{x} используя большие числа с плавающей точкой и 
применяет @code{floor} к результирующему значению. 
Из-за того, что @code{floor} использует вычисления с числами с плавающей точкой, возможно, хотя маловероятно, 
что @code{floor} может вернуть ошибочное значение для константных 
входных данных. Чтобы застраховаться от ошибок, вычисление с числами с плавающей точкой выполняется, 
используя три значения для @code{fpprec}.

Для неконстантных входных данных, @code{floor} пытается вернуть упрощенное
значение.  Вот примеры упрощений, о которых @code{floor}
знает:

@c ===beg===
@c floor (ceiling (x));
@c floor (floor (x));
@c declare (n, integer)$
@c [floor (n), floor (abs (n)), floor (min (n, 6))];
@c assume (x > 0, x < 1)$
@c floor (x);
@c tex (floor (a));
@c ===end===
@example
(%i1) floor (ceiling (x));
(%o1)                      ceiling(x)
(%i2) floor (floor (x));
(%o2)                       floor(x)
(%i3) declare (n, integer)$
(%i4) [floor (n), floor (abs (n)), floor (min (n, 6))];
(%o4)                [n, abs(n), min(n, 6)]
(%i5) assume (x > 0, x < 1)$
(%i6) floor (x);
(%o6)                           0
(%i7) tex (floor (a));
$$\left \lfloor a \right \rfloor$$
(%o7)                         false
@end example

Функция @code{floor} автоматически не распространяется (map) для списков или матриц.
Наконец, для всех входных данных, которые заданы как комплексные, @code{floor} возвращает невычисляемую форму.

Если диапазон функции есть подмножество целых, она может быть
объявлена как @code{integervalued}. Обе функции @code{ceiling} и @code{floor} 
могут использовать эту информацию. Например:

@c ===beg===
@c declare (f, integervalued)$
@c floor (f(x));
@c ceiling (f(x) - 1);
@c ===end===
@example
(%i1) declare (f, integervalued)$
(%i2) floor (f(x));
(%o2)                         f(x)
(%i3) ceiling (f(x) - 1);
(%o3)                       f(x) - 1
@end example

@opencatbox
@category{Математические функции} 
@closecatbox

@end deffn

@deffn {Функция} notequal (@var{a}, @var{b})
Представляет собой отрицание @code{equal(@var{a}, @var{b})}.

Примеры:

@c ===beg===
@c equal (a, b);
@c maybe (equal (a, b));
@c notequal (a, b);
@c not equal (a, b);
@c maybe (notequal (a, b));
@c assume (a > b);
@c equal (a, b);
@c maybe (equal (a, b));
@c notequal (a, b);
@c maybe (notequal (a, b));
@c ===end===
@example
(%i1) equal (a, b);
(%o1)                      equal(a, b)
(%i2) maybe (equal (a, b));
(%o2)                        unknown
(%i3) notequal (a, b);
(%o3)                    notequal(a, b)
(%i4) not equal (a, b);
(%o4)                    notequal(a, b)
(%i5) maybe (notequal (a, b));
(%o5)                        unknown
(%i6) assume (a > b);
(%o6)                        [a > b]
(%i7) equal (a, b);
(%o7)                      equal(a, b)
(%i8) maybe (equal (a, b));
(%o8)                         false
(%i9) notequal (a, b);
(%o9)                    notequal(a, b)
(%i10) maybe (notequal (a, b));
(%o10)                        true
@end example

@opencatbox
@category{Операторы} 
@closecatbox

@end deffn

@c NEEDS EXPANSION, CLARIFICATION, AND EXAMPLES
@c NOTE THAT eval IS RECOGNIZED ONLY AS AN ARGUMENT TO ev,
@c BUT FOR SOME REASON eval DOES NOT HAVE THE evflag PROPERTY
@deffn {Оператор} eval
Как аргумент в вызове к @code{ev (@var{expr})},
@code{eval} вызывает дополнительное вычисление @var{expr}.
См. @code{ev}.

@opencatbox
@category{Флаги вычисления} 
@closecatbox

@end deffn

@deffn {Функция} evenp (@var{expr})
Возвращает @code{true} если @var{expr} есть четное целое.
@c THIS IS STRANGE -- SHOULD RETURN NOUN FORM IF INDETERMINATE
@code{false} возвращается во всех других случаях.

@opencatbox
@category{Функции предикаты} 
@closecatbox

@end deffn

@deffn {Функция} fix (@var{x})
Синоним для @code{entier (@var{x})}.

@opencatbox
@category{Математические функции} 
@closecatbox

@end deffn

@deffn {Функция} fullmap (@var{f}, @var{expr_1}, ...)
Аналогично @code{map}, но @code{fullmap} продолжает процедуру распространения 
для всех подвыражений до тех пор, пока основные операторы более не остаются теми же самыми.

Функция @code{fullmap} используется Maxima
упрощателем для некоторых матричных манипуляций. Таким образом, Maxima иногда генерирует
сообщение об ошибке, касающееся @code{fullmap} хотя @code{fullmap} явно не вызывалась пользователем.

Примеры:

@c ===beg===
@c a + b * c;
@c fullmap (g, %);
@c map (g, %th(2));
@c ===end===
@example
(%i1) a + b * c;
(%o1)                        b c + a
(%i2) fullmap (g, %);
(%o2)                   g(b) g(c) + g(a)
(%i3) map (g, %th(2));
(%o3)                     g(b c) + g(a)
@end example

@opencatbox
@category{Применение функций} @category{Выражения}
@closecatbox

@end deffn

@deffn {Функция} fullmapl (@var{f}, @var{list_1}, ...)
Аналогично @code{fullmap}, но @code{fullmapl} только распространяется на
списки и матрицы.

Пример:

@c ===beg===
@c fullmapl ("+", [3, [4, 5]], [[a, 1], [0, -1.5]]);
@c ===end===
@example
(%i1) fullmapl ("+", [3, [4, 5]], [[a, 1], [0, -1.5]]);
(%o1)                [[a + 3, 4], [4, 3.5]]
@end example

@opencatbox
@category{Применение функций} @category{Выражения}
@closecatbox

@end deffn

@deffn {Функция} is (@var{expr})
Пытается определить, является ли предикат @var{expr} 
доказуемым из фактов в базе данных @code{assume}.

Если этот предикат является доказуемым как @code{true} или @code{false},
@code{is} возвращает @code{true} или @code{false}, соответственно.
Иначе, возвращаемое значение управляется глобальным флагом @code{prederror}.
Когда @code{prederror} есть @code{true},
@code{is} выдает сообщение об ошибке.
Иначе, @code{is} возвращает @code{unknown}.

Выражение @code{ev(@var{expr}, pred)}
(который можно переписать как @code{@var{expr}, pred} в интерактивной строке)
эквивалентно @code{is(@var{expr})}.

См. также @code{assume}, @code{facts} и @code{maybe}.

Примеры:

@code{is} вызывает вычисление предикатов.

@c ===beg===
@c %pi > %e;
@c is (%pi > %e);
@c ===end===
@example
(%i1) %pi > %e;
(%o1)                       %pi > %e
(%i2) is (%pi > %e);
(%o2)                         true
@end example

@code{is} пытается вывести предикаты из базы данных @code{assume}.

@c ===beg===
@c assume (a > b);
@c assume (b > c);
@c is (a < b);
@c is (a > c);
@c is (equal (a, c));
@c ===end===
@example
(%i1) assume (a > b);
(%o1)                        [a > b]
(%i2) assume (b > c);
(%o2)                        [b > c]
(%i3) is (a < b);
(%o3)                         false
(%i4) is (a > c);
(%o4)                         true
(%i5) is (equal (a, c));
(%o5)                         false
@end example

Если @code{is} не может доказать или опровергнуть предикат из базы данных @code{assume},
глобальный флаг @code{prederror} управляет поведением @code{is}.

@c ===beg===
@c assume (a > b);
@c prederror: true$
@c is (a > 0);
@c prederror: false$
@c is (a > 0);
@c ===end===
@example
(%i1) assume (a > b);
(%o1)                        [a > b]
(%i2) prederror: true$
(%i3) is (a > 0);
Maxima was unable to evaluate the predicate:
a > 0
 -- an error.  Quitting.  To debug this try debugmode(true);
(%i4) prederror: false$
(%i5) is (a > 0);
(%o5)                        unknown
@end example

@opencatbox
@category{Функции предикаты} @category{Факты и выводы}
@closecatbox

@end deffn

@deffn {Функция} maybe (@var{expr})
Пытается определить, является ли предикат @var{expr} 
 доказуемым исходя из фактов в базе данных @code{assume}.

Если этот предикат доказуем как @code{true} или @code{false},
@code{maybe} возвращает @code{true} или @code{false}, соответственно.
Иначе, @code{maybe} возвращает @code{unknown}.

@code{maybe} функционально эквивалентен @code{is} с @code{prederror: false},
но результат вычислен без реального присвоение значения @code{prederror}.

См. также @code{assume}, @code{facts} и @code{is}.

Примеры:

@c ===beg===
@c maybe (x > 0);
@c assume (x > 1);
@c maybe (x > 0);
@c ===end===
@example
(%i1) maybe (x > 0);
(%o1)                        unknown
(%i2) assume (x > 1);
(%o2)                        [x > 1]
(%i3) maybe (x > 0);
(%o3)                         true
@end example

@opencatbox
@category{Функции предикаты} @category{Факты и выводы}
@closecatbox

@end deffn

@deffn {Функция} isqrt (@var{x})
Возвращает "целый квадратный корень"
абсолютного значения @var{x},
которое есть целое.

@opencatbox
@category{Математические функции}
@closecatbox

@end deffn

@deffn {Функция} lmax (@var{L})

Когда @var{L} есть список или множество, возвращает @code{apply ('max, args (@var{L}))}.  Когда @var{L} не является 
списком или множеством, выдает ошибку.

@opencatbox
@category{Математические функции} @category{Списки} @category{Множества}
@closecatbox

@end deffn

@deffn {Функция} lmin (@var{L})

Когда @var{L} есть список или множество, возвращает @code{apply ('min, args (@var{L}))}. Когда @var{L} не является 
списком или множеством, выдает ошибку.

@opencatbox
@category{Математические функции} @category{Списки} @category{Множества}
@closecatbox

@end deffn

@deffn {Функция} max (@var{x_1}, ..., @var{x_n})

Возвращает упрощенное значение максимума выражений от @var{x_1} до @var{x_n}.
Когда @code{get (trylevel, maxmin)} есть 2 или больше, @code{max} использует  упрощение 
@code{max (e, -e) --> |e|}.  Когда @code{get (trylevel, maxmin)} есть 3 или больше, @var{max} старается
исключить выражения, заключенные по значению между двумя другими аргументами. Например,
@code{max (x, 2*x, 3*x) --> max (x, 3*x)}. Для установки значения  @code{trylevel} в 2, используется
@code{put (trylevel, 2, maxmin)}.

@opencatbox
@category{Математические функции}
@closecatbox

@end deffn

@deffn {Функция} min (@var{x_1}, ..., @var{x_n})

Возвращает упрощенное значение минимума выражений от @var{x_1} до @var{x_n}.
Когда @code{get (trylevel, maxmin)} есть 2 или больше, @code{min} использует  упрощение
@code{min (e, -e) --> -|e|}.  Когда @code{get (trylevel, maxmin)} есть 3 или больше, @var{min} старается
исключить выражения, заключенные по значению между двумя другими аргументами. Например,
@code{min (x, 2*x, 3*x) --> min (x, 3*x)}. Для установки значения  @code{trylevel} в 2, используется
@code{put (trylevel, 2, maxmin)}.

@opencatbox
@category{Математические функции}
@closecatbox

@end deffn

@deffn {Функция} polymod (@var{p})
@deffnx {Функция} polymod (@var{p}, @var{m})
Конвертирует многочлен @var{p} в модулярное представление,
с учетом текущего модуля, которое является значением переменной
@code{modulus}.  

@code{polymod (@var{p}, @var{m})} определяет модуль @var{m}, который будет использоваться 
вместо текущего значения @code{modulus}.

См. @code{modulus}.

@opencatbox
@category{Многочлены}
@closecatbox

@end deffn

@deffn {Функция} mod (@var{x}, @var{y})

Если @var{x} и @var{y} есть вещественные числа и @var{y} не отрицательно,
возвращает @code{@var{x} - @var{y} * floor(@var{x} / @var{y})}.
Далее для всех вещественных @var{x} имеем @code{mod (@var{x}, 0) = @var{x}}. Подробное обсуждение 
определения @code{mod (@var{x}, 0) = @var{x}} есть в разделе 3.4 "Concrete Mathematics," 
авторов Graham, Knuth и Patashnik. Функция @code{mod (@var{x}, 1)} 
есть пилообразная функция с периодом 1, @code{mod (1, 1) = 0} и 
@code{mod (0, 1) = 0}.

Чтобы найти главный аргумент (число в интервале @code{(-%pi, %pi]}) для комплексного числа, 
используется функция @code{@var{x} |-> %pi - mod (%pi - @var{x}, 2*%pi)}, где 
@var{x} есть аргумент.

Когда @var{x} и @var{y} есть константные выражения (например @code{10 * %pi}), @code{mod}
использует то же вычисления с числами с плавающей точкой повышенной точности, что и,  @code{floor} и @code{ceiling}.
Опять же, возможно, хотя маловероятно, что @code{mod} может вернуть ошибочное значение в таких случаях.

Для не численных аргументов @var{x} или @var{y}, @code{mod} знает несколько правил упрощения:

@c ===beg===
@c mod (x, 0);
@c mod (a*x, a*y);
@c mod (0, x);
@c ===end===
@example
(%i1) mod (x, 0);
(%o1)                           x
(%i2) mod (a*x, a*y);
(%o2)                      a mod(x, y)
(%i3) mod (0, x);
(%o3)                           0
@end example

@opencatbox
@category{Математические функции}
@closecatbox

@end deffn

@deffn {Функция} oddp (@var{expr})
есть @code{true} если @var{expr} есть нечетное целое.
@c THIS IS STRANGE -- SHOULD RETURN NOUN FORM IF INDETERMINATE
@code{false} возвращается во всех других случаях.

@opencatbox
@category{Функции предикаты}
@closecatbox

@end deffn

@c NEEDS EXPANSION, CLARIFICATION, AND EXAMPLES
@c NOTE THAT pred IS RECOGNIZED ONLY AS AN ARGUMENT TO ev,
@c BUT FOR SOME REASON pred DOES NOT HAVE THE evflag PROPERTY
@deffn {Оператор} pred
В качестве аргумента в вызове @code{ev (@var{expr})},
@code{pred} вызывает вычисление предикатов (выражений, которые вычисляются в @code{true}
или @code{false}) .
См. @code{ev}.

@opencatbox
@category{Флаги вычисления}
@closecatbox

@end deffn

@deffn {Функция} make_random_state (@var{n})
@deffnx {Функция} make_random_state (@var{s})
@deffnx {Функция} make_random_state (true)
@deffnx {Функция} make_random_state (false)
@c OMIT THIS FOR NOW. SEE COMMENT BELOW.
@c @defunx make_random_state (@var{a})

Объект случайного состояния представляет собой состояние генератора случайных чисел.
Оно содержит 627 32-битных слова.

@code{make_random_state (@var{n})} возвращает новое случайное состояние объекта
созданного из затравочного целого числа, равного @var{n} по модулю 2^32.
@var{n} может быть отрицательным.

@c OMIT THIS FOR NOW. NOT SURE HOW THIS IS SUPPOSED TO WORK.
@c @code{make_random_state (@var{a})} returns a new random state object
@c created from an array @var{a}, which must be a Lisp array of 32 unsigned bytes.

@code{make_random_state (@var{s})} возвращает копию случайного состояния @var{s}.

@code{make_random_state (true)} возвращает новое случайное состояние объекта,
используя текущее значение часов компьютера в качестве затравочного числа.

@code{make_random_state (false)} возвращает копию текущего состояния
генератора случайных чисел.

@opencatbox
@category{Случайные числа}
@closecatbox

@end deffn

@deffn {Функция} set_random_state (@var{s})
Копирует @var{s} в состояние генератора случайных чисел.

@code{set_random_state} всегда возвращает @code{done}.

@opencatbox
@category{Случайные числа}
@closecatbox

@end deffn

@deffn {Функция} random (@var{x})
Возвращает псевдослучайное число. Если @var{x} есть целое, @code{random (@var{x})} возвращает 
целое в пределах от 0 до @code{@var{x} - 1} включительно. Если @var{x} есть число с плавающей точкой,
@code{random (@var{x})} возвращает неотрицательное число с плавающей точкой меньше чем @var{x}.
Функция @code{random} выдает сообщение об ошибке, если @var{x} не есть целое, или не число с плавающей точкой, 
или если @var{x} неположительное.

Функции @code{make_random_state} и @code{set_random_state}
сохраняют состояние генератора случайных чисел.

Генератор случайных чисел Maxima - это реализация Mersenne twister MT 19937.

Примеры:

@c ===beg===
@c s1: make_random_state (654321)$
@c set_random_state (s1);
@c random (1000);
@c random (9573684);
@c random (2^75);
@c s2: make_random_state (false)$
@c random (1.0);
@c random (10.0);
@c random (100.0);
@c set_random_state (s2);
@c random (1.0);
@c random (10.0);
@c random (100.0);
@c ===end===
@example
(%i1) s1: make_random_state (654321)$
(%i2) set_random_state (s1);
(%o2)                         done
(%i3) random (1000);
(%o3)                          768
(%i4) random (9573684);
(%o4)                        7657880
(%i5) random (2^75);
(%o5)                11804491615036831636390
(%i6) s2: make_random_state (false)$
(%i7) random (1.0);
(%o7)                   .2310127244107132
(%i8) random (10.0);
(%o8)                   4.394553645870825
(%i9) random (100.0);
(%o9)                   32.28666704056853
(%i10) set_random_state (s2);
(%o10)                        done
(%i11) random (1.0);
(%o11)                  .2310127244107132
(%i12) random (10.0);
(%o12)                  4.394553645870825
(%i13) random (100.0);
(%o13)                  32.28666704056853
@end example

@opencatbox
@category{Случайные числа} @category{Численные методы}
@closecatbox

@end deffn

@deffn {Функция} rationalize (@var{expr})

Конвертирует все числа с плавающей точкой двойной точности и повышенной точности в выражении
@var{expr} в рациональные эквивалентны. Если вы не знакомы с
бинарным представлением чисел с плавающей точкой, вы может
быть удивлены тем, что @code{rationalize (0.1)} не равно 1/10.  Это поведение
имеет место не только в Maxima -- число 1/10 имеет периодическое, не заканчивающееся,
двоичное представление.

@c ===beg===
@c rationalize (0.5);
@c rationalize (0.1);
@c fpprec : 5$
@c rationalize (0.1b0);
@c fpprec : 20$
@c rationalize (0.1b0);
@c rationalize (sin (0.1*x + 5.6));
@c ===end===
@example
(%i1) rationalize (0.5);
                                1
(%o1)                           -
                                2
(%i2) rationalize (0.1);
                               1
(%o2)                          --
                               10
(%i3) fpprec : 5$
(%i4) rationalize (0.1b0);
                             209715
(%o4)                        -------
                             2097152
(%i5) fpprec : 20$
(%i6) rationalize (0.1b0);
                     236118324143482260685
(%o6)                ----------------------
                     2361183241434822606848
(%i7) rationalize (sin (0.1*x + 5.6));
                              x    28
(%o7)                     sin(-- + --)
                              10   5
@end example

Пример использования:

@c ===beg===
@c unitfrac(r) := block([uf : [], q],
@c     if not(ratnump(r)) then 
@c        error("The input to 'unitfrac' must be a rational number"),
@c     while r # 0 do (
@c         uf : cons(q : 1/ceiling(1/r), uf),
@c         r : r - q),
@c     reverse(uf));
@c unitfrac (9/10);
@c apply ("+", %);
@c unitfrac (-9/10);
@c apply ("+", %);
@c unitfrac (36/37);
@c apply ("+", %);
@c ===end===
@example
(%i1) unitfrac(r) := block([uf : [], q],
    if not(ratnump(r)) then
       error("The input to 'unitfrac' must be a rational number"),
    while r # 0 do (
        uf : cons(q : 1/ceiling(1/r), uf),
        r : r - q),
    reverse(uf));
(%o1) unitfrac(r) := block([uf : [], q], 
if not ratnump(r) then
   error("The input to 'unitfrac' must be a rational number"),
                                  1
while r # 0 do (uf : cons(q : ----------, uf), r : r - q), 
                                      1
                              ceiling(-)
                                      r
reverse(uf))
(%i2) unitfrac (9/10);
                            1  1  1
(%o2)                      [-, -, --]
                            2  3  15
(%i3) apply ("+", %);
                               9
(%o3)                          --
                               10
(%i4) unitfrac (-9/10);
                                  1
(%o4)                       [- 1, --]
                                  10
(%i5) apply ("+", %);
                                9
(%o5)                         - --
                                10
(%i6) unitfrac (36/37);
                        1  1  1  1    1
(%o6)                  [-, -, -, --, ----]
                        2  3  8  69  6808
(%i7) apply ("+", %);
                               36
(%o7)                          --
                               37
@end example

@opencatbox
@category{Численное вычисление}
@closecatbox

@end deffn


@deffn {Функция} round (@var{x})

Если @var{x} является вещественным числом, то возвращает ближайшее к @var{x}
целое.  Числа, кратные 1/2, округляются до ближайшего четного целого.
Вычисление @var{x} аналогично функциям @code{floor} и @code{ceiling}.

@opencatbox
@category{Математические функции}
@closecatbox
@end deffn

@deffn {Функция} sign (@var{expr})
Пытается определить знак @var{expr}
на основе фактов в текущей базе данных. Она возвращает один из
следующих ответов: @code{pos} (положительное), @code{neg} (отрицательное), @code{zero} (нулевое), @code{pz}
(положительное или ноль), @code{nz} (отрицательное или ноль), @code{pn} (положительное или отрицательное),
или @code{pnz} (положительное, отрицательное или ноль, т.е. ничего не известно).

@opencatbox
@category{Факты и выводы}
@closecatbox

@end deffn

@deffn {Функция} signum (@var{x})
Для численного значения @var{x}, возвращает 0, если @var{x} есть 0, иначе возвращает -1 или +1,
когда @var{x} меньше чем или больше чем 0, соответственно.

Если @var{x} не есть численное значение, то возвращается эквивалентная, но упрощенная форма.
Например, @code{signum(-x)} дает @code{-signum(x)}.
@c UMM, THIS ISN'T THE WHOLE STORY, AS IT APPEARS signum CONSULTS THE assume DATABASE FOR SYMBOLIC ARGUMENT

@opencatbox
@category{Математические функции}
@closecatbox

@end deffn

@deffn {Функция} sort (@var{L}, @var{P})
@deffnx {Функция} sort (@var{L})
Сортирует список @var{L} согласно предикату @code{P} двух аргументов,
так чтобы @code{@var{P} (@var{L}[k], @var{L}[k + 1])} было равно @code{true}
для любых двух последовательных элементов.
Предикат может быть задан как имя функции или бинарный инфиксный оператор,
или как лямбда-выражение.
Если он задан как имя оператора,
это имя берется в "двойные кавычки".

Отсортированный список возвращается как новый объект;
аргумент @var{L} не изменяется.
При возврате значения,
@code{sort} делает копию верхнего уровня (shallow copy) элементов @var{L}.
@c DUNNO IF WE NEED TO GO INTO THE IMPLICATIONS OF SHALLOW COPY HERE ...

@c MIGHT CONSIDER A REF FOR TOTAL ORDER HERE
Если предикат @var{P} не задает полное упорядочивание элементов @var{L},
то @code{sort} может пробежать до конца без ошибки,
но результат будет неопределенный.
@code{sort} выдает сообщение, если предикат вычисляется до чего-то отличного
от @code{true} или @code{false}.

@code{sort (@var{L})} эквивалентно @code{sort (@var{L}, orderlessp)}.
То есть, порядок сортировки по умолчанию будет восходящим,
как определено для @code{orderlessp}.
Все Maxima атомы и выражения сравнимы по @code{orderlessp},
хотя есть отдельные примеры выражений, для которых @code{orderlessp} не транзитивна
(это ошибка).

Примеры:

@c ===beg===
@c sort ([11, -17, 29b0, 7.55, 3, -5/2, b + a, 9 * c, 
@c       19 - 3 * x]);
@c sort ([11, -17, 29b0, 7.55, 3, -5/2, b + a, 9 * c, 19 - 3 * x], 
@c       ordergreatp);
@c sort ([%pi, 3, 4, %e, %gamma]);
@c sort ([%pi, 3, 4, %e, %gamma], "<");
@c my_list : [[aa, hh, uu], [ee, cc], [zz, xx, mm, cc], [%pi, %e]];
@c sort (my_list);
@c sort (my_list, lambda ([a, b], orderlessp (reverse (a), 
@c       reverse (b))));
@c ===end===
@example
(%i1) sort ([11, -17, 29b0, 7.55, 3, -5/2, b + a, 9 * c,
      19 - 3 * x]);
               5
(%o1) [- 17, - -, 3, 7.55, 11, 2.9b1, b + a, 9 c, 19 - 3 x]
               2
(%i2) sort ([11, -17, 29b0, 7.55, 3, -5/2, b + a, 9*c, 19 - 3*x],
      ordergreatp);
                                                   5
(%o2) [19 - 3 x, 9 c, b + a, 2.9b1, 11, 7.55, 3, - -, - 17]
                                                   2
(%i3) sort ([%pi, 3, 4, %e, %gamma]);
(%o3)                [3, 4, %e, %gamma, %pi]
(%i4) sort ([%pi, 3, 4, %e, %gamma], "<");
(%o4)                [%gamma, %e, 3, %pi, 4]
(%i5) my_list: [[aa,hh,uu], [ee,cc], [zz,xx,mm,cc], [%pi,%e]];
(%o5) [[aa, hh, uu], [ee, cc], [zz, xx, mm, cc], [%pi, %e]]
(%i6) sort (my_list);
(%o6) [[%pi, %e], [aa, hh, uu], [ee, cc], [zz, xx, mm, cc]]
(%i7) sort (my_list, lambda ([a, b], orderlessp (reverse (a),
      reverse (b))));
(%o7) [[%pi, %e], [ee, cc], [zz, xx, mm, cc], [aa, hh, uu]]
@end example

@opencatbox
@category{Списки}
@closecatbox

@end deffn

@deffn {Функция} sqrt (@var{x})
Квадратный корень @var{x}. Внутренне представляется как
@code{@var{x}^(1/2)}.  См. также @code{rootscontract}.

@code{radexpand}, если @code{true}, вызовет то, что n-ные корни множителей произведения,
которые есть степени n, будут вынесены за пределы радикала. Например,
@code{sqrt(16*x^2)} станет @code{4*x}, только если @code{radexpand} есть @code{true}.

@opencatbox
@category{Математические функции}
@closecatbox

@end deffn

@defvr {Управляющая переменная} sqrtdispflag
Значение по умолчанию: @code{true}

Когда @code{sqrtdispflag} есть @code{false},
то @code{sqrt} выводится как степень с показателем 1/2.
@c AND OTHERWISE ... ??

@opencatbox
@category{Математические функции} @category{Переменные и флаги вывода}
@closecatbox

@end defvr

@c NEEDS EXPANSION, CLARIFICATION, MORE EXAMPLES
@c sublis CAN ONLY SUBSTITUTE FOR ATOMS, RIGHT ?? IF SO, SAY SO
@deffn {Функция} sublis (@var{list}, @var{expr})
Производит множественные параллельные подстановки в выражение.

Переменная @code{sublis_apply_lambda} управляет упрощением после
@code{sublis}.

Пример:

@c ===beg===
@c sublis ([a=b, b=a], sin(a) + cos(b));
@c ===end===
@example
(%i1) sublis ([a=b, b=a], sin(a) + cos(b));
(%o1)                    sin(b) + cos(a)
@end example

@opencatbox
@category{Выражения}
@closecatbox

@end deffn

@deffn {Функция} sublist (@var{list}, @var{p})
Возвращает список элементов @var{list}, для которого 
предикат @code{p} возвращает @code{true}.

Пример:

@c ===beg===
@c L: [1, 2, 3, 4, 5, 6];
@c sublist (L, evenp);
@c ===end===
@example
(%i1) L: [1, 2, 3, 4, 5, 6];
(%o1)                  [1, 2, 3, 4, 5, 6]
(%i2) sublist (L, evenp);
(%o2)                       [2, 4, 6]
@end example

@opencatbox
@category{Списки}
@closecatbox

@end deffn

@defvr {Управляющая переменная} sublis_apply_lambda
Значение по умолчанию: @code{true}

Управляет, будет ли подстановки для @code{lambda} применены в упрощении, 
после того как используется @code{sublis} или
нужно ли выполнить @code{ev}, чтобы эти элементы применились. 
@code{true} означает - выполнить применение.

@opencatbox
@category{Выражения}
@closecatbox

@end defvr

@c NEEDS CLARIFICATION, MORE EXAMPLES
@deffn {Функция} subst (@var{a}, @var{b}, @var{c})
Делает подстановку @var{a} для @var{b} в @var{c}.  
@var{b} должен быть атомом или полным подвыражением в @var{c}.  Например, @code{x+y+z} есть полное
подвыражение @code{2*(x+y+z)/w}, а @code{x+y} нет. Когда @var{b} не имеет
эти характеристики, можно иногда использовать @code{substpart} или @code{ratsubst}
(см. ниже).  Альтернативно, если @var{b} задано в форме @code{e/f}, то можно
использовать @code{subst (a*f, e, c)}, в то время как, если @var{b} задано в  форме @code{e^(1/f)}, то можно 
использовать @code{subst (a^f, e, c)}.  @code{subst} также различает @code{x^y} в @code{x^-y},
так что @code{subst (a, sqrt(x), 1/sqrt(x))} дает @code{1/a}.  Аргументы @var{a} и @var{b} могут также быть
операторами выражения, заключенными в двойные кавычки @code{"}, или могут быть именами функций. 
Если есть желание подставить независимую переменную в
производных формах, то следует использовать функцию @code{at} (см. ниже).

@c UMM, REVERSE THIS AND MOVE IT TO substitute ??
@code{subst} - это псевдоним для @code{substitute}.

Выражения @code{subst (@var{eq_1}, @var{expr})} или @code{subst ([@var{eq_1}, ..., @var{eq_k}], @var{expr})}
- есть другие допустимые формы.  
@var{eq_i} - уравнения, указывающие какие подстановки нужно сделать.
Для каждого уравнения, правая сторона будет подставлена вместо левой в выражении @var{expr}.

Если @code{exptsubst} равно @code{true}, то позволяются подстановки,
на подобии @code{y} для @code{%e^x} в @code{%e^(a*x)}.

@c WHAT IS THIS ABOUT ??
Когда @code{opsubst} есть @code{false},
@code{subst} не пытается подставить в оператор выражения.
Например, @code{(opsubst: false, subst (x^2, r, r+r[0]))} будет работать.

Примеры:

@c ===beg===
@c subst (a, x+y, x + (x+y)^2 + y);
@c subst (-%i, %i, a + b*%i);
@c ===end===
@example
(%i1) subst (a, x+y, x + (x+y)^2 + y);
                                    2
(%o1)                      y + x + a
(%i2) subst (-%i, %i, a + b*%i);
(%o2)                       a - %i b
@end example

@noindent
Чтобы узнать о других примерах, выполните @code{example (subst)}.

@opencatbox
@category{Выражения}
@closecatbox

@end deffn

@c NEEDS CLARIFICATION
@deffn {Функция} substinpart (@var{x}, @var{expr}, @var{n_1}, ..., @var{n_k})
Аналогично @code{substpart}, но @code{substinpart} работает с 
внутренним представление @var{expr}.

Примеры:

@c ===beg===
@c x . 'diff (f(x), x, 2);
@c substinpart (d^2, %, 2);
@c substinpart (f1, f[1](x + 1), 0);
@c ===end===
@example
(%i1) x . 'diff (f(x), x, 2);
                              2
                             d
(%o1)                   x . (--- (f(x)))
                               2
                             dx
(%i2) substinpart (d^2, %, 2);
                                  2
(%o2)                        x . d
(%i3) substinpart (f1, f[1](x + 1), 0);
(%o3)                       f1(x + 1)
@end example

Если последний аргумент функции @code{part} есть список индексов, то будут выбраны
несколько подвыражений, каждый из которых будет соответствовать 
индексу в списке. Таким образом

@c ===beg===
@c part (x + y + z, [1, 3]);
@c ===end===
@example
(%i1) part (x + y + z, [1, 3]);
(%o1)                         z + x
@end example

Переменная @code{piece} содержит значение последнего выражения, выбранного при использовании функции @code{part}.
Оно устанавливается во время выполнения функции и,
таким образом, может быть передано в саму функцию как показано ниже.
Если @code{partswitch} равно @code{true}, то @code{end} возвращается когда 
выбранная часть выражения не существует, иначе 
выдается сообщение об ошибке.

@c ===beg===
@c expr: 27*y^3 + 54*x*y^2 + 36*x^2*y + y + 8*x^3 + x + 1;
@c part (expr, 2, [1, 3]);
@c sqrt (piece/54);
@c substpart (factor (piece), expr, [1, 2, 3, 5]);
@c expr: 1/x + y/x - 1/z;
@c substpart (xthru (piece), expr, [2, 3]);
@c ===end===
@example
(%i1) expr: 27*y^3 + 54*x*y^2 + 36*x^2*y + y + 8*x^3 + x + 1;
              3         2       2            3
(%o1)     27 y  + 54 x y  + 36 x  y + y + 8 x  + x + 1
(%i2) part (expr, 2, [1, 3]);
                                  2
(%o2)                         54 y
(%i3) sqrt (piece/54);
(%o3)                        abs(y)
(%i4) substpart (factor (piece), expr, [1, 2, 3, 5]);
                               3
(%o4)               (3 y + 2 x)  + y + x + 1
(%i5) expr: 1/x + y/x - 1/z;
                             1   y   1
(%o5)                      - - + - + -
                             z   x   x
(%i6) substpart (xthru (piece), expr, [2, 3]);
                            y + 1   1
(%o6)                       ----- - -
                              x     z
@end example

Также, установка опции @code{inflag} в @code{true} и вызов @code{part} или @code{substpart} есть 
тоже самое, что и вызов @code{inpart} или @code{substinpart}.

@opencatbox
@category{Выражения}
@closecatbox

@end deffn

@c NEEDS CLARIFICATION
@deffn {Функция} substpart (@var{x}, @var{expr}, @var{n_1}, ..., @var{n_k})
Делает подстановку @var{x} в подвыражение,
выбираемое последними аргументами, как в @code{part}. Возвращает 
новое значение @var{expr}.  @var{x} может быть некоторым оператором для подстановки вместо
оператора в @var{expr}. В некоторых случаях @var{x} нужно заключать в двойной кавычки @code{"}
(Например, @code{substpart ("+", a*b, 0)} дает @code{b + a}).

@c ===beg===
@c 1/(x^2 + 2);
@c substpart (3/2, %, 2, 1, 2);
@c a*x + f(b, y);
@c substpart ("+", %, 1, 0);
@c ===end===
@example
(%i1) 1/(x^2 + 2);
                               1
(%o1)                        ------
                              2
                             x  + 2
(%i2) substpart (3/2, %, 2, 1, 2);
                               1
(%o2)                       --------
                             3/2
                            x    + 2
(%i3) a*x + f(b, y);
(%o3)                     a x + f(b, y)
(%i4) substpart ("+", %, 1, 0);
(%o4)                    x + f(b, y) + a
@end example

Также, установка опции @code{inflag} в @code{true} и вызов @code{part} или @code{substpart}, есть 
тоже самое, что и вызов @code{inpart} или @code{substinpart}.

@opencatbox
@category{Выражения}
@closecatbox

@end deffn

@c NEEDS EXPANSION AND EXAMPLES
@deffn {Функция} subvarp (@var{expr})
Возвращает @code{true}, если @var{expr} есть переменная с индексом,
например @code{a[i]}.

@opencatbox
@category{Функции предикаты}
@closecatbox

@end deffn

@deffn {Функция} symbolp (@var{expr})
Возвращает @code{true}, если @var{expr} есть символ, иначе @code{false}.
На самом деле, @code{symbolp(x)} эквивалентно предикату @code{atom(x) and not numberp(x)}.

@c FOLLOWING REALLY WANTS TO BE @xref{Identiifers} BUT THAT
@c LEAVES THE UNPLEASANT RESIDUE *Note ...:: IN THE OUTPUT OF describe
См. также @ref{Identifiers}.

@opencatbox
@category{Функции предикаты}
@closecatbox

@end deffn

@deffn {Функция} unorder ()
Блокирует связывания, созданные последним вызовом упорядочивающих
команд @code{ordergreat} и @code{orderless}. @code{ordergreat} и @code{orderless} не могут
использоваться больше одного раза каждый, без вызова @code{unorder}. 
См. также @code{ordergreat} и @code{orderless}.

Примеры:

@c HMM, IN THIS EXAMPLE, WHY ISN'T %o5 EQUAL TO ZERO ???
@c ===beg===
@c unorder();
@c b*x + a^2;
@c ordergreat (a);
@c b*x + a^2;
@c  %th(1) - %th(3);
@c unorder();
@c ===end===
@example
(%i1) unorder();
(%o1)                          []
(%i2) b*x + a^2;
                                   2
(%o2)                       b x + a
(%i3) ordergreat (a);
(%o3)                         done
(%i4) b*x + a^2;
 %th(1) - %th(3);
                             2
(%o4)                       a  + b x
(%i5) unorder();
                              2    2
(%o5)                        a  - a
@end example

@opencatbox
@category{Выражения}
@closecatbox

@end deffn

@c THIS ITEM SEEMS OUT OF PLACE -- IS IT FROM A SHARE PACKAGE ??
@c NEEDS EXAMPLES
@deffn {Функция} vectorpotential (@var{givencurl})
Возвращает векторный потенциал заданного
вектора кручения, в текущей системе координат.
@code{potentialzeroloc} имеет аналогичную роль для @code{potential}, но порядок 
левосторонних частей уравнений должен быть циклической перестановкой 
координатных переменных.

@opencatbox
@category{Пакет vect}
@closecatbox

@end deffn

@deffn {Функция} xthru (@var{expr})
Объединяет все члены @var{expr} (которое должно быть суммой) для общего знаменателя 
без раскрытия произведений и степеней сумм,
что делает @code{ratsimp}.  Функция @code{xthru} сокращает общие множители в числителе и
знаменателе рациональных выражений, но только если эти множители явные.

@c REPHRASE IN NEUTRAL TONE (GET RID OF "IT IS BETTER")
Иногда лучше использовать @code{xthru} перед выражением, упрощенным с помощью @code{ratsimp}, 
для того чтобы вызывать сокращение явных множителей наибольшего общего делителя 
числителя и знаменателя, таким образом, упрощая выражение перед @code{ratsimp}.

@c ===beg===
@c ((x+2)^20 - 2*y)/(x+y)^20 + (x+y)^(-19) - x/(x+y)^20;
@c xthru (%);
@c ===end===
@example
(%i1) ((x+2)^20 - 2*y)/(x+y)^20 + (x+y)^(-19) - x/(x+y)^20;
                                20
                 1       (x + 2)   - 2 y       x
(%o1)        --------- + --------------- - ---------
                    19             20             20
             (y + x)        (y + x)        (y + x)
(%i2) xthru (%);
                                 20
                          (x + 2)   - y
(%o2)                     -------------
                                   20
                            (y + x)
@end example

@opencatbox
@category{Выражения}
@closecatbox

@end deffn

@c THIS FUNCTION APPEARS TO BE A HACK; SEE 4'TH ITEM BELOW
@c DUNNO WHETHER WE CAN CLEAR THIS UP
@deffn {Функция} zeroequiv (@var{expr}, @var{v})
Проверяет эквивалентно ли выражение @var{expr} в переменной
@var{v} нулю, возвращает @code{true}, @code{false} или
@code{dontknow}.

@code{zeroequiv} имеет следующие ограничения:
@enumerate
@item
Не используйте функции, для которых Maxima не знает как 
их дифференцировать и вычислять.
@item
Если выражение имеет полюсы на вещественной прямой, могут быть ошибки
в результате (это может произойти с малой вероятностью).
@item
Если выражение содержит функции, который не являются решением 
дифференциальных уравнений первого порядка (например, функции Бесселя), 
могут быть некорректные результаты.
@item
Этот алгоритм использует вычисление в случайно выбранных точках для
аккуратно выбранных подвыражений. Это всегда, в некотором смысле,
рискованное дело, хотя алгоритм пытается минимизировать возможность ошибки.
@end enumerate

Например @code{zeroequiv (sin(2*x) - 2*sin(x)*cos(x), x)} возвращает
@code{true} и @code{zeroequiv (%e^x + x, x)} возвращает @code{false}.
С другой стороны @code{zeroequiv (log(a*b) - log(a) - log(b), a)} возвращает 
@code{dontknow} из-за присутствия дополнительного параметра @code{b}.

@opencatbox
@category{Функции предикаты}
@closecatbox

@end deffn
