Documentation |
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 overloadhas 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)