Maxima Manual: Введение в работу с множествами

Next: Функции и переменные для работы с множествами, Previous: Множества, Up: Множества [Contents][Index]

### 36.1 Введение в работу с множествами

Maxima предоставляет функции, такие как пересечение или объединение, для работы с конечными множествами, определяемыми перечислением элементов. Maxima трактует списки и множества как различные объекты. Это позволяет работать с множествами, элементами которых сами могут быть списками или множествами.

В дополнение к функциям для работы конечными множествами Maxima определяет некоторые функции, относящиеся к комбинаторике, что включает: числа Стирлинга первого и второго рода, числа Белла, мультиномиальные коэффициенты, разбиения неотрицательных целых чисел и некоторые другие. Maxima также определяет дельта-функцию Кронекера.

#### 36.1.1 Использование

Для того, чтобы задать множество с элементами `a_1, ..., a_n`, следует написать `set(a_1, ..., a_n)` или `{a_1, ..., a_n}`; для пустого множества надо написать `set()` или `{}`. При вводе формы `set(...)` и `{ ... }` эквивалентны. При выводе множества всегда печатаются с фигурными скобками.

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

    (%i1) set();
    (%o1)                          {}
    (%i2) set(a, b, a);
    (%o2)                        {a, b}
    (%i3) set(a, set(b));
    (%o3)                       {a, {b}}
    (%i4) set(a, [b]);
    (%o4)                       {a, [b]}
    (%i5) {};
    (%o5)                          {}
    (%i6) {a, b, a};
    (%o6)                        {a, b}
    (%i7) {a, {b}};
    (%o7)                       {a, {b}}
    (%i8) {a, [b]};
    (%o8)                       {a, [b]}

Два элемента x и y являются повторяющимися (т.е. рассматриваются совпадающими с точки зрения включения в множество), тогда и только тогда, когда `is(x = y)` дает `true`. Заметим, что `is(equal(x, y))` может давать `true`, тогда как `is(x = y)` дает `false`. В этом случае элементы x и y считаются различными.

    (%i1) x: a/c + b/c;
                                  b   a
    (%o1)                         - + -
                                  c   c
    (%i2) y: a/c + b/c;
                                  b   a
    (%o2)                         - + -
                                  c   c
    (%i3) z: (a + b)/c;
                                  b + a
    (%o3)                         -----
                                    c
    (%i4) is (x = y);
    (%o4)                         true
    (%i5) is (y = z);
    (%o5)                         false
    (%i6) is (equal (y, z));
    (%o6)                         true
    (%i7) y - z;
                               b + a   b   a
    (%o7)                    - ----- + - + -
                                 c     c   c
    (%i8) ratsimp (%);
    (%o8)                           0
    (%i9) {x, y, z};
                              b + a  b   a
    (%o9)                    {-----, - + -}
                                c    c   c

Для того, чтобы создать множество из элементов списка, используется `setify`.

    (%i1) setify ([b, a]);
    (%o1)                        {a, b}

Элементы множества `x` и `y` равны если `is(x = y)` вычисляется в `true`. Тогда `rat(x)` и `x` являются равными элементами множества, и, следовательно

    (%i1) {x, rat(x)};
    (%o1)                          {x}

Далее, поскольку `is((x - 1)*(x + 1) = x^2 - 1)` вычисляется в `false`, то `(x - 1)*(x + 1)` и `x^2 - 1` есть различные элементы, и

    (%i1) {(x - 1)*(x + 1), x^2 - 1};
                                           2
    (%o1)               {(x - 1) (x + 1), x  - 1}

Для приведения этого множества к одноэлементному следует применить `rat` к каждому элементу:

    (%i1) {(x - 1)*(x + 1), x^2 - 1};
                                           2
    (%o1)               {(x - 1) (x + 1), x  - 1}
    (%i2) map (rat, %);
                                  2
    (%o2)/R/                    {x  - 1}

Для удаления повторов из множеств другого вида может потребоваться применение других упрощающих функций. Вот пример, использующий `trigsimp`:

    (%i1) {1, cos(x)^2 + sin(x)^2};
                                2         2
    (%o1)                {1, sin (x) + cos (x)}
    (%i2) map (trigsimp, %);
    (%o2)                          {1}

Множество является упрощенным, если его элементы не повторяются и упорядочены. Текущая реализация Maxima функций для работы с множествами использует функцию `orderlessp` для упорядочения, однако будущие версии могут использовать другую упорядочивающую функцию.

Некоторые операции над множествами, такие как подстановки, вызывают автоматическое упрощение. Например,

    (%i1) s: {a, b, c}$
    (%i2) subst (c=a, s);
    (%o2)                        {a, b}
    (%i3) subst ([a=x, b=x, c=x], s);
    (%o3)                          {x}
    (%i4) map (lambda ([x], x^2), set (-1, 0, 1));
    (%o4)                        {0, 1}

