## `op` -- the operands of an object

#### Introduction

`op(`object`)` returns all operands of the object.

`op(`object, i`)` returns the `i`-th operand.

`op(`object, i..j`)` returns the `i`-th to `j`-th operands.

#### Call(s)

`op(object)`
`op(object, i)`
`op(object, i..j)`
`op(object, [i1, i2...])`

#### Parameters

`object` | - | an arbitrary MuPAD object
`i, j` | - | nonnegative integers
`i1, i2, ...` | - | nonnegative integers or ranges of such integers

#### Returns

a sequence of operands or the requested operand. `FAIL` is returned if no corresponding operand exists.

### Overloadable:

`object`

#### Related Functions

`_index`, `contains`, `extnops`, `extop`, `extsubsop`, `map`, `new`, `nops`, `select`, `split`, `subsop`, `zip`

#### Details

- MuPAD objects are composed of simpler parts: the ``operands''. The function `op` is the tool to decompose objects and to extract individual parts. The actual definition of an operand depends on the type of the object. The 'Background' section below explains the meaning for some of the basic data types.
- `op(`object`)` returns a sequence of all operands except the 0-th one. This call is equivalent to `op(object, 1..nops(object))`. Cf. example 1.
- `op(`object, i`)` returns the `i`-th operand. Cf. example 2.
- `op(`object, i..j`)` returns the `i`-th to `j`-th operands as an expression sequence; `i` and `j` must be nonnegative integers with `i` smaller or equal to `j`. This sequence is equivalent to ``op(`object, k`)` $k = i..j`. Cf. example 3.
- `op(`object, [i1, i2, ...]`)` is an abbreviation for the recursive call
  `op(`...`op(``op(`object, i1`)`, i2`)`, ...`)` if `i1, i2, ...` are integers.

  A call such as `op(`object, [i..j, i2]`)` with integers `i < j` corresponds to
  `map(op(object, i..j), op, i2)`. Cf. example 4.

- `op` returns `FAIL` if the specified operand does not exist. Cf. example 5.
- Expressions of domain type `DOM_EXPR` and arrays have a 0-th operand.
  - For expressions, this is ``the operator'' connecting the other operands. In particular, for symbolic function calls, it is the name of the function.
  - For an array, the 0-th operand is a sequence consisting of an integer (the dimension of the array) and a range for each array index.
  Other basic data types such as lists or sets do not have a 0-th operand. Cf. example 6.
- For library domains, `op` is overloadable. In the `"`op" method, the internal representation can be accessed with `extop`. It is sufficient to handle the cases ``op`(x)`, ``op`(x, i)`, and ``op`(x, i..j)` in the overloading method, the call ``op`(x, [i1, i2, ...])` needs not be considered. Cf. example 7.
- `op` is not overloadable for kernel domains.
- `op` is a function of the system kernel.

#### Example 1

The call `op(`object`)` returns all operands:

    >> op([a, b, c, [d, e], x + y])

                              a, b, c, [d, e], x + y

    >> op(a + b + c^d)

                                            d
                                     a, b, c

    >> op(f(x1, x2, x3))

                                    x1, x2, x3

#### Example 2

The call `op(`object, i`)` extracts a single operand:

    >> op([a, b, c, [d, e], x + y], 4)

                                      [d, e]

    >> op(a + b + c^d, 3)

                                         d
                                        c

    >> op(f(x1, x2, x3), 2)

                                        x2

#### Example 3

The call `op(`object, i..j`)` extracts a range of operands:

    >> op([a, b, c, [d, e], x + y], 3..5)

                                 c, [d, e], x + y

    >> op(a + b + c^d, 2..3)

                                           d
                                       b, c

    >> op(f(x1, x2, x3), 2..3)

                                      x2, x3

A range may include the 0-th operand if it exists:

    >> op(a + b + c^d, 0..2)

                                    _plus, a, b

    >> op(f(x1, x2, x3), 0..2)

                                     f, x1, x2

#### Example 4

The call `op(`object, [i1, i2, ...]`)` specifies suboperands:

    >> op([a, b, c, [d, e], x + y], [4, 1])

                                         d

    >> op(a + b + c^d, [3, 2])

                                         d

    >> op(f(x1, x2, x3 + 17), [3, 2])

                                        17

Also ranges of suboperands can be specified:

    >> op([a, b, c, [d, e], x + y], [4..5, 2])

                                       e, y

    >> op(a + b + c^d, [2..3, 1])

                                       b, c

    >> op(f(x1, x2, x3 + 17), [2..3, 1])

                                      x2, x3

#### Example 5

Nonexisting operands are returned as `FAIL`:

    >> op([a, b, c, [d, e], x + y], 8), op(a + b + c^d, 4),
       op(f(x1, x2, x3), 4)

                                 FAIL, FAIL, FAIL

#### Example 6

For expressions of type `DOM_EXPR`, the 0-th operand is ``the operator'' connecting the other operands:

    >> op(a + b + c, 0), op(a*b*c, 0), op(a^b, 0), op(a[1, 2], 0)

                           _plus, _mult, _power, _index

For symbolic function calls, it is the name of the function:

    >> op(f(x1, x2, x3), 0), op(sin(x + y), 0), op(besselJ(0, x), 0)

                                  f, sin, besselJ

