Documentation

# `has`

Check if an object occurs in another object

MuPAD® notebooks will be removed in a future release. Use MATLAB® live scripts instead.

MATLAB live scripts support most MuPAD functionality, though there are some differences. For more information, see Convert MuPAD Notebooks to MATLAB Live Scripts.

## Syntax

```has(`object1`, `object2`)
has(`object1`, `l`)
```

## Description

`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.

## Examples

### Example 1

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)`

### Example 2

`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)`

### Example 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})`

### Example 4

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)])`

### Example 5

`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)```

### Example 6

`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)```

### Example 7

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)`

## Parameters

 `object1`, `object2` Arbitrary MuPAD objects `l` A list or a set

## Return Values

Either `TRUE` or `FALSE`

`object1`