## `assume` -- attach a property to an identifier

#### Introduction

`assume(`x, prop`)` attaches the property `prop` to the identifier `x`.

`assume(`prop`)` sets a ``global property'' that is valid for all identifiers.

#### Call(s)

`assume(x, prop <, _and_or>)`
`assume(prop <, _and_or>)`
`assume(y rel z <, _and_or>)`

#### Parameters

`x` | - | an identifier or one of the expressions `Re(u)` or `Im(u)` with an identifier `u`
`prop` | - | a property
`_and_or` | - | either `_and` or `_or`. Without this optional argument, any previously attached property is overwritten by the new property. With `_and` or `_or`, existing properties are not deleted but logically combined with the new property by 'and' or 'or', respectively.
`y, z` | - | arithmetical expressions
`rel` | - | one of the relational operators `<`, `<=`, `=`, `<>`, `>=`, `>`

#### Returns

a property of type `Type::Property`.

#### Related Functions

`_assign`, `anames`, `getprop`, `is`, `property::hasprop`, `property::implies`, `Type`, `Type::Property`, `unassume`

#### Details

- Properties represent subsets of the complex plane. Attaching a property `prop` to an identifier `x` corresponds to the statement ``x` represents a number of the set `prop`'. Various pre-defined properties are installed in the `Type` library. Request `?properties` for a list of all available properties. By default, library functions regard identifiers as symbols representing complex numbers. For this reason, certain expressions such as `sign(1 + x^2)` cannot be simplified in any way unless `x` is restricted to some subset of the complex plane. E.g., if `x` is assumed to be a real number, the expression may be simplified to `sign(1 + x^2)` = `1`.

  Thus, properties help to simplify expressions. Various system functions react to properties and yield simpler results. Cf. example 7.

  Properties of identifiers are set via `assume`. Properties of expressions are queried by the functions `getprop` and `is`.

- `assume(`x, prop`)` attaches the property `prop` to the identifier `x`. Without `_and_or`, existing properties of `x` are overwritten.
- If the optional argument `_and` or `_or` is given, existing properties of `x`, `y`, or `z`, if any, are not overwritten, but logically combined with the new property via 'and' or 'or'. The resulting property is then attached to `x`, `y`, or `z`. Cf. example 2.
- It may happen that the resulting property cannot be represented explicitly. In this case, a weaker property is attached instead. Cf. example 8.
- `assume(``Re(u)`, prop`)` and `assume(``Im(u)`, prop`)` attach the property to the real and the imaginary part of the identifier `u`, respectively. Cf. example 3.
- In `assume(`y rel z`)`, at least one of `y` or `z` must be an identifier or of the form `Re(u)` or `Im(u)`. The other one may be an arbitrary arithmetical expression.

  The property representing the relation is attached to the identifier(s) `y` and/or `z`. In particular, if both `y` and `z` are identifiers or of the form `Re(u)`, `Im(u)`, then any existing property of both `y` and `z` are overwritten, unless `_and_or` is specified.

  If `rel` is one of `<`, `>`, `<=` or `>=`, and `y` or `z` is an identifier or `Re(u)`, `Im(u)`, then the property `Type::Real` is implicitly attached to `y` and/or `z`.

  Cf. example 4.

- The call `assume(`prop <, _and_or>`)` defines a ``global property'' `prop` that is assumed to hold for all identifiers. When querying properties of expressions (e.g., via `is`), this global property is logically combined with the properties of individual identifiers via `and'.

  The argument `_and_or` indicates that an existing global property is combined logically with the new global property. The protected identifier `Global` is used to store global properties.

  The calls `assume(`prop <, _and_or>`)` and `assume(`Global, prop <, _and_or>`)` are equivalent.

  Cf. example 5.

- Properties of an identifier `x` are deleted via `unassume(x)` or `delete x`. The global property is deleted via `unassume()` or `unassume(Global)` (this does not affect the individual properties of identifiers).

  When assigning a value to an identifier with properties, the assigned value needs not be consistent in any way with previously assigned properties. Properties are overwritten by an assignment. Cf. example 6.

#### Example 1

The following command marks the identifier `n` as an integer:

    >> assume(n, Type::Integer)

                                   Type::Integer