The 0-th operand of an array is a sequence consisting of the dimension of the array and a range for each array index:

    >> op(array(3..100), 0)

                                     1, 3..100

    >> op(array(1..2, 1..3, 2..4), 0)

                                3, 1..2, 1..3, 2..4

No 0-th operand exists for other kernel domains:

    >> op([1, 2, 3], 0), op({1, 2, 3}, 0), op(table(1 = y), 0)

                                 FAIL, FAIL, FAIL

#### Example 7

For library domains, `op` is overloadable. First, a new domain `d` is defined via `newDomain`. The `"new"` method serves for creating elements of this type. The internal representation of the domain is a list of all arguments of this `"new"` method:

    >> d := newDomain("d"):  d::new := () -> new(dom, [args()]):

The `"op"` method of this domain is defined. It is to return the elements of a sorted copy of the internal list which is accessed via `extop`:

    >> d::op := proc(x, i = null())
                  local internalList;
                begin
                  internalList := extop(x, 1);
                  op(sort(internalList), i)
                end_proc:

By overloading, this method is called when the operands of an object of type `d` are requested via `op`:

    >> e := d(3, 7, 1):  op(e);  op(e, 2);  op(e, 1..2)

                                      1, 3, 7

                                         3

                                       1, 3

    >> delete d, e:

#### Example 8

Identifiers, integers, real floating point numbers, character strings, and the Boolean constants are ``atomic'' objects. The only operand is the object itself:

    >> op(x), op(17), op(0.1234), op("Hello World!")

                           x, 17, 0.1234, "Hello World!"

For rational numbers, the operands are the numerator and the denominator:

    >> op(17/3)

                                       17, 3

For complex numbers, the operands are the real part and the imaginary part:

    >> op(17 - 7/3*I)

                                     17, -7/3

#### Example 9

For sets, `op` returns the elements according to the internal order. Note that this order may differ from the ordering with which sets are printed on the screen:

    >> s := {1, 2, 3}

                                     {1, 2, 3}

    >> op(s)

                                      3, 2, 1

Indexed access to set elements uses the ordering visible on the screen:

    >> s[1], s[2], s[3]

                                      1, 2, 3

Note that access to set elements via `op` is much faster than indexed calls:

    >> s := {sqrt(i) $ i = 1..500}:
       time([op(s)])/time([s[i] $ i = 1..nops(s)]);

                                       1/364

    >> delete s:

#### Example 10

The operands of a list are its entries:

    >> op([a, b, c, [d, e]])

                                  a, b, c, [d, e]

    >> op([[a11, a12], [a21, a22]], [2, 1])

                                        a21

#### Example 11

Internally, the operands of an array form a ``linear'' sequence containing all entries:

    >> op(array(1..2, 1..2, [[11, 12], [21, 22]]))

                                  11, 12, 21, 22

Undefined entries are returned as `NIL`:

    >> op(array(1..2, 1..2))

                                NIL, NIL, NIL, NIL

#### Example 12

The operands of a table consist of equations relating the indices and the corresponding entries:

    >> T := table((1, 2) = x + y, "diff(sin)" = cos, a = b)

                               table(
                                 a = b,
                                 "diff(sin)" = cos,
                                 (1, 2) = x + y
                               )

    >> op(T)

                     a = b, "diff(sin)" = cos, (1, 2) = x + y

    >> delete T:

#### Example 13

Expression sequences are not flattened:

    >> op((a, b, c), 2)

                                         b

Note, however, that the arguments passed to `op` are evaluated. In the following call, evaluation of `x` flattens this object:

    >> x := hold((1, 2), (3, 4)):  op(x, 1)

                                         1

Use `val` to prevent simplification of `x`:

    >> op(val(x), 1)

                                       1, 2

    >> delete x:

#### Background

- We explain the meaning of ``operands'' for some basic data types:
  - Identifiers, integers, real floating point numbers, character strings, as well as the Boolean constants are ``atomic'' objects. They have only one operand: the object itself. Cf. example 8.
  - A rational number of type `DOM_RAT` has two operands: the numerator and the denominator. Cf. example 8.
  - A complex number of type `DOM_COMPLEX` has two operands: the real part and the imaginary part. Cf. example 8.
  - The operands of a set are its elements.

    Note that the ordering of the elements as printed on the screen does not necessarily coincide with the internal ordering referred to by `op`. Cf. example 9.

  - The operands of a list are its elements. Cf. example 10.
  - The operands of arrays are its entries. Undefined entries are returned as `NIL`. Cf. the examples 11 and 6.
  - The operands of tables are the equations associating an index with the corresponding entry. Cf. example 12.
  - The operands of an expression sequence are its elements. Note that such sequences are not flattened by `op`. Cf. example 13.
  - The operands of a symbolic function call such as `f(x, y, ...)` are the arguments `x`, `y` etc. The function name `f` is the 0-the operand.
  - In general, the operands of expressions of type `DOM_EXPR` are given by their internal representation. There is a 0-th operand (``the operator'') corresponding to the type of the expression. Internally, the operator is a system function, the expression corresponds to a function call. E.g., `a + b + c` has to be interpreted as `_plus(a, b, c)`, a symbolic indexed call such as `A[i, j]` corresponds to `_index(A, i, j)`. The name of the system function is the 0-th operand (i.e., `_plus` and `_index` in the previous examples), the arguments of the function call are the further operands.

#### Changes

- no changes

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