Check a mathematical property of an expression
This functionality does not run in MATLAB.
is(cond) is(ex, set)
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.
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.
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)
is can derive certain facts even when no properties were assumed explicitly:
is(x > x + 1), is(abs(x) >= 0)
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: Cannot evaluate to Boolean. [_leequal]
bool(sin(10^20) > 0)
Error: Cannot evaluate to Boolean. [_less]
is(exp(5), Type::Real), is(PI, Type::PosInt)
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)
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)
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)
Error: Cannot 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:
assume(x >= 0 and x <= 1): is(x in Dom::Interval([0, 1])), is(x in R_)
unassume(x): solutionset := solve(sin(x) = 0, x)
is can be used to check whether an expression is contained in this set:
is(20*PI in solutionset), is(PI/2 in solutionset)