Documentation

# `is`

Check a mathematical property of an expression

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

```is(`cond`)
is(`ex`, `set`)
```

## Description

`is(cond)` checks whether the condition `cond` holds for all possible values.

`is(ex, set)` checks whether the expression `ex` lies in the set `set`.

The property mechanism helps to simplify expressions involving expressions that carry “mathematical properties”. The function `assume` allows to assume “assumptions” such as ``x` is a real number' or ``x` is an odd integer' to an identifier `x`, say. Arithmetical expressions involving `x` may inherit such properties. E.g., ``1 + x^2` is positive' if ``x` is a real number'. The function `is` is the basic tool for querying mathematical properties.

`is` queries the assumptions of all involved identifiers and checks whether the condition `cond` holds for all possible values. If this is the case, then `is` returns `TRUE`. If `is` derives that cond is not satisfied by any possible value it returns `FALSE`. Otherwise, `is` returns `UNKNOWN`.

If a relation is given to `is`, and the operands are complex numbers or identifiers with this property, `is` returns `FALSE`, because a relations holds only with real objects. Cf. Example 4.

It may happen that `is` returns `UNKNOWN`, although the queried property holds mathematically. Cf. Example 5.

In MuPAD®, there also exists the function `bool` to check a relation ```y rel z```. However, there are two main differences between `bool` and `is`:

1. `bool` produces an error if it cannot decide whether the relation holds or not; ```is(y rel z)``` returns `UNKNOWN` in this case.

2. `bool` does not take properties into account.

Cf. Example 3.

If `bool(y rel z)` returns `TRUE`, then so does ```is(y rel z)```. However, `is` is more powerful than `bool`, even when no properties are involved. Cf. Example 3. On the other hand, `is` is usually much slower than `bool`.

### Note

Be careful when using `is` in a condition of an `if` statement or a `for`, `while`, or `repeat` loop: these constructs cannot handle the value `UNKNOWN`. Use either ```is(...) = TRUE``` or a `case` statement. Cf. Example 6.

If `is` needs to check whether a constant symbolic expression is zero, then it may employ a heuristic numerical zero test based on floating-point evaluation. Despite internal numerical stabilization, this zero test may return the wrong answer in exceptional pathological cases; in such a case, `is` may return a wrong result as well.

## Examples

### Example 1

The identifier `x` is assumed to be an integer:

```assume(x, Type::Integer): is(x, Type::Integer), is(x > 0), is(x^2 >= 0)```
` `

The identifier `x` is assumed to be a positive real number:

```assume(x > 0): is(x > 1), is(x >= 0), is(x < 0)```
` `
`unassume(x):`

### Example 2

`is` can derive certain facts even when no properties were assumed explicitly:

`is(x > x + 1), is(abs(x) >= 0)`
` `
`is(Re(exp(x)), Type::Real)`
` `

### Example 3

For relations between numbers, `is` yields the same answers as `bool`:

`bool(1 > 0), is(1 > 0)`
` `

`is` resolves more constant symbolic expressions than `bool`:

```is(sqrt(14) <= sqrt(2)*sqrt(7)), is(sin(10^20) > 0), is(sqrt(2) > 1.41)```
` `
`bool(sqrt(14) <= sqrt(2)*sqrt(7))`
```Error: Unable to evaluate to Boolean. [_leequal] ```
`bool(sin(10^20) > 0)`
```Error: Unable to evaluate to Boolean. [_less] ```
`is(exp(5), Type::Real), is(PI, Type::PosInt)`
` `

### Example 4

In the next example a relation with complex objects is given, the returned value is `FALSE`:

`is(0 < I), is(I + 1 > I), is(1 + 2*I <= 2 + 3*I)`
` `

The identifier in the next example is assumed to be complex, but it could be real too:

```assume(x, Type::Complex): is(x > 0)```
` `

The next relation is false, either the identifier `x` is real, then the relation is false, or the identifiers is not real, then the comparison is illegal:

```unassume(x): is(x + 1 < x)```
` `
`unassume(x):`

### Example 5

Here are some examples where the queried property can be derived mathematically. However, the current implementation of `is` is not yet strong enough to derive the property:

```assume(x in Z_ and y in Z_ and x^2 + y^2 = 2); is(x > 1)```
` `
`unassume(x):`

### Example 6

Care must be taken when using `is` in `if` statements or `for`, `repeat`, `while` loops:

```myabs := proc(x) begin if is(x >= 0) then x elif is(x < 0) then -x else procname(x) end_if end_proc:```
`assume(x < 0): myabs(1), myabs(-2), myabs(x)`
` `

When the call of `is` returns `UNKNOWN`, an error occurs because `if` expects `TRUE` or `FALSE`:

`unassume(x): myabs(x)`
```Error: Unable to evaluate to Boolean. [if] Evaluating: myabs ```

The easiest way to achieve the desired functionality is a comparison of the result of `is` with `TRUE`:

```myabs := proc(x) begin if is(x >= 0) = TRUE then x elif is(x < 0) = TRUE then -x else procname(x) end_if end_proc:```
`myabs(x)`
` `
`delete myabs:`

### Example 7

`is` can handle sets returned by `solve`. These include intervals of type `Dom::Interval` and `R_` = `solvelib::BasicSet(Dom::Real)`:

```assume(x >= 0 and x <= 1): is(x in Dom::Interval([0, 1])), is(x in R_)```
` `

The following `solve` command returns the solution as an infinite parameterized set of type `Dom::ImageSet`:

`unassume(x): solutionset := solve(sin(x) = 0, x)`
` `
`domtype(solutionset)`
` `

`is` can be used to check whether an expression is contained in this set:

`is(20*PI in solutionset), is(PI/2 in solutionset)`
` `
`delete solutionset:`

## Parameters

 `cond` A condition `ex` arithmetical expression `set` A property representing a set of numbers (e.g., `Type::PosInt`) or a set returned by `solve`; such a set can be an element of `Dom::Interval`, `Dom::ImageSet`, `piecewise`, or one of `C_`, `R_`, `Q_`, `Z_`.