Check if an object occurs in another object

This functionality does not run in MATLAB.

has(`object1`

,`object2`

) has(`object1`

,`l`

)

`has(object1, object2)`

checks, whether `object2`

occurs
syntactically in `object1`

.

`has`

is a fast test for the existence of sub-objects
or subexpressions. It works syntactically, i.e., mathematically equivalent
objects are considered to be equal only if they are syntactically
identical. See Example 2.

If `object1`

is an expression,
then `has(object1, object2)`

tests whether `object1`

contains `object2`

as
a subexpression. Only complete subexpressions and objects occurring
in the 0th operand of a subexpression
are found (see Example 1).

If `object1`

is a container, then `has`

checks
whether `object2`

occurs in an entry of `object1`

.
See Example 5.

In this context, a floating-point interval is
considered a container for (an infinite number of) complex numbers
and `has`

checks whether a given number is *inside* the
interval. See Example 4.

If the second argument is a list or
a set `l`

, then `has`

returns `TRUE`

if
at least one of the elements in `l`

occurs in `object1`

(see Example 3). In particular, if `l`

is
the empty list or the empty set, then the return value is `FALSE`

.

If `object1`

is an element of a domain with
a `"has"`

slot, then the slot routine is called with
the same arguments, and its result is returned. If the domain does
not have such a slot, then `FALSE`

will be returned. See Example 7.

If `has`

is called with a list or set as second
argument, then the `"has"`

slot of the domain of `object1`

is
called for each object of the list or the set. When the first object
is found that occurs in `object1`

, the evaluation
is terminated and `TRUE`

is returned. If none of the objects
occurs in `object1`

, `FALSE`

will be returned.

The given expression has `x`

as an operand:

has(x + y + z, x)

Note that `x + y`

is not a complete subexpression.
Only `x`

, `y`

, `z`

and ```
x
+ y + z
```

are complete subexpressions:

has(x + y + z, x + y)

However, `has`

also finds objects in the 0th
operand of a subexpression:

has(x + sin(x), sin)

Every object occurs in itself:

has(x, x)

`has`

works in a purely syntactical fashion.
Although the two expressions `y*(x + 1)`

and ```
y*x
+ y
```

are mathematically equivalent, they differ syntactically:

has(sin(y*(x + 1)), y*x + y), has(sin(y*(x + 1)), y*(x + 1))

Complex numbers are not regarded as atomic objects:

has(2 + 5*I, 2), has(2 + 5*I, 5), has(2 + 5*I, I)

In contrast, rational numbers are considered to be atomic:

has(2/3*x, 2), has(2/3*x, 3), has(2/3*x, 2/3)

If the second argument is a list or a set, `has`

checks
whether one of the entries occurs in the first argument:

has((x + y)*z, [x, t])

0th operands of subexpressions are checked as well:

has((a + b)*c, {_plus, _mult})

On floating-point intervals, `has`

performs
a containment check, not just testing the borders:

has(1...3, 1)

has(1...3, 2.7182), has(1...3, exp(1)), has(1...3, PI)

has(1...(3+I), [2, ln(3)])

`has`

works for lists, sets, tables, arrays, and hfarrays:

has([sin(f(a) + 2), cos(x), 3], {f, g})

has({a, b, c, d, e}, {a, z})

has(array(1..2, 1..2, [[1, 2], [3, 4]]), 2)

For an array `A`

, the command `has(A,NIL)`

checks
whether the array has any uninitialized entries:

has(array(1..2, 1 = x), NIL), has(array(1..2, [2, 3]), NIL)

For tables, `has`

checks indices, entries,
as well as the internal operands of a table, given by equations of
the form `index=entry`

:

T := table(a = 1, b = 2, c = 3): has(T, a), has(T, 2), has(T, b = 2)

`has`

works syntactically. Although the variable `x`

does
not occur mathematically in the constant polynomial `p`

in
the following example, the identifier `x`

occurs
syntactically in `p`

, namely, in the second operand:

delete x: p := poly(1, [x]): has(p, x)

The second argument may be an arbitrary MuPAD^{®} object, even
from a user-defined domain:

T := newDomain("T"): e := new(T, 1, 2); f := [e, 3];

has(f, e), has(f, new(T, 1))

If the first argument of `has`

belongs to a domain without
a `"has"`

slot, then `has`

always
returns `FALSE`

:

has(e, 1)

Users can overload`has`

for
their own domains.
For illustration, we supply the domain `T`

with a `"has"`

slot,
which puts the internal operands of its first argument in a list and
calls `has`

for the list:

T::has := (object1, object2) -> has([extop(object1)], object2):

If we now call `has`

with the object `e`

of
domain type `T`

, the slot routine `T::has`

is
invoked:

has(e, 1), has(e, 3)

The slot routine is also called if an object of domain type `T`

occurs
syntactically in the first argument:

has(f, 1), has(f, 3)

`object1`

Was this topic helpful?