## `-` -- subtract expressions

#### Introduction

`x - y` computes the difference of `x` and `y`.

#### Call(s)

x - y `_subtract(x, y)`

#### Parameters

`x, y` | - | arithmetical expressions, polynomials of type `DOM_POLY`, or sets

#### Returns

an arithmetical expression, a polynomial, or a set.

### Overloadable:

`x`, `y`

#### Related Functions

`_invert`, `_negate`, `^`, `/`, `*`, `+`, `poly`, `Pref::keepOrder`

#### Details

- `x - y` is equivalent to the function call `_subtract(x, y)`.
- For numbers of type `Type::Numeric`, the difference is returned as a number.
- If neither `x` nor `y` are elements of library domains with `"_subtract"` methods, `x - y` is internally represented as `x + y*(-1)` = `_plus(x, _mult(y, -1))`.
- If `x` or `y` is an element of a domain with a slot `"_subtract"`, then this method is used to compute `x - y`. Many library domains overload the `-` operator by an appropriate `"_subtract"` slot. Differences are processed as follows:

  `x - y` is searched for elements of library domains from left to right. Let `z` (either `x` or `y`) be the first term that is not of one of the basic types provided by the kernel (numbers, expressions, etc.). If the domain `d` = `z::dom` = `domtype(z)` has a slot `"_subtract"`, it is called in the form `d::_subtract(x, y)`. The result returned by `d::_subtract` is the result of `x - y`.

  Users should implement the slot `d::_subtract` of their domains `d` according to the following convention:

  - If both `x` and `y` are elements of `d`, an appropriate difference of type `d` should be returned.
  - If either `x` or `y` cannot be converted to an element of `d`, the slot should return `FAIL`.
  - Care must be taken if either `x` or `y` is not of type `d`, but can be converted to type `d`. This object should be converted only if the mathematical semantics is obvious to any user who uses this domain as a 'black box' (e.g., integers may be regarded as rational numbers because of the natural mathematical embedding). If in doubt, the `"_subtract"` method should return `FAIL` instead of using implicit conversions. If implicit conversions are used, they must be well-documented.
  Cf. examples 4 and 5.

  Most of the library domains in MuPAD's standard installation comply with this convention.

- Polynomials of type `DOM_POLY` are subtracted by `-`, if they have the same indeterminates and the same coefficient ring.
- For finite sets `X`, `Y`, the difference `X - Y` is the set {x - y; x in X; y in Y}.
- `_subtract` is a function of the system kernel.

#### Example 1

The difference of numbers is simplified to a number:

    >> 1234 - 234, I + x - y - 4*I, 3 + x - y - 29/3

                          1000, x - y - 3 I, x - y - 20/3

Internally, a symbolic difference `x - y` is represented as the sum `x + y*(-1)`:

    >> type(x - y), op(x - y, 0), op(x - y, 1), op(x - y, 2)

                               "_plus", _plus, x, -y

    >> op(op(x - y, 2))

                                       y, -1

#### Example 2

Polynomials of type `DOM_POLY` are subtracted by `-`, if they have the same indeterminates and the same coefficient ring:

    >> poly(x^2 + 1, [x]) - poly(x^2 + x - 1, [x])

                                poly(- x + 2, [x])

Symbolic differences are returned if the indeterminates or the coefficient rings do not match:

    >> poly(x, [x]) - poly(x, [x, y])

                        poly(x, [x]) + poly((-1) x, [x, y])

    >> poly(x, [x]) - poly(x, [x], Dom::Integer)

                  poly(x, [x]) + poly((-1) x, [x], Dom::Integer)

#### Example 3

For finite sets `X`, `Y`, the difference `X - Y` is the set {x - y; x in X; y in Y}:

    >> {a, b, c} - {1, 2}

                    {a - 1, a - 2, b - 1, b - 2, c - 1, c - 2}

#### Example 4