MuPAD can now derive that `n^2` is a nonnegative integer:

    >> getprop(n^2), is(n^2, Type::NonNegInt)

                               Type::NonNegInt, TRUE

Also other system functions react to this property:

    >> abs(n^2 + 1), simplify(sin(2*n*PI))

                                      2
                                     n  + 1, 0

    >> delete n:

#### Example 2

Using `_and` or `_or`, existing properties are not deleted, but combined with new properties:

    >> assume(n, Type::NonNegInt)

                                  Type::NonNegInt

    >> assume(n, Type::NegInt, _or)

                                   Type::Integer

    >> assume(n, Type::Positive, _and)

                                   Type::PosInt

    >> delete n:

#### Example 3

Properties of the real and the imaginary part of an identifier can be defined separately:

    >> assume(Re(z) > 0), assume(Im(z) < 0, _and)

                        Re(.) > 0, Re(.) > 0 and Im(.) < 0

    >> abs(Re(z)), sign(Im(z))

                                     Re(z), -1

    >> is(z, Type::Real), is(z > 0)

                                   FALSE, FALSE

    >> delete z:

#### Example 4

Assuming relations such as `x > y` affects the properties of both identifiers:

    >> assume(x > y)

                                        < x

Properties can be queried by `getprop`. Both `x` and `y` have properties:

    >> getprop(x), getprop(y)

                                     > y, < x

In the next command, `_and` is used to prevent that the previous property of `y` is deleted: `y` is assumed to be greater than `0` and less than `x`:

    >> assume(y > 0, _and)

                               ]0, x[ of Type::Real

    >> is(x^2 >= y^2)

                                       TRUE

The second `assume` in the next example without the operator `_and` would have overwritten the property '`> 0`' of `x`. With `_and`, the assumption `x >= 0` stays valid:

    >> unassume(y):
       assume(x >= 0): assume(y >= x, _and): is(y >= 0)

                                       TRUE

Relations such as `x > y` imply that the involved identifiers are real:

    >> is(x, Type::Real), is(y, Type::Real)

                                    TRUE, TRUE

    >> delete x, y:

#### Example 5

In the next example, a global property is defined:

    >> assume(Type::NonNegative)

                                 Type::NonNegative

Now, any identifier is assumed to be nonnegative and real:

    >> Re(x), Im(y), sign(1 + z^2)

                                      x, 0, 1

Individual assumptions may be attached to identifiers independent of the global property:

    >> assume(x, Type::Integer)

                                   Type::Integer

Deductions of properties via `getprop` or `is` combine individual properties with the global property:

    >> getprop(x), is(x < 0)

                              Type::NonNegInt, FALSE

Also the global property can be modified using `_and` and `_or`:

    >> assume(Type::Negative, _or)

                                    Type::Real

To define a relation as a global property, the identifier `Global` must be used:

    >> assume(Global > 0): is(x + y + z > 0)

                                       TRUE

The global property can only be deleted with the call `unassume()`:

    >> delete x: unassume():

#### Example 6

`_assign` and `:=` do not check the properties of an identifier. All properties are overwritten:

    >> assume(a > 0): a := -2: a, getprop(a)

                                      -2, -2

    >> delete a:

#### Example 7

Some system functions take properties of identifiers into account:

    >> assume(x > 0): abs(x), sign(x), Re(x), Im(x)

                                    x, 1, x, 0

The equation `ln(z1*z2) = ln(z1) + ln(z2)` does not hold for arbitrary `z1`, `z2` in the complex plane:

    >> expand(ln(z1*z2))

                                     ln(z1 z2)

However, this identity holds if at least one of the numbers is real and positive:

    >> assume(z1 > 0): expand(ln(z1*z2))

                                  ln(z1) + ln(z2)

    >> unassume(x): unassume(z1):

#### Example 8

If a combination of properties cannot be represented explicitly, `assume` may attach a weaker property to the identifier. In this example, the property ``a prime number or the negative of a prime number'' is generalized to the property ``integer unequal to zero'':

    >> assume(x, Type::Prime):
       assume(x, -Type::Prime, _or)

                         Type::Integer and not Type::Zero

    >> unassume(x):

#### Background

- `assume` is an exported function of the library `property`.

#### Changes

- The property mechanism was improved.

Do you have questions or comments?
Copyright © SciFace Software GmbH & Co. KG 2000