-
-- subtract expressionsx - y
computes the difference of x
and
y
.
x - y _subtract(x, y)
x, y |
- | arithmetical expressions,
polynomials of type DOM_POLY , or sets |
an arithmetical expression, a polynomial, or a set.
x
, y
_invert
, _negate
, ^
, /
, *
, +
, poly
, Pref::keepOrder
x - y
is equivalent to the function call
_subtract(x, y)
.Type::Numeric
, the difference is
returned as a number.x
nor y
are elements of library domains with
"_subtract"
methods, x - y
is internally
represented as x + y*(-1)
= _plus(x, _mult(y,
-1))
.x
or y
is an element of a domain with
a slot "_subtract"
, then this
method is used to compute x - y
. Many library domains overload the
-
operator by an appropriate "_subtract"
slot. Differences are processed as follows:
x - y
is searched for elements of library domains from
left to right. Let z
(either x
or
y
) be the first term that is not of one of the basic types
provided by the kernel (numbers, expressions, etc.). If the domain
d
= z::dom
= domtype(z)
has a slot "_subtract"
, it is called in the
form d::_subtract(x, y)
. The result returned by
d::_subtract
is the result of x - y
.
Users should implement the slot d::_subtract
of their
domains d
according to the following convention:
x
and y
are elements of
d
, an appropriate difference of type d
should
be returned.x
or y
cannot be converted to
an element of d
, the slot should return FAIL
.x
or y
is
not of type d
, but can be converted to type
d
. This object should be converted only if the
mathematical semantics is obvious to any user who uses this domain as a
'black box' (e.g., integers may be regarded as rational numbers because
of the natural mathematical embedding). If in doubt, the
"_subtract"
method should return FAIL
instead of using implicit
conversions. If implicit conversions are used, they must be
well-documented.Most of the library domains in MuPAD's standard installation comply with this convention.
DOM_POLY
are subtracted by
-
, if they have the same indeterminates and the same
coefficient ring.X
, Y
, the difference
X - Y
is the set {x - y; x in X; y in Y}._subtract
is a function of the system kernel.The difference of numbers is simplified to a number:
>> 1234 - 234, I + x - y - 4*I, 3 + x - y - 29/3
1000, x - y - 3 I, x - y - 20/3
Internally, a symbolic difference x - y
is
represented as the sum x + y*(-1)
:
>> type(x - y), op(x - y, 0), op(x - y, 1), op(x - y, 2)
"_plus", _plus, x, -y
>> op(op(x - y, 2))
y, -1
Polynomials of type DOM_POLY
are subtracted by
-
, if they have the same indeterminates and the same
coefficient ring:
>> poly(x^2 + 1, [x]) - poly(x^2 + x - 1, [x])
poly(- x + 2, [x])
Symbolic differences are returned if the indeterminates or the coefficient rings do not match:
>> poly(x, [x]) - poly(x, [x, y])
poly(x, [x]) + poly((-1) x, [x, y])
>> poly(x, [x]) - poly(x, [x], Dom::Integer)
poly(x, [x]) + poly((-1) x, [x], Dom::Integer)
For finite sets X
, Y
, the
difference X - Y
is the set {x - y; x in X; y in
Y}:
>> {a, b, c} - {1, 2}
{a - 1, a - 2, b - 1, b - 2, c - 1, c - 2}
Various library domains such as matrix domains overload
_subtract
:
>> x := Dom::Matrix(Dom::Integer)([2, 2]): y := Dom::Matrix(Dom::Rational)([1, 3]): x - y, y - x
+- -+ +- -+ | 1 | | -1 | | |, | | | -1 | | 1 | +- -+ +- -+
If the terms in x - y
are of different
type, the first term x
tries to convert y
to
the data type of x
. If successful, the difference is of
the same type as x
. In the previous example,
x
and y
have different types (both are
matrices, but the component domains differ). Consequently, x -
y
and y - x
have different types, because they
inherit their type from the first term:
>> domtype(x - y), domtype(y - x)
Dom::Matrix(Dom::Integer), Dom::Matrix(Dom::Rational)
If x
does not succeed to convert
y
, then FAIL
is returned. In the following call, the component 2/3
cannot be converted to an integer:
>> y := Dom::Matrix(Dom::Rational)([2/3, 3]): x - y
FAIL
The matrix domain defines x - y
as x
+ (-y)
:
>> x::dom::_subtract
(x, y) -> dom::_plus(x, dom::_negate(y))
>> delete x, y:
This example demonstrates how to implement a slot "_subtract"
for a domain. The
following domain myString
is to represent character
strings. The difference x - y
of such strings is to remove
all characters in y
from x
.
The "new"
method uses expr2text
to convert any
MuPAD object to a string. This string is the internal
representation of elements of myString
. The
"print"
method turns this string into the screen
output:
>> myString := newDomain("myString"): myString::new := proc(x) begin if args(0) = 0 then x := "" end_if; case domtype(x) of myString do return(x); of DOM_STRING do return(new(dom, x)); otherwise return(new(dom, expr2text(x))); end_case end_proc: myString::print := x -> extop(x, 1):
Without a "_subtract"
method, the system
handles elements of this domain like any symbolic object:
>> x := myString(x): y := myString(y): x - y
x - y
Now, we implement the "_subtract"
method.
It checks all arguments. Arguments are converted if they are not of
type myString
. Generally, such an implicit conversion
should be avoided. In this case, however, any object has a
corresponding string representation via expr2text
and an implicit
conversion is implemented. Finally, the difference x - y
of myString
objects removes all characters in the string
y
from the string x
:
>> myString::_subtract := proc(x, y) local i, char; begin userinfo(10, "myString::_subtract called with ". "the arguments:", args()): // Convert all arguments to myString. if domtype(x) <> myString then x := myString::new(x) end_if; if domtype(y) <> myString then y := myString::new(y) end_if; // extract the internal strings x := extop(x, 1): y := extop(y, 1): // convert the strings to a list/set of characters x := [x[i] $ i = 0 .. length(x) - 1]; y := {y[i] $ i = 0 .. length(y) - 1}; // remove all characters in y from x for char in y do x := subs(x, char = null()); end_for: // concat the remaining characters in x myString::new(_concat(op(x))) end_proc: setuserinfo(myString::_subtract, 10):
Now, myString
objects can be
subtracted:
>> myString("This is a string") - myString("is")
Info: myString::_subtract called with the arguments:, This is \ a string, is Th a trng
In the following, y
is the first term that
is an element of a library domain with a "_subtract"
slot.
This slot is called, converts xyz
to an element of
myString
, and removes the character y
:
>> xyz - y
Info: myString::_subtract called with the arguments:, xyz, y xz
The following xyz - x - y
= (xyz - x)
- y
calls the "_subtract"
method twice:
>> xyz - x - y
Info: myString::_subtract called with the arguments:, xyz, x Info: myString::_subtract called with the arguments:, yz, y z
>> delete myString, x, y: