has
-- check if an object occurs in
another objecthas(
object1, object2)
checks, whether
object2
occurs syntactically in object1
.
has(object1, object2)
has(object1, l)
object1, object2 |
- | arbitrary MuPAD objects |
l |
- | a list or a set |
object1
_in
, _index
, contains
, hastype
, op
, subs
, subsex
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.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).object1
is a container, then has
checks whether object2
occurs in an entry of
object1
. See example 4.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
.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 6.
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.
has
is a function of the system kernel.The given expression has x
as an
operand:
>> has(x + y + z, x)
TRUE
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)
FALSE
However, has
also finds objects in the
0th operand of a subexpression:
>> has(x + sin(x), sin)
TRUE
Every object occurs in itself:
>> has(x, x)
TRUE
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))
FALSE, TRUE
Complex numbers are not regarded as atomic objects:
>> has(2 + 5*I, 2), has(2 + 5*I, 5), has(2 + 5*I, I)
TRUE, TRUE, TRUE
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)
FALSE, FALSE, TRUE
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])
TRUE
0th operands of subexpressions are checked as well:
>> has((a + b)*c, {_plus, _mult})
TRUE
has
works for lists, sets, tables, and arrays:
>> has([sin(f(a) + 2), cos(x), 3], {f, g})
TRUE
>> has({a, b, c, d, e}, {a, z})
TRUE
>> has(array(1..2, 1..2, [[1, 2], [3, 4]]), 2)
TRUE
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)
TRUE, FALSE
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)
TRUE, TRUE, TRUE
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)
TRUE
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];
new(T, 1, 2) [new(T, 1, 2), 3]
>> has(f, e), has(f, new(T, 1))
TRUE, FALSE
If the first argument of has
belongs to a
domain without a "
has" slot,
then has
always returns FALSE
:
>> has(e, 1)
FALSE
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)
TRUE, FALSE
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)
TRUE, TRUE