## `and, or, not` -- Boolean operators

#### Introduction

`b1 and b2` represents the logical 'and' of the Boolean expressions `b1`, `b2`.

`b1 or b2` represents the logical 'or' of the Boolean expressions `b1`, `b2`.

`not b` represents the logical negation of the Boolean expression `b`.

#### Call(s)

b1 and b2 `_and(b1, b2...)`
b1 or b2 `_or(b1, b2...)`
not b `_not(b)`

#### Parameters

`b, b1, b2, ...` | - | Boolean expressions

#### Returns

a Boolean expression.

### Overloadable:

`b`, `b1`, `b2`, `...`

#### Related Functions

`_lazy_and`, `_lazy_or`, `bool`, `is`, `FALSE`, `TRUE`, `UNKNOWN`

#### Details

- MuPAD uses a three state logic with the Boolean constants `TRUE`, `FALSE`, and `UNKNOWN`. These are processed as follows:

  `and` | `TRUE` | `FALSE` | `UNKNOWN`
  `TRUE` | `TRUE` | `FALSE` | `UNKNOWN`
  `FALSE` | `FALSE` | `FALSE` | `FALSE`
  `UNKNOWN` | `UNKNOWN` | `FALSE` | `UNKNOWN`

  `or` | `TRUE` | `FALSE` | `UNKNOWN`
  `TRUE` | `TRUE` | `TRUE` | `TRUE`
  `FALSE` | `TRUE` | `FALSE` | `UNKNOWN`
  `UNKNOWN` | `TRUE` | `UNKNOWN` | `UNKNOWN`

  `not TRUE = FALSE`, `not FALSE = TRUE`, `not UNKNOWN = UNKNOWN` .
- Boolean expressions may be composed of these constants as well as of arbitrary arithmetical expressions. Typically, equations such as `x = y` and inequalities such as `x <> y`, `x < y`, `x <= y` etc. are used to construct Boolean expressions.
- `_and(b1, b2, ...)` is equivalent to `b1 and b2 and ...`. This expression represents `TRUE` if each single expression evaluates to `TRUE`. It represents `FALSE` if at least one expression evaluates to `FALSE`. It represents `UNKNOWN` if at least one expression evaluates to `UNKNOWN` and all others evaluate to `TRUE`.

  `_and()` returns `TRUE`.

- `_or(b1, b2, ...)` is equivalent to `b1 or b2 or ...`. This expression represents `FALSE` if each single expression evaluates to `FALSE`. It represents `TRUE` if at least one expression evaluates to `TRUE`. It represents `UNKNOWN` if at least one expression evaluates to `UNKNOWN` and all others evaluate to `FALSE`.

  `_or()` returns `FALSE`.

- `_not(b)` is equivalent to `not b`.
- Combinations of the constants `TRUE`, `FALSE`, `UNKNOWN` inside a Boolean expression are simplified automatically. However, symbolic Boolean subexpressions, equalities, and inequalities are not evaluated and simplified by `and`, `or`, `not`. Use `bool` to evaluate such expressions to one of the Boolean constants. Note, however, that `bool` can evaluate inequalities `x < y`, `x <= y` etc. only if they are composed of numbers of type `Type::Real`. Cf. example 2.

  Use `simplify` with the option `logic` to simplify expressions involving symbolic Boolean subexpressions. Cf. example 3.

- The precedences of `and`, `or`, `not` are as follows: The operator `not` is stronger binding than `and`, i.e,
  `not b1 and b2` = `(not b1) and b2`.
  The operator `and` is stronger binding than `or`, i.e.,
  `b1 and b2 or b3` = `(b1 and b2) or b3`.
  If in doubt, use brackets to make sure that the expression is parsed as desired.