Various library domains such as matrix domains overload `_subtract`:

    >> x := Dom::Matrix(Dom::Integer)([2, 2]):
       y := Dom::Matrix(Dom::Rational)([1, 3]):
       x - y, y - x

                                +-    -+  +-    -+
                                |   1  |  |  -1  |
                                |      |, |      |
                                |  -1  |  |   1  |
                                +-    -+  +-    -+

If the terms in `x - y` are of different type, the first term `x` tries to convert `y` to the data type of `x`. If successful, the difference is of the same type as `x`. In the previous example, `x` and `y` have different types (both are matrices, but the component domains differ). Consequently, `x - y` and `y - x` have different types, because they inherit their type from the first term:

    >> domtype(x - y), domtype(y - x)

               Dom::Matrix(Dom::Integer), Dom::Matrix(Dom::Rational)

If `x` does not succeed to convert `y`, then `FAIL` is returned. In the following call, the component `2/3` cannot be converted to an integer:

    >> y := Dom::Matrix(Dom::Rational)([2/3, 3]): x - y

                                       FAIL

The matrix domain defines `x - y` as `x + (-y)`:

    >> x::dom::_subtract

                     (x, y) -> dom::_plus(x, dom::_negate(y))

    >> delete x, y:

#### Example 5

This example demonstrates how to implement a slot `"_subtract"` for a domain. The following domain `myString` is to represent character strings. The difference `x - y` of such strings is to remove all characters in `y` from `x`.

The `"new"` method uses `expr2text` to convert any MuPAD object to a string. This string is the internal representation of elements of `myString`. The `"print"` method turns this string into the screen output:

    >> myString := newDomain("myString"):
       myString::new := proc(x)
       begin
         if args(0) = 0 then x := "" end_if;
         case domtype(x)
           of myString do return(x);
           of DOM_STRING do return(new(dom, x));
           otherwise return(new(dom, expr2text(x)));
         end_case
       end_proc:
       myString::print := x -> extop(x, 1):

Without a `"_subtract"` method, the system handles elements of this domain like any symbolic object:

    >> x := myString(x): y := myString(y): x - y

                                       x - y

Now, we implement the `"_subtract"` method. It checks all arguments. Arguments are converted if they are not of type `myString`. Generally, such an implicit conversion should be avoided. In this case, however, any object has a corresponding string representation via `expr2text` and an implicit conversion is implemented. Finally, the difference `x - y` of `myString` objects removes all characters in the string `y` from the string `x`:

    >> myString::_subtract := proc(x, y)
       local i, char;
       begin
         userinfo(10, "myString::_subtract called with ".
                  "the arguments:", args()):
         // Convert all arguments to myString.
         if domtype(x) <> myString then x := myString::new(x) end_if;
         if domtype(y) <> myString then y := myString::new(y) end_if;
         // extract the internal strings
         x := extop(x, 1):
         y := extop(y, 1):
         // convert the strings to a list/set of characters
         x := [x[i] $ i = 0 .. length(x) - 1];
         y := {y[i] $ i = 0 .. length(y) - 1};
         // remove all characters in y from x
         for char in y do
           x := subs(x, char = null());
         end_for:
         // concat the remaining characters in x
         myString::new(_concat(op(x)))
       end_proc:

       setuserinfo(myString::_subtract, 10):

Now, `myString` objects can be subtracted:

    >> myString("This is a string") - myString("is")

          Info: myString::_subtract called with the arguments:, This is \
          a string, is

                                    Th  a trng

In the following, `y` is the first term that is an element of a library domain with a `"_subtract"` slot. This slot is called, converts `xyz` to an element of `myString`, and removes the character `y`:

    >> xyz - y

          Info: myString::_subtract called with the arguments:, xyz, y

                                        xz

The following `xyz - x - y` = `(xyz - x) - y` calls the `"_subtract"` method twice:

    >> xyz - x - y

          Info: myString::_subtract called with the arguments:, xyz, x
          Info: myString::_subtract called with the arguments:, yz, y

                                         z

    >> delete myString, x, y:

#### Changes

- no changes

Do you have questions or comments?
Copyright © SciFace Software GmbH & Co. KG 2000