Maxima рассматривает списки и множества как различные объекты; функции, подобные `union` и `intersection`, сигнализируют об ошибке если их аргументы не являются множествами. Если необходимо применить функцию для работы с множествами к списку, то надо сначала использовать `setify` для преобразования списка в множество. Таким образом

    (%i1) union ([1, 2], {a, b});
    Function union expects a set, instead found [1,2]
     -- an error.  Quitting.  To debug this try debugmode(true);
    (%i2) union (setify ([1, 2]), {a, b});
    (%o2)                     {1, 2, a, b}

Для того, чтобы получить все элементы множества `s`, удовлетворяющие предикату `f`, используйте `subset(s, f)` (предикат – функция, дающая логическое значение). Например, чтобы найти в заданном множестве уравнения, которые не зависят от переменной `z`, используйте

    (%i1) subset ({x + y + z, x - y + 4, x + y - 5},
                                        lambda ([e], freeof (z, e)));
    (%o1)               {- y + x + 4, y + x - 5}

Раздел Функции и переменные для работы с множествами содержит полный список функций Maxima, предназначенных для работы с множествами.

Категории:Множества ·

#### 36.1.2 Итерация по элементам множества

Существует два способа организации цикла по элементам множества. Один способ – использовать `map`, например:

    (%i1) map (f, {a, b, c});
    (%o1)                  {f(a), f(b), f(c)}

Другой способ – использовать `for x in s do`

    (%i1) s: {a, b, c};
    (%o1)                       {a, b, c}
    (%i2) for si in s do print (concat (si, 1));
    a1
    b1
    c1
    (%o2)                         done

Maxima функции `first` и `rest` правильно работают с множествами. Примененная к множеству, `first` возвращает первый элемент множества, какой именно – может зависеть от реализации. Если `s` является множеством, то `rest(s)` эквивалентно `disjoin(first(s), s)`. В настоящий момент есть другие функции Maxima, корректно работающие с множествами. В будущих версиях функции `first` и `rest` могут работать на множествах иначе или не работать вовсе.

#### 36.1.3 Ошибки

Функции для работы с множествами используют Maxima функцию `orderlessp` для сортировки элементов множества и Lisp функцию `like` для проверки равенства элементов. Обе эти функции имеют известные ошибки, которые проявляются при попытке использовать множества, элементы которых являются списками или матрицами, включающими выражения в канонической рациональной форме (КРВ). Например

    (%i1) {[x], [rat (x)]};
    Maxima encountered a Lisp error:

      The value #:X1440 is not of type LIST.

    Automatically continuing.
    To reenable the Lisp debugger set *debugger-hook* to nil.

Это выражение вызывает ошибку (сообщение об ошибке зависит от версии Lisp и Maxima). Другой пример

    (%i1) setify ([[rat(a)], [rat(b)]]);
    Maxima encountered a Lisp error:

      The value #:A1440 is not of type LIST.

    Automatically continuing.
    To reenable the Lisp debugger set *debugger-hook* to nil.

Эти ошибки вызваны ошибками в `orderlessp` и `like`, а не ошибками в реализации функций работы с множествами. Для иллюстрации попробуем следующие выражения

    (%i1) orderlessp ([rat(a)], [rat(b)]);
    Maxima encountered a Lisp error:

      The value #:B1441 is not of type LIST.

    Automatically continuing.
    To reenable the Lisp debugger set *debugger-hook* to nil.
    (%i2) is ([rat(a)] = [rat(a)]);
    (%o2)                         false

До тех пор, пока эти ошибки не исправлены, не следует использовать множества с элементами в виде списков и матриц, содержащих выражения в формате КРВ. Множества, просто содержащие выражения КРВ в качестве элементов, не создают проблем.

    (%i1) {x, rat (x)};
    (%o1)                          {x}

Maxima функция `orderlessp` имеет еще одну ошибку, которая может создать проблемы при работе с множествами. А именно, упорядочивающий предикат `orderlessp` не является транзитивным. Простейший известный пример, демонстрирующий это

    (%i1) q: x^2$
    (%i2) r: (x + 1)^2$
    (%i3) s: x*(x + 2)$
    (%i4) orderlessp (q, r);
    (%o4)                         true
    (%i5) orderlessp (r, s);
    (%o5)                         true
    (%i6) orderlessp (q, s);
    (%o6)                         false

Эта ошибка вызывает проблемы со всеми функциями для работы с множествами и даже с другими функциями Maxima. Возможно, но точно не известно, что эту ошибку можно обойти, если все элементы множества или являются КРВ, или упрощены с помощью `ratsimp`.

Механизмы Maxima `orderless` и `ordergreat` не совместимы с функциями для работы с множествами. Если требуется использовать либо `orderless`, либо `ordergreat`, то следует вызывать эти функции до формирования множеств, и не следует использовать `unorder`.

Если вы встретите что-то, что может быть ошибкой в функциях работы с множествами, пожалуйста, сообщите об этом в базу данных ошибок Maxima. См. `bug_report`.

#### 36.1.4 Авторы

Функции для работы с множествами Maxima и документация к ним написаны Ставросом Макракисом (Stavros Macrakis of Cambridge, Massachusetts) и Бартоном Уиллисом (Barton Willis of the University of Nebraska at Kearney (UNK)).

Next: Функции и переменные для работы с множествами, Previous: Множества, Up: Множества [Contents][Index]