- Further logical operators can be implemented easily by the user. Cf. example 5.
- In the conditional context of `if`, `repeat`, and `while` statements, Boolean expressions are evaluated via ``lazy evaluation'' (see `_lazy_and`, `_lazy_or`). In any other context, all operands are evaluated.
- `_and` is a function of the system kernel.
- `_or` is a function of the system kernel.
- `_not` is a function of the system kernel.

#### Example 1

Combinations of the Boolean constants `TRUE`, `FALSE`, and `UNKNOWN` are simplified automatically to one of these constants:

    >> TRUE and not (FALSE or TRUE)

                                       FALSE

    >> FALSE and UNKNOWN, TRUE and UNKNOWN

                                  FALSE, UNKNOWN

    >> FALSE or UNKNOWN, TRUE or UNKNOWN

                                   UNKNOWN, TRUE

    >> not UNKNOWN

                                      UNKNOWN

#### Example 2

The operators `and`, `or`, `not` simplify subexpressions that evaluate to the constants `TRUE`, `FALSE`, `UNKNOWN`.

    >> b1 or b2 and TRUE

                                     b1 or b2

    >> FALSE or ((not b1) and TRUE)

                                      not b1

    >> b1 and (b2 or FALSE) and UNKNOWN

                               UNKNOWN and b1 and b2

    >> FALSE or (b1 and UNKNOWN) or x < 1

                              UNKNOWN and b1 or x < 1

    >> TRUE and ((b1 and FALSE) or (b1 and TRUE))

                                        b1

However, equalities and inequalities are not evaluated:

    >> (x = x) and (1 < 2) and (2 < 3) and (3 < 4)

                        x = x and 1 < 2 and 2 < 3 and 3 < 4

Boolean evaluation is enforced via `bool`:

    >> bool(%)

                                       TRUE

Note that `bool` can compare only real numbers of syntactical type `Type::Real`:

    >> bool(1 < 2 and PI < sqrt(10))

          Error: Can't evaluate to boolean [_less]

#### Example 3

Expressions involving symbolic Boolean subexpressions are not simplified by `and`, `or`, `not`. Simplification has to be requested explicitly via the function `simplify`:

    >> (b1 and b2) or (b1 and (not b2)) and (1 < 2)

                       b1 and b2 or b1 and not b2 and 1 < 2

    >> simplify(%, logic)

                                        b1

#### Example 4

The Boolean functions `_and` and `_or` accept arbitrary sequences of Boolean expressions. The following call uses `isprime` to check whether all elements of the given set are prime:

    >> Set := {1987, 1993, 1997, 1999, 2001}:
       _and(isprime(i) $ i in Set)

                                       FALSE

The following call checks whether at least one of the numbers is prime:

    >> _or(isprime(i) $ i in Set)

                                       TRUE

    >> delete Set:

#### Example 5

The following function implements the logical 'exclusive or':

    >> exor := (b1, b2) -> (b1 or b2) and not (b1 and b2):

It satisfies the following logical rules:

    >> for b1 in [TRUE, FALSE, UNKNOWN] do
         for b2 in [TRUE, FALSE, UNKNOWN] do
           print(hold(exor)(b1, b2) = exor(b1, b2))
         end_for
       end_for:

                             exor(TRUE, TRUE) = FALSE

                             exor(TRUE, FALSE) = TRUE

                           exor(TRUE, UNKNOWN) = UNKNOWN

                             exor(FALSE, TRUE) = TRUE

                            exor(FALSE, FALSE) = FALSE

                          exor(FALSE, UNKNOWN) = UNKNOWN

                           exor(UNKNOWN, TRUE) = UNKNOWN

                          exor(UNKNOWN, FALSE) = UNKNOWN

                         exor(UNKNOWN, UNKNOWN) = UNKNOWN

The following command creates an operator `exor`, such that `b1 exor b2` calls `exor(b1, b2)`:

    >> operator("exor", exor, Binary, 50): TRUE exor FALSE

                                       TRUE

    >> operator("exor", Delete): delete exor, b1, b2:

#### Changes

- no changes